From d12e347b6f650dec302aef80046202a88b660c44 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 19 Oct 2023 09:47:23 +0200 Subject: [PATCH 01/58] tst_QMetaEnum: add round-trip testing to valueToKeys() ... adding a bit of test coverage of keysToValue(). This is not intended as a reproducer for QTBUG-118240, because that is concerned with inputs valueToKeys() cannot produce. Manual conflict resolutions: - no QFlags::toInt() in Qt 5, cast to QFlags::Int intead, invoking QFlags::operator Int(). Task-number: QTBUG-118240 Change-Id: I5d772be4231717cdbb5d033b1f11ae31e4c57c0b Reviewed-by: Friedemann Kleint (cherry picked from commit 38994ab9accc9aecf1139eb02f7e5fc75fccceec) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit bd242a7d2da27a4b461ba9ed466b80baed2bad01) (cherry picked from commit f47a9d72e46a0d4b6d136e2002c2497e5b127924) (cherry picked from commit 5bb7c46e71904fafb9f10da19dcfb52b6421beda) --- tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp index 6ed0a6caa9a..9bd42788cee 100644 --- a/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp +++ b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp @@ -98,6 +98,10 @@ void tst_QMetaEnum::valuesToKeys() QMetaEnum me = QMetaEnum::fromType(); QCOMPARE(me.valueToKeys(windowFlags), expected); + bool ok = false; + using U = Qt::WindowFlags::Int; + QCOMPARE(U(me.keysToValue(expected, &ok)), U(windowFlags)); + QVERIFY(ok); } void tst_QMetaEnum::defaultConstructed() From 84e4342080f86e9e297438b6f29c17adddb055cc Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 8 Nov 2023 14:59:10 +0100 Subject: [PATCH 02/58] Fix WinRT/ARM build Since the latest harfbuzz update the WinRT ARMv7 MSVC 2019 build failed during the submodule update in CI with "hb-subset.cc : fatal error C1128: number of sections exceeded object file format limit: compile with /bigobj". Fix this by following the compiler's kind suggestion. Pick-to: 5.15.16 Fixes: QTBUG-118896 Change-Id: I65f7a4529b1b8a283209378d6af2a7f3c24366ca Reviewed-by: Fabian Kosmale --- src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index 8b201ac229f..d9f843ccdba 100644 --- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro +++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro @@ -26,6 +26,7 @@ DEFINES += HB_EXTERN= DEFINES += HAVE_ATEXIT unix: DEFINES += HAVE_PTHREAD HAVE_SCHED_H HAVE_SCHED_YIELD win32: DEFINES += HB_NO_WIN1256 +msvc:winrt: QMAKE_CXXFLAGS += /bigobj # prevent error C1128 #Workaround https://code.google.com/p/android/issues/detail?id=194631 android: DEFINES += _POSIX_C_SOURCE=200112L From d5d70450651eac4ed9c7fb8f1b6016be22131b0e Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Tue, 7 Nov 2023 21:28:10 +0100 Subject: [PATCH 03/58] SQLite: Update SQLite to v3.44.0 [ChangeLog][Third-Party Code] Updated SQLite to v3.44.0 Change-Id: Ibdf8a6e0baf3d2b1bf0f9ffb48e908e2691b6a8d Reviewed-by: Andy Shaw (cherry picked from commit c63a21ae5c3bf7d105ee79caa0d7a1f3fa14e1c2) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 9224284f7a593412efbf314d12d283e13e475931) (cherry picked from commit 9433dff701d663748f712eda1aa3b57728421003) (cherry picked from commit 061fb5ae76d73eb820884016cf326cba3585d829) --- src/3rdparty/sqlite/qt_attribution.json | 4 +- src/3rdparty/sqlite/sqlite3.c | 6460 +++++++++++++++-------- src/3rdparty/sqlite/sqlite3.h | 199 +- 3 files changed, 4298 insertions(+), 2365 deletions(-) diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json index 3508d9af185..5d16c702117 100644 --- a/src/3rdparty/sqlite/qt_attribution.json +++ b/src/3rdparty/sqlite/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Homepage": "https://www.sqlite.org/", - "Version": "3.43.2", - "DownloadLocation": "https://sqlite.org/2023/sqlite-amalgamation-3430200.zip", + "Version": "3.44.0", + "DownloadLocation": "https://sqlite.org/2023/sqlite-amalgamation-3440000.zip", "License": "Public Domain", "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." } diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index a1fbd604923..8f9309a8ba7 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.43.2. By combining all the individual C code files into this +** version 3.44.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** 310099cce5a487035fa535dd3002c59ac7f. +** 17129ba1ff7f0daf37100ee82d507aef7827. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -459,9 +459,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.43.2" -#define SQLITE_VERSION_NUMBER 3043002 -#define SQLITE_SOURCE_ID "2023-10-10 12:14:04 4310099cce5a487035fa535dd3002c59ac7f1d1bec68d7cf317fd3e769484790" +#define SQLITE_VERSION "3.44.0" +#define SQLITE_VERSION_NUMBER 3044000 +#define SQLITE_SOURCE_ID "2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -2440,7 +2440,7 @@ struct sqlite3_mem_methods { ** is stored in each sorted record and the required column values loaded ** from the database as records are returned in sorted order. The default ** value for this option is to never use this optimization. Specifying a -** negative value for this option restores the default behaviour. +** negative value for this option restores the default behavior. ** This option is only available if SQLite is compiled with the ** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. ** @@ -2615,7 +2615,7 @@ struct sqlite3_mem_methods { ** database handle, SQLite checks if this will mean that there are now no ** connections at all to the database. If so, it performs a checkpoint ** operation before closing the connection. This option may be used to -** override this behaviour. The first parameter passed to this operation +** override this behavior. The first parameter passed to this operation ** is an integer - positive to disable checkpoints-on-close, or zero (the ** default) to enable them, and negative to leave the setting unchanged. ** The second parameter is a pointer to an integer @@ -4268,6 +4268,7 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** text that describes the error, as either UTF-8 or UTF-16 respectively. +** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by @@ -5638,6 +5639,7 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); */ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); + /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines} @@ -6192,32 +6194,32 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to -** associate metadata with argument values. If the same value is passed to -** multiple invocations of the same SQL function during query execution, under -** some circumstances the associated metadata may be preserved. An example -** of where this might be useful is in a regular-expression matching -** function. The compiled version of the regular expression can be stored as -** metadata associated with the pattern string. +** associate auxiliary data with argument values. If the same argument +** value is passed to multiple invocations of the same SQL function during +** query execution, under some circumstances the associated auxiliary data +** might be preserved. An example of where this might be useful is in a +** regular-expression matching function. The compiled version of the regular +** expression can be stored as auxiliary data associated with the pattern string. ** Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data ** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument ** value to the application-defined function. ^N is zero for the left-most -** function argument. ^If there is no metadata +** function argument. ^If there is no auxiliary data ** associated with the function argument, the sqlite3_get_auxdata(C,N) interface ** returns a NULL pointer. ** -** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th -** argument of the application-defined function. ^Subsequent +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the +** N-th argument of the application-defined function. ^Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent -** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or -** NULL if the metadata has been discarded. +** sqlite3_set_auxdata(C,N,P,X) call if the auxiliary data is still valid or +** NULL if the auxiliary data has been discarded. ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, ** SQLite will invoke the destructor function X with parameter P exactly -** once, when the metadata is discarded. -** SQLite is free to discard the metadata at any time, including:
    +** once, when the auxiliary data is discarded. +** SQLite is free to discard the auxiliary data at any time, including:
      **
    • ^(when the corresponding function parameter changes)^, or **
    • ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the ** SQL statement)^, or @@ -6233,7 +6235,7 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** function implementation should not make any use of P after ** sqlite3_set_auxdata() has been called. ** -** ^(In practice, metadata is preserved between function calls for +** ^(In practice, auxiliary data is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** @@ -6243,10 +6245,67 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** ** These routines must be called from the same thread in which ** the SQL function is running. +** +** See also: [sqlite3_get_clientdata()] and [sqlite3_set_clientdata()]. */ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); +/* +** CAPI3REF: Database Connection Client Data +** METHOD: sqlite3 +** +** These functions are used to associate one or more named pointers +** with a [database connection]. +** A call to sqlite3_set_clientdata(D,N,P,X) causes the pointer P +** to be attached to [database connection] D using name N. Subsequent +** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P +** or a NULL pointer if there were no prior calls to +** sqlite3_set_clientdata() with the same values of D and N. +** Names are compared using strcmp() and are thus case sensitive. +** +** If P and X are both non-NULL, then the destructor X is invoked with +** argument P on the first of the following occurrences: +**
        +**
      • An out-of-memory error occurs during the call to +** sqlite3_set_clientdata() which attempts to register pointer P. +**
      • A subsequent call to sqlite3_set_clientdata(D,N,P,X) is made +** with the same D and N parameters. +**
      • The database connection closes. SQLite does not make any guarantees +** about the order in which destructors are called, only that all +** destructors will be called exactly once at some point during the +** database connection closing process. +**
      +** +** SQLite does not do anything with client data other than invoke +** destructors on the client data at the appropriate time. The intended +** use for client data is to provide a mechanism for wrapper libraries +** to store additional information about an SQLite database connection. +** +** There is no limit (other than available memory) on the number of different +** client data pointers (with different names) that can be attached to a +** single database connection. However, the implementation is optimized +** for the case of having only one or two different client data names. +** Applications and wrapper libraries are discouraged from using more than +** one client data name each. +** +** There is no way to enumerate the client data pointers +** associated with a database connection. The N parameter can be thought +** of as a secret key such that only code that knows the secret key is able +** to access the associated data. +** +** Security Warning: These interfaces should not be exposed in scripting +** languages or in other circumstances where it might be possible for an +** an attacker to invoke them. Any agent that can invoke these interfaces +** can probably also take control of the process. +** +** Database connection client data is only available for SQLite +** version 3.44.0 ([dateof:3.44.0]) and later. +** +** See also: [sqlite3_set_auxdata()] and [sqlite3_get_auxdata()]. +*/ +SQLITE_API void *sqlite3_get_clientdata(sqlite3*,const char*); +SQLITE_API int sqlite3_set_clientdata(sqlite3*, const char*, void*, void(*)(void*)); /* ** CAPI3REF: Constants Defining Special Destructor Behavior @@ -6879,7 +6938,7 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); /* -** CAPI3REF: Allowed return values from [sqlite3_txn_state()] +** CAPI3REF: Allowed return values from sqlite3_txn_state() ** KEYWORDS: {transaction state} ** ** These constants define the current transaction state of a database file. @@ -7011,7 +7070,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** ^Each call to the sqlite3_autovacuum_pages() interface overrides all ** previous invocations for that database connection. ^If the callback ** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer, -** then the autovacuum steps callback is cancelled. The return value +** then the autovacuum steps callback is canceled. The return value ** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might ** be some other error code if something goes wrong. The current ** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other @@ -7530,6 +7589,10 @@ struct sqlite3_module { /* The methods above are in versions 1 and 2 of the sqlite_module object. ** Those below are for version 3 and greater. */ int (*xShadowName)(const char*); + /* The methods above are in versions 1 through 3 of the sqlite_module object. + ** Those below are for version 4 and greater. */ + int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema, + const char *zTabName, int mFlags, char **pzErr); }; /* @@ -8017,7 +8080,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); ** code is returned and the transaction rolled back. ** ** Calling this function with an argument that is not a NULL pointer or an -** open blob handle results in undefined behaviour. ^Calling this routine +** open blob handle results in undefined behavior. ^Calling this routine ** with a null pointer (such as would be returned by a failed call to ** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function ** is passed a valid open blob handle, the values returned by the @@ -8497,6 +8560,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */ +#define SQLITE_TESTCTRL_FK_NO_ACTION 7 #define SQLITE_TESTCTRL_BITVEC_TEST 8 #define SQLITE_TESTCTRL_FAULT_INSTALL 9 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 @@ -9558,8 +9622,8 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is cancelled. ^The blocked connections -** unlock-notify callback may also be cancelled by closing the blocked +** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** ** The unlock-notify callback is not reentrant. If an application invokes @@ -10862,6 +10926,13 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy ** of the database exists. ** +** After the call, if the SQLITE_SERIALIZE_NOCOPY bit had been set, +** the returned buffer content will remain accessible and unchanged +** until either the next write operation on the connection or when +** the connection is closed, and applications must not modify the +** buffer. If the bit had been clear, the returned buffer will not +** be accessed by SQLite after the call. +** ** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the ** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory ** allocation error occurs. @@ -10910,6 +10981,9 @@ SQLITE_API unsigned char *sqlite3_serialize( ** SQLite will try to increase the buffer size using sqlite3_realloc64() ** if writes on the database cause it to grow larger than M bytes. ** +** Applications must not modify the buffer P or invalidate it before +** the database connection D is closed. +** ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. @@ -10918,6 +10992,13 @@ SQLITE_API unsigned char *sqlite3_serialize( ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. ** +** The deserialized database should not be in [WAL mode]. If the database +** is in WAL mode, then any attempt to use the database file will result +** in an [SQLITE_CANTOPEN] error. The application can set the +** [file format version numbers] (bytes 18 and 19) of the input database P +** to 0x01 prior to invoking sqlite3_deserialize(D,S,P,N,M,F) to force the +** database file into rollback mode and work around this limitation. +** ** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then ** [sqlite3_free()] is invoked on argument P prior to returning. @@ -11990,6 +12071,18 @@ SQLITE_API int sqlite3changeset_concat( ); +/* +** CAPI3REF: Upgrade the Schema of a Changeset/Patchset +*/ +SQLITE_API int sqlite3changeset_upgrade( + sqlite3 *db, + const char *zDb, + int nIn, const void *pIn, /* Input changeset */ + int *pnOut, void **ppOut /* OUT: Inverse of input */ +); + + + /* ** CAPI3REF: Changegroup Handle ** @@ -12036,6 +12129,38 @@ typedef struct sqlite3_changegroup sqlite3_changegroup; */ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); +/* +** CAPI3REF: Add a Schema to a Changegroup +** METHOD: sqlite3_changegroup_schema +** +** This method may be used to optionally enforce the rule that the changesets +** added to the changegroup handle must match the schema of database zDb +** ("main", "temp", or the name of an attached database). If +** sqlite3changegroup_add() is called to add a changeset that is not compatible +** with the configured schema, SQLITE_SCHEMA is returned and the changegroup +** object is left in an undefined state. +** +** A changeset schema is considered compatible with the database schema in +** the same way as for sqlite3changeset_apply(). Specifically, for each +** table in the changeset, there exists a database table with: +** +**
        +**
      • The name identified by the changeset, and +**
      • at least as many columns as recorded in the changeset, and +**
      • the primary key columns in the same position as recorded in +** the changeset. +**
      +** +** The output of the changegroup object always has the same schema as the +** database nominated using this function. In cases where changesets passed +** to sqlite3changegroup_add() have fewer columns than the corresponding table +** in the database schema, these are filled in using the default column +** values from the database schema. This makes it possible to combined +** changesets that have different numbers of columns for a single table +** within a changegroup, provided that they are otherwise compatible. +*/ +SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb); + /* ** CAPI3REF: Add A Changeset To A Changegroup ** METHOD: sqlite3_changegroup @@ -12104,13 +12229,18 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); ** If the new changeset contains changes to a table that is already present ** in the changegroup, then the number of columns and the position of the ** primary key columns for the table must be consistent. If this is not the -** case, this function fails with SQLITE_SCHEMA. If the input changeset -** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is -** returned. Or, if an out-of-memory condition occurs during processing, this -** function returns SQLITE_NOMEM. In all cases, if an error occurs the state -** of the final contents of the changegroup is undefined. +** case, this function fails with SQLITE_SCHEMA. Except, if the changegroup +** object has been configured with a database schema using the +** sqlite3changegroup_schema() API, then it is possible to combine changesets +** with different numbers of columns for a single table, provided that +** they are otherwise compatible. ** -** If no error occurs, SQLITE_OK is returned. +** If the input changeset appears to be corrupt and the corruption is +** detected, SQLITE_CORRUPT is returned. Or, if an out-of-memory condition +** occurs during processing, this function returns SQLITE_NOMEM. +** +** In all cases, if an error occurs the state of the final contents of the +** changegroup is undefined. If no error occurs, SQLITE_OK is returned. */ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); @@ -12375,10 +12505,17 @@ SQLITE_API int sqlite3changeset_apply_v2( **
    • an insert change if all fields of the conflicting row match ** the row being inserted. **
    +** +**
    SQLITE_CHANGESETAPPLY_FKNOACTION
    +** If this flag it set, then all foreign key constraints in the target +** database behave as if they were declared with "ON UPDATE NO ACTION ON +** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL +** or SET DEFAULT. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 +#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 /* ** CAPI3REF: Constants Passed To The Conflict Handler @@ -13769,6 +13906,16 @@ struct fts5_api { # endif #endif +/* +** Enable SQLITE_USE_SEH by default on MSVC builds. Only omit +** SEH support if the -DSQLITE_OMIT_SEH option is given. +*/ +#if defined(_MSC_VER) && !defined(SQLITE_OMIT_SEH) +# define SQLITE_USE_SEH 1 +#else +# undef SQLITE_USE_SEH +#endif + /* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never @@ -14662,16 +14809,33 @@ typedef INT16_TYPE LogEst; ** using C-preprocessor macros. If that is unsuccessful, or if ** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined ** at run-time. +** +** If you are building SQLite on some obscure platform for which the +** following ifdef magic does not work, you can always include either: +** +** -DSQLITE_BYTEORDER=1234 +** +** or +** +** -DSQLITE_BYTEORDER=4321 +** +** to cause the build to work for little-endian or big-endian processors, +** respectively. */ -#ifndef SQLITE_BYTEORDER -# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ +#ifndef SQLITE_BYTEORDER /* Replicate changes at tag-20230904a */ +# if defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ +# define SQLITE_BYTEORDER 4321 +# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ +# define SQLITE_BYTEORDER 1234 +# elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 +# define SQLITE_BYTEORDER 4321 +# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64) -# define SQLITE_BYTEORDER 1234 -# elif defined(sparc) || defined(__ppc__) || \ - defined(__ARMEB__) || defined(__AARCH64EB__) -# define SQLITE_BYTEORDER 4321 +# define SQLITE_BYTEORDER 1234 +# elif defined(sparc) || defined(__ARMEB__) || defined(__AARCH64EB__) +# define SQLITE_BYTEORDER 4321 # else # define SQLITE_BYTEORDER 0 # endif @@ -14995,6 +15159,7 @@ typedef struct Column Column; typedef struct Cte Cte; typedef struct CteUse CteUse; typedef struct Db Db; +typedef struct DbClientData DbClientData; typedef struct DbFixer DbFixer; typedef struct Schema Schema; typedef struct Expr Expr; @@ -16435,19 +16600,20 @@ typedef struct VdbeOpList VdbeOpList; #define OP_VCreate 171 #define OP_VDestroy 172 #define OP_VOpen 173 -#define OP_VInitIn 174 /* synopsis: r[P2]=ValueList(P1,P3) */ -#define OP_VColumn 175 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 176 -#define OP_Pagecount 177 -#define OP_MaxPgcnt 178 -#define OP_ClrSubtype 179 /* synopsis: r[P1].subtype = 0 */ -#define OP_FilterAdd 180 /* synopsis: filter(P1) += key(P3@P4) */ -#define OP_Trace 181 -#define OP_CursorHint 182 -#define OP_ReleaseReg 183 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 184 -#define OP_Explain 185 -#define OP_Abortable 186 +#define OP_VCheck 174 +#define OP_VInitIn 175 /* synopsis: r[P2]=ValueList(P1,P3) */ +#define OP_VColumn 176 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 177 +#define OP_Pagecount 178 +#define OP_MaxPgcnt 179 +#define OP_ClrSubtype 180 /* synopsis: r[P1].subtype = 0 */ +#define OP_FilterAdd 181 /* synopsis: filter(P1) += key(P3@P4) */ +#define OP_Trace 182 +#define OP_CursorHint 183 +#define OP_ReleaseReg 184 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 185 +#define OP_Explain 186 +#define OP_Abortable 187 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -16482,9 +16648,9 @@ typedef struct VdbeOpList VdbeOpList; /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x50, 0x40,\ -/* 176 */ 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00,\ -/* 184 */ 0x00, 0x00, 0x00,} +/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ +/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00,\ +/* 184 */ 0x00, 0x00, 0x00, 0x00,} /* The resolve3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -17393,6 +17559,7 @@ struct sqlite3 { i64 nDeferredCons; /* Net deferred constraints this transaction. */ i64 nDeferredImmCons; /* Net deferred immediate constraints */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ + DbClientData *pDbData; /* sqlite3_set_clientdata() content */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY /* The following variables are all protected by the STATIC_MAIN ** mutex, not by sqlite3.mutex. They are used by code in notify.c. @@ -17475,6 +17642,7 @@ struct sqlite3 { /* the count using a callback. */ #define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */ #define SQLITE_ReadUncommit HI(0x00004) /* READ UNCOMMITTED in shared-cache */ +#define SQLITE_FkNoAction HI(0x00008) /* Treat all FK as NO ACTION */ /* Flags used only if debugging */ #ifdef SQLITE_DEBUG @@ -18490,6 +18658,9 @@ struct AggInfo { FuncDef *pFunc; /* The aggregate function implementation */ int iDistinct; /* Ephemeral table used to enforce DISTINCT */ int iDistAddr; /* Address of OP_OpenEphemeral */ + int iOBTab; /* Ephemeral table to implement ORDER BY */ + u8 bOBPayload; /* iOBTab has payload columns separate from key */ + u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ @@ -18674,7 +18845,7 @@ struct Expr { #define EP_Reduced 0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ #define EP_Win 0x008000 /* Contains window functions */ #define EP_TokenOnly 0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ - /* 0x020000 // Available for reuse */ +#define EP_FullSize 0x020000 /* Expr structure must remain full sized */ #define EP_IfNullRow 0x040000 /* The TK_IF_NULL_ROW opcode */ #define EP_Unlikely 0x080000 /* unlikely() or likelihood() function */ #define EP_ConstFunc 0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ @@ -18704,6 +18875,7 @@ struct Expr { #define ExprClearProperty(E,P) (E)->flags&=~(P) #define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue) #define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse) +#define ExprIsFullSize(E) (((E)->flags&(EP_Reduced|EP_TokenOnly))==0) /* Macros used to ensure that the correct members of unions are accessed ** in Expr. @@ -18821,6 +18993,7 @@ struct ExprList { #define ENAME_NAME 0 /* The AS clause of a result set */ #define ENAME_SPAN 1 /* Complete text of the result set expression */ #define ENAME_TAB 2 /* "DB.TABLE.NAME" for the result set */ +#define ENAME_ROWID 3 /* "DB.TABLE._rowid_" for * expansion of rowid */ /* ** An instance of this structure can hold a simple list of identifiers, @@ -19429,6 +19602,7 @@ struct Parse { int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */ + IndexedExpr *pIdxPartExpr; /* Exprs constrained by index WHERE clauses */ Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ @@ -19700,6 +19874,7 @@ struct Returning { int iRetCur; /* Transient table holding RETURNING results */ int nRetCol; /* Number of in pReturnEL after expansion */ int iRetReg; /* Register array for holding a row of RETURNING */ + char zName[40]; /* Name of trigger: "sqlite_returning_%p" */ }; /* @@ -20000,6 +20175,16 @@ struct CteUse { }; +/* Client data associated with sqlite3_set_clientdata() and +** sqlite3_get_clientdata(). +*/ +struct DbClientData { + DbClientData *pNext; /* Next in a linked list */ + void *pData; /* The data */ + void (*xDestructor)(void*); /* Destructor. Might be NULL */ + char zName[1]; /* Name of this client data. MUST BE LAST */ +}; + #ifdef SQLITE_DEBUG /* ** An instance of the TreeView object is used for printing the content of @@ -20404,6 +20589,8 @@ SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*); SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*); SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int); +SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*); +SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse*,Expr*); SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); @@ -20640,6 +20827,7 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); SQLITE_PRIVATE int sqlite3IsRowid(const char*); +SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab); SQLITE_PRIVATE void sqlite3GenerateRowDelete( Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); @@ -20911,7 +21099,8 @@ SQLITE_PRIVATE int sqlite3MatchEName( const struct ExprList_item*, const char*, const char*, - const char* + const char*, + int* ); SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr*); SQLITE_PRIVATE u8 sqlite3StrIHash(const char*); @@ -20968,7 +21157,7 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); SQLITE_PRIVATE char *sqlite3RCStrRef(char*); -SQLITE_PRIVATE void sqlite3RCStrUnref(char*); +SQLITE_PRIVATE void sqlite3RCStrUnref(void*); SQLITE_PRIVATE char *sqlite3RCStrNew(u64); SQLITE_PRIVATE char *sqlite3RCStrResize(char*,u64); @@ -21804,6 +21993,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS "EXPLAIN_ESTIMATED_ROWS", #endif +#ifdef SQLITE_EXTRA_AUTOEXT + "EXTRA_AUTOEXT=" CTIMEOPT_VAL(SQLITE_EXTRA_AUTOEXT), +#endif #ifdef SQLITE_EXTRA_IFNULLROW "EXTRA_IFNULLROW", #endif @@ -22085,6 +22277,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS "OMIT_SCHEMA_VERSION_PRAGMAS", #endif +#ifdef SQLITE_OMIT_SEH + "OMIT_SEH", +#endif #ifdef SQLITE_OMIT_SHARED_CACHE "OMIT_SHARED_CACHE", #endif @@ -25044,13 +25239,16 @@ static void strftimeFunc( computeJD(&x); computeYMD_HMS(&x); for(i=j=0; zFmt[i]; i++){ + char cf; if( zFmt[i]!='%' ) continue; if( j12 ) h -= 12; + if( h==0 ) h = 12; + sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h); break; } case 'W': /* Fall thru */ @@ -25072,7 +25283,7 @@ static void strftimeFunc( y.D = 1; computeJD(&y); nDay = (int)((x.iJD-y.iJD+43200000)/86400000); - if( zFmt[i]=='W' ){ + if( cf=='W' ){ int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ wd = (int)(((x.iJD+43200000)/86400000)%7); sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7); @@ -25093,6 +25304,19 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes,"%02d",x.m); break; } + case 'p': /* Fall thru */ + case 'P': { + if( x.h>=12 ){ + sqlite3_str_append(&sRes, cf=='p' ? "PM" : "pm", 2); + }else{ + sqlite3_str_append(&sRes, cf=='p' ? "AM" : "am", 2); + } + break; + } + case 'R': { + sqlite3_str_appendf(&sRes, "%02d:%02d", x.h, x.m); + break; + } case 's': { if( x.useSubsec ){ sqlite3_str_appendf(&sRes,"%.3f", @@ -25107,9 +25331,15 @@ static void strftimeFunc( sqlite3_str_appendf(&sRes,"%02d",(int)x.s); break; } + case 'T': { + sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); + break; + } + case 'u': /* Fall thru */ case 'w': { - sqlite3_str_appendchar(&sRes, 1, - (char)(((x.iJD+129600000)/86400000) % 7) + '0'); + char c = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; + if( c=='0' && cf=='u' ) c = '7'; + sqlite3_str_appendchar(&sRes, 1, c); break; } case 'Y': { @@ -28198,7 +28428,7 @@ static void checkMutexFree(sqlite3_mutex *p){ assert( SQLITE_MUTEX_FAST<2 ); assert( SQLITE_MUTEX_WARNONCONTENTION<2 ); -#if SQLITE_ENABLE_API_ARMOR +#ifdef SQLITE_ENABLE_API_ARMOR if( ((CheckMutex*)p)->iType<2 ) #endif { @@ -28870,7 +29100,7 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ */ static void pthreadMutexFree(sqlite3_mutex *p){ assert( p->nRef==0 ); -#if SQLITE_ENABLE_API_ARMOR +#ifdef SQLITE_ENABLE_API_ARMOR if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ) #endif { @@ -30434,7 +30664,7 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ if( db->mallocFailed || rc ){ return apiHandleError(db, rc); } - return rc & db->errMask; + return 0; } /************** End of malloc.c **********************************************/ @@ -31830,7 +32060,7 @@ SQLITE_PRIVATE char *sqlite3RCStrRef(char *z){ ** Decrease the reference count by one. Free the string when the ** reference count reaches zero. */ -SQLITE_PRIVATE void sqlite3RCStrUnref(char *z){ +SQLITE_PRIVATE void sqlite3RCStrUnref(void *z){ RCStr *p = (RCStr*)z; assert( p!=0 ); p--; @@ -32293,6 +32523,7 @@ SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u sqlite3TreeViewItem(pView, "FILTER", 1); sqlite3TreeViewExpr(pView, pWin->pFilter, 0); sqlite3TreeViewPop(&pView); + if( pWin->eFrmType==TK_FILTER ) return; } sqlite3TreeViewPush(&pView, more); if( pWin->zName ){ @@ -32302,7 +32533,7 @@ SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u } if( pWin->zBase ) nElement++; if( pWin->pOrderBy ) nElement++; - if( pWin->eFrmType ) nElement++; + if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ) nElement++; if( pWin->eExclude ) nElement++; if( pWin->zBase ){ sqlite3TreeViewPush(&pView, (--nElement)>0); @@ -32315,7 +32546,7 @@ SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u if( pWin->pOrderBy ){ sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY"); } - if( pWin->eFrmType ){ + if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ){ char zBuf[30]; const char *zFrmType = "ROWS"; if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE"; @@ -32563,7 +32794,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m assert( ExprUseXList(pExpr) ); pFarg = pExpr->x.pList; #ifndef SQLITE_OMIT_WINDOWFUNC - pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0; + pWin = IsWindowFunc(pExpr) ? pExpr->y.pWin : 0; #else pWin = 0; #endif @@ -32589,7 +32820,13 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); } if( pFarg ){ - sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); + sqlite3TreeViewExprList(pView, pFarg, pWin!=0 || pExpr->pLeft, 0); + if( pExpr->pLeft ){ + Expr *pOB = pExpr->pLeft; + assert( pOB->op==TK_ORDER ); + assert( ExprUseXList(pOB) ); + sqlite3TreeViewExprList(pView, pOB->x.pList, pWin!=0, "ORDERBY"); + } } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ @@ -32598,6 +32835,10 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m #endif break; } + case TK_ORDER: { + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, "ORDERBY"); + break; + } #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: { assert( ExprUseXSelect(pExpr) ); @@ -34362,12 +34603,16 @@ SQLITE_PRIVATE void sqlite3ProgressCheck(Parse *p){ p->rc = SQLITE_INTERRUPT; } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK - if( db->xProgress && (++p->nProgressSteps)>=db->nProgressOps ){ - if( db->xProgress(db->pProgressArg) ){ - p->nErr++; - p->rc = SQLITE_INTERRUPT; + if( db->xProgress ){ + if( p->rc==SQLITE_INTERRUPT ){ + p->nProgressSteps = 0; + }else if( (++p->nProgressSteps)>=db->nProgressOps ){ + if( db->xProgress(db->pProgressArg) ){ + p->nErr++; + p->rc = SQLITE_INTERRUPT; + } + p->nProgressSteps = 0; } - p->nProgressSteps = 0; } #endif } @@ -35523,121 +35768,32 @@ SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ ** this function assumes the single-byte case has already been handled. */ SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ - u32 a,b; + u64 v64; + u8 n; - /* The 1-byte case. Overwhelmingly the most common. Handled inline - ** by the getVarin32() macro */ - a = *p; - /* a: p0 (unmasked) */ -#ifndef getVarint32 - if (!(a&0x80)) - { - /* Values between 0 and 127 */ - *v = a; - return 1; - } -#endif + /* Assume that the single-byte case has already been handled by + ** the getVarint32() macro */ + assert( (p[0] & 0x80)!=0 ); - /* The 2-byte case */ - p++; - b = *p; - /* b: p1 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 128 and 16383 */ - a &= 0x7f; - a = a<<7; - *v = a | b; + if( (p[1] & 0x80)==0 ){ + /* This is the two-byte case */ + *v = ((p[0]&0x7f)<<7) | p[1]; return 2; } - - /* The 3-byte case */ - p++; - a = a<<14; - a |= *p; - /* a: p0<<14 | p2 (unmasked) */ - if (!(a&0x80)) - { - /* Values between 16384 and 2097151 */ - a &= (0x7f<<14)|(0x7f); - b &= 0x7f; - b = b<<7; - *v = a | b; + if( (p[2] & 0x80)==0 ){ + /* This is the three-byte case */ + *v = ((p[0]&0x7f)<<14) | ((p[1]&0x7f)<<7) | p[2]; return 3; } - - /* A 32-bit varint is used to store size information in btrees. - ** Objects are rarely larger than 2MiB limit of a 3-byte varint. - ** A 3-byte varint is sufficient, for example, to record the size - ** of a 1048569-byte BLOB or string. - ** - ** We only unroll the first 1-, 2-, and 3- byte cases. The very - ** rare larger cases can be handled by the slower 64-bit varint - ** routine. - */ -#if 1 - { - u64 v64; - u8 n; - - n = sqlite3GetVarint(p-2, &v64); - assert( n>3 && n<=9 ); - if( (v64 & SQLITE_MAX_U32)!=v64 ){ - *v = 0xffffffff; - }else{ - *v = (u32)v64; - } - return n; - } - -#else - /* For following code (kept for historical record only) shows an - ** unrolling for the 3- and 4-byte varint cases. This code is - ** slightly faster, but it is also larger and much harder to test. - */ - p++; - b = b<<14; - b |= *p; - /* b: p1<<14 | p3 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 2097152 and 268435455 */ - b &= (0x7f<<14)|(0x7f); - a &= (0x7f<<14)|(0x7f); - a = a<<7; - *v = a | b; - return 4; - } - - p++; - a = a<<14; - a |= *p; - /* a: p0<<28 | p2<<14 | p4 (unmasked) */ - if (!(a&0x80)) - { - /* Values between 268435456 and 34359738367 */ - a &= SLOT_4_2_0; - b &= SLOT_4_2_0; - b = b<<7; - *v = a | b; - return 5; - } - - /* We can only reach this point when reading a corrupt database - ** file. In that case we are not in any hurry. Use the (relatively - ** slow) general-purpose sqlite3GetVarint() routine to extract the - ** value. */ - { - u64 v64; - u8 n; - - p -= 4; - n = sqlite3GetVarint(p, &v64); - assert( n>5 && n<=9 ); + /* four or more bytes */ + n = sqlite3GetVarint(p, &v64); + assert( n>3 && n<=9 ); + if( (v64 & SQLITE_MAX_U32)!=v64 ){ + *v = 0xffffffff; + }else{ *v = (u32)v64; - return n; } -#endif + return n; } /* @@ -36633,19 +36789,20 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 171 */ "VCreate" OpHelp(""), /* 172 */ "VDestroy" OpHelp(""), /* 173 */ "VOpen" OpHelp(""), - /* 174 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), - /* 175 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 176 */ "VRename" OpHelp(""), - /* 177 */ "Pagecount" OpHelp(""), - /* 178 */ "MaxPgcnt" OpHelp(""), - /* 179 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), - /* 180 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), - /* 181 */ "Trace" OpHelp(""), - /* 182 */ "CursorHint" OpHelp(""), - /* 183 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), - /* 184 */ "Noop" OpHelp(""), - /* 185 */ "Explain" OpHelp(""), - /* 186 */ "Abortable" OpHelp(""), + /* 174 */ "VCheck" OpHelp(""), + /* 175 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), + /* 176 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 177 */ "VRename" OpHelp(""), + /* 178 */ "Pagecount" OpHelp(""), + /* 179 */ "MaxPgcnt" OpHelp(""), + /* 180 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), + /* 181 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), + /* 182 */ "Trace" OpHelp(""), + /* 183 */ "CursorHint" OpHelp(""), + /* 184 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 185 */ "Noop" OpHelp(""), + /* 186 */ "Explain" OpHelp(""), + /* 187 */ "Abortable" OpHelp(""), }; return azName[i]; } @@ -40787,9 +40944,6 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { unixInodeInfo *pInode; afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; int skipShared = 0; -#ifdef SQLITE_TEST - int h = pFile->h; -#endif assert( pFile ); OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, @@ -40805,9 +40959,6 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); - SimulateIOErrorBenign(1); - SimulateIOError( h=(-1) ) - SimulateIOErrorBenign(0); #ifdef SQLITE_DEBUG /* When reducing a lock such that other processes can start @@ -40856,9 +41007,6 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte; pInode->nShared--; if( pInode->nShared==0 ){ - SimulateIOErrorBenign(1); - SimulateIOError( h=(-1) ) - SimulateIOErrorBenign(0); if( !skipShared ){ rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0); } @@ -57729,9 +57877,32 @@ static int writeJournalHdr(Pager *pPager){ memset(zHeader, 0, sizeof(aJournalMagic)+4); } + + /* The random check-hash initializer */ - sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ + sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + } +#ifdef SQLITE_DEBUG + else{ + /* The Pager.cksumInit variable is usually randomized above to protect + ** against there being existing records in the journal file. This is + ** dangerous, as following a crash they may be mistaken for records + ** written by the current transaction and rolled back into the database + ** file, causing corruption. The following assert statements verify + ** that this is not required in "journal_mode=memory" mode, as in that + ** case the journal file is always 0 bytes in size at this point. + ** It is advantageous to avoid the sqlite3_randomness() call if possible + ** as it takes the global PRNG mutex. */ + i64 sz = 0; + sqlite3OsFileSize(pPager->jfd, &sz); + assert( sz==0 ); + assert( pPager->journalOff==journalHdrOffset(pPager) ); + assert( sqlite3JournalIsInMemory(pPager->jfd) ); + } +#endif put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); + /* The initial database size */ put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize); /* The assumed sector size for this process */ @@ -58375,6 +58546,9 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ return (rc==SQLITE_OK?rc2:rc); } +/* Forward reference */ +static int pager_playback(Pager *pPager, int isHot); + /* ** Execute a rollback if a transaction is active and unlock the ** database file. @@ -58403,6 +58577,21 @@ static void pagerUnlockAndRollback(Pager *pPager){ assert( pPager->eState==PAGER_READER ); pager_end_transaction(pPager, 0, 0); } + }else if( pPager->eState==PAGER_ERROR + && pPager->journalMode==PAGER_JOURNALMODE_MEMORY + && isOpen(pPager->jfd) + ){ + /* Special case for a ROLLBACK due to I/O error with an in-memory + ** journal: We have to rollback immediately, before the journal is + ** closed, because once it is closed, all content is forgotten. */ + int errCode = pPager->errCode; + u8 eLock = pPager->eLock; + pPager->eState = PAGER_OPEN; + pPager->errCode = SQLITE_OK; + pPager->eLock = EXCLUSIVE_LOCK; + pager_playback(pPager, 1); + pPager->errCode = errCode; + pPager->eLock = eLock; } pager_unlock(pPager); } @@ -61895,8 +62084,20 @@ SQLITE_PRIVATE int sqlite3PagerGet( DbPage **ppPage, /* Write a pointer to the page here */ int flags /* PAGER_GET_XXX flags */ ){ - /* printf("PAGE %u\n", pgno); fflush(stdout); */ +#if 0 /* Trace page fetch by setting to 1 */ + int rc; + printf("PAGE %u\n", pgno); + fflush(stdout); + rc = pPager->xGet(pPager, pgno, ppPage, flags); + if( rc ){ + printf("PAGE %u failed with 0x%02x\n", pgno, rc); + fflush(stdout); + } + return rc; +#else + /* Normal, high-speed version of sqlite3PagerGet() */ return pPager->xGet(pPager, pgno, ppPage, flags); +#endif } /* @@ -62772,6 +62973,13 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0); if( rc==SQLITE_OK ){ rc = pager_write_pagelist(pPager, pList); + if( rc==SQLITE_OK && pPager->dbSize>pPager->dbFileSize ){ + char *pTmp = pPager->pTmpSpace; + int szPage = (int)pPager->pageSize; + memset(pTmp, 0, szPage); + rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, + ((i64)pPager->dbSize*pPager->pageSize)-szPage); + } if( rc==SQLITE_OK ){ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); } @@ -63583,7 +63791,7 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ } assert( state==pPager->eState ); } - }else if( eMode==PAGER_JOURNALMODE_OFF ){ + }else if( eMode==PAGER_JOURNALMODE_OFF || eMode==PAGER_JOURNALMODE_MEMORY ){ sqlite3OsClose(pPager->jfd); } } @@ -69196,7 +69404,7 @@ struct IntegrityCk { BtShared *pBt; /* The tree being checked out */ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ u8 *aPgRef; /* 1 bit per page in the db (see above) */ - Pgno nPage; /* Number of pages in the database */ + Pgno nCkPage; /* Pages in the database. 0 for partial check */ int mxErr; /* Stop accumulating errors when this reaches zero */ int nErr; /* Number of messages written to zErrMsg so far */ int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */ @@ -69529,7 +69737,6 @@ SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){ /************** End of btmutex.c *********************************************/ /************** Begin file btree.c *******************************************/ - /* ** 2004 April 6 ** @@ -77027,7 +77234,7 @@ static int rebuildPage( assert( nCell>0 ); assert( i(u32)usableSize) ){ j = 0; } + if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); for(k=0; ALWAYS(kixNx[k]<=i; k++){} @@ -79991,7 +80198,8 @@ static void checkAppendMsg( ** corresponds to page iPg is already set. */ static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ - assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); + assert( pCheck->aPgRef!=0 ); + assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07))); } @@ -79999,7 +80207,8 @@ static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ ** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg. */ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ - assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); + assert( pCheck->aPgRef!=0 ); + assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07)); } @@ -80013,7 +80222,7 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, Pgno iPage){ - if( iPage>pCheck->nPage || iPage==0 ){ + if( iPage>pCheck->nCkPage || iPage==0 ){ checkAppendMsg(pCheck, "invalid page number %u", iPage); return 1; } @@ -80240,6 +80449,7 @@ static int checkTreePage( if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ checkAppendMsg(pCheck, "unable to get the page. error code=%d", rc); + if( rc==SQLITE_IOERR_NOMEM ) pCheck->rc = SQLITE_NOMEM; goto end_of_check; } @@ -80510,15 +80720,15 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( sCheck.db = db; sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; - sCheck.nPage = btreePagecount(sCheck.pBt); + sCheck.nCkPage = btreePagecount(sCheck.pBt); sCheck.mxErr = mxErr; sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; - if( sCheck.nPage==0 ){ + if( sCheck.nCkPage==0 ){ goto integrity_ck_cleanup; } - sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); + sCheck.aPgRef = sqlite3MallocZero((sCheck.nCkPage / 8)+ 1); if( !sCheck.aPgRef ){ checkOom(&sCheck); goto integrity_ck_cleanup; @@ -80530,7 +80740,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( } i = PENDING_BYTE_PAGE(pBt); - if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); + if( i<=sCheck.nCkPage ) setPageReferenced(&sCheck, i); /* Check the integrity of the freelist */ @@ -80581,7 +80791,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( /* Make sure every page in the file is referenced */ if( !bPartial ){ - for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ + for(i=1; i<=sCheck.nCkPage && sCheck.mxErr; i++){ #ifdef SQLITE_OMIT_AUTOVACUUM if( getPageReferenced(&sCheck, i)==0 ){ checkAppendMsg(&sCheck, "Page %u: never used", i); @@ -82022,7 +82232,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ pMem->flags |= MEM_Term; return; } - if( pMem->xDel==(void(*)(void*))sqlite3RCStrUnref ){ + if( pMem->xDel==sqlite3RCStrUnref ){ /* Blindly assume that all RCStr objects are zero-terminated */ pMem->flags |= MEM_Term; return; @@ -83402,6 +83612,7 @@ static int valueFromExpr( if( pVal ){ pVal->flags = MEM_Int; pVal->u.i = pExpr->u.zToken[4]==0; + sqlite3ValueApplyAffinity(pVal, affinity, enc); } } @@ -84715,6 +84926,10 @@ SQLITE_PRIVATE void sqlite3VdbeNoJumpsOutsideSubrtn( int iDest = pOp->p2; /* Jump destination */ if( iDest==0 ) continue; if( pOp->opcode==OP_Gosub ) continue; + if( pOp->p3==20230325 && pOp->opcode==OP_NotNull ){ + /* This is a deliberately taken illegal branch. tag-20230325-2 */ + continue; + } if( iDest<0 ){ int j = ADDR(iDest); assert( j>=0 ); @@ -88174,20 +88389,33 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem return n1 - n2; } +/* The following two functions are used only within testcase() to prove +** test coverage. These functions do no exist for production builds. +** We must use separate SQLITE_NOINLINE functions here, since otherwise +** optimizer code movement causes gcov to become very confused. +*/ +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +static int SQLITE_NOINLINE doubleLt(double a, double b){ return a8 ){ + if( sqlite3IsNaN(r) ){ + /* SQLite considers NaN to be a NULL. And all integer values are greater + ** than NULL */ + return 1; + } + if( sqlite3Config.bUseLongDouble ){ LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; testcase( xr ); testcase( x==r ); - if( xr ) return +1; /*NO_TEST*/ /* work around bugs in gcov */ - return 0; /*NO_TEST*/ /* work around bugs in gcov */ + return (xr); }else{ i64 y; double s; @@ -88197,9 +88425,10 @@ SQLITE_PRIVATE int sqlite3IntFloatCompare(i64 i, double r){ if( iy ) return +1; s = (double)i; - if( sr ) return +1; - return 0; + testcase( doubleLt(s,r) ); + testcase( doubleLt(r,s) ); + testcase( doubleEq(r,s) ); + return (sr); } } @@ -89567,7 +89796,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){ ** is too big or if an OOM occurs. ** ** The invokeValueDestructor(P,X) routine invokes destructor function X() -** on value P is not going to be used and need to be destroyed. +** on value P if P is not going to be used and need to be destroyed. */ static void setResultStrOrError( sqlite3_context *pCtx, /* Function context */ @@ -89597,7 +89826,7 @@ static void setResultStrOrError( static int invokeValueDestructor( const void *p, /* Value to destroy */ void (*xDel)(void*), /* The destructor */ - sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */ + sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if not NULL */ ){ assert( xDel!=SQLITE_DYNAMIC ); if( xDel==0 ){ @@ -89607,7 +89836,14 @@ static int invokeValueDestructor( }else{ xDel((void*)p); } +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx!=0 ){ + sqlite3_result_error_toobig(pCtx); + } +#else + assert( pCtx!=0 ); sqlite3_result_error_toobig(pCtx); +#endif return SQLITE_TOOBIG; } SQLITE_API void sqlite3_result_blob( @@ -89616,6 +89852,12 @@ SQLITE_API void sqlite3_result_blob( int n, void (*xDel)(void *) ){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 || n<0 ){ + invokeValueDestructor(z, xDel, pCtx); + return; + } +#endif assert( n>=0 ); assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, 0, xDel); @@ -89626,8 +89868,14 @@ SQLITE_API void sqlite3_result_blob64( sqlite3_uint64 n, void (*xDel)(void *) ){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); if( n>0x7fffffff ){ (void)invokeValueDestructor(z, xDel, pCtx); }else{ @@ -89635,30 +89883,48 @@ SQLITE_API void sqlite3_result_blob64( } } SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); } SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); } #ifndef SQLITE_OMIT_UTF16 SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); } #endif SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); } SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); } SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } @@ -89668,14 +89934,25 @@ SQLITE_API void sqlite3_result_pointer( const char *zPType, void (*xDestructor)(void*) ){ - Mem *pOut = pCtx->pOut; + Mem *pOut; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(pPtr, xDestructor, 0); + return; + } +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); sqlite3VdbeMemRelease(pOut); pOut->flags = MEM_Null; sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); } SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ - Mem *pOut = pCtx->pOut; + Mem *pOut; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); pOut->eSubtype = eSubtype & 0xff; pOut->flags |= MEM_Subtype; @@ -89686,6 +89963,12 @@ SQLITE_API void sqlite3_result_text( int n, void (*xDel)(void *) ){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); } @@ -89696,6 +89979,12 @@ SQLITE_API void sqlite3_result_text64( void (*xDel)(void *), unsigned char enc ){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); if( enc!=SQLITE_UTF8 ){ @@ -89739,7 +90028,16 @@ SQLITE_API void sqlite3_result_text16le( } #endif /* SQLITE_OMIT_UTF16 */ SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ - Mem *pOut = pCtx->pOut; + Mem *pOut; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; + if( pValue==0 ){ + sqlite3_result_null(pCtx); + return; + } +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemCopy(pOut, pValue); sqlite3VdbeChangeEncoding(pOut, pCtx->enc); @@ -89751,7 +90049,12 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0); } SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ - Mem *pOut = pCtx->pOut; + Mem *pOut; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return SQLITE_MISUSE_BKPT; +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(pCtx); @@ -89765,6 +90068,9 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ #endif } SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif pCtx->isError = errCode ? errCode : -1; #ifdef SQLITE_DEBUG if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; @@ -89777,6 +90083,9 @@ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ /* Force an SQLITE_TOOBIG error. */ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_TOOBIG; sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, @@ -89785,6 +90094,9 @@ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ /* An SQLITE_NOMEM error. */ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM_BKPT; @@ -90037,7 +90349,11 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ ** pointer to it. */ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else assert( p && p->pFunc ); +#endif return p->pFunc->pUserData; } @@ -90052,7 +90368,11 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ ** application defined function. */ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else assert( p && p->pOut ); +#endif return p->pOut->db; } @@ -90071,7 +90391,11 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ ** value, as a signal to the xUpdate routine that the column is unchanged. */ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else assert( p ); +#endif return sqlite3_value_nochange(p->pOut); } @@ -90099,7 +90423,7 @@ static int valueFromValueList( ValueList *pRhs; *ppOut = 0; - if( pVal==0 ) return SQLITE_MISUSE; + if( pVal==0 ) return SQLITE_MISUSE_BKPT; if( (pVal->flags & MEM_Dyn)==0 || pVal->xDel!=sqlite3VdbeValueListFree ){ return SQLITE_ERROR; }else{ @@ -90230,6 +90554,9 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ AuxData *pAuxData; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return 0; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #if SQLITE_ENABLE_STAT4 if( pCtx->pVdbe==0 ) return 0; @@ -90262,8 +90589,12 @@ SQLITE_API void sqlite3_set_auxdata( void (*xDelete)(void*) ){ AuxData *pAuxData; - Vdbe *pVdbe = pCtx->pVdbe; + Vdbe *pVdbe; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + pVdbe= pCtx->pVdbe; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #ifdef SQLITE_ENABLE_STAT4 if( pVdbe==0 ) goto failed; @@ -90700,7 +91031,7 @@ static int vdbeUnbind(Vdbe *p, unsigned int i){ } sqlite3_mutex_enter(p->db->mutex); if( p->eVdbeState!=VDBE_READY_STATE ){ - sqlite3Error(p->db, SQLITE_MISUSE); + sqlite3Error(p->db, SQLITE_MISUSE_BKPT); sqlite3_mutex_leave(p->db->mutex); sqlite3_log(SQLITE_MISUSE, "bind on a busy prepared statement: [%s]", p->zSql); @@ -90929,6 +91260,9 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){ int rc; Vdbe *p = (Vdbe *)pStmt; +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(p->db->mutex); if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){ rc = SQLITE_TOOBIG; @@ -91055,6 +91389,9 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){ Vdbe *v = (Vdbe*)pStmt; int rc; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(v->db->mutex); if( ((int)v->explain)==eMode ){ rc = SQLITE_OK; @@ -91221,10 +91558,16 @@ static UnpackedRecord *vdbeUnpackRecord( ** a field of the row currently being updated or deleted. */ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; Mem *pMem; int rc = SQLITE_OK; +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 || ppValue==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + p = db->pPreUpdate; /* Test that this call is being made from within an SQLITE_DELETE or ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */ if( !p || p->op==SQLITE_INSERT ){ @@ -91285,7 +91628,12 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa ** the number of columns in the row being updated, deleted or inserted. */ SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif return (p ? p->keyinfo.nKeyField : 0); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -91303,7 +91651,12 @@ SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ ** or SET DEFAULT action is considered a trigger. */ SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif return (p ? p->v->nFrame : 0); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -91314,7 +91667,12 @@ SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){ ** only. */ SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif return (p ? p->iBlobWrite : -1); } #endif @@ -91325,10 +91683,16 @@ SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *db){ ** a field of the row currently being updated or inserted. */ SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; int rc = SQLITE_OK; Mem *pMem; +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 || ppValue==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + p = db->pPreUpdate; if( !p || p->op==SQLITE_DELETE ){ rc = SQLITE_MISUSE_BKPT; goto preupdate_new_out; @@ -91407,11 +91771,20 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( void *pOut /* OUT: Write the answer here */ ){ Vdbe *p = (Vdbe*)pStmt; - VdbeOp *aOp = p->aOp; - int nOp = p->nOp; + VdbeOp *aOp; + int nOp; ScanStatus *pScan = 0; int idx; +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 || pOut==0 + || iScanStatusOpSQLITE_SCANSTAT_NCYCLE ){ + return 1; + } +#endif + aOp = p->aOp; + nOp = p->nOp; if( p->pFrame ){ VdbeFrame *pFrame; for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); @@ -91558,7 +91931,7 @@ SQLITE_API int sqlite3_stmt_scanstatus( SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; int ii; - for(ii=0; iinOp; ii++){ + for(ii=0; p!=0 && iinOp; ii++){ Op *pOp = &p->aOp[ii]; pOp->nExec = 0; pOp->nCycle = 0; @@ -92527,11 +92900,11 @@ static SQLITE_NOINLINE int vdbeColumnFromOverflow( sqlite3RCStrRef(pBuf); if( t&1 ){ rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, encoding, - (void(*)(void*))sqlite3RCStrUnref); + sqlite3RCStrUnref); pDest->flags |= MEM_Term; }else{ rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, 0, - (void(*)(void*))sqlite3RCStrUnref); + sqlite3RCStrUnref); } }else{ rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, iOffset, len, pDest); @@ -95406,7 +95779,6 @@ case OP_MakeRecord: { /* NULL value. No change in zPayload */ }else{ u64 v; - u32 i; if( serial_type==7 ){ assert( sizeof(v)==sizeof(pRec->u.r) ); memcpy(&v, &pRec->u.r, sizeof(v)); @@ -95414,12 +95786,17 @@ case OP_MakeRecord: { }else{ v = pRec->u.i; } - len = i = sqlite3SmallTypeSizes[serial_type]; - assert( i>0 ); - while( 1 /*exit-by-break*/ ){ - zPayload[--i] = (u8)(v&0xFF); - if( i==0 ) break; - v >>= 8; + len = sqlite3SmallTypeSizes[serial_type]; + assert( len>=1 && len<=8 && len!=5 && len!=7 ); + switch( len ){ + default: zPayload[7] = (u8)(v&0xff); v >>= 8; + zPayload[6] = (u8)(v&0xff); v >>= 8; + case 6: zPayload[5] = (u8)(v&0xff); v >>= 8; + zPayload[4] = (u8)(v&0xff); v >>= 8; + case 4: zPayload[3] = (u8)(v&0xff); v >>= 8; + case 3: zPayload[2] = (u8)(v&0xff); v >>= 8; + case 2: zPayload[1] = (u8)(v&0xff); v >>= 8; + case 1: zPayload[0] = (u8)(v&0xff); } zPayload += len; } @@ -97536,8 +97913,13 @@ case OP_RowCell: { ** the "primary" delete. The others are all on OPFLAG_FORDELETE ** cursors or else are marked with the AUXDELETE flag. ** -** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row -** change count is incremented (otherwise not). +** If the OPFLAG_NCHANGE (0x01) flag of P2 (NB: P2 not P5) is set, then +** the row change count is incremented (otherwise not). +** +** If the OPFLAG_ISNOOP (0x40) flag of P2 (not P5!) is set, then the +** pre-update-hook for deletes is run, but the btree is otherwise unchanged. +** This happens when the OP_Delete is to be shortly followed by an OP_Insert +** with the same key, causing the btree entry to be overwritten. ** ** P1 must not be pseudo-table. It has to be a real table with ** multiple rows. @@ -98662,13 +99044,41 @@ case OP_CreateBtree: { /* out2 */ /* Opcode: SqlExec * * * P4 * ** ** Run the SQL statement or statements specified in the P4 string. +** Disable Auth and Trace callbacks while those statements are running if +** P1 is true. */ case OP_SqlExec: { + char *zErr; +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth; +#endif + u8 mTrace; + sqlite3VdbeIncrWriteCounter(p, 0); db->nSqlExec++; - rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0); + zErr = 0; +#ifndef SQLITE_OMIT_AUTHORIZATION + xAuth = db->xAuth; +#endif + mTrace = db->mTrace; + if( pOp->p1 ){ +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = 0; +#endif + db->mTrace = 0; + } + rc = sqlite3_exec(db, pOp->p4.z, 0, 0, &zErr); db->nSqlExec--; - if( rc ) goto abort_due_to_error; +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + db->mTrace = mTrace; + if( zErr || rc ){ + sqlite3VdbeError(p, "%s", zErr); + sqlite3_free(zErr); + if( rc==SQLITE_NOMEM ) goto no_mem; + goto abort_due_to_error; + } break; } @@ -99889,6 +100299,53 @@ case OP_VOpen: { /* ncycle */ } #endif /* SQLITE_OMIT_VIRTUALTABLE */ +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VCheck P1 P2 P3 P4 * +** +** P4 is a pointer to a Table object that is a virtual table in schema P1 +** that supports the xIntegrity() method. This opcode runs the xIntegrity() +** method for that virtual table, using P3 as the integer argument. If +** an error is reported back, the table name is prepended to the error +** message and that message is stored in P2. If no errors are seen, +** register P2 is set to NULL. +*/ +case OP_VCheck: { /* out2 */ + Table *pTab; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + char *zErr = 0; + + pOut = &aMem[pOp->p2]; + sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ + assert( pOp->p4type==P4_TABLE ); + pTab = pOp->p4.pTab; + assert( pTab!=0 ); + assert( IsVirtual(pTab) ); + assert( pTab->u.vtab.p!=0 ); + pVtab = pTab->u.vtab.p->pVtab; + assert( pVtab!=0 ); + pModule = pVtab->pModule; + assert( pModule!=0 ); + assert( pModule->iVersion>=4 ); + assert( pModule->xIntegrity!=0 ); + pTab->nTabRef++; + sqlite3VtabLock(pTab->u.vtab.p); + assert( pOp->p1>=0 && pOp->p1nDb ); + rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName, + pOp->p3, &zErr); + sqlite3VtabUnlock(pTab->u.vtab.p); + sqlite3DeleteTable(db, pTab); + if( rc ){ + sqlite3_free(zErr); + goto abort_due_to_error; + } + if( zErr ){ + sqlite3VdbeMemSetStr(pOut, zErr, -1, SQLITE_UTF8, sqlite3_free); + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VInitIn P1 P2 P3 * * ** Synopsis: r[P2]=ValueList(P1,P3) @@ -100918,7 +101375,7 @@ SQLITE_API int sqlite3_blob_open( #endif *ppBlob = 0; #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ + if( !sqlite3SafetyCheckOk(db) || zTable==0 || zColumn==0 ){ return SQLITE_MISUSE_BKPT; } #endif @@ -101480,7 +101937,7 @@ struct SorterFile { struct SorterList { SorterRecord *pList; /* Linked list of records */ u8 *aMemory; /* If non-NULL, bulk memory to hold pList */ - int szPMA; /* Size of pList as PMA in bytes */ + i64 szPMA; /* Size of pList as PMA in bytes */ }; /* @@ -101589,10 +102046,10 @@ typedef int (*SorterCompare)(SortSubtask*,int*,const void*,int,const void*,int); struct SortSubtask { SQLiteThread *pThread; /* Background thread, if any */ int bDone; /* Set if thread is finished but not joined */ + int nPMA; /* Number of PMAs currently in file */ VdbeSorter *pSorter; /* Sorter that owns this sub-task */ UnpackedRecord *pUnpacked; /* Space to unpack a record */ SorterList list; /* List for thread to write to a PMA */ - int nPMA; /* Number of PMAs currently in file */ SorterCompare xCompare; /* Compare function to use */ SorterFile file; /* Temp file for level-0 PMAs */ SorterFile file2; /* Space for other PMAs */ @@ -103066,8 +103523,8 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite( int rc = SQLITE_OK; /* Return Code */ SorterRecord *pNew; /* New list element */ int bFlush; /* True to flush contents of memory to PMA */ - int nReq; /* Bytes of memory required */ - int nPMA; /* Bytes of PMA space required */ + i64 nReq; /* Bytes of memory required */ + i64 nPMA; /* Bytes of PMA space required */ int t; /* serial type of first record field */ assert( pCsr->eCurType==CURTYPE_SORTER ); @@ -104491,7 +104948,8 @@ static sqlite3_module bytecodevtabModule = { /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; @@ -105320,21 +105778,36 @@ static void resolveAlias( } /* -** Subqueries stores the original database, table and column names for their -** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN". -** Check to see if the zSpan given to this routine matches the zDb, zTab, -** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will -** match anything. +** Subqueries store the original database, table and column names for their +** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN", +** and mark the expression-list item by setting ExprList.a[].fg.eEName +** to ENAME_TAB. +** +** Check to see if the zSpan/eEName of the expression-list item passed to this +** routine matches the zDb, zTab, and zCol. If any of zDb, zTab, and zCol are +** NULL then those fields will match anything. Return true if there is a match, +** or false otherwise. +** +** SF_NestedFrom subqueries also store an entry for the implicit rowid (or +** _rowid_, or oid) column by setting ExprList.a[].fg.eEName to ENAME_ROWID, +** and setting zSpan to "DATABASE.TABLE.". This type of pItem +** argument matches if zCol is a rowid alias. If it is not NULL, (*pbRowid) +** is set to 1 if there is this kind of match. */ SQLITE_PRIVATE int sqlite3MatchEName( const struct ExprList_item *pItem, const char *zCol, const char *zTab, - const char *zDb + const char *zDb, + int *pbRowid ){ int n; const char *zSpan; - if( pItem->fg.eEName!=ENAME_TAB ) return 0; + int eEName = pItem->fg.eEName; + if( eEName!=ENAME_TAB && (eEName!=ENAME_ROWID || NEVER(pbRowid==0)) ){ + return 0; + } + assert( pbRowid==0 || *pbRowid==0 ); zSpan = pItem->zEName; for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ @@ -105346,9 +105819,11 @@ SQLITE_PRIVATE int sqlite3MatchEName( return 0; } zSpan += n+1; - if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){ - return 0; + if( zCol ){ + if( eEName==ENAME_TAB && sqlite3StrICmp(zSpan, zCol)!=0 ) return 0; + if( eEName==ENAME_ROWID && sqlite3IsRowid(zCol)==0 ) return 0; } + if( eEName==ENAME_ROWID ) *pbRowid = 1; return 1; } @@ -105481,7 +105956,7 @@ static int lookupName( ){ int i, j; /* Loop counters */ int cnt = 0; /* Number of matching column names */ - int cntTab = 0; /* Number of matching table names */ + int cntTab = 0; /* Number of potential "rowid" matches */ int nSubquery = 0; /* How many levels of subquery */ sqlite3 *db = pParse->db; /* The database connection */ SrcItem *pItem; /* Use for looping over pSrcList items */ @@ -105558,39 +106033,49 @@ static int lookupName( assert( pEList!=0 ); assert( pEList->nExpr==pTab->nCol ); for(j=0; jnExpr; j++){ - if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ + int bRowid = 0; /* True if possible rowid match */ + if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){ continue; } - if( cnt>0 ){ - if( pItem->fg.isUsing==0 - || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 - ){ - /* Two or more tables have the same column name which is - ** not joined by USING. This is an error. Signal as much - ** by clearing pFJMatch and letting cnt go above 1. */ - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else - if( (pItem->fg.jointype & JT_RIGHT)==0 ){ - /* An INNER or LEFT JOIN. Use the left-most table */ - continue; - }else - if( (pItem->fg.jointype & JT_LEFT)==0 ){ - /* A RIGHT JOIN. Use the right-most table */ - cnt = 0; - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else{ - /* For a FULL JOIN, we must construct a coalesce() func */ - extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + if( bRowid==0 ){ + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 + ){ + /* Two or more tables have the same column name which is + ** not joined by USING. This is an error. Signal as much + ** by clearing pFJMatch and letting cnt go above 1. */ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ + continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + } } + cnt++; + hit = 1; + }else if( cnt>0 ){ + /* This is a potential rowid match, but there has already been + ** a real match found. So this can be ignored. */ + continue; } - cnt++; - cntTab = 2; + cntTab++; pMatch = pItem; pExpr->iColumn = j; pEList->a[j].fg.bUsed = 1; - hit = 1; + + /* rowid cannot be part of a USING clause - assert() this. */ + assert( bRowid==0 || pEList->a[j].fg.bUsingTerm==0 ); if( pEList->a[j].fg.bUsingTerm ) break; } if( hit || zTab==0 ) continue; @@ -105785,10 +106270,10 @@ static int lookupName( && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) - && ALWAYS(VisibleRowid(pMatch->pTab)) + && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) ){ cnt = 1; - pExpr->iColumn = -1; + if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; pExpr->affExpr = SQLITE_AFF_INTEGER; } @@ -106241,6 +106726,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0); #endif assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); + assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); zId = pExpr->u.zToken; pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ @@ -106382,6 +106868,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pNC->nNcErr++; } #endif + else if( is_agg==0 && pExpr->pLeft ){ + sqlite3ExprOrderByAggregateError(pParse, pExpr); + pNC->nNcErr++; + } if( is_agg ){ /* Window functions may not be arguments of aggregate functions. ** Or arguments of other window functions. But aggregate functions @@ -106400,6 +106890,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif sqlite3WalkExprList(pWalker, pList); if( is_agg ){ + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); + } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ Select *pSel = pNC->pWinSelect; @@ -106963,10 +107458,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ while( p ){ assert( (p->selFlags & SF_Expanded)!=0 ); assert( (p->selFlags & SF_Resolved)==0 ); - assert( db->suppressErr==0 ); /* SF_Resolved not set if errors suppressed */ p->selFlags |= SF_Resolved; - /* Resolve the expressions in the LIMIT and OFFSET clauses. These ** are not allowed to refer to any names, so pass an empty NameContext. */ @@ -107972,6 +108465,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprForVectorField( */ pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0); if( pRet ){ + ExprSetProperty(pRet, EP_FullSize); pRet->iTable = nField; pRet->iColumn = iField; pRet->pLeft = pVector; @@ -108562,6 +109056,69 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction( return pNew; } +/* +** Report an error when attempting to use an ORDER BY clause within +** the arguments of a non-aggregate function. +*/ +SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse *pParse, Expr *p){ + sqlite3ErrorMsg(pParse, + "ORDER BY may not be used with non-aggregate %#T()", p + ); +} + +/* +** Attach an ORDER BY clause to a function call. +** +** functionname( arguments ORDER BY sortlist ) +** \_____________________/ \______/ +** pExpr pOrderBy +** +** The ORDER BY clause is inserted into a new Expr node of type TK_ORDER +** and added to the Expr.pLeft field of the parent TK_FUNCTION node. +*/ +SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The function call to which ORDER BY is to be added */ + ExprList *pOrderBy /* The ORDER BY clause to add */ +){ + Expr *pOB; + sqlite3 *db = pParse->db; + if( NEVER(pOrderBy==0) ){ + assert( db->mallocFailed ); + return; + } + if( pExpr==0 ){ + assert( db->mallocFailed ); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + assert( pExpr->op==TK_FUNCTION ); + assert( pExpr->pLeft==0 ); + assert( ExprUseXList(pExpr) ); + if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){ + /* Ignore ORDER BY on zero-argument aggregates */ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3ExprListDelete, + pOrderBy); + return; + } + if( IsWindowFunc(pExpr) ){ + sqlite3ExprOrderByAggregateError(pParse, pExpr); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + + pOB = sqlite3ExprAlloc(db, TK_ORDER, 0, 0); + if( pOB==0 ){ + sqlite3ExprListDelete(db, pOrderBy); + return; + } + pOB->x.pList = pOrderBy; + assert( ExprUseXList(pOB) ); + pExpr->pLeft = pOB; + ExprSetProperty(pOB, EP_FullSize); +} + /* ** Check to see if a function is usable according to current access ** rules: @@ -108815,11 +109372,7 @@ static int dupedExprStructSize(const Expr *p, int flags){ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( EXPR_FULLSIZE<=0xfff ); assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); - if( 0==flags || p->op==TK_SELECT_COLUMN -#ifndef SQLITE_OMIT_WINDOWFUNC - || ExprHasProperty(p, EP_WinFunc) -#endif - ){ + if( 0==flags || ExprHasProperty(p, EP_FullSize) ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); @@ -108850,56 +109403,93 @@ static int dupedExprNodeSize(const Expr *p, int flags){ /* ** Return the number of bytes required to create a duplicate of the -** expression passed as the first argument. The second argument is a -** mask containing EXPRDUP_XXX flags. +** expression passed as the first argument. ** ** The value returned includes space to create a copy of the Expr struct ** itself and the buffer referred to by Expr.u.zToken, if any. ** -** If the EXPRDUP_REDUCE flag is set, then the return value includes -** space to duplicate all Expr nodes in the tree formed by Expr.pLeft -** and Expr.pRight variables (but not for any structures pointed to or -** descended from the Expr.x.pList or Expr.x.pSelect variables). +** The return value includes space to duplicate all Expr nodes in the +** tree formed by Expr.pLeft and Expr.pRight, but not any other +** substructure such as Expr.x.pList, Expr.x.pSelect, and Expr.y.pWin. */ -static int dupedExprSize(const Expr *p, int flags){ - int nByte = 0; - if( p ){ - nByte = dupedExprNodeSize(p, flags); - if( flags&EXPRDUP_REDUCE ){ - nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags); - } - } +static int dupedExprSize(const Expr *p){ + int nByte; + assert( p!=0 ); + nByte = dupedExprNodeSize(p, EXPRDUP_REDUCE); + if( p->pLeft ) nByte += dupedExprSize(p->pLeft); + if( p->pRight ) nByte += dupedExprSize(p->pRight); + assert( nByte==ROUND8(nByte) ); return nByte; } /* -** This function is similar to sqlite3ExprDup(), except that if pzBuffer -** is not NULL then *pzBuffer is assumed to point to a buffer large enough -** to store the copy of expression p, the copies of p->u.zToken -** (if applicable), and the copies of the p->pLeft and p->pRight expressions, -** if any. Before returning, *pzBuffer is set to the first byte past the -** portion of the buffer copied into by this function. +** An EdupBuf is a memory allocation used to stored multiple Expr objects +** together with their Expr.zToken content. This is used to help implement +** compression while doing sqlite3ExprDup(). The top-level Expr does the +** allocation for itself and many of its decendents, then passes an instance +** of the structure down into exprDup() so that they decendents can have +** access to that memory. */ -static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){ +typedef struct EdupBuf EdupBuf; +struct EdupBuf { + u8 *zAlloc; /* Memory space available for storage */ +#ifdef SQLITE_DEBUG + u8 *zEnd; /* First byte past the end of memory */ +#endif +}; + +/* +** This function is similar to sqlite3ExprDup(), except that if pEdupBuf +** is not NULL then it points to memory that can be used to store a copy +** of the input Expr p together with its p->u.zToken (if any). pEdupBuf +** is updated with the new buffer tail prior to returning. +*/ +static Expr *exprDup( + sqlite3 *db, /* Database connection (for memory allocation) */ + const Expr *p, /* Expr tree to be duplicated */ + int dupFlags, /* EXPRDUP_REDUCE for compression. 0 if not */ + EdupBuf *pEdupBuf /* Preallocated storage space, or NULL */ +){ Expr *pNew; /* Value to return */ - u8 *zAlloc; /* Memory space from which to build Expr object */ + EdupBuf sEdupBuf; /* Memory space from which to build Expr object */ u32 staticFlag; /* EP_Static if space not obtained from malloc */ + int nToken = -1; /* Space needed for p->u.zToken. -1 means unknown */ assert( db!=0 ); assert( p ); assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE ); - assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE ); + assert( pEdupBuf==0 || dupFlags==EXPRDUP_REDUCE ); /* Figure out where to write the new Expr structure. */ - if( pzBuffer ){ - zAlloc = *pzBuffer; + if( pEdupBuf ){ + sEdupBuf.zAlloc = pEdupBuf->zAlloc; +#ifdef SQLITE_DEBUG + sEdupBuf.zEnd = pEdupBuf->zEnd; +#endif staticFlag = EP_Static; - assert( zAlloc!=0 ); + assert( sEdupBuf.zAlloc!=0 ); + assert( dupFlags==EXPRDUP_REDUCE ); }else{ - zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags)); + int nAlloc; + if( dupFlags ){ + nAlloc = dupedExprSize(p); + }else if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30NN(p->u.zToken)+1; + nAlloc = ROUND8(EXPR_FULLSIZE + nToken); + }else{ + nToken = 0; + nAlloc = ROUND8(EXPR_FULLSIZE); + } + assert( nAlloc==ROUND8(nAlloc) ); + sEdupBuf.zAlloc = sqlite3DbMallocRawNN(db, nAlloc); +#ifdef SQLITE_DEBUG + sEdupBuf.zEnd = sEdupBuf.zAlloc ? sEdupBuf.zAlloc+nAlloc : 0; +#endif + staticFlag = 0; } - pNew = (Expr *)zAlloc; + pNew = (Expr *)sEdupBuf.zAlloc; + assert( EIGHT_BYTE_ALIGNMENT(pNew) ); if( pNew ){ /* Set nNewSize to the size allocated for the structure pointed to @@ -108908,22 +109498,27 @@ static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){ ** by the copy of the p->u.zToken string (if any). */ const unsigned nStructSize = dupedExprStructSize(p, dupFlags); - const int nNewSize = nStructSize & 0xfff; - int nToken; - if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - nToken = sqlite3Strlen30(p->u.zToken) + 1; - }else{ - nToken = 0; + int nNewSize = nStructSize & 0xfff; + if( nToken<0 ){ + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30(p->u.zToken) + 1; + }else{ + nToken = 0; + } } if( dupFlags ){ + assert( (int)(sEdupBuf.zEnd - sEdupBuf.zAlloc) >= nNewSize+nToken ); assert( ExprHasProperty(p, EP_Reduced)==0 ); - memcpy(zAlloc, p, nNewSize); + memcpy(sEdupBuf.zAlloc, p, nNewSize); }else{ u32 nSize = (u32)exprStructSize(p); - memcpy(zAlloc, p, nSize); + assert( (int)(sEdupBuf.zEnd - sEdupBuf.zAlloc) >= + (int)EXPR_FULLSIZE+nToken ); + memcpy(sEdupBuf.zAlloc, p, nSize); if( nSizeu.zToken string, if any. */ - if( nToken ){ - char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize]; + assert( nToken>=0 ); + if( nToken>0 ){ + char *zToken = pNew->u.zToken = (char*)&sEdupBuf.zAlloc[nNewSize]; memcpy(zToken, p->u.zToken, nToken); + nNewSize += nToken; } + sEdupBuf.zAlloc += ROUND8(nNewSize); + + if( ((p->flags|pNew->flags)&(EP_TokenOnly|EP_Leaf))==0 ){ - if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){ /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ if( ExprUseXSelect(p) ){ pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags); }else{ - pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags); + pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, + p->op!=TK_ORDER ? dupFlags : 0); } - } - /* Fill in pNew->pLeft and pNew->pRight. */ - if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){ - zAlloc += dupedExprNodeSize(p, dupFlags); - if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){ - pNew->pLeft = p->pLeft ? - exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0; - pNew->pRight = p->pRight ? - exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0; - } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(p, EP_WinFunc) ){ pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin); assert( ExprHasProperty(pNew, EP_WinFunc) ); } #endif /* SQLITE_OMIT_WINDOWFUNC */ - if( pzBuffer ){ - *pzBuffer = zAlloc; - } - }else{ - if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ - if( pNew->op==TK_SELECT_COLUMN ){ + + /* Fill in pNew->pLeft and pNew->pRight. */ + if( dupFlags ){ + if( p->op==TK_SELECT_COLUMN ){ pNew->pLeft = p->pLeft; - assert( p->pRight==0 || p->pRight==p->pLeft - || ExprHasProperty(p->pLeft, EP_Subquery) ); + assert( p->pRight==0 + || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); + }else{ + pNew->pLeft = p->pLeft ? + exprDup(db, p->pLeft, EXPRDUP_REDUCE, &sEdupBuf) : 0; + } + pNew->pRight = p->pRight ? + exprDup(db, p->pRight, EXPRDUP_REDUCE, &sEdupBuf) : 0; + }else{ + if( p->op==TK_SELECT_COLUMN ){ + pNew->pLeft = p->pLeft; + assert( p->pRight==0 + || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); }else{ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); } @@ -108981,6 +109582,8 @@ static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){ } } } + if( pEdupBuf ) memcpy(pEdupBuf, &sEdupBuf, sizeof(sEdupBuf)); + assert( sEdupBuf.zAlloc <= sEdupBuf.zEnd ); return pNew; } @@ -109245,11 +109848,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags) ** initially NULL, then create a new expression list. ** ** The pList argument must be either NULL or a pointer to an ExprList -** obtained from a prior call to sqlite3ExprListAppend(). This routine -** may not be used with an ExprList obtained from sqlite3ExprListDup(). -** Reason: This routine assumes that the number of slots in pList->a[] -** is a power of two. That is true for sqlite3ExprListAppend() returns -** but is not necessarily true from the return value of sqlite3ExprListDup(). +** obtained from a prior call to sqlite3ExprListAppend(). ** ** If a memory allocation error occurs, the entire list is freed and ** NULL is returned. If non-NULL is returned, then it is guaranteed @@ -110075,6 +110674,27 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ return 0; } +/* +** Return a pointer to a buffer containing a usable rowid alias for table +** pTab. An alias is usable if there is not an explicit user-defined column +** of the same name. +*/ +SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab){ + const char *azOpt[] = {"_ROWID_", "ROWID", "OID"}; + int ii; + assert( VisibleRowid(pTab) ); + for(ii=0; iinCol; iCol++){ + if( sqlite3_stricmp(azOpt[ii], pTab->aCol[iCol].zCnName)==0 ) break; + } + if( iCol==pTab->nCol ){ + return azOpt[ii]; + } + } + return 0; +} + /* ** pX is the RHS of an IN operator. If pX is a SELECT statement ** that can be simplified to a direct table access, then return @@ -111612,6 +112232,41 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup( } +/* +** Expresion pExpr is guaranteed to be a TK_COLUMN or equivalent. This +** function checks the Parse.pIdxPartExpr list to see if this column +** can be replaced with a constant value. If so, it generates code to +** put the constant value in a register (ideally, but not necessarily, +** register iTarget) and returns the register number. +** +** Or, if the TK_COLUMN cannot be replaced by a constant, zero is +** returned. +*/ +static int exprPartidxExprLookup(Parse *pParse, Expr *pExpr, int iTarget){ + IndexedExpr *p; + for(p=pParse->pIdxPartExpr; p; p=p->pIENext){ + if( pExpr->iColumn==p->iIdxCol && pExpr->iTable==p->iDataCur ){ + Vdbe *v = pParse->pVdbe; + int addr = 0; + int ret; + + if( p->bMaybeNullRow ){ + addr = sqlite3VdbeAddOp1(v, OP_IfNullRow, p->iIdxCur); + } + ret = sqlite3ExprCodeTarget(pParse, p->pExpr, iTarget); + sqlite3VdbeAddOp4(pParse->pVdbe, OP_Affinity, ret, 1, 0, + (const char*)&p->aff, 1); + if( addr ){ + sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeChangeP3(v, addr, ret); + } + return ret; + } + } + return 0; +} + + /* ** Generate code into the current Vdbe to evaluate the given ** expression. Attempt to store the results in register "target". @@ -111648,6 +112303,7 @@ expr_code_doover: assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); op = pExpr->op; } + assert( op!=TK_ORDER ); switch( op ){ case TK_AGG_COLUMN: { AggInfo *pAggInfo = pExpr->pAggInfo; @@ -111661,7 +112317,7 @@ expr_code_doover: #ifdef SQLITE_VDBE_COVERAGE /* Verify that the OP_Null above is exercised by tests ** tag-20230325-2 */ - sqlite3VdbeAddOp2(v, OP_NotNull, target, 1); + sqlite3VdbeAddOp3(v, OP_NotNull, target, 1, 20230325); VdbeCoverageNeverTaken(v); #endif break; @@ -111769,6 +112425,11 @@ expr_code_doover: iTab = pParse->iSelfTab - 1; } } + else if( pParse->pIdxPartExpr + && 0!=(r1 = exprPartidxExprLookup(pParse, pExpr, target)) + ){ + return r1; + } assert( ExprUseYTab(pExpr) ); assert( pExpr->y.pTab!=0 ); iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, @@ -112429,7 +113090,7 @@ expr_code_doover: ** once. If no functions are involved, then factor the code out and put it at ** the end of the prepared statement in the initialization section. ** -** If regDest>=0 then the result is always stored in that register and the +** If regDest>0 then the result is always stored in that register and the ** result is not reusable. If regDest<0 then this routine is free to ** store the value wherever it wants. The register where the expression ** is stored is returned. When regDest<0, two identical expressions might @@ -112444,6 +113105,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce( ){ ExprList *p; assert( ConstFactorOk(pParse) ); + assert( regDest!=0 ); p = pParse->pConstExpr; if( regDest<0 && p ){ struct ExprList_item *pItem; @@ -113728,6 +114390,12 @@ SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList assert( pExpr->op==TK_AGG_FUNCTION ); assert( ExprUseXList(pExpr) ); sqlite3WalkExprList(&w, pExpr->x.pList); + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + assert( pExpr->pLeft->x.pList!=0 ); + sqlite3WalkExprList(&w, pExpr->pLeft->x.pList); + } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); @@ -113992,14 +114660,42 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ u8 enc = ENC(pParse->db); i = addAggInfoFunc(pParse->db, pAggInfo); if( i>=0 ){ + int nArg; assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); pItem = &pAggInfo->aFunc[i]; pItem->pFExpr = pExpr; assert( ExprUseUToken(pExpr) ); + nArg = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; pItem->pFunc = sqlite3FindFunction(pParse->db, - pExpr->u.zToken, - pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0); - if( pExpr->flags & EP_Distinct ){ + pExpr->u.zToken, nArg, enc, 0); + assert( pItem->bOBUnique==0 ); + if( pExpr->pLeft + && (pItem->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)==0 + ){ + /* The NEEDCOLL test above causes any ORDER BY clause on + ** aggregate min() or max() to be ignored. */ + ExprList *pOBList; + assert( nArg>0 ); + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + pItem->iOBTab = pParse->nTab++; + pOBList = pExpr->pLeft->x.pList; + assert( pOBList->nExpr>0 ); + assert( pItem->bOBUnique==0 ); + if( pOBList->nExpr==1 + && nArg==1 + && sqlite3ExprCompare(0,pOBList->a[0].pExpr, + pExpr->x.pList->a[0].pExpr,0)==0 + ){ + pItem->bOBPayload = 0; + pItem->bOBUnique = ExprHasProperty(pExpr, EP_Distinct); + }else{ + pItem->bOBPayload = 1; + } + }else{ + pItem->iOBTab = -1; + } + if( ExprHasProperty(pExpr, EP_Distinct) && !pItem->bOBUnique ){ pItem->iDistinct = pParse->nTab++; }else{ pItem->iDistinct = -1; @@ -114635,14 +115331,19 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ /* Verify that constraints are still satisfied */ if( pNew->pCheck!=0 || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0) + || (pTab->tabFlags & TF_Strict)!=0 ){ sqlite3NestedParse(pParse, "SELECT CASE WHEN quick_check GLOB 'CHECK*'" " THEN raise(ABORT,'CHECK constraint failed')" + " WHEN quick_check GLOB 'non-* value in*'" + " THEN raise(ABORT,'type mismatch on DEFAULT')" " ELSE raise(ABORT,'NOT NULL constraint failed')" " END" " FROM pragma_quick_check(%Q,%Q)" - " WHERE quick_check GLOB 'CHECK*' OR quick_check GLOB 'NULL*'", + " WHERE quick_check GLOB 'CHECK*'" + " OR quick_check GLOB 'NULL*'" + " OR quick_check GLOB 'non-* value in*'", zTab, zDb ); } @@ -119621,19 +120322,14 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ */ if( pParse->pAinc ) sqlite3AutoincrementBegin(pParse); - /* Code constant expressions that where factored out of inner loops. - ** - ** The pConstExpr list might also contain expressions that we simply - ** want to keep around until the Parse object is deleted. Such - ** expressions have iConstExprReg==0. Do not generate code for - ** those expressions, of course. + /* Code constant expressions that were factored out of inner loops. */ if( pParse->pConstExpr ){ ExprList *pEL = pParse->pConstExpr; pParse->okConstFactor = 0; for(i=0; inExpr; i++){ - int iReg = pEL->a[i].u.iConstExprReg; - sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg); + assert( pEL->a[i].u.iConstExprReg>0 ); + sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); } } @@ -120787,20 +121483,13 @@ SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ } #endif -/* -** Name of the special TEMP trigger used to implement RETURNING. The -** name begins with "sqlite_" so that it is guaranteed not to collide -** with any application-generated triggers. -*/ -#define RETURNING_TRIGGER_NAME "sqlite_returning" - /* ** Clean up the data structures associated with the RETURNING clause. */ static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ Hash *pHash; pHash = &(db->aDb[1].pSchema->trigHash); - sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, 0); + sqlite3HashInsert(pHash, pRet->zName, 0); sqlite3ExprListDelete(db, pRet->pReturnEL); sqlite3DbFree(db, pRet); } @@ -120843,7 +121532,9 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); testcase( pParse->earlyCleanup ); if( db->mallocFailed ) return; - pRet->retTrig.zName = RETURNING_TRIGGER_NAME; + sqlite3_snprintf(sizeof(pRet->zName), pRet->zName, + "sqlite_returning_%p", pParse); + pRet->retTrig.zName = pRet->zName; pRet->retTrig.op = TK_RETURNING; pRet->retTrig.tr_tm = TRIGGER_AFTER; pRet->retTrig.bReturning = 1; @@ -120854,9 +121545,9 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ pRet->retTStep.pTrig = &pRet->retTrig; pRet->retTStep.pExprList = pList; pHash = &(db->aDb[1].pSchema->trigHash); - assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 + assert( sqlite3HashFind(pHash, pRet->zName)==0 || pParse->nErr || pParse->ifNotExists ); - if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig) + if( sqlite3HashInsert(pHash, pRet->zName, &pRet->retTrig) ==&pRet->retTrig ){ sqlite3OomFault(db); } @@ -122300,6 +122991,17 @@ SQLITE_PRIVATE void sqlite3EndTable( /* Reparse everything to update our internal data structures */ sqlite3VdbeAddParseSchemaOp(v, iDb, sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0); + + /* Test for cycles in generated columns and illegal expressions + ** in CHECK constraints and in DEFAULT clauses. */ + if( p->tabFlags & TF_HasGenerated ){ + sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, + sqlite3MPrintf(db, "SELECT*FROM\"%w\".\"%w\"", + db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); + } + sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, + sqlite3MPrintf(db, "PRAGMA \"%w\".integrity_check(%Q)", + db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); } /* Add the table to the in-memory representation of the database. @@ -127902,7 +128604,8 @@ static void hexFunc( *(z++) = hexdigits[c&0xf]; } *z = 0; - sqlite3_result_text(context, zHex, n*2, sqlite3_free); + sqlite3_result_text64(context, zHex, (u64)(z-zHex), + sqlite3_free, SQLITE_UTF8); } } @@ -128196,6 +128899,81 @@ static void trimFunc( sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); } +/* The core implementation of the CONCAT(...) and CONCAT_WS(SEP,...) +** functions. +** +** Return a string value that is the concatenation of all non-null +** entries in argv[]. Use zSep as the separator. +*/ +static void concatFuncCore( + sqlite3_context *context, + int argc, + sqlite3_value **argv, + int nSep, + const char *zSep +){ + i64 j, k, n = 0; + int i; + char *z; + for(i=0; i0 ){ + const char *v = (const char*)sqlite3_value_text(argv[i]); + if( v!=0 ){ + if( j>0 && nSep>0 ){ + memcpy(&z[j], zSep, nSep); + j += nSep; + } + memcpy(&z[j], v, k); + j += k; + } + } + } + z[j] = 0; + assert( j<=n ); + sqlite3_result_text64(context, z, j, sqlite3_free, SQLITE_UTF8); +} + +/* +** The CONCAT(...) function. Generate a string result that is the +** concatentation of all non-null arguments. +*/ +static void concatFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + concatFuncCore(context, argc, argv, 0, ""); +} + +/* +** The CONCAT_WS(separator, ...) function. +** +** Generate a string that is the concatenation of 2nd through the Nth +** argument. Use the first argument (which must be non-NULL) as the +** separator. +*/ +static void concatwsFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int nSep = sqlite3_value_bytes(argv[0]); + const char *zSep = (const char*)sqlite3_value_text(argv[0]); + if( zSep==0 ) return; + concatFuncCore(context, argc-1, argv+1, nSep, zSep); +} + #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION /* @@ -128617,6 +129395,7 @@ static void minMaxFinalize(sqlite3_context *context){ /* ** group_concat(EXPR, ?SEPARATOR?) +** string_agg(EXPR, SEPARATOR) ** ** The SEPARATOR goes before the EXPR string. This is tragic. The ** groupConcatInverse() implementation would have been easier if the @@ -129207,6 +129986,11 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(hex, 1, 0, 0, hexFunc ), FUNCTION(unhex, 1, 0, 0, unhexFunc ), FUNCTION(unhex, 2, 0, 0, unhexFunc ), + FUNCTION(concat, -1, 0, 0, concatFunc ), + FUNCTION(concat, 0, 0, 0, 0 ), + FUNCTION(concat_ws, -1, 0, 0, concatwsFunc ), + FUNCTION(concat_ws, 0, 0, 0, 0 ), + FUNCTION(concat_ws, 1, 0, 0, 0 ), INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ), VFUNCTION(random, 0, 0, 0, randomFunc ), VFUNCTION(randomblob, 1, 0, 0, randomBlob ), @@ -129236,6 +130020,8 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), + WAGGREGATE(string_agg, 2, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), #ifdef SQLITE_CASE_SENSITIVE_LIKE @@ -130178,6 +130964,7 @@ static int isSetNullAction(Parse *pParse, FKey *pFKey){ if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull) || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull) ){ + assert( (pTop->db->flags & SQLITE_FkNoAction)==0 ); return 1; } } @@ -130372,6 +131159,8 @@ SQLITE_PRIVATE void sqlite3FkCheck( } if( regOld!=0 ){ int eAction = pFKey->aAction[aChange!=0]; + if( (db->flags & SQLITE_FkNoAction) ) eAction = OE_None; + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); /* If this is a deferred FK constraint, or a CASCADE or SET NULL ** action applies, then any foreign key violations caused by @@ -130487,7 +131276,11 @@ SQLITE_PRIVATE int sqlite3FkRequired( /* Check if any parent key columns are being modified. */ for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ if( fkParentIsModified(pTab, p, aChange, chngRowid) ){ - if( p->aAction[1]!=OE_None ) return 2; + if( (pParse->db->flags & SQLITE_FkNoAction)==0 + && p->aAction[1]!=OE_None + ){ + return 2; + } bHaveFK = 1; } } @@ -130537,6 +131330,7 @@ static Trigger *fkActionTrigger( int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ action = pFKey->aAction[iAction]; + if( (db->flags & SQLITE_FkNoAction) ) action = OE_None; if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){ return 0; } @@ -134492,6 +135286,9 @@ struct sqlite3_api_routines { int (*is_interrupted)(sqlite3*); /* Version 3.43.0 and later */ int (*stmt_explain)(sqlite3_stmt*,int); + /* Version 3.44.0 and later */ + void *(*get_clientdata)(sqlite3*,const char*); + int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); }; /* @@ -134822,6 +135619,9 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_is_interrupted sqlite3_api->is_interrupted /* Version 3.43.0 and later */ #define sqlite3_stmt_explain sqlite3_api->stmt_explain +/* Version 3.44.0 and later */ +#define sqlite3_get_clientdata sqlite3_api->get_clientdata +#define sqlite3_set_clientdata sqlite3_api->set_clientdata #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) @@ -135340,7 +136140,10 @@ static const sqlite3_api_routines sqlite3Apis = { /* Version 3.41.0 and later */ sqlite3_is_interrupted, /* Version 3.43.0 and later */ - sqlite3_stmt_explain + sqlite3_stmt_explain, + /* Version 3.44.0 and later */ + sqlite3_get_clientdata, + sqlite3_set_clientdata }; /* True if x is the directory separator character @@ -135556,6 +136359,9 @@ SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){ ** default so as not to open security holes in older applications. */ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(db->mutex); if( onoff ){ db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc; @@ -135605,6 +136411,9 @@ SQLITE_API int sqlite3_auto_extension( void (*xInit)(void) ){ int rc = SQLITE_OK; +#ifdef SQLITE_ENABLE_API_ARMOR + if( xInit==0 ) return SQLITE_MISUSE_BKPT; +#endif #ifndef SQLITE_OMIT_AUTOINIT rc = sqlite3_initialize(); if( rc ){ @@ -135657,6 +136466,9 @@ SQLITE_API int sqlite3_cancel_auto_extension( int i; int n = 0; wsdAutoextInit; +#ifdef SQLITE_ENABLE_API_ARMOR + if( xInit==0 ) return 0; +#endif sqlite3_mutex_enter(mutex); for(i=(int)wsdAutoext.nExt-1; i>=0; i--){ if( wsdAutoext.aExt[i]==xInit ){ @@ -137526,7 +138338,11 @@ SQLITE_PRIVATE void sqlite3Pragma( #endif if( sqlite3GetBoolean(zRight, 0) ){ - db->flags |= mask; + if( (mask & SQLITE_WriteSchema)==0 + || (db->flags & SQLITE_Defensive)==0 + ){ + db->flags |= mask; + } }else{ db->flags &= ~mask; if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; @@ -138159,8 +138975,31 @@ SQLITE_PRIVATE void sqlite3Pragma( int r2; /* Previous key for WITHOUT ROWID tables */ int mxCol; /* Maximum non-virtual column number */ - if( !IsOrdinaryTable(pTab) ) continue; if( pObjTab && pObjTab!=pTab ) continue; + if( !IsOrdinaryTable(pTab) ){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3_vtab *pVTab; + int a1; + if( !IsVirtual(pTab) ) continue; + if( pTab->nCol<=0 ){ + const char *zMod = pTab->u.vtab.azArg[0]; + if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; + } + sqlite3ViewGetColumnNames(pParse, pTab); + if( pTab->u.vtab.p==0 ) continue; + pVTab = pTab->u.vtab.p->pVtab; + if( NEVER(pVTab==0) ) continue; + if( NEVER(pVTab->pModule==0) ) continue; + if( pVTab->pModule->iVersion<4 ) continue; + if( pVTab->pModule->xIntegrity==0 ) continue; + sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, a1); +#endif + continue; + } if( isQuick || HasRowid(pTab) ){ pPk = 0; r2 = 0; @@ -139286,7 +140125,8 @@ static const sqlite3_module pragmaVtabModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* @@ -139910,8 +140750,6 @@ SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){ db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; assert( pParse->db->pParse==pParse ); db->pParse = pParse->pOuterParse; - pParse->db = 0; - pParse->disableLookaside = 0; } /* @@ -140849,6 +141687,7 @@ static void unsetJoinExpr(Expr *p, int iTable, int nullable){ } if( p->op==TK_FUNCTION ){ assert( ExprUseXList(p) ); + assert( p->pLeft==0 ); if( p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ @@ -146509,6 +147348,7 @@ static int selectExpander(Walker *pWalker, Select *p){ char *zTName = 0; /* text of name of TABLE */ int iErrOfst; if( pE->op==TK_DOT ){ + assert( (selFlags & SF_NestedFrom)==0 ); assert( pE->pLeft!=0 ); assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); zTName = pE->pLeft->u.zToken; @@ -146519,6 +147359,7 @@ static int selectExpander(Walker *pWalker, Select *p){ iErrOfst = pE->w.iOfst; } for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + int nAdd; /* Number of cols including rowid */ Table *pTab = pFrom->pTab; /* Table for this data source */ ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ char *zTabName; /* AS name for this data source */ @@ -146536,6 +147377,7 @@ static int selectExpander(Walker *pWalker, Select *p){ pNestedFrom = pFrom->pSelect->pEList; assert( pNestedFrom!=0 ); assert( pNestedFrom->nExpr==pTab->nCol ); + assert( VisibleRowid(pTab)==0 ); }else{ if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ continue; @@ -146566,33 +147408,48 @@ static int selectExpander(Walker *pWalker, Select *p){ }else{ pUsing = 0; } - for(j=0; jnCol; j++){ - char *zName = pTab->aCol[j].zCnName; + + nAdd = pTab->nCol + (VisibleRowid(pTab) && (selFlags&SF_NestedFrom)); + for(j=0; ja[j], 0, zTName, 0)==0 - ){ - continue; - } + if( j==pTab->nCol ){ + zName = sqlite3RowidAlias(pTab); + if( zName==0 ) continue; + }else{ + zName = pTab->aCol[j].zCnName; - /* If a column is marked as 'hidden', omit it from the expanded - ** result-set list unless the SELECT has the SF_IncludeHidden - ** bit set. - */ - if( (p->selFlags & SF_IncludeHidden)==0 - && IsHiddenColumn(&pTab->aCol[j]) - ){ - continue; - } - if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 - && zTName==0 - && (selFlags & (SF_NestedFrom))==0 - ){ - continue; + /* If pTab is actually an SF_NestedFrom sub-select, do not + ** expand any ENAME_ROWID columns. */ + if( pNestedFrom && pNestedFrom->a[j].fg.eEName==ENAME_ROWID ){ + continue; + } + + if( zTName + && pNestedFrom + && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0, 0)==0 + ){ + continue; + } + + /* If a column is marked as 'hidden', omit it from the expanded + ** result-set list unless the SELECT has the SF_IncludeHidden + ** bit set. + */ + if( (p->selFlags & SF_IncludeHidden)==0 + && IsHiddenColumn(&pTab->aCol[j]) + ){ + continue; + } + if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + && zTName==0 + && (selFlags & (SF_NestedFrom))==0 + ){ + continue; + } } + assert( zName ); tableSeen = 1; if( i>0 && zTName==0 && (selFlags & SF_NestedFrom)==0 ){ @@ -146642,11 +147499,11 @@ static int selectExpander(Walker *pWalker, Select *p){ zSchemaName, zTabName, zName); testcase( pX->zEName==0 ); } - pX->fg.eEName = ENAME_TAB; + pX->fg.eEName = (j==pTab->nCol ? ENAME_ROWID : ENAME_TAB); if( (pFrom->fg.isUsing && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0) || (pUsing && sqlite3IdListIndex(pUsing, zName)>=0) - || (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + || (jnCol && (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)) ){ pX->fg.bNoExpand = 1; } @@ -146867,8 +147724,14 @@ static void analyzeAggFuncArgs( pNC->ncFlags |= NC_InAggFunc; for(i=0; inFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pFExpr; + assert( pExpr->op==TK_FUNCTION || pExpr->op==TK_AGG_FUNCTION ); assert( ExprUseXList(pExpr) ); sqlite3ExprAnalyzeAggList(pNC, pExpr->x.pList); + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + sqlite3ExprAnalyzeAggList(pNC, pExpr->pLeft->x.pList); + } #ifndef SQLITE_OMIT_WINDOWFUNC assert( !IsWindowFunc(pExpr) ); if( ExprHasProperty(pExpr, EP_WinFunc) ){ @@ -147023,6 +147886,32 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ pFunc->pFunc->zName)); } } + if( pFunc->iOBTab>=0 ){ + ExprList *pOBList; + KeyInfo *pKeyInfo; + int nExtra = 0; + assert( pFunc->pFExpr->pLeft!=0 ); + assert( pFunc->pFExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pFunc->pFExpr->pLeft) ); + pOBList = pFunc->pFExpr->pLeft->x.pList; + if( !pFunc->bOBUnique ){ + nExtra++; /* One extra column for the OP_Sequence */ + } + if( pFunc->bOBPayload ){ + /* extra columns for the function arguments */ + assert( ExprUseXList(pFunc->pFExpr) ); + nExtra += pFunc->pFExpr->x.pList->nExpr; + } + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra); + if( !pFunc->bOBUnique && pParse->nErr==0 ){ + pKeyInfo->nKeyField++; + } + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + pFunc->iOBTab, pOBList->nExpr+nExtra, 0, + (char*)pKeyInfo, P4_KEYINFO); + ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s(ORDER BY)", + pFunc->pFunc->zName)); + } } } @@ -147038,13 +147927,46 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); pList = pF->pFExpr->x.pList; + if( pF->iOBTab>=0 ){ + /* For an ORDER BY aggregate, calls to OP_AggStep where deferred and + ** all content was stored in emphermal table pF->iOBTab. Extract that + ** content now (in ORDER BY order) and make all calls to OP_AggStep + ** before doing the OP_AggFinal call. */ + int iTop; /* Start of loop for extracting columns */ + int nArg; /* Number of columns to extract */ + int nKey; /* Key columns to be skipped */ + int regAgg; /* Extract into this array */ + int j; /* Loop counter */ + + nArg = pList->nExpr; + regAgg = sqlite3GetTempRange(pParse, nArg); + + if( pF->bOBPayload==0 ){ + nKey = 0; + }else{ + assert( pF->pFExpr->pLeft!=0 ); + assert( ExprUseXList(pF->pFExpr->pLeft) ); + assert( pF->pFExpr->pLeft->x.pList!=0 ); + nKey = pF->pFExpr->pLeft->x.pList->nExpr; + if( ALWAYS(!pF->bOBUnique) ) nKey++; + } + iTop = sqlite3VdbeAddOp1(v, OP_Rewind, pF->iOBTab); VdbeCoverage(v); + for(j=nArg-1; j>=0; j--){ + sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j); + } + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, iTop); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); + } sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i), pList ? pList->nExpr : 0); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); } } - /* ** Generate code that will update the accumulator memory cells for an ** aggregate based on the current cursor position. @@ -147053,6 +147975,13 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ ** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator ** registers if register regAcc contains 0. The caller will take care ** of setting and clearing regAcc. +** +** For an ORDER BY aggregate, the actual accumulator memory cell update +** is deferred until after all input rows have been received, so that they +** can be run in the requested order. In that case, instead of invoking +** OP_AggStep to update the accumulator, just add the arguments that would +** have been passed into OP_AggStep into the sorting ephemeral table +** (along with the appropriate sort key). */ static void updateAccumulator( Parse *pParse, @@ -147074,6 +148003,8 @@ static void updateAccumulator( int nArg; int addrNext = 0; int regAgg; + int regAggSz = 0; + int regDistinct = 0; ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); assert( !IsWindowFunc(pF->pFExpr) ); @@ -147100,9 +148031,44 @@ static void updateAccumulator( addrNext = sqlite3VdbeMakeLabel(pParse); sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL); } - if( pList ){ + if( pF->iOBTab>=0 ){ + /* Instead of invoking AggStep, we must push the arguments that would + ** have been passed to AggStep onto the sorting table. */ + int jj; /* Registered used so far in building the record */ + ExprList *pOBList; /* The ORDER BY clause */ + assert( pList!=0 ); + nArg = pList->nExpr; + assert( nArg>0 ); + assert( pF->pFExpr->pLeft!=0 ); + assert( pF->pFExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pF->pFExpr->pLeft) ); + pOBList = pF->pFExpr->pLeft->x.pList; + assert( pOBList!=0 ); + assert( pOBList->nExpr>0 ); + regAggSz = pOBList->nExpr; + if( !pF->bOBUnique ){ + regAggSz++; /* One register for OP_Sequence */ + } + if( pF->bOBPayload ){ + regAggSz += nArg; + } + regAggSz++; /* One extra register to hold result of MakeRecord */ + regAgg = sqlite3GetTempRange(pParse, regAggSz); + regDistinct = regAgg; + sqlite3ExprCodeExprList(pParse, pOBList, regAgg, 0, SQLITE_ECEL_DUP); + jj = pOBList->nExpr; + if( !pF->bOBUnique ){ + sqlite3VdbeAddOp2(v, OP_Sequence, pF->iOBTab, regAgg+jj); + jj++; + } + if( pF->bOBPayload ){ + regDistinct = regAgg+jj; + sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP); + } + }else if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); + regDistinct = regAgg; sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP); }else{ nArg = 0; @@ -147113,26 +148079,37 @@ static void updateAccumulator( addrNext = sqlite3VdbeMakeLabel(pParse); } pF->iDistinct = codeDistinct(pParse, eDistinctType, - pF->iDistinct, addrNext, pList, regAgg); + pF->iDistinct, addrNext, pList, regDistinct); } - if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ - CollSeq *pColl = 0; - struct ExprList_item *pItem; - int j; - assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ - for(j=0, pItem=pList->a; !pColl && jpExpr); + if( pF->iOBTab>=0 ){ + /* Insert a new record into the ORDER BY table */ + sqlite3VdbeAddOp3(v, OP_MakeRecord, regAgg, regAggSz-1, + regAgg+regAggSz-1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pF->iOBTab, regAgg+regAggSz-1, + regAgg, regAggSz-1); + sqlite3ReleaseTempRange(pParse, regAgg, regAggSz); + }else{ + /* Invoke the AggStep function */ + if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl = 0; + struct ExprList_item *pItem; + int j; + assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ + for(j=0, pItem=pList->a; !pColl && jpExpr); + } + if( !pColl ){ + pColl = pParse->db->pDfltColl; + } + if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, + (char *)pColl, P4_COLLSEQ); } - if( !pColl ){ - pColl = pParse->db->pDfltColl; - } - if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; - sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); } - sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); - sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); - sqlite3ReleaseTempRange(pParse, regAgg, nArg); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } @@ -149193,6 +150170,10 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); goto trigger_orphan_error; } + if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ + sqlite3ErrorMsg(pParse, "cannot create triggers on shadow tables"); + goto trigger_orphan_error; + } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ @@ -149976,10 +150957,17 @@ static void codeReturningTrigger( SrcList sFrom; assert( v!=0 ); - assert( pParse->bReturning ); + if( !pParse->bReturning ){ + /* This RETURNING trigger must be for a different statement as + ** this statement lacks a RETURNING clause. */ + return; + } assert( db->pParse==pParse ); pReturning = pParse->u1.pReturning; - assert( pTrigger == &(pReturning->retTrig) ); + if( pTrigger != &(pReturning->retTrig) ){ + /* This RETURNING trigger is for a different statement */ + return; + } memset(&sSelect, 0, sizeof(sSelect)); memset(&sFrom, 0, sizeof(sFrom)); sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); @@ -153416,7 +154404,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sqlite3_mutex_enter(db->mutex); pCtx = db->pVtabCtx; if( !pCtx || pCtx->bDeclared ){ - sqlite3Error(db, SQLITE_MISUSE); + sqlite3Error(db, SQLITE_MISUSE_BKPT); sqlite3_mutex_leave(db->mutex); return SQLITE_MISUSE_BKPT; } @@ -154607,7 +155595,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ -#define WHERE_VIEWSCAN 0x02000000 /* A full-scan of a VIEW or subquery */ + /* 0x02000000 -- available for reuse */ #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ #endif /* !defined(SQLITE_WHEREINT_H) */ @@ -160402,13 +161390,17 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */ int iCur; /* Cursor for table getting the filter */ IndexedExpr *saved_pIdxEpr; /* saved copy of Parse.pIdxEpr */ + IndexedExpr *saved_pIdxPartExpr; /* saved copy of Parse.pIdxPartExpr */ saved_pIdxEpr = pParse->pIdxEpr; + saved_pIdxPartExpr = pParse->pIdxPartExpr; pParse->pIdxEpr = 0; + pParse->pIdxPartExpr = 0; assert( pLoop!=0 ); assert( v!=0 ); assert( pLoop->wsFlags & WHERE_BLOOMFILTER ); + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ); addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); do{ @@ -160498,6 +161490,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( }while( iLevel < pWInfo->nLevel ); sqlite3VdbeJumpHere(v, addrOnce); pParse->pIdxEpr = saved_pIdxEpr; + pParse->pIdxPartExpr = saved_pIdxPartExpr; } @@ -162757,6 +163750,100 @@ static SQLITE_NOINLINE u32 whereIsCoveringIndex( return rc; } +/* +** This is an sqlite3ParserAddCleanup() callback that is invoked to +** free the Parse->pIdxEpr list when the Parse object is destroyed. +*/ +static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ + IndexedExpr **pp = (IndexedExpr**)pObject; + while( *pp!=0 ){ + IndexedExpr *p = *pp; + *pp = p->pIENext; + sqlite3ExprDelete(db, p->pExpr); + sqlite3DbFreeNN(db, p); + } +} + +/* +** This function is called for a partial index - one with a WHERE clause - in +** two scenarios. In both cases, it determines whether or not the WHERE +** clause on the index implies that a column of the table may be safely +** replaced by a constant expression. For example, in the following +** SELECT: +** +** CREATE INDEX i1 ON t1(b, c) WHERE a=; +** SELECT a, b, c FROM t1 WHERE a= AND b=?; +** +** The "a" in the select-list may be replaced by , iff: +** +** (a) is a constant expression, and +** (b) The (a=) comparison uses the BINARY collation sequence, and +** (c) Column "a" has an affinity other than NONE or BLOB. +** +** If argument pItem is NULL, then pMask must not be NULL. In this case this +** function is being called as part of determining whether or not pIdx +** is a covering index. This function clears any bits in (*pMask) +** corresponding to columns that may be replaced by constants as described +** above. +** +** Otherwise, if pItem is not NULL, then this function is being called +** as part of coding a loop that uses index pIdx. In this case, add entries +** to the Parse.pIdxPartExpr list for each column that can be replaced +** by a constant. +*/ +static void wherePartIdxExpr( + Parse *pParse, /* Parse context */ + Index *pIdx, /* Partial index being processed */ + Expr *pPart, /* WHERE clause being processed */ + Bitmask *pMask, /* Mask to clear bits in */ + int iIdxCur, /* Cursor number for index */ + SrcItem *pItem /* The FROM clause entry for the table */ +){ + assert( pItem==0 || (pItem->fg.jointype & JT_RIGHT)==0 ); + assert( (pItem==0 || pMask==0) && (pMask!=0 || pItem!=0) ); + + if( pPart->op==TK_AND ){ + wherePartIdxExpr(pParse, pIdx, pPart->pRight, pMask, iIdxCur, pItem); + pPart = pPart->pLeft; + } + + if( (pPart->op==TK_EQ || pPart->op==TK_IS) ){ + Expr *pLeft = pPart->pLeft; + Expr *pRight = pPart->pRight; + u8 aff; + + if( pLeft->op!=TK_COLUMN ) return; + if( !sqlite3ExprIsConstant(pRight) ) return; + if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return; + if( pLeft->iColumn<0 ) return; + aff = pIdx->pTable->aCol[pLeft->iColumn].affinity; + if( aff>=SQLITE_AFF_TEXT ){ + if( pItem ){ + sqlite3 *db = pParse->db; + IndexedExpr *p = (IndexedExpr*)sqlite3DbMallocRaw(db, sizeof(*p)); + if( p ){ + int bNullRow = (pItem->fg.jointype&(JT_LEFT|JT_LTORJ))!=0; + p->pExpr = sqlite3ExprDup(db, pRight, 0); + p->iDataCur = pItem->iCursor; + p->iIdxCur = iIdxCur; + p->iIdxCol = pLeft->iColumn; + p->bMaybeNullRow = bNullRow; + p->pIENext = pParse->pIdxPartExpr; + p->aff = aff; + pParse->pIdxPartExpr = p; + if( p->pIENext==0 ){ + void *pArg = (void*)&pParse->pIdxPartExpr; + sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); + } + } + }else if( pLeft->iColumn<(BMS-1) ){ + *pMask &= ~((Bitmask)1 << pLeft->iColumn); + } + } + } +} + + /* ** Add all WhereLoop objects for a single table of the join where the table ** is identified by pBuilder->pNew->iTab. That table is guaranteed to be @@ -162960,9 +164047,6 @@ static int whereLoopAddBtree( #else pNew->rRun = rSize + 16; #endif - if( IsView(pTab) || (pTab->tabFlags & TF_Ephemeral)!=0 ){ - pNew->wsFlags |= WHERE_VIEWSCAN; - } ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); @@ -162975,6 +164059,11 @@ static int whereLoopAddBtree( pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; }else{ m = pSrc->colUsed & pProbe->colNotIdxed; + if( pProbe->pPartIdxWhere ){ + wherePartIdxExpr( + pWInfo->pParse, pProbe, pProbe->pPartIdxWhere, &m, 0, 0 + ); + } pNew->wsFlags = WHERE_INDEXED; if( m==TOPBIT || (pProbe->bHasExpr && !pProbe->bHasVCol && m!=0) ){ u32 isCov = whereIsCoveringIndex(pWInfo, pProbe, pSrc->iCursor); @@ -163357,7 +164446,7 @@ SQLITE_API int sqlite3_vtab_rhs_value( sqlite3_value *pVal = 0; int rc = SQLITE_OK; if( iCons<0 || iCons>=pIdxInfo->nConstraint ){ - rc = SQLITE_MISUSE; /* EV: R-30545-25046 */ + rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ }else{ if( pH->aRhs[iCons]==0 ){ WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset]; @@ -164381,14 +165470,6 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */ } - /* TUNING: A full-scan of a VIEW or subquery in the outer loop - ** is not so bad. */ - if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 && nLoop>1 ){ - rCost += -10; - nOut += -30; - WHERETRACE(0x80,("VIEWSCAN cost reduction for %c\n",pWLoop->cId)); - } - /* Check to see if pWLoop should be added to the set of ** mxChoice best-so-far paths. ** @@ -164938,20 +166019,6 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( } } -/* -** This is an sqlite3ParserAddCleanup() callback that is invoked to -** free the Parse->pIdxEpr list when the Parse object is destroyed. -*/ -static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ - Parse *pParse = (Parse*)pObject; - while( pParse->pIdxEpr!=0 ){ - IndexedExpr *p = pParse->pIdxEpr; - pParse->pIdxEpr = p->pIENext; - sqlite3ExprDelete(db, p->pExpr); - sqlite3DbFreeNN(db, p); - } -} - /* ** The index pIdx is used by a query and contains one or more expressions. ** In other words pIdx is an index on an expression. iIdxCur is the cursor @@ -165013,7 +166080,8 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( #endif pParse->pIdxEpr = p; if( p->pIENext==0 ){ - sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pParse); + void *pArg = (void*)&pParse->pIdxEpr; + sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); } } } @@ -165403,6 +166471,16 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( wherePathSolver(pWInfo, pWInfo->nRowOut+1); if( db->mallocFailed ) goto whereBeginError; } + + /* TUNING: Assume that a DISTINCT clause on a subquery reduces + ** the output size by a factor of 8 (LogEst -30). + */ + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){ + WHERETRACE(0x0080,("nRowOut reduced from %d to %d due to DISTINCT\n", + pWInfo->nRowOut, pWInfo->nRowOut-30)); + pWInfo->nRowOut -= 30; + } + } assert( pWInfo->pTabList!=0 ); if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ @@ -165615,6 +166693,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( pIx->bHasExpr && OptimizationEnabled(db, SQLITE_IndexedExpr) ){ whereAddIndexedExpr(pParse, pIx, iIndexCur, pTabItem); } + if( pIx->pPartIdxWhere && (pTabItem->fg.jointype & JT_RIGHT)==0 ){ + wherePartIdxExpr( + pParse, pIx, pIx->pPartIdxWhere, 0, iIndexCur, pTabItem + ); + } } pLevel->iIdxCur = iIndexCur; assert( pIx!=0 ); @@ -167431,8 +168514,9 @@ SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ if( p ){ assert( p->op==TK_FUNCTION ); assert( pWin ); + assert( ExprIsFullSize(p) ); p->y.pWin = pWin; - ExprSetProperty(p, EP_WinFunc); + ExprSetProperty(p, EP_WinFunc|EP_FullSize); pWin->pOwner = p; if( (p->flags & EP_Distinct) && pWin->eFrmType!=TK_FILTER ){ sqlite3ErrorMsg(pParse, @@ -169734,18 +170818,18 @@ typedef union { #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 575 -#define YYNRULE 403 -#define YYNRULE_WITH_ACTION 338 +#define YYNSTATE 579 +#define YYNRULE 405 +#define YYNRULE_WITH_ACTION 340 #define YYNTOKEN 185 -#define YY_MAX_SHIFT 574 -#define YY_MIN_SHIFTREDUCE 833 -#define YY_MAX_SHIFTREDUCE 1235 -#define YY_ERROR_ACTION 1236 -#define YY_ACCEPT_ACTION 1237 -#define YY_NO_ACTION 1238 -#define YY_MIN_REDUCE 1239 -#define YY_MAX_REDUCE 1641 +#define YY_MAX_SHIFT 578 +#define YY_MIN_SHIFTREDUCE 838 +#define YY_MAX_SHIFTREDUCE 1242 +#define YY_ERROR_ACTION 1243 +#define YY_ACCEPT_ACTION 1244 +#define YY_NO_ACTION 1245 +#define YY_MIN_REDUCE 1246 +#define YY_MAX_REDUCE 1650 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -169812,218 +170896,218 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2096) +#define YY_ACTTAB_COUNT (2100) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 568, 208, 568, 118, 115, 229, 568, 118, 115, 229, - /* 10 */ 568, 1310, 377, 1289, 408, 562, 562, 562, 568, 409, - /* 20 */ 378, 1310, 1272, 41, 41, 41, 41, 208, 1520, 71, - /* 30 */ 71, 969, 419, 41, 41, 491, 303, 279, 303, 970, - /* 40 */ 397, 71, 71, 125, 126, 80, 1210, 1210, 1047, 1050, - /* 50 */ 1037, 1037, 123, 123, 124, 124, 124, 124, 476, 409, - /* 60 */ 1237, 1, 1, 574, 2, 1241, 550, 118, 115, 229, - /* 70 */ 317, 480, 146, 480, 524, 118, 115, 229, 529, 1323, - /* 80 */ 417, 523, 142, 125, 126, 80, 1210, 1210, 1047, 1050, - /* 90 */ 1037, 1037, 123, 123, 124, 124, 124, 124, 118, 115, - /* 100 */ 229, 327, 122, 122, 122, 122, 121, 121, 120, 120, - /* 110 */ 120, 119, 116, 444, 284, 284, 284, 284, 442, 442, - /* 120 */ 442, 1559, 376, 1561, 1186, 375, 1157, 565, 1157, 565, - /* 130 */ 409, 1559, 537, 259, 226, 444, 101, 145, 449, 316, - /* 140 */ 559, 240, 122, 122, 122, 122, 121, 121, 120, 120, - /* 150 */ 120, 119, 116, 444, 125, 126, 80, 1210, 1210, 1047, - /* 160 */ 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, 142, - /* 170 */ 294, 1186, 339, 448, 120, 120, 120, 119, 116, 444, - /* 180 */ 127, 1186, 1187, 1186, 148, 441, 440, 568, 119, 116, - /* 190 */ 444, 124, 124, 124, 124, 117, 122, 122, 122, 122, - /* 200 */ 121, 121, 120, 120, 120, 119, 116, 444, 454, 113, - /* 210 */ 13, 13, 546, 122, 122, 122, 122, 121, 121, 120, - /* 220 */ 120, 120, 119, 116, 444, 422, 316, 559, 1186, 1187, - /* 230 */ 1186, 149, 1218, 409, 1218, 124, 124, 124, 124, 122, - /* 240 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116, - /* 250 */ 444, 465, 342, 1034, 1034, 1048, 1051, 125, 126, 80, - /* 260 */ 1210, 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, - /* 270 */ 124, 124, 1275, 522, 222, 1186, 568, 409, 224, 514, - /* 280 */ 175, 82, 83, 122, 122, 122, 122, 121, 121, 120, - /* 290 */ 120, 120, 119, 116, 444, 1005, 16, 16, 1186, 133, - /* 300 */ 133, 125, 126, 80, 1210, 1210, 1047, 1050, 1037, 1037, - /* 310 */ 123, 123, 124, 124, 124, 124, 122, 122, 122, 122, - /* 320 */ 121, 121, 120, 120, 120, 119, 116, 444, 1038, 546, - /* 330 */ 1186, 373, 1186, 1187, 1186, 252, 1429, 399, 504, 501, - /* 340 */ 500, 111, 560, 566, 4, 924, 924, 433, 499, 340, - /* 350 */ 460, 328, 360, 394, 1231, 1186, 1187, 1186, 563, 568, - /* 360 */ 122, 122, 122, 122, 121, 121, 120, 120, 120, 119, - /* 370 */ 116, 444, 284, 284, 369, 1572, 1598, 441, 440, 154, - /* 380 */ 409, 445, 71, 71, 1282, 565, 1215, 1186, 1187, 1186, - /* 390 */ 85, 1217, 271, 557, 543, 515, 515, 568, 98, 1216, - /* 400 */ 6, 1274, 472, 142, 125, 126, 80, 1210, 1210, 1047, - /* 410 */ 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, 550, - /* 420 */ 13, 13, 1024, 507, 1218, 1186, 1218, 549, 109, 109, - /* 430 */ 222, 568, 1232, 175, 568, 427, 110, 197, 445, 569, - /* 440 */ 445, 430, 1546, 1014, 325, 551, 1186, 270, 287, 368, - /* 450 */ 510, 363, 509, 257, 71, 71, 543, 71, 71, 359, - /* 460 */ 316, 559, 1604, 122, 122, 122, 122, 121, 121, 120, - /* 470 */ 120, 120, 119, 116, 444, 1014, 1014, 1016, 1017, 27, - /* 480 */ 284, 284, 1186, 1187, 1186, 1152, 568, 1603, 409, 899, - /* 490 */ 190, 550, 356, 565, 550, 935, 533, 517, 1152, 516, - /* 500 */ 413, 1152, 552, 1186, 1187, 1186, 568, 544, 544, 51, - /* 510 */ 51, 214, 125, 126, 80, 1210, 1210, 1047, 1050, 1037, - /* 520 */ 1037, 123, 123, 124, 124, 124, 124, 1186, 474, 135, - /* 530 */ 135, 409, 284, 284, 1484, 505, 121, 121, 120, 120, - /* 540 */ 120, 119, 116, 444, 1005, 565, 518, 217, 541, 541, - /* 550 */ 316, 559, 142, 6, 532, 125, 126, 80, 1210, 1210, - /* 560 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, - /* 570 */ 1548, 122, 122, 122, 122, 121, 121, 120, 120, 120, - /* 580 */ 119, 116, 444, 485, 1186, 1187, 1186, 482, 281, 1263, - /* 590 */ 955, 252, 1186, 373, 504, 501, 500, 1186, 340, 570, - /* 600 */ 1186, 570, 409, 292, 499, 955, 874, 191, 480, 316, - /* 610 */ 559, 384, 290, 380, 122, 122, 122, 122, 121, 121, - /* 620 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1210, - /* 630 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 640 */ 124, 409, 394, 1132, 1186, 867, 100, 284, 284, 1186, - /* 650 */ 1187, 1186, 373, 1089, 1186, 1187, 1186, 1186, 1187, 1186, - /* 660 */ 565, 455, 32, 373, 233, 125, 126, 80, 1210, 1210, - /* 670 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, - /* 680 */ 1428, 957, 568, 228, 956, 122, 122, 122, 122, 121, - /* 690 */ 121, 120, 120, 120, 119, 116, 444, 1152, 228, 1186, - /* 700 */ 157, 1186, 1187, 1186, 1547, 13, 13, 301, 955, 1226, - /* 710 */ 1152, 153, 409, 1152, 373, 1575, 1170, 5, 369, 1572, - /* 720 */ 429, 1232, 3, 955, 122, 122, 122, 122, 121, 121, - /* 730 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1210, - /* 740 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 750 */ 124, 409, 208, 567, 1186, 1025, 1186, 1187, 1186, 1186, - /* 760 */ 388, 850, 155, 1546, 286, 402, 1094, 1094, 488, 568, - /* 770 */ 465, 342, 1315, 1315, 1546, 125, 126, 80, 1210, 1210, - /* 780 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, - /* 790 */ 129, 568, 13, 13, 374, 122, 122, 122, 122, 121, - /* 800 */ 121, 120, 120, 120, 119, 116, 444, 302, 568, 453, - /* 810 */ 528, 1186, 1187, 1186, 13, 13, 1186, 1187, 1186, 1293, - /* 820 */ 463, 1263, 409, 1313, 1313, 1546, 1010, 453, 452, 200, - /* 830 */ 299, 71, 71, 1261, 122, 122, 122, 122, 121, 121, - /* 840 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1210, - /* 850 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 860 */ 124, 409, 227, 1069, 1152, 284, 284, 419, 312, 278, - /* 870 */ 278, 285, 285, 1415, 406, 405, 382, 1152, 565, 568, - /* 880 */ 1152, 1189, 565, 1592, 565, 125, 126, 80, 1210, 1210, - /* 890 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, - /* 900 */ 453, 1476, 13, 13, 1530, 122, 122, 122, 122, 121, - /* 910 */ 121, 120, 120, 120, 119, 116, 444, 201, 568, 354, - /* 920 */ 1578, 574, 2, 1241, 838, 839, 840, 1554, 317, 1205, - /* 930 */ 146, 6, 409, 255, 254, 253, 206, 1323, 9, 1189, - /* 940 */ 262, 71, 71, 424, 122, 122, 122, 122, 121, 121, - /* 950 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1210, - /* 960 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 970 */ 124, 568, 284, 284, 568, 1206, 409, 573, 313, 1241, - /* 980 */ 349, 1292, 352, 419, 317, 565, 146, 491, 525, 1635, - /* 990 */ 395, 371, 491, 1323, 70, 70, 1291, 71, 71, 240, - /* 1000 */ 1321, 104, 80, 1210, 1210, 1047, 1050, 1037, 1037, 123, - /* 1010 */ 123, 124, 124, 124, 124, 122, 122, 122, 122, 121, - /* 1020 */ 121, 120, 120, 120, 119, 116, 444, 1110, 284, 284, - /* 1030 */ 428, 448, 1519, 1206, 439, 284, 284, 1483, 1348, 311, - /* 1040 */ 474, 565, 1111, 969, 491, 491, 217, 1259, 565, 1532, - /* 1050 */ 568, 970, 207, 568, 1024, 240, 383, 1112, 519, 122, - /* 1060 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116, - /* 1070 */ 444, 1015, 107, 71, 71, 1014, 13, 13, 910, 568, - /* 1080 */ 1489, 568, 284, 284, 97, 526, 491, 448, 911, 1322, - /* 1090 */ 1318, 545, 409, 284, 284, 565, 151, 209, 1489, 1491, - /* 1100 */ 262, 450, 55, 55, 56, 56, 565, 1014, 1014, 1016, - /* 1110 */ 443, 332, 409, 527, 12, 295, 125, 126, 80, 1210, - /* 1120 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 1130 */ 124, 347, 409, 862, 1528, 1206, 125, 126, 80, 1210, - /* 1140 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 1150 */ 124, 1133, 1633, 474, 1633, 371, 125, 114, 80, 1210, - /* 1160 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, - /* 1170 */ 124, 1489, 329, 474, 331, 122, 122, 122, 122, 121, - /* 1180 */ 121, 120, 120, 120, 119, 116, 444, 203, 1415, 568, - /* 1190 */ 1290, 862, 464, 1206, 436, 122, 122, 122, 122, 121, - /* 1200 */ 121, 120, 120, 120, 119, 116, 444, 553, 1133, 1634, - /* 1210 */ 539, 1634, 15, 15, 890, 122, 122, 122, 122, 121, - /* 1220 */ 121, 120, 120, 120, 119, 116, 444, 568, 298, 538, - /* 1230 */ 1131, 1415, 1552, 1553, 1327, 409, 6, 6, 1163, 1264, - /* 1240 */ 415, 320, 284, 284, 1415, 508, 565, 525, 300, 457, - /* 1250 */ 43, 43, 568, 891, 12, 565, 330, 478, 425, 407, - /* 1260 */ 126, 80, 1210, 1210, 1047, 1050, 1037, 1037, 123, 123, - /* 1270 */ 124, 124, 124, 124, 568, 57, 57, 288, 1186, 1415, - /* 1280 */ 496, 458, 392, 392, 391, 273, 389, 1131, 1551, 847, - /* 1290 */ 1163, 407, 6, 568, 321, 1152, 470, 44, 44, 1550, - /* 1300 */ 1110, 426, 234, 6, 323, 256, 540, 256, 1152, 431, - /* 1310 */ 568, 1152, 322, 17, 487, 1111, 58, 58, 122, 122, - /* 1320 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 444, - /* 1330 */ 1112, 216, 481, 59, 59, 1186, 1187, 1186, 111, 560, - /* 1340 */ 324, 4, 236, 456, 526, 568, 237, 456, 568, 437, - /* 1350 */ 168, 556, 420, 141, 479, 563, 568, 293, 568, 1091, - /* 1360 */ 568, 293, 568, 1091, 531, 568, 870, 8, 60, 60, - /* 1370 */ 235, 61, 61, 568, 414, 568, 414, 568, 445, 62, - /* 1380 */ 62, 45, 45, 46, 46, 47, 47, 199, 49, 49, - /* 1390 */ 557, 568, 359, 568, 100, 486, 50, 50, 63, 63, - /* 1400 */ 64, 64, 561, 415, 535, 410, 568, 1024, 568, 534, - /* 1410 */ 316, 559, 316, 559, 65, 65, 14, 14, 568, 1024, - /* 1420 */ 568, 512, 930, 870, 1015, 109, 109, 929, 1014, 66, - /* 1430 */ 66, 131, 131, 110, 451, 445, 569, 445, 416, 177, - /* 1440 */ 1014, 132, 132, 67, 67, 568, 467, 568, 930, 471, - /* 1450 */ 1360, 283, 226, 929, 315, 1359, 407, 568, 459, 407, - /* 1460 */ 1014, 1014, 1016, 239, 407, 86, 213, 1346, 52, 52, - /* 1470 */ 68, 68, 1014, 1014, 1016, 1017, 27, 1577, 1174, 447, - /* 1480 */ 69, 69, 288, 97, 108, 1535, 106, 392, 392, 391, - /* 1490 */ 273, 389, 568, 877, 847, 881, 568, 111, 560, 466, - /* 1500 */ 4, 568, 152, 30, 38, 568, 1128, 234, 396, 323, - /* 1510 */ 111, 560, 527, 4, 563, 53, 53, 322, 568, 163, - /* 1520 */ 163, 568, 337, 468, 164, 164, 333, 563, 76, 76, - /* 1530 */ 568, 289, 1508, 568, 31, 1507, 568, 445, 338, 483, - /* 1540 */ 100, 54, 54, 344, 72, 72, 296, 236, 1076, 557, - /* 1550 */ 445, 877, 1356, 134, 134, 168, 73, 73, 141, 161, - /* 1560 */ 161, 1566, 557, 535, 568, 319, 568, 348, 536, 1007, - /* 1570 */ 473, 261, 261, 889, 888, 235, 535, 568, 1024, 568, - /* 1580 */ 475, 534, 261, 367, 109, 109, 521, 136, 136, 130, - /* 1590 */ 130, 1024, 110, 366, 445, 569, 445, 109, 109, 1014, - /* 1600 */ 162, 162, 156, 156, 568, 110, 1076, 445, 569, 445, - /* 1610 */ 410, 351, 1014, 568, 353, 316, 559, 568, 343, 568, - /* 1620 */ 100, 497, 357, 258, 100, 896, 897, 140, 140, 355, - /* 1630 */ 1306, 1014, 1014, 1016, 1017, 27, 139, 139, 362, 451, - /* 1640 */ 137, 137, 138, 138, 1014, 1014, 1016, 1017, 27, 1174, - /* 1650 */ 447, 568, 372, 288, 111, 560, 1018, 4, 392, 392, - /* 1660 */ 391, 273, 389, 568, 1137, 847, 568, 1072, 568, 258, - /* 1670 */ 492, 563, 568, 211, 75, 75, 555, 960, 234, 261, - /* 1680 */ 323, 111, 560, 927, 4, 113, 77, 77, 322, 74, - /* 1690 */ 74, 42, 42, 1369, 445, 48, 48, 1414, 563, 972, - /* 1700 */ 973, 1088, 1087, 1088, 1087, 860, 557, 150, 928, 1342, - /* 1710 */ 113, 1354, 554, 1419, 1018, 1271, 1262, 1250, 236, 1249, - /* 1720 */ 1251, 445, 1585, 1339, 308, 276, 168, 309, 11, 141, - /* 1730 */ 393, 310, 232, 557, 1401, 1024, 335, 291, 1396, 219, - /* 1740 */ 336, 109, 109, 934, 297, 1406, 235, 341, 477, 110, - /* 1750 */ 502, 445, 569, 445, 1389, 1405, 1014, 400, 1289, 365, - /* 1760 */ 223, 1480, 1024, 1479, 1351, 1352, 1350, 1349, 109, 109, - /* 1770 */ 204, 1588, 1226, 558, 265, 218, 110, 205, 445, 569, - /* 1780 */ 445, 410, 387, 1014, 1527, 179, 316, 559, 1014, 1014, - /* 1790 */ 1016, 1017, 27, 230, 1525, 1223, 79, 560, 85, 4, - /* 1800 */ 418, 215, 548, 81, 84, 188, 1402, 173, 181, 461, - /* 1810 */ 451, 35, 462, 563, 183, 1014, 1014, 1016, 1017, 27, - /* 1820 */ 184, 1485, 185, 186, 495, 242, 98, 398, 1408, 36, - /* 1830 */ 1407, 484, 91, 469, 401, 1410, 445, 192, 1474, 246, - /* 1840 */ 1496, 490, 346, 277, 248, 196, 493, 511, 557, 350, - /* 1850 */ 1252, 249, 250, 403, 1309, 1308, 111, 560, 432, 4, - /* 1860 */ 1307, 1300, 93, 1602, 881, 1601, 224, 404, 434, 520, - /* 1870 */ 263, 435, 1571, 563, 1279, 1278, 364, 1024, 306, 1277, - /* 1880 */ 264, 1600, 1557, 109, 109, 370, 1299, 307, 1556, 438, - /* 1890 */ 128, 110, 1374, 445, 569, 445, 445, 546, 1014, 10, - /* 1900 */ 1461, 105, 381, 1373, 34, 571, 99, 1332, 557, 314, - /* 1910 */ 1180, 530, 272, 274, 379, 210, 1331, 547, 385, 386, - /* 1920 */ 275, 572, 1247, 1242, 411, 412, 1512, 165, 178, 1513, - /* 1930 */ 1014, 1014, 1016, 1017, 27, 1511, 1510, 1024, 78, 147, - /* 1940 */ 166, 220, 221, 109, 109, 834, 304, 167, 446, 212, - /* 1950 */ 318, 110, 231, 445, 569, 445, 144, 1086, 1014, 1084, - /* 1960 */ 326, 180, 169, 1205, 182, 334, 238, 913, 241, 1100, - /* 1970 */ 187, 170, 171, 421, 87, 88, 423, 189, 89, 90, - /* 1980 */ 172, 1103, 243, 1099, 244, 158, 18, 245, 345, 247, - /* 1990 */ 1014, 1014, 1016, 1017, 27, 261, 1092, 193, 1220, 489, - /* 2000 */ 194, 37, 366, 849, 494, 251, 195, 506, 92, 19, - /* 2010 */ 498, 358, 20, 503, 879, 361, 94, 892, 305, 159, - /* 2020 */ 513, 39, 95, 1168, 160, 1053, 964, 1139, 96, 174, - /* 2030 */ 1138, 225, 280, 282, 198, 958, 113, 1158, 1154, 260, - /* 2040 */ 21, 22, 23, 1156, 1162, 1161, 1143, 24, 33, 25, - /* 2050 */ 202, 542, 26, 100, 1067, 102, 1054, 103, 7, 1052, - /* 2060 */ 1056, 1109, 1057, 1108, 266, 267, 28, 40, 390, 1019, - /* 2070 */ 861, 112, 29, 564, 1176, 1175, 268, 176, 143, 923, - /* 2080 */ 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, - /* 2090 */ 1238, 1238, 1238, 1238, 269, 1593, + /* 0 */ 572, 210, 572, 119, 116, 231, 572, 119, 116, 231, + /* 10 */ 572, 1317, 379, 1296, 410, 566, 566, 566, 572, 411, + /* 20 */ 380, 1317, 1279, 42, 42, 42, 42, 210, 1529, 72, + /* 30 */ 72, 974, 421, 42, 42, 495, 305, 281, 305, 975, + /* 40 */ 399, 72, 72, 126, 127, 81, 1217, 1217, 1054, 1057, + /* 50 */ 1044, 1044, 124, 124, 125, 125, 125, 125, 480, 411, + /* 60 */ 1244, 1, 1, 578, 2, 1248, 554, 119, 116, 231, + /* 70 */ 319, 484, 147, 484, 528, 119, 116, 231, 533, 1330, + /* 80 */ 419, 527, 143, 126, 127, 81, 1217, 1217, 1054, 1057, + /* 90 */ 1044, 1044, 124, 124, 125, 125, 125, 125, 119, 116, + /* 100 */ 231, 329, 123, 123, 123, 123, 122, 122, 121, 121, + /* 110 */ 121, 120, 117, 448, 286, 286, 286, 286, 446, 446, + /* 120 */ 446, 1568, 378, 1570, 1193, 377, 1164, 569, 1164, 569, + /* 130 */ 411, 1568, 541, 261, 228, 448, 102, 146, 453, 318, + /* 140 */ 563, 242, 123, 123, 123, 123, 122, 122, 121, 121, + /* 150 */ 121, 120, 117, 448, 126, 127, 81, 1217, 1217, 1054, + /* 160 */ 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, 143, + /* 170 */ 296, 1193, 341, 452, 121, 121, 121, 120, 117, 448, + /* 180 */ 128, 1193, 1194, 1193, 149, 445, 444, 572, 120, 117, + /* 190 */ 448, 125, 125, 125, 125, 118, 123, 123, 123, 123, + /* 200 */ 122, 122, 121, 121, 121, 120, 117, 448, 458, 114, + /* 210 */ 13, 13, 550, 123, 123, 123, 123, 122, 122, 121, + /* 220 */ 121, 121, 120, 117, 448, 424, 318, 563, 1193, 1194, + /* 230 */ 1193, 150, 1225, 411, 1225, 125, 125, 125, 125, 123, + /* 240 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117, + /* 250 */ 448, 469, 344, 1041, 1041, 1055, 1058, 126, 127, 81, + /* 260 */ 1217, 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, + /* 270 */ 125, 125, 1282, 526, 224, 1193, 572, 411, 226, 519, + /* 280 */ 177, 83, 84, 123, 123, 123, 123, 122, 122, 121, + /* 290 */ 121, 121, 120, 117, 448, 1010, 16, 16, 1193, 134, + /* 300 */ 134, 126, 127, 81, 1217, 1217, 1054, 1057, 1044, 1044, + /* 310 */ 124, 124, 125, 125, 125, 125, 123, 123, 123, 123, + /* 320 */ 122, 122, 121, 121, 121, 120, 117, 448, 1045, 550, + /* 330 */ 1193, 375, 1193, 1194, 1193, 254, 1438, 401, 508, 505, + /* 340 */ 504, 112, 564, 570, 4, 929, 929, 435, 503, 342, + /* 350 */ 464, 330, 362, 396, 1238, 1193, 1194, 1193, 567, 572, + /* 360 */ 123, 123, 123, 123, 122, 122, 121, 121, 121, 120, + /* 370 */ 117, 448, 286, 286, 371, 1581, 1607, 445, 444, 155, + /* 380 */ 411, 449, 72, 72, 1289, 569, 1222, 1193, 1194, 1193, + /* 390 */ 86, 1224, 273, 561, 547, 520, 520, 572, 99, 1223, + /* 400 */ 6, 1281, 476, 143, 126, 127, 81, 1217, 1217, 1054, + /* 410 */ 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, 554, + /* 420 */ 13, 13, 1031, 511, 1225, 1193, 1225, 553, 110, 110, + /* 430 */ 224, 572, 1239, 177, 572, 429, 111, 199, 449, 573, + /* 440 */ 449, 432, 1555, 1019, 327, 555, 1193, 272, 289, 370, + /* 450 */ 514, 365, 513, 259, 72, 72, 547, 72, 72, 361, + /* 460 */ 318, 563, 1613, 123, 123, 123, 123, 122, 122, 121, + /* 470 */ 121, 121, 120, 117, 448, 1019, 1019, 1021, 1022, 28, + /* 480 */ 286, 286, 1193, 1194, 1193, 1159, 572, 1612, 411, 904, + /* 490 */ 192, 554, 358, 569, 554, 940, 537, 521, 1159, 437, + /* 500 */ 415, 1159, 556, 1193, 1194, 1193, 572, 548, 548, 52, + /* 510 */ 52, 216, 126, 127, 81, 1217, 1217, 1054, 1057, 1044, + /* 520 */ 1044, 124, 124, 125, 125, 125, 125, 1193, 478, 136, + /* 530 */ 136, 411, 286, 286, 1493, 509, 122, 122, 121, 121, + /* 540 */ 121, 120, 117, 448, 1010, 569, 522, 219, 545, 545, + /* 550 */ 318, 563, 143, 6, 536, 126, 127, 81, 1217, 1217, + /* 560 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, + /* 570 */ 1557, 123, 123, 123, 123, 122, 122, 121, 121, 121, + /* 580 */ 120, 117, 448, 489, 1193, 1194, 1193, 486, 283, 1270, + /* 590 */ 960, 254, 1193, 375, 508, 505, 504, 1193, 342, 574, + /* 600 */ 1193, 574, 411, 294, 503, 960, 879, 193, 484, 318, + /* 610 */ 563, 386, 292, 382, 123, 123, 123, 123, 122, 122, + /* 620 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, + /* 630 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, + /* 640 */ 125, 411, 396, 1139, 1193, 872, 101, 286, 286, 1193, + /* 650 */ 1194, 1193, 375, 1096, 1193, 1194, 1193, 1193, 1194, 1193, + /* 660 */ 569, 459, 33, 375, 235, 126, 127, 81, 1217, 1217, + /* 670 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, + /* 680 */ 1437, 962, 572, 230, 961, 123, 123, 123, 123, 122, + /* 690 */ 122, 121, 121, 121, 120, 117, 448, 1159, 230, 1193, + /* 700 */ 158, 1193, 1194, 1193, 1556, 13, 13, 303, 960, 1233, + /* 710 */ 1159, 154, 411, 1159, 375, 1584, 1177, 5, 371, 1581, + /* 720 */ 431, 1239, 3, 960, 123, 123, 123, 123, 122, 122, + /* 730 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, + /* 740 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, + /* 750 */ 125, 411, 210, 571, 1193, 1032, 1193, 1194, 1193, 1193, + /* 760 */ 390, 855, 156, 1555, 376, 404, 1101, 1101, 492, 572, + /* 770 */ 469, 344, 1322, 1322, 1555, 126, 127, 81, 1217, 1217, + /* 780 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, + /* 790 */ 130, 572, 13, 13, 532, 123, 123, 123, 123, 122, + /* 800 */ 122, 121, 121, 121, 120, 117, 448, 304, 572, 457, + /* 810 */ 229, 1193, 1194, 1193, 13, 13, 1193, 1194, 1193, 1300, + /* 820 */ 467, 1270, 411, 1320, 1320, 1555, 1015, 457, 456, 436, + /* 830 */ 301, 72, 72, 1268, 123, 123, 123, 123, 122, 122, + /* 840 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, + /* 850 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, + /* 860 */ 125, 411, 384, 1076, 1159, 286, 286, 421, 314, 280, + /* 870 */ 280, 287, 287, 461, 408, 407, 1539, 1159, 569, 572, + /* 880 */ 1159, 1196, 569, 409, 569, 126, 127, 81, 1217, 1217, + /* 890 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, + /* 900 */ 457, 1485, 13, 13, 1541, 123, 123, 123, 123, 122, + /* 910 */ 122, 121, 121, 121, 120, 117, 448, 202, 572, 462, + /* 920 */ 1587, 578, 2, 1248, 843, 844, 845, 1563, 319, 409, + /* 930 */ 147, 6, 411, 257, 256, 255, 208, 1330, 9, 1196, + /* 940 */ 264, 72, 72, 1436, 123, 123, 123, 123, 122, 122, + /* 950 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217, + /* 960 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, + /* 970 */ 125, 572, 286, 286, 572, 1213, 411, 577, 315, 1248, + /* 980 */ 421, 371, 1581, 356, 319, 569, 147, 495, 529, 1644, + /* 990 */ 397, 935, 495, 1330, 71, 71, 934, 72, 72, 242, + /* 1000 */ 1328, 105, 81, 1217, 1217, 1054, 1057, 1044, 1044, 124, + /* 1010 */ 124, 125, 125, 125, 125, 123, 123, 123, 123, 122, + /* 1020 */ 122, 121, 121, 121, 120, 117, 448, 1117, 286, 286, + /* 1030 */ 1422, 452, 1528, 1213, 443, 286, 286, 1492, 1355, 313, + /* 1040 */ 478, 569, 1118, 454, 351, 495, 354, 1266, 569, 209, + /* 1050 */ 572, 418, 179, 572, 1031, 242, 385, 1119, 523, 123, + /* 1060 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117, + /* 1070 */ 448, 1020, 108, 72, 72, 1019, 13, 13, 915, 572, + /* 1080 */ 1498, 572, 286, 286, 98, 530, 1537, 452, 916, 1334, + /* 1090 */ 1329, 203, 411, 286, 286, 569, 152, 211, 1498, 1500, + /* 1100 */ 426, 569, 56, 56, 57, 57, 569, 1019, 1019, 1021, + /* 1110 */ 447, 572, 411, 531, 12, 297, 126, 127, 81, 1217, + /* 1120 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, + /* 1130 */ 125, 572, 411, 867, 15, 15, 126, 127, 81, 1217, + /* 1140 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, + /* 1150 */ 125, 373, 529, 264, 44, 44, 126, 115, 81, 1217, + /* 1160 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, + /* 1170 */ 125, 1498, 478, 1271, 417, 123, 123, 123, 123, 122, + /* 1180 */ 122, 121, 121, 121, 120, 117, 448, 205, 1213, 495, + /* 1190 */ 430, 867, 468, 322, 495, 123, 123, 123, 123, 122, + /* 1200 */ 122, 121, 121, 121, 120, 117, 448, 572, 557, 1140, + /* 1210 */ 1642, 1422, 1642, 543, 572, 123, 123, 123, 123, 122, + /* 1220 */ 122, 121, 121, 121, 120, 117, 448, 572, 1422, 572, + /* 1230 */ 13, 13, 542, 323, 1325, 411, 334, 58, 58, 349, + /* 1240 */ 1422, 1170, 326, 286, 286, 549, 1213, 300, 895, 530, + /* 1250 */ 45, 45, 59, 59, 1140, 1643, 569, 1643, 565, 417, + /* 1260 */ 127, 81, 1217, 1217, 1054, 1057, 1044, 1044, 124, 124, + /* 1270 */ 125, 125, 125, 125, 1367, 373, 500, 290, 1193, 512, + /* 1280 */ 1366, 427, 394, 394, 393, 275, 391, 896, 1138, 852, + /* 1290 */ 478, 258, 1422, 1170, 463, 1159, 12, 331, 428, 333, + /* 1300 */ 1117, 460, 236, 258, 325, 460, 544, 1544, 1159, 1098, + /* 1310 */ 491, 1159, 324, 1098, 440, 1118, 335, 516, 123, 123, + /* 1320 */ 123, 123, 122, 122, 121, 121, 121, 120, 117, 448, + /* 1330 */ 1119, 318, 563, 1138, 572, 1193, 1194, 1193, 112, 564, + /* 1340 */ 201, 4, 238, 433, 935, 490, 285, 228, 1517, 934, + /* 1350 */ 170, 560, 572, 142, 1516, 567, 572, 60, 60, 572, + /* 1360 */ 416, 572, 441, 572, 535, 302, 875, 8, 487, 572, + /* 1370 */ 237, 572, 416, 572, 485, 61, 61, 572, 449, 62, + /* 1380 */ 62, 332, 63, 63, 46, 46, 47, 47, 361, 572, + /* 1390 */ 561, 572, 48, 48, 50, 50, 51, 51, 572, 295, + /* 1400 */ 64, 64, 482, 295, 539, 412, 471, 1031, 572, 538, + /* 1410 */ 318, 563, 65, 65, 66, 66, 409, 475, 572, 1031, + /* 1420 */ 572, 14, 14, 875, 1020, 110, 110, 409, 1019, 572, + /* 1430 */ 474, 67, 67, 111, 455, 449, 573, 449, 98, 317, + /* 1440 */ 1019, 132, 132, 133, 133, 572, 1561, 572, 974, 409, + /* 1450 */ 6, 1562, 68, 68, 1560, 6, 975, 572, 6, 1559, + /* 1460 */ 1019, 1019, 1021, 6, 346, 218, 101, 531, 53, 53, + /* 1470 */ 69, 69, 1019, 1019, 1021, 1022, 28, 1586, 1181, 451, + /* 1480 */ 70, 70, 290, 87, 215, 31, 1363, 394, 394, 393, + /* 1490 */ 275, 391, 350, 109, 852, 107, 572, 112, 564, 483, + /* 1500 */ 4, 1212, 572, 239, 153, 572, 39, 236, 1299, 325, + /* 1510 */ 112, 564, 1298, 4, 567, 572, 32, 324, 572, 54, + /* 1520 */ 54, 572, 1135, 353, 398, 165, 165, 567, 166, 166, + /* 1530 */ 572, 291, 355, 572, 17, 357, 572, 449, 77, 77, + /* 1540 */ 1313, 55, 55, 1297, 73, 73, 572, 238, 470, 561, + /* 1550 */ 449, 472, 364, 135, 135, 170, 74, 74, 142, 163, + /* 1560 */ 163, 374, 561, 539, 572, 321, 572, 886, 540, 137, + /* 1570 */ 137, 339, 1353, 422, 298, 237, 539, 572, 1031, 572, + /* 1580 */ 340, 538, 101, 369, 110, 110, 162, 131, 131, 164, + /* 1590 */ 164, 1031, 111, 368, 449, 573, 449, 110, 110, 1019, + /* 1600 */ 157, 157, 141, 141, 572, 111, 572, 449, 573, 449, + /* 1610 */ 412, 288, 1019, 572, 882, 318, 563, 572, 219, 572, + /* 1620 */ 241, 1012, 477, 263, 263, 894, 893, 140, 140, 138, + /* 1630 */ 138, 1019, 1019, 1021, 1022, 28, 139, 139, 525, 455, + /* 1640 */ 76, 76, 78, 78, 1019, 1019, 1021, 1022, 28, 1181, + /* 1650 */ 451, 572, 1083, 290, 112, 564, 1575, 4, 394, 394, + /* 1660 */ 393, 275, 391, 572, 1023, 852, 572, 479, 345, 263, + /* 1670 */ 101, 567, 882, 1376, 75, 75, 1421, 501, 236, 260, + /* 1680 */ 325, 112, 564, 359, 4, 101, 43, 43, 324, 49, + /* 1690 */ 49, 901, 902, 161, 449, 101, 977, 978, 567, 1079, + /* 1700 */ 1349, 260, 965, 932, 263, 114, 561, 1095, 517, 1095, + /* 1710 */ 1083, 1094, 865, 1094, 151, 933, 1144, 114, 238, 1361, + /* 1720 */ 558, 449, 1023, 559, 1426, 1278, 170, 1269, 1257, 142, + /* 1730 */ 1601, 1256, 1258, 561, 1594, 1031, 496, 278, 213, 1346, + /* 1740 */ 310, 110, 110, 939, 311, 312, 237, 11, 234, 111, + /* 1750 */ 221, 449, 573, 449, 293, 395, 1019, 1408, 337, 1403, + /* 1760 */ 1396, 338, 1031, 299, 343, 1413, 1412, 481, 110, 110, + /* 1770 */ 506, 402, 225, 1296, 206, 367, 111, 1358, 449, 573, + /* 1780 */ 449, 412, 1359, 1019, 1489, 1488, 318, 563, 1019, 1019, + /* 1790 */ 1021, 1022, 28, 562, 207, 220, 80, 564, 389, 4, + /* 1800 */ 1597, 1357, 552, 1356, 1233, 181, 267, 232, 1536, 1534, + /* 1810 */ 455, 1230, 420, 567, 82, 1019, 1019, 1021, 1022, 28, + /* 1820 */ 86, 217, 85, 1494, 190, 175, 183, 465, 185, 466, + /* 1830 */ 36, 1409, 186, 187, 188, 499, 449, 244, 37, 99, + /* 1840 */ 400, 1415, 1414, 488, 1417, 194, 473, 403, 561, 1483, + /* 1850 */ 248, 92, 1505, 494, 198, 279, 112, 564, 250, 4, + /* 1860 */ 348, 497, 405, 352, 1259, 251, 252, 515, 1316, 434, + /* 1870 */ 1315, 1314, 94, 567, 1307, 886, 1306, 1031, 226, 406, + /* 1880 */ 1611, 1610, 438, 110, 110, 1580, 1286, 524, 439, 308, + /* 1890 */ 266, 111, 1285, 449, 573, 449, 449, 309, 1019, 366, + /* 1900 */ 1284, 1609, 265, 1566, 1565, 442, 372, 1381, 561, 129, + /* 1910 */ 550, 1380, 10, 1470, 383, 106, 316, 551, 100, 35, + /* 1920 */ 534, 575, 212, 1339, 381, 387, 1187, 1338, 274, 276, + /* 1930 */ 1019, 1019, 1021, 1022, 28, 277, 413, 1031, 576, 1254, + /* 1940 */ 388, 1521, 1249, 110, 110, 167, 1522, 168, 148, 1520, + /* 1950 */ 1519, 111, 306, 449, 573, 449, 222, 223, 1019, 839, + /* 1960 */ 169, 79, 450, 214, 414, 233, 320, 145, 1093, 1091, + /* 1970 */ 328, 182, 171, 1212, 918, 184, 240, 336, 243, 1107, + /* 1980 */ 189, 172, 173, 423, 425, 88, 180, 191, 89, 90, + /* 1990 */ 1019, 1019, 1021, 1022, 28, 91, 174, 1110, 245, 1106, + /* 2000 */ 246, 159, 18, 247, 347, 1099, 263, 195, 1227, 493, + /* 2010 */ 249, 196, 38, 854, 498, 368, 253, 360, 897, 197, + /* 2020 */ 502, 93, 19, 20, 507, 884, 363, 510, 95, 307, + /* 2030 */ 160, 96, 518, 97, 1175, 1060, 1146, 40, 21, 227, + /* 2040 */ 176, 1145, 282, 284, 969, 200, 963, 114, 262, 1165, + /* 2050 */ 22, 23, 24, 1161, 1169, 25, 1163, 1150, 34, 26, + /* 2060 */ 1168, 546, 27, 204, 101, 103, 104, 1074, 7, 1061, + /* 2070 */ 1059, 1063, 1116, 1064, 1115, 268, 269, 29, 41, 270, + /* 2080 */ 1024, 866, 113, 30, 568, 392, 1183, 144, 178, 1182, + /* 2090 */ 271, 928, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1602, }; static const YYCODETYPE yy_lookahead[] = { /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276, @@ -170102,7 +171186,7 @@ static const YYCODETYPE yy_lookahead[] = { /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, /* 750 */ 57, 19, 193, 193, 59, 23, 116, 117, 118, 59, - /* 760 */ 201, 21, 241, 304, 22, 206, 127, 128, 129, 193, + /* 760 */ 201, 21, 241, 304, 193, 206, 127, 128, 129, 193, /* 770 */ 128, 129, 235, 236, 304, 43, 44, 45, 46, 47, /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, /* 790 */ 22, 193, 216, 217, 193, 102, 103, 104, 105, 106, @@ -170113,129 +171197,129 @@ static const YYCODETYPE yy_lookahead[] = { /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, /* 860 */ 57, 19, 193, 123, 76, 239, 240, 193, 253, 239, - /* 870 */ 240, 239, 240, 193, 106, 107, 193, 89, 252, 193, - /* 880 */ 92, 59, 252, 141, 252, 43, 44, 45, 46, 47, + /* 870 */ 240, 239, 240, 244, 106, 107, 193, 89, 252, 193, + /* 880 */ 92, 59, 252, 254, 252, 43, 44, 45, 46, 47, /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, /* 900 */ 284, 161, 216, 217, 193, 102, 103, 104, 105, 106, - /* 910 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 16, - /* 920 */ 187, 188, 189, 190, 7, 8, 9, 309, 195, 25, + /* 910 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 244, + /* 920 */ 187, 188, 189, 190, 7, 8, 9, 309, 195, 254, /* 930 */ 197, 313, 19, 127, 128, 129, 262, 204, 22, 117, - /* 940 */ 24, 216, 217, 263, 102, 103, 104, 105, 106, 107, + /* 940 */ 24, 216, 217, 273, 102, 103, 104, 105, 106, 107, /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, /* 970 */ 57, 193, 239, 240, 193, 59, 19, 188, 253, 190, - /* 980 */ 77, 226, 79, 193, 195, 252, 197, 193, 19, 301, - /* 990 */ 302, 193, 193, 204, 216, 217, 226, 216, 217, 266, + /* 980 */ 193, 311, 312, 16, 195, 252, 197, 193, 19, 301, + /* 990 */ 302, 135, 193, 204, 216, 217, 140, 216, 217, 266, /* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52, /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240, - /* 1030 */ 232, 298, 238, 117, 253, 239, 240, 238, 259, 260, - /* 1040 */ 193, 252, 27, 31, 193, 193, 142, 204, 252, 193, - /* 1050 */ 193, 39, 262, 193, 100, 266, 278, 42, 204, 102, + /* 1030 */ 193, 298, 238, 117, 253, 239, 240, 238, 259, 260, + /* 1040 */ 193, 252, 27, 193, 77, 193, 79, 204, 252, 262, + /* 1050 */ 193, 299, 300, 193, 100, 266, 278, 42, 204, 102, /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, /* 1070 */ 113, 117, 159, 216, 217, 121, 216, 217, 63, 193, - /* 1080 */ 193, 193, 239, 240, 115, 116, 193, 298, 73, 238, + /* 1080 */ 193, 193, 239, 240, 115, 116, 193, 298, 73, 240, /* 1090 */ 238, 231, 19, 239, 240, 252, 22, 24, 211, 212, - /* 1100 */ 24, 193, 216, 217, 216, 217, 252, 153, 154, 155, - /* 1110 */ 253, 16, 19, 144, 213, 268, 43, 44, 45, 46, + /* 1100 */ 263, 252, 216, 217, 216, 217, 252, 153, 154, 155, + /* 1110 */ 253, 193, 19, 144, 213, 268, 43, 44, 45, 46, /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1130 */ 57, 238, 19, 59, 193, 59, 43, 44, 45, 46, + /* 1130 */ 57, 193, 19, 59, 216, 217, 43, 44, 45, 46, /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1150 */ 57, 22, 23, 193, 25, 193, 43, 44, 45, 46, + /* 1150 */ 57, 193, 19, 24, 216, 217, 43, 44, 45, 46, /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1170 */ 57, 284, 77, 193, 79, 102, 103, 104, 105, 106, - /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 286, 193, 193, - /* 1190 */ 193, 117, 291, 117, 232, 102, 103, 104, 105, 106, - /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 204, 22, 23, - /* 1210 */ 66, 25, 216, 217, 35, 102, 103, 104, 105, 106, - /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 193, 268, 85, - /* 1230 */ 101, 193, 309, 309, 240, 19, 313, 313, 94, 208, - /* 1240 */ 209, 193, 239, 240, 193, 66, 252, 19, 268, 244, - /* 1250 */ 216, 217, 193, 74, 213, 252, 161, 19, 263, 254, + /* 1170 */ 57, 284, 193, 208, 209, 102, 103, 104, 105, 106, + /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 286, 59, 193, + /* 1190 */ 232, 117, 291, 193, 193, 102, 103, 104, 105, 106, + /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 193, 204, 22, + /* 1210 */ 23, 193, 25, 66, 193, 102, 103, 104, 105, 106, + /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 193, 193, 193, + /* 1230 */ 216, 217, 85, 193, 238, 19, 16, 216, 217, 238, + /* 1240 */ 193, 94, 193, 239, 240, 231, 117, 268, 35, 116, + /* 1250 */ 216, 217, 216, 217, 22, 23, 252, 25, 208, 209, /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 1270 */ 54, 55, 56, 57, 193, 216, 217, 5, 59, 193, - /* 1280 */ 19, 244, 10, 11, 12, 13, 14, 101, 309, 17, - /* 1290 */ 146, 254, 313, 193, 193, 76, 115, 216, 217, 309, - /* 1300 */ 12, 263, 30, 313, 32, 46, 87, 46, 89, 130, - /* 1310 */ 193, 92, 40, 22, 263, 27, 216, 217, 102, 103, + /* 1270 */ 54, 55, 56, 57, 193, 193, 19, 5, 59, 66, + /* 1280 */ 193, 263, 10, 11, 12, 13, 14, 74, 101, 17, + /* 1290 */ 193, 46, 193, 146, 193, 76, 213, 77, 263, 79, + /* 1300 */ 12, 260, 30, 46, 32, 264, 87, 193, 89, 29, + /* 1310 */ 263, 92, 40, 33, 232, 27, 193, 108, 102, 103, /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - /* 1330 */ 42, 150, 291, 216, 217, 116, 117, 118, 19, 20, - /* 1340 */ 193, 22, 70, 260, 116, 193, 24, 264, 193, 263, - /* 1350 */ 78, 63, 61, 81, 116, 36, 193, 260, 193, 29, - /* 1360 */ 193, 264, 193, 33, 145, 193, 59, 48, 216, 217, - /* 1370 */ 98, 216, 217, 193, 115, 193, 115, 193, 59, 216, - /* 1380 */ 217, 216, 217, 216, 217, 216, 217, 255, 216, 217, - /* 1390 */ 71, 193, 131, 193, 25, 65, 216, 217, 216, 217, - /* 1400 */ 216, 217, 208, 209, 85, 133, 193, 100, 193, 90, - /* 1410 */ 138, 139, 138, 139, 216, 217, 216, 217, 193, 100, - /* 1420 */ 193, 108, 135, 116, 117, 106, 107, 140, 121, 216, - /* 1430 */ 217, 216, 217, 114, 162, 116, 117, 118, 299, 300, - /* 1440 */ 121, 216, 217, 216, 217, 193, 244, 193, 135, 244, - /* 1450 */ 193, 256, 257, 140, 244, 193, 254, 193, 193, 254, - /* 1460 */ 153, 154, 155, 141, 254, 149, 150, 258, 216, 217, + /* 1330 */ 42, 138, 139, 101, 193, 116, 117, 118, 19, 20, + /* 1340 */ 255, 22, 70, 130, 135, 65, 256, 257, 193, 140, + /* 1350 */ 78, 63, 193, 81, 193, 36, 193, 216, 217, 193, + /* 1360 */ 115, 193, 263, 193, 145, 268, 59, 48, 193, 193, + /* 1370 */ 98, 193, 115, 193, 291, 216, 217, 193, 59, 216, + /* 1380 */ 217, 161, 216, 217, 216, 217, 216, 217, 131, 193, + /* 1390 */ 71, 193, 216, 217, 216, 217, 216, 217, 193, 260, + /* 1400 */ 216, 217, 19, 264, 85, 133, 244, 100, 193, 90, + /* 1410 */ 138, 139, 216, 217, 216, 217, 254, 244, 193, 100, + /* 1420 */ 193, 216, 217, 116, 117, 106, 107, 254, 121, 193, + /* 1430 */ 115, 216, 217, 114, 162, 116, 117, 118, 115, 244, + /* 1440 */ 121, 216, 217, 216, 217, 193, 309, 193, 31, 254, + /* 1450 */ 313, 309, 216, 217, 309, 313, 39, 193, 313, 309, + /* 1460 */ 153, 154, 155, 313, 193, 150, 25, 144, 216, 217, /* 1470 */ 216, 217, 153, 154, 155, 156, 157, 0, 1, 2, - /* 1480 */ 216, 217, 5, 115, 158, 193, 160, 10, 11, 12, - /* 1490 */ 13, 14, 193, 59, 17, 126, 193, 19, 20, 129, - /* 1500 */ 22, 193, 22, 22, 24, 193, 23, 30, 25, 32, - /* 1510 */ 19, 20, 144, 22, 36, 216, 217, 40, 193, 216, - /* 1520 */ 217, 193, 152, 129, 216, 217, 193, 36, 216, 217, - /* 1530 */ 193, 99, 193, 193, 53, 193, 193, 59, 23, 193, - /* 1540 */ 25, 216, 217, 193, 216, 217, 152, 70, 59, 71, - /* 1550 */ 59, 117, 193, 216, 217, 78, 216, 217, 81, 216, - /* 1560 */ 217, 318, 71, 85, 193, 133, 193, 193, 90, 23, - /* 1570 */ 23, 25, 25, 120, 121, 98, 85, 193, 100, 193, - /* 1580 */ 23, 90, 25, 121, 106, 107, 19, 216, 217, 216, + /* 1480 */ 216, 217, 5, 149, 150, 22, 193, 10, 11, 12, + /* 1490 */ 13, 14, 193, 158, 17, 160, 193, 19, 20, 116, + /* 1500 */ 22, 25, 193, 24, 22, 193, 24, 30, 226, 32, + /* 1510 */ 19, 20, 226, 22, 36, 193, 53, 40, 193, 216, + /* 1520 */ 217, 193, 23, 193, 25, 216, 217, 36, 216, 217, + /* 1530 */ 193, 99, 193, 193, 22, 193, 193, 59, 216, 217, + /* 1540 */ 193, 216, 217, 193, 216, 217, 193, 70, 129, 71, + /* 1550 */ 59, 129, 193, 216, 217, 78, 216, 217, 81, 216, + /* 1560 */ 217, 193, 71, 85, 193, 133, 193, 126, 90, 216, + /* 1570 */ 217, 152, 258, 61, 152, 98, 85, 193, 100, 193, + /* 1580 */ 23, 90, 25, 121, 106, 107, 23, 216, 217, 216, /* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121, - /* 1600 */ 216, 217, 216, 217, 193, 114, 117, 116, 117, 118, - /* 1610 */ 133, 193, 121, 193, 193, 138, 139, 193, 23, 193, - /* 1620 */ 25, 23, 23, 25, 25, 7, 8, 216, 217, 193, - /* 1630 */ 193, 153, 154, 155, 156, 157, 216, 217, 193, 162, + /* 1600 */ 216, 217, 216, 217, 193, 114, 193, 116, 117, 118, + /* 1610 */ 133, 22, 121, 193, 59, 138, 139, 193, 142, 193, + /* 1620 */ 141, 23, 23, 25, 25, 120, 121, 216, 217, 216, + /* 1630 */ 217, 153, 154, 155, 156, 157, 216, 217, 19, 162, /* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1, - /* 1650 */ 2, 193, 193, 5, 19, 20, 59, 22, 10, 11, - /* 1660 */ 12, 13, 14, 193, 97, 17, 193, 23, 193, 25, - /* 1670 */ 288, 36, 193, 242, 216, 217, 236, 23, 30, 25, + /* 1650 */ 2, 193, 59, 5, 19, 20, 318, 22, 10, 11, + /* 1660 */ 12, 13, 14, 193, 59, 17, 193, 23, 23, 25, + /* 1670 */ 25, 36, 117, 193, 216, 217, 193, 23, 30, 25, /* 1680 */ 32, 19, 20, 23, 22, 25, 216, 217, 40, 216, - /* 1690 */ 217, 216, 217, 193, 59, 216, 217, 193, 36, 83, - /* 1700 */ 84, 153, 153, 155, 155, 23, 71, 25, 23, 193, - /* 1710 */ 25, 193, 193, 193, 117, 193, 193, 193, 70, 193, - /* 1720 */ 193, 59, 193, 255, 255, 287, 78, 255, 243, 81, - /* 1730 */ 191, 255, 297, 71, 271, 100, 293, 245, 267, 214, - /* 1740 */ 246, 106, 107, 108, 246, 271, 98, 245, 293, 114, - /* 1750 */ 220, 116, 117, 118, 267, 271, 121, 271, 225, 219, - /* 1760 */ 229, 219, 100, 219, 259, 259, 259, 259, 106, 107, - /* 1770 */ 249, 196, 60, 280, 141, 243, 114, 249, 116, 117, - /* 1780 */ 118, 133, 245, 121, 200, 297, 138, 139, 153, 154, - /* 1790 */ 155, 156, 157, 297, 200, 38, 19, 20, 151, 22, - /* 1800 */ 200, 150, 140, 294, 294, 22, 272, 43, 234, 18, - /* 1810 */ 162, 270, 200, 36, 237, 153, 154, 155, 156, 157, - /* 1820 */ 237, 283, 237, 237, 18, 199, 149, 246, 272, 270, - /* 1830 */ 272, 200, 158, 246, 246, 234, 59, 234, 246, 199, - /* 1840 */ 290, 62, 289, 200, 199, 22, 221, 115, 71, 200, - /* 1850 */ 200, 199, 199, 221, 218, 218, 19, 20, 64, 22, - /* 1860 */ 218, 227, 22, 224, 126, 224, 165, 221, 24, 305, - /* 1870 */ 200, 113, 312, 36, 218, 220, 218, 100, 282, 218, - /* 1880 */ 91, 218, 317, 106, 107, 221, 227, 282, 317, 82, - /* 1890 */ 148, 114, 265, 116, 117, 118, 59, 145, 121, 22, - /* 1900 */ 277, 158, 200, 265, 25, 202, 147, 250, 71, 279, - /* 1910 */ 13, 146, 194, 194, 249, 248, 250, 140, 247, 246, - /* 1920 */ 6, 192, 192, 192, 303, 303, 213, 207, 300, 213, - /* 1930 */ 153, 154, 155, 156, 157, 213, 213, 100, 213, 222, - /* 1940 */ 207, 214, 214, 106, 107, 4, 222, 207, 3, 22, - /* 1950 */ 163, 114, 15, 116, 117, 118, 16, 23, 121, 23, - /* 1960 */ 139, 151, 130, 25, 142, 16, 24, 20, 144, 1, - /* 1970 */ 142, 130, 130, 61, 53, 53, 37, 151, 53, 53, - /* 1980 */ 130, 116, 34, 1, 141, 5, 22, 115, 161, 141, - /* 1990 */ 153, 154, 155, 156, 157, 25, 68, 68, 75, 41, - /* 2000 */ 115, 24, 131, 20, 19, 125, 22, 96, 22, 22, - /* 2010 */ 67, 23, 22, 67, 59, 24, 22, 28, 67, 23, - /* 2020 */ 22, 22, 149, 23, 23, 23, 116, 23, 25, 37, - /* 2030 */ 97, 141, 23, 23, 22, 143, 25, 75, 88, 34, - /* 2040 */ 34, 34, 34, 86, 75, 93, 23, 34, 22, 34, - /* 2050 */ 25, 24, 34, 25, 23, 142, 23, 142, 44, 23, - /* 2060 */ 23, 23, 11, 23, 25, 22, 22, 22, 15, 23, - /* 2070 */ 23, 22, 22, 25, 1, 1, 141, 25, 23, 135, - /* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2090 */ 319, 319, 319, 319, 141, 141, 319, 319, 319, 319, + /* 1690 */ 217, 7, 8, 23, 59, 25, 83, 84, 36, 23, + /* 1700 */ 193, 25, 23, 23, 25, 25, 71, 153, 145, 155, + /* 1710 */ 117, 153, 23, 155, 25, 23, 97, 25, 70, 193, + /* 1720 */ 193, 59, 117, 236, 193, 193, 78, 193, 193, 81, + /* 1730 */ 141, 193, 193, 71, 193, 100, 288, 287, 242, 255, + /* 1740 */ 255, 106, 107, 108, 255, 255, 98, 243, 297, 114, + /* 1750 */ 214, 116, 117, 118, 245, 191, 121, 271, 293, 267, + /* 1760 */ 267, 246, 100, 246, 245, 271, 271, 293, 106, 107, + /* 1770 */ 220, 271, 229, 225, 249, 219, 114, 259, 116, 117, + /* 1780 */ 118, 133, 259, 121, 219, 219, 138, 139, 153, 154, + /* 1790 */ 155, 156, 157, 280, 249, 243, 19, 20, 245, 22, + /* 1800 */ 196, 259, 140, 259, 60, 297, 141, 297, 200, 200, + /* 1810 */ 162, 38, 200, 36, 294, 153, 154, 155, 156, 157, + /* 1820 */ 151, 150, 294, 283, 22, 43, 234, 18, 237, 200, + /* 1830 */ 270, 272, 237, 237, 237, 18, 59, 199, 270, 149, + /* 1840 */ 246, 272, 272, 200, 234, 234, 246, 246, 71, 246, + /* 1850 */ 199, 158, 290, 62, 22, 200, 19, 20, 199, 22, + /* 1860 */ 289, 221, 221, 200, 200, 199, 199, 115, 218, 64, + /* 1870 */ 218, 218, 22, 36, 227, 126, 227, 100, 165, 221, + /* 1880 */ 224, 224, 24, 106, 107, 312, 218, 305, 113, 282, + /* 1890 */ 91, 114, 220, 116, 117, 118, 59, 282, 121, 218, + /* 1900 */ 218, 218, 200, 317, 317, 82, 221, 265, 71, 148, + /* 1910 */ 145, 265, 22, 277, 200, 158, 279, 140, 147, 25, + /* 1920 */ 146, 202, 248, 250, 249, 247, 13, 250, 194, 194, + /* 1930 */ 153, 154, 155, 156, 157, 6, 303, 100, 192, 192, + /* 1940 */ 246, 213, 192, 106, 107, 207, 213, 207, 222, 213, + /* 1950 */ 213, 114, 222, 116, 117, 118, 214, 214, 121, 4, + /* 1960 */ 207, 213, 3, 22, 303, 15, 163, 16, 23, 23, + /* 1970 */ 139, 151, 130, 25, 20, 142, 24, 16, 144, 1, + /* 1980 */ 142, 130, 130, 61, 37, 53, 300, 151, 53, 53, + /* 1990 */ 153, 154, 155, 156, 157, 53, 130, 116, 34, 1, + /* 2000 */ 141, 5, 22, 115, 161, 68, 25, 68, 75, 41, + /* 2010 */ 141, 115, 24, 20, 19, 131, 125, 23, 28, 22, + /* 2020 */ 67, 22, 22, 22, 67, 59, 24, 96, 22, 67, + /* 2030 */ 23, 149, 22, 25, 23, 23, 23, 22, 34, 141, + /* 2040 */ 37, 97, 23, 23, 116, 22, 143, 25, 34, 75, + /* 2050 */ 34, 34, 34, 88, 75, 34, 86, 23, 22, 34, + /* 2060 */ 93, 24, 34, 25, 25, 142, 142, 23, 44, 23, + /* 2070 */ 23, 23, 23, 11, 23, 25, 22, 22, 22, 141, + /* 2080 */ 23, 23, 22, 22, 25, 15, 1, 23, 25, 1, + /* 2090 */ 141, 135, 319, 319, 319, 319, 319, 319, 319, 141, /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, @@ -170254,176 +171338,177 @@ static const YYCODETYPE yy_lookahead[] = { /* 2250 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2260 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, /* 2270 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - /* 2280 */ 319, + /* 2280 */ 319, 319, 319, 319, 319, }; -#define YY_SHIFT_COUNT (574) +#define YY_SHIFT_COUNT (578) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2074) +#define YY_SHIFT_MAX (2088) static const unsigned short int yy_shift_ofst[] = { /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1837, /* 10 */ 1837, 1837, 471, 0, 0, 214, 1093, 1837, 1837, 1837, /* 20 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 30 */ 271, 271, 1219, 1219, 216, 88, 1, 1, 1, 1, - /* 40 */ 1, 40, 111, 258, 361, 469, 512, 583, 622, 693, - /* 50 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093, + /* 30 */ 1837, 271, 271, 1219, 1219, 216, 88, 1, 1, 1, + /* 40 */ 1, 1, 40, 111, 258, 361, 469, 512, 583, 622, + /* 50 */ 693, 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, - /* 70 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, 1662, - /* 80 */ 1777, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, + /* 70 */ 1093, 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, + /* 80 */ 1662, 1777, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, /* 90 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, /* 100 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, /* 110 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, /* 120 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, - /* 130 */ 137, 181, 181, 181, 181, 181, 181, 181, 94, 430, - /* 140 */ 66, 65, 112, 366, 533, 533, 740, 1261, 533, 533, - /* 150 */ 79, 79, 533, 412, 412, 412, 77, 412, 123, 113, - /* 160 */ 113, 22, 22, 2096, 2096, 328, 328, 328, 239, 468, - /* 170 */ 468, 468, 468, 1015, 1015, 409, 366, 1129, 1186, 533, - /* 180 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, - /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 969, - /* 200 */ 621, 621, 533, 642, 788, 788, 1228, 1228, 822, 822, - /* 210 */ 67, 1274, 2096, 2096, 2096, 2096, 2096, 2096, 2096, 1307, - /* 220 */ 954, 954, 585, 472, 640, 387, 695, 538, 541, 700, - /* 230 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, - /* 240 */ 222, 533, 533, 533, 533, 533, 533, 533, 533, 533, - /* 250 */ 533, 533, 533, 1179, 1179, 1179, 533, 533, 533, 565, - /* 260 */ 533, 533, 533, 916, 1144, 533, 533, 1288, 533, 533, - /* 270 */ 533, 533, 533, 533, 533, 533, 639, 1330, 209, 1076, - /* 280 */ 1076, 1076, 1076, 580, 209, 209, 1313, 768, 917, 649, - /* 290 */ 1181, 1316, 405, 1316, 1238, 249, 1181, 1181, 249, 1181, - /* 300 */ 405, 1238, 1369, 464, 1259, 1012, 1012, 1012, 1368, 1368, - /* 310 */ 1368, 1368, 184, 184, 1326, 904, 1287, 1480, 1712, 1712, - /* 320 */ 1633, 1633, 1757, 1757, 1633, 1647, 1651, 1783, 1764, 1791, - /* 330 */ 1791, 1791, 1791, 1633, 1806, 1677, 1651, 1651, 1677, 1783, - /* 340 */ 1764, 1677, 1764, 1677, 1633, 1806, 1674, 1779, 1633, 1806, - /* 350 */ 1823, 1633, 1806, 1633, 1806, 1823, 1732, 1732, 1732, 1794, - /* 360 */ 1840, 1840, 1823, 1732, 1738, 1732, 1794, 1732, 1732, 1701, - /* 370 */ 1844, 1758, 1758, 1823, 1633, 1789, 1789, 1807, 1807, 1742, - /* 380 */ 1752, 1877, 1633, 1743, 1742, 1759, 1765, 1677, 1879, 1897, - /* 390 */ 1897, 1914, 1914, 1914, 2096, 2096, 2096, 2096, 2096, 2096, - /* 400 */ 2096, 2096, 2096, 2096, 2096, 2096, 2096, 2096, 2096, 207, - /* 410 */ 1095, 331, 620, 903, 806, 1074, 1483, 1432, 1481, 1322, - /* 420 */ 1370, 1394, 1515, 1291, 1546, 1547, 1557, 1595, 1598, 1599, - /* 430 */ 1434, 1453, 1618, 1462, 1567, 1489, 1644, 1654, 1616, 1660, - /* 440 */ 1548, 1549, 1682, 1685, 1597, 742, 1941, 1945, 1927, 1787, - /* 450 */ 1937, 1940, 1934, 1936, 1821, 1810, 1832, 1938, 1938, 1942, - /* 460 */ 1822, 1947, 1824, 1949, 1968, 1828, 1841, 1938, 1842, 1912, - /* 470 */ 1939, 1938, 1826, 1921, 1922, 1925, 1926, 1850, 1865, 1948, - /* 480 */ 1843, 1982, 1980, 1964, 1872, 1827, 1928, 1970, 1929, 1923, - /* 490 */ 1958, 1848, 1885, 1977, 1983, 1985, 1871, 1880, 1984, 1943, - /* 500 */ 1986, 1987, 1988, 1990, 1946, 1955, 1991, 1911, 1989, 1994, - /* 510 */ 1951, 1992, 1996, 1873, 1998, 2000, 2001, 2002, 2003, 2004, - /* 520 */ 1999, 1933, 1890, 2009, 2010, 1910, 2005, 2012, 1892, 2011, - /* 530 */ 2006, 2007, 2008, 2013, 1950, 1962, 1957, 2014, 1969, 1952, - /* 540 */ 2015, 2023, 2026, 2027, 2025, 2028, 2018, 1913, 1915, 2031, - /* 550 */ 2011, 2033, 2036, 2037, 2038, 2039, 2040, 2043, 2051, 2044, - /* 560 */ 2045, 2046, 2047, 2049, 2050, 2048, 1944, 1935, 1953, 1954, - /* 570 */ 2052, 2055, 2053, 2073, 2074, + /* 130 */ 1837, 137, 181, 181, 181, 181, 181, 181, 181, 94, + /* 140 */ 430, 66, 65, 112, 366, 533, 533, 740, 1257, 533, + /* 150 */ 533, 79, 79, 533, 412, 412, 412, 77, 412, 123, + /* 160 */ 113, 113, 113, 22, 22, 2100, 2100, 328, 328, 328, + /* 170 */ 239, 468, 468, 468, 468, 1015, 1015, 409, 366, 1187, + /* 180 */ 1232, 533, 533, 533, 533, 533, 533, 533, 533, 533, + /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, + /* 200 */ 533, 969, 621, 621, 533, 642, 788, 788, 1133, 1133, + /* 210 */ 822, 822, 67, 1193, 2100, 2100, 2100, 2100, 2100, 2100, + /* 220 */ 2100, 1307, 954, 954, 585, 472, 640, 387, 695, 538, + /* 230 */ 541, 700, 533, 533, 533, 533, 533, 533, 533, 533, + /* 240 */ 533, 533, 222, 533, 533, 533, 533, 533, 533, 533, + /* 250 */ 533, 533, 533, 533, 533, 1213, 1213, 1213, 533, 533, + /* 260 */ 533, 565, 533, 533, 533, 916, 1147, 533, 533, 1288, + /* 270 */ 533, 533, 533, 533, 533, 533, 533, 533, 639, 1280, + /* 280 */ 209, 1129, 1129, 1129, 1129, 580, 209, 209, 1209, 768, + /* 290 */ 917, 649, 1315, 1334, 405, 1334, 1383, 249, 1315, 1315, + /* 300 */ 249, 1315, 405, 1383, 1441, 464, 1245, 1417, 1417, 1417, + /* 310 */ 1323, 1323, 1323, 1323, 184, 184, 1335, 1476, 856, 1482, + /* 320 */ 1744, 1744, 1665, 1665, 1773, 1773, 1665, 1669, 1671, 1802, + /* 330 */ 1782, 1809, 1809, 1809, 1809, 1665, 1817, 1690, 1671, 1671, + /* 340 */ 1690, 1802, 1782, 1690, 1782, 1690, 1665, 1817, 1693, 1791, + /* 350 */ 1665, 1817, 1832, 1665, 1817, 1665, 1817, 1832, 1752, 1752, + /* 360 */ 1752, 1805, 1850, 1850, 1832, 1752, 1749, 1752, 1805, 1752, + /* 370 */ 1752, 1713, 1858, 1775, 1775, 1832, 1665, 1799, 1799, 1823, + /* 380 */ 1823, 1761, 1765, 1890, 1665, 1757, 1761, 1771, 1774, 1690, + /* 390 */ 1894, 1913, 1913, 1929, 1929, 1929, 2100, 2100, 2100, 2100, + /* 400 */ 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, + /* 410 */ 2100, 207, 1220, 331, 620, 967, 806, 1074, 1499, 1432, + /* 420 */ 1463, 1479, 1419, 1422, 1557, 1512, 1598, 1599, 1644, 1645, + /* 430 */ 1654, 1660, 1555, 1505, 1684, 1462, 1670, 1563, 1619, 1593, + /* 440 */ 1676, 1679, 1613, 1680, 1554, 1558, 1689, 1692, 1605, 1589, + /* 450 */ 1955, 1959, 1941, 1803, 1950, 1951, 1945, 1946, 1831, 1820, + /* 460 */ 1842, 1948, 1948, 1952, 1833, 1954, 1834, 1961, 1978, 1838, + /* 470 */ 1851, 1948, 1852, 1922, 1947, 1948, 1836, 1932, 1935, 1936, + /* 480 */ 1942, 1866, 1881, 1964, 1859, 1998, 1996, 1980, 1888, 1843, + /* 490 */ 1937, 1981, 1939, 1933, 1968, 1869, 1896, 1988, 1993, 1995, + /* 500 */ 1884, 1891, 1997, 1953, 1999, 2000, 1994, 2001, 1957, 1966, + /* 510 */ 2002, 1931, 1990, 2006, 1962, 2003, 2007, 2004, 1882, 2010, + /* 520 */ 2011, 2012, 2008, 2013, 2015, 1944, 1898, 2019, 2020, 1928, + /* 530 */ 2014, 2023, 1903, 2022, 2016, 2017, 2018, 2021, 1965, 1974, + /* 540 */ 1970, 2024, 1979, 1967, 2025, 2034, 2036, 2037, 2038, 2039, + /* 550 */ 2028, 1923, 1924, 2044, 2022, 2046, 2047, 2048, 2049, 2050, + /* 560 */ 2051, 2054, 2062, 2055, 2056, 2057, 2058, 2060, 2061, 2059, + /* 570 */ 1956, 1938, 1949, 1958, 2063, 2064, 2070, 2085, 2088, }; -#define YY_REDUCE_COUNT (408) +#define YY_REDUCE_COUNT (410) #define YY_REDUCE_MIN (-271) -#define YY_REDUCE_MAX (1740) +#define YY_REDUCE_MAX (1753) static const short yy_reduce_ofst[] = { /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187, /* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489, - /* 20 */ 576, -175, 598, 686, 615, 725, 860, 778, 781, 857, - /* 30 */ 616, 887, 87, 240, -192, 408, 626, 796, 843, 854, - /* 40 */ 1003, -271, -271, -271, -271, -271, -271, -271, -271, -271, + /* 20 */ 576, 598, -175, 686, 860, 615, 725, 1014, 778, 781, + /* 30 */ 857, 616, 887, 87, 240, -192, 408, 626, 796, 843, + /* 40 */ 854, 1004, -271, -271, -271, -271, -271, -271, -271, -271, /* 50 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, /* 60 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, - /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, 80, 83, - /* 80 */ 313, 886, 888, 996, 1034, 1059, 1081, 1100, 1117, 1152, - /* 90 */ 1155, 1163, 1165, 1167, 1169, 1172, 1180, 1182, 1184, 1198, - /* 100 */ 1200, 1213, 1215, 1225, 1227, 1252, 1254, 1264, 1299, 1303, - /* 110 */ 1308, 1312, 1325, 1328, 1337, 1340, 1343, 1371, 1373, 1384, - /* 120 */ 1386, 1411, 1420, 1424, 1426, 1458, 1470, 1473, 1475, 1479, - /* 130 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271, - /* 140 */ -271, 138, 459, 396, -158, 470, 302, -212, 521, 201, - /* 150 */ -195, -92, 559, 630, 632, 630, -271, 632, 901, 63, - /* 160 */ 407, -271, -271, -271, -271, 161, 161, 161, 251, 335, - /* 170 */ 847, 960, 980, 537, 588, 618, 628, 688, 688, -166, - /* 180 */ -161, 674, 790, 794, 799, 851, 852, -122, 680, -120, - /* 190 */ 995, 1038, 415, 1051, 893, 798, 962, 400, 1086, 779, - /* 200 */ 923, 924, 263, 1041, 979, 990, 1083, 1097, 1031, 1194, - /* 210 */ 362, 994, 1139, 1005, 1037, 1202, 1205, 1195, 1210, -194, - /* 220 */ 56, 185, -135, 232, 522, 560, 601, 617, 669, 683, - /* 230 */ 711, 856, 908, 941, 1048, 1101, 1147, 1257, 1262, 1265, - /* 240 */ 392, 1292, 1333, 1339, 1342, 1346, 1350, 1359, 1374, 1418, - /* 250 */ 1421, 1436, 1437, 593, 755, 770, 997, 1445, 1459, 1209, - /* 260 */ 1500, 1504, 1516, 1132, 1243, 1518, 1519, 1440, 1520, 560, - /* 270 */ 1522, 1523, 1524, 1526, 1527, 1529, 1382, 1438, 1431, 1468, - /* 280 */ 1469, 1472, 1476, 1209, 1431, 1431, 1485, 1525, 1539, 1435, - /* 290 */ 1463, 1471, 1492, 1487, 1443, 1494, 1474, 1484, 1498, 1486, - /* 300 */ 1502, 1455, 1530, 1531, 1533, 1540, 1542, 1544, 1505, 1506, - /* 310 */ 1507, 1508, 1521, 1528, 1493, 1537, 1532, 1575, 1488, 1496, - /* 320 */ 1584, 1594, 1509, 1510, 1600, 1538, 1534, 1541, 1574, 1577, - /* 330 */ 1583, 1585, 1586, 1612, 1626, 1581, 1556, 1558, 1587, 1559, - /* 340 */ 1601, 1588, 1603, 1592, 1631, 1640, 1550, 1553, 1643, 1645, - /* 350 */ 1625, 1649, 1652, 1650, 1653, 1632, 1636, 1637, 1642, 1634, - /* 360 */ 1639, 1641, 1646, 1656, 1655, 1658, 1659, 1661, 1663, 1560, - /* 370 */ 1564, 1596, 1605, 1664, 1670, 1565, 1571, 1627, 1638, 1657, - /* 380 */ 1665, 1623, 1702, 1630, 1666, 1667, 1671, 1673, 1703, 1718, - /* 390 */ 1719, 1729, 1730, 1731, 1621, 1622, 1628, 1720, 1713, 1716, - /* 400 */ 1722, 1723, 1733, 1717, 1724, 1727, 1728, 1725, 1740, + /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, 80, + /* 80 */ 83, 313, 886, 888, 918, 938, 1021, 1034, 1036, 1141, + /* 90 */ 1159, 1163, 1166, 1168, 1170, 1176, 1178, 1180, 1184, 1196, + /* 100 */ 1198, 1205, 1215, 1225, 1227, 1236, 1252, 1254, 1264, 1303, + /* 110 */ 1309, 1312, 1322, 1325, 1328, 1337, 1340, 1343, 1353, 1371, + /* 120 */ 1373, 1384, 1386, 1411, 1413, 1420, 1424, 1426, 1458, 1470, + /* 130 */ 1473, -271, -271, -271, -271, -271, -271, -271, -271, -271, + /* 140 */ -271, -271, 138, 459, 396, -158, 470, 302, -212, 521, + /* 150 */ 201, -195, -92, 559, 630, 632, 630, -271, 632, 901, + /* 160 */ 63, 407, 670, -271, -271, -271, -271, 161, 161, 161, + /* 170 */ 251, 335, 847, 979, 1097, 537, 588, 618, 628, 688, + /* 180 */ 688, -166, -161, 674, 787, 794, 799, 852, 996, -122, + /* 190 */ 837, -120, 1018, 1035, 415, 1047, 1001, 958, 1082, 400, + /* 200 */ 1099, 779, 1137, 1142, 263, 1083, 1145, 1150, 1041, 1139, + /* 210 */ 965, 1050, 362, 849, 752, 629, 675, 1162, 1173, 1090, + /* 220 */ 1195, -194, 56, 185, -135, 232, 522, 560, 571, 601, + /* 230 */ 617, 669, 683, 711, 850, 893, 1000, 1040, 1049, 1081, + /* 240 */ 1087, 1101, 392, 1114, 1123, 1155, 1161, 1175, 1271, 1293, + /* 250 */ 1299, 1330, 1339, 1342, 1347, 593, 1282, 1286, 1350, 1359, + /* 260 */ 1368, 1314, 1480, 1483, 1507, 1085, 1338, 1526, 1527, 1487, + /* 270 */ 1531, 560, 1532, 1534, 1535, 1538, 1539, 1541, 1448, 1450, + /* 280 */ 1496, 1484, 1485, 1489, 1490, 1314, 1496, 1496, 1504, 1536, + /* 290 */ 1564, 1451, 1486, 1492, 1509, 1493, 1465, 1515, 1494, 1495, + /* 300 */ 1517, 1500, 1519, 1474, 1550, 1543, 1548, 1556, 1565, 1566, + /* 310 */ 1518, 1523, 1542, 1544, 1525, 1545, 1513, 1553, 1552, 1604, + /* 320 */ 1508, 1510, 1608, 1609, 1520, 1528, 1612, 1540, 1559, 1560, + /* 330 */ 1592, 1591, 1595, 1596, 1597, 1629, 1638, 1594, 1569, 1570, + /* 340 */ 1600, 1568, 1610, 1601, 1611, 1603, 1643, 1651, 1562, 1571, + /* 350 */ 1655, 1659, 1640, 1663, 1666, 1664, 1667, 1641, 1650, 1652, + /* 360 */ 1653, 1647, 1656, 1657, 1658, 1668, 1672, 1681, 1649, 1682, + /* 370 */ 1683, 1573, 1582, 1607, 1615, 1685, 1702, 1586, 1587, 1642, + /* 380 */ 1646, 1673, 1675, 1636, 1714, 1637, 1677, 1674, 1678, 1694, + /* 390 */ 1719, 1734, 1735, 1746, 1747, 1750, 1633, 1661, 1686, 1738, + /* 400 */ 1728, 1733, 1736, 1737, 1740, 1726, 1730, 1742, 1743, 1748, + /* 410 */ 1753, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1639, 1639, 1639, 1469, 1236, 1347, 1236, 1236, 1236, 1469, - /* 10 */ 1469, 1469, 1236, 1377, 1377, 1522, 1269, 1236, 1236, 1236, - /* 20 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1468, 1236, 1236, - /* 30 */ 1236, 1236, 1555, 1555, 1236, 1236, 1236, 1236, 1236, 1236, - /* 40 */ 1236, 1236, 1386, 1236, 1393, 1236, 1236, 1236, 1236, 1236, - /* 50 */ 1470, 1471, 1236, 1236, 1236, 1521, 1523, 1486, 1400, 1399, - /* 60 */ 1398, 1397, 1504, 1365, 1391, 1384, 1388, 1465, 1466, 1464, - /* 70 */ 1617, 1471, 1470, 1236, 1387, 1433, 1449, 1432, 1236, 1236, - /* 80 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 90 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 100 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 110 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 120 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 130 */ 1441, 1448, 1447, 1446, 1455, 1445, 1442, 1435, 1434, 1436, - /* 140 */ 1437, 1236, 1236, 1260, 1236, 1236, 1257, 1311, 1236, 1236, - /* 150 */ 1236, 1236, 1236, 1541, 1540, 1236, 1438, 1236, 1269, 1427, - /* 160 */ 1426, 1452, 1439, 1451, 1450, 1529, 1591, 1590, 1487, 1236, - /* 170 */ 1236, 1236, 1236, 1236, 1236, 1555, 1236, 1236, 1236, 1236, - /* 180 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 190 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1367, - /* 200 */ 1555, 1555, 1236, 1269, 1555, 1555, 1368, 1368, 1265, 1265, - /* 210 */ 1371, 1236, 1536, 1338, 1338, 1338, 1338, 1347, 1338, 1236, - /* 220 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 230 */ 1236, 1236, 1236, 1236, 1526, 1524, 1236, 1236, 1236, 1236, - /* 240 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 250 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 260 */ 1236, 1236, 1236, 1343, 1236, 1236, 1236, 1236, 1236, 1236, - /* 270 */ 1236, 1236, 1236, 1236, 1236, 1584, 1236, 1499, 1325, 1343, - /* 280 */ 1343, 1343, 1343, 1345, 1326, 1324, 1337, 1270, 1243, 1631, - /* 290 */ 1403, 1392, 1344, 1392, 1628, 1390, 1403, 1403, 1390, 1403, - /* 300 */ 1344, 1628, 1286, 1606, 1281, 1377, 1377, 1377, 1367, 1367, - /* 310 */ 1367, 1367, 1371, 1371, 1467, 1344, 1337, 1236, 1631, 1631, - /* 320 */ 1353, 1353, 1630, 1630, 1353, 1487, 1614, 1412, 1314, 1320, - /* 330 */ 1320, 1320, 1320, 1353, 1254, 1390, 1614, 1614, 1390, 1412, - /* 340 */ 1314, 1390, 1314, 1390, 1353, 1254, 1503, 1625, 1353, 1254, - /* 350 */ 1477, 1353, 1254, 1353, 1254, 1477, 1312, 1312, 1312, 1301, - /* 360 */ 1236, 1236, 1477, 1312, 1286, 1312, 1301, 1312, 1312, 1573, - /* 370 */ 1236, 1481, 1481, 1477, 1353, 1565, 1565, 1380, 1380, 1385, - /* 380 */ 1371, 1472, 1353, 1236, 1385, 1383, 1381, 1390, 1304, 1587, - /* 390 */ 1587, 1583, 1583, 1583, 1636, 1636, 1536, 1599, 1269, 1269, - /* 400 */ 1269, 1269, 1599, 1288, 1288, 1270, 1270, 1269, 1599, 1236, - /* 410 */ 1236, 1236, 1236, 1236, 1236, 1594, 1236, 1531, 1488, 1357, - /* 420 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 430 */ 1236, 1236, 1236, 1236, 1542, 1236, 1236, 1236, 1236, 1236, - /* 440 */ 1236, 1236, 1236, 1236, 1236, 1417, 1236, 1239, 1533, 1236, - /* 450 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1394, 1395, 1358, - /* 460 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1409, 1236, 1236, - /* 470 */ 1236, 1404, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 480 */ 1627, 1236, 1236, 1236, 1236, 1236, 1236, 1502, 1501, 1236, - /* 490 */ 1236, 1355, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 500 */ 1236, 1236, 1236, 1236, 1236, 1284, 1236, 1236, 1236, 1236, - /* 510 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 520 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1382, - /* 530 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 540 */ 1236, 1236, 1236, 1236, 1570, 1372, 1236, 1236, 1236, 1236, - /* 550 */ 1618, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - /* 560 */ 1236, 1236, 1236, 1236, 1236, 1610, 1328, 1418, 1236, 1421, - /* 570 */ 1258, 1236, 1248, 1236, 1236, + /* 0 */ 1648, 1648, 1648, 1478, 1243, 1354, 1243, 1243, 1243, 1478, + /* 10 */ 1478, 1478, 1243, 1384, 1384, 1531, 1276, 1243, 1243, 1243, + /* 20 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1477, 1243, + /* 30 */ 1243, 1243, 1243, 1564, 1564, 1243, 1243, 1243, 1243, 1243, + /* 40 */ 1243, 1243, 1243, 1393, 1243, 1400, 1243, 1243, 1243, 1243, + /* 50 */ 1243, 1479, 1480, 1243, 1243, 1243, 1530, 1532, 1495, 1407, + /* 60 */ 1406, 1405, 1404, 1513, 1372, 1398, 1391, 1395, 1474, 1475, + /* 70 */ 1473, 1626, 1480, 1479, 1243, 1394, 1442, 1458, 1441, 1243, + /* 80 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 90 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 100 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 110 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 120 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 130 */ 1243, 1450, 1457, 1456, 1455, 1464, 1454, 1451, 1444, 1443, + /* 140 */ 1445, 1446, 1243, 1243, 1267, 1243, 1243, 1264, 1318, 1243, + /* 150 */ 1243, 1243, 1243, 1243, 1550, 1549, 1243, 1447, 1243, 1276, + /* 160 */ 1435, 1434, 1433, 1461, 1448, 1460, 1459, 1538, 1600, 1599, + /* 170 */ 1496, 1243, 1243, 1243, 1243, 1243, 1243, 1564, 1243, 1243, + /* 180 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 190 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 200 */ 1243, 1374, 1564, 1564, 1243, 1276, 1564, 1564, 1375, 1375, + /* 210 */ 1272, 1272, 1378, 1243, 1545, 1345, 1345, 1345, 1345, 1354, + /* 220 */ 1345, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 230 */ 1243, 1243, 1243, 1243, 1243, 1243, 1535, 1533, 1243, 1243, + /* 240 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 250 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 260 */ 1243, 1243, 1243, 1243, 1243, 1350, 1243, 1243, 1243, 1243, + /* 270 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1593, 1243, 1508, + /* 280 */ 1332, 1350, 1350, 1350, 1350, 1352, 1333, 1331, 1344, 1277, + /* 290 */ 1250, 1640, 1410, 1399, 1351, 1399, 1637, 1397, 1410, 1410, + /* 300 */ 1397, 1410, 1351, 1637, 1293, 1615, 1288, 1384, 1384, 1384, + /* 310 */ 1374, 1374, 1374, 1374, 1378, 1378, 1476, 1351, 1344, 1243, + /* 320 */ 1640, 1640, 1360, 1360, 1639, 1639, 1360, 1496, 1623, 1419, + /* 330 */ 1321, 1327, 1327, 1327, 1327, 1360, 1261, 1397, 1623, 1623, + /* 340 */ 1397, 1419, 1321, 1397, 1321, 1397, 1360, 1261, 1512, 1634, + /* 350 */ 1360, 1261, 1486, 1360, 1261, 1360, 1261, 1486, 1319, 1319, + /* 360 */ 1319, 1308, 1243, 1243, 1486, 1319, 1293, 1319, 1308, 1319, + /* 370 */ 1319, 1582, 1243, 1490, 1490, 1486, 1360, 1574, 1574, 1387, + /* 380 */ 1387, 1392, 1378, 1481, 1360, 1243, 1392, 1390, 1388, 1397, + /* 390 */ 1311, 1596, 1596, 1592, 1592, 1592, 1645, 1645, 1545, 1608, + /* 400 */ 1276, 1276, 1276, 1276, 1608, 1295, 1295, 1277, 1277, 1276, + /* 410 */ 1608, 1243, 1243, 1243, 1243, 1243, 1243, 1603, 1243, 1540, + /* 420 */ 1497, 1364, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 430 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1551, 1243, + /* 440 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1424, + /* 450 */ 1243, 1246, 1542, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 460 */ 1243, 1401, 1402, 1365, 1243, 1243, 1243, 1243, 1243, 1243, + /* 470 */ 1243, 1416, 1243, 1243, 1243, 1411, 1243, 1243, 1243, 1243, + /* 480 */ 1243, 1243, 1243, 1243, 1636, 1243, 1243, 1243, 1243, 1243, + /* 490 */ 1243, 1511, 1510, 1243, 1243, 1362, 1243, 1243, 1243, 1243, + /* 500 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1291, + /* 510 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 520 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + /* 530 */ 1243, 1243, 1243, 1389, 1243, 1243, 1243, 1243, 1243, 1243, + /* 540 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1579, 1379, + /* 550 */ 1243, 1243, 1243, 1243, 1627, 1243, 1243, 1243, 1243, 1243, + /* 560 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1619, + /* 570 */ 1335, 1425, 1243, 1428, 1265, 1243, 1255, 1243, 1243, }; /********** End of lemon-generated parsing tables *****************************/ @@ -171230,221 +172315,223 @@ static const char *const yyRuleName[] = { /* 185 */ "expr ::= expr COLLATE ID|STRING", /* 186 */ "expr ::= CAST LP expr AS typetoken RP", /* 187 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP", - /* 188 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", - /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", - /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", - /* 191 */ "term ::= CTIME_KW", - /* 192 */ "expr ::= LP nexprlist COMMA expr RP", - /* 193 */ "expr ::= expr AND expr", - /* 194 */ "expr ::= expr OR expr", - /* 195 */ "expr ::= expr LT|GT|GE|LE expr", - /* 196 */ "expr ::= expr EQ|NE expr", - /* 197 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 198 */ "expr ::= expr PLUS|MINUS expr", - /* 199 */ "expr ::= expr STAR|SLASH|REM expr", - /* 200 */ "expr ::= expr CONCAT expr", - /* 201 */ "likeop ::= NOT LIKE_KW|MATCH", - /* 202 */ "expr ::= expr likeop expr", - /* 203 */ "expr ::= expr likeop expr ESCAPE expr", - /* 204 */ "expr ::= expr ISNULL|NOTNULL", - /* 205 */ "expr ::= expr NOT NULL", - /* 206 */ "expr ::= expr IS expr", - /* 207 */ "expr ::= expr IS NOT expr", - /* 208 */ "expr ::= expr IS NOT DISTINCT FROM expr", - /* 209 */ "expr ::= expr IS DISTINCT FROM expr", - /* 210 */ "expr ::= NOT expr", - /* 211 */ "expr ::= BITNOT expr", - /* 212 */ "expr ::= PLUS|MINUS expr", - /* 213 */ "expr ::= expr PTR expr", - /* 214 */ "between_op ::= BETWEEN", - /* 215 */ "between_op ::= NOT BETWEEN", - /* 216 */ "expr ::= expr between_op expr AND expr", - /* 217 */ "in_op ::= IN", - /* 218 */ "in_op ::= NOT IN", - /* 219 */ "expr ::= expr in_op LP exprlist RP", - /* 220 */ "expr ::= LP select RP", - /* 221 */ "expr ::= expr in_op LP select RP", - /* 222 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 223 */ "expr ::= EXISTS LP select RP", - /* 224 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 225 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 226 */ "case_exprlist ::= WHEN expr THEN expr", - /* 227 */ "case_else ::= ELSE expr", - /* 228 */ "case_else ::=", - /* 229 */ "case_operand ::=", - /* 230 */ "exprlist ::=", - /* 231 */ "nexprlist ::= nexprlist COMMA expr", - /* 232 */ "nexprlist ::= expr", - /* 233 */ "paren_exprlist ::=", - /* 234 */ "paren_exprlist ::= LP exprlist RP", - /* 235 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", - /* 236 */ "uniqueflag ::= UNIQUE", - /* 237 */ "uniqueflag ::=", - /* 238 */ "eidlist_opt ::=", - /* 239 */ "eidlist_opt ::= LP eidlist RP", - /* 240 */ "eidlist ::= eidlist COMMA nm collate sortorder", - /* 241 */ "eidlist ::= nm collate sortorder", - /* 242 */ "collate ::=", - /* 243 */ "collate ::= COLLATE ID|STRING", - /* 244 */ "cmd ::= DROP INDEX ifexists fullname", - /* 245 */ "cmd ::= VACUUM vinto", - /* 246 */ "cmd ::= VACUUM nm vinto", - /* 247 */ "vinto ::= INTO expr", - /* 248 */ "vinto ::=", - /* 249 */ "cmd ::= PRAGMA nm dbnm", - /* 250 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 251 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 252 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 253 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 254 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 255 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 256 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 257 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 258 */ "trigger_time ::= BEFORE|AFTER", - /* 259 */ "trigger_time ::= INSTEAD OF", - /* 260 */ "trigger_time ::=", - /* 261 */ "trigger_event ::= DELETE|INSERT", - /* 262 */ "trigger_event ::= UPDATE", - /* 263 */ "trigger_event ::= UPDATE OF idlist", - /* 264 */ "when_clause ::=", - /* 265 */ "when_clause ::= WHEN expr", - /* 266 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 267 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 268 */ "trnm ::= nm DOT nm", - /* 269 */ "tridxby ::= INDEXED BY nm", - /* 270 */ "tridxby ::= NOT INDEXED", - /* 271 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", - /* 272 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 273 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 274 */ "trigger_cmd ::= scanpt select scanpt", - /* 275 */ "expr ::= RAISE LP IGNORE RP", - /* 276 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 277 */ "raisetype ::= ROLLBACK", - /* 278 */ "raisetype ::= ABORT", - /* 279 */ "raisetype ::= FAIL", - /* 280 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 281 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 282 */ "cmd ::= DETACH database_kw_opt expr", - /* 283 */ "key_opt ::=", - /* 284 */ "key_opt ::= KEY expr", - /* 285 */ "cmd ::= REINDEX", - /* 286 */ "cmd ::= REINDEX nm dbnm", - /* 287 */ "cmd ::= ANALYZE", - /* 288 */ "cmd ::= ANALYZE nm dbnm", - /* 289 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 290 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 291 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", - /* 292 */ "add_column_fullname ::= fullname", - /* 293 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", - /* 294 */ "cmd ::= create_vtab", - /* 295 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 296 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 297 */ "vtabarg ::=", - /* 298 */ "vtabargtoken ::= ANY", - /* 299 */ "vtabargtoken ::= lp anylist RP", - /* 300 */ "lp ::= LP", - /* 301 */ "with ::= WITH wqlist", - /* 302 */ "with ::= WITH RECURSIVE wqlist", - /* 303 */ "wqas ::= AS", - /* 304 */ "wqas ::= AS MATERIALIZED", - /* 305 */ "wqas ::= AS NOT MATERIALIZED", - /* 306 */ "wqitem ::= nm eidlist_opt wqas LP select RP", - /* 307 */ "wqlist ::= wqitem", - /* 308 */ "wqlist ::= wqlist COMMA wqitem", - /* 309 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", - /* 310 */ "windowdefn ::= nm AS LP window RP", - /* 311 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", - /* 312 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", - /* 313 */ "window ::= ORDER BY sortlist frame_opt", - /* 314 */ "window ::= nm ORDER BY sortlist frame_opt", - /* 315 */ "window ::= nm frame_opt", - /* 316 */ "frame_opt ::=", - /* 317 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", - /* 318 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", - /* 319 */ "range_or_rows ::= RANGE|ROWS|GROUPS", - /* 320 */ "frame_bound_s ::= frame_bound", - /* 321 */ "frame_bound_s ::= UNBOUNDED PRECEDING", - /* 322 */ "frame_bound_e ::= frame_bound", - /* 323 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", - /* 324 */ "frame_bound ::= expr PRECEDING|FOLLOWING", - /* 325 */ "frame_bound ::= CURRENT ROW", - /* 326 */ "frame_exclude_opt ::=", - /* 327 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", - /* 328 */ "frame_exclude ::= NO OTHERS", - /* 329 */ "frame_exclude ::= CURRENT ROW", - /* 330 */ "frame_exclude ::= GROUP|TIES", - /* 331 */ "window_clause ::= WINDOW windowdefn_list", - /* 332 */ "filter_over ::= filter_clause over_clause", - /* 333 */ "filter_over ::= over_clause", - /* 334 */ "filter_over ::= filter_clause", - /* 335 */ "over_clause ::= OVER LP window RP", - /* 336 */ "over_clause ::= OVER nm", - /* 337 */ "filter_clause ::= FILTER LP WHERE expr RP", - /* 338 */ "input ::= cmdlist", - /* 339 */ "cmdlist ::= cmdlist ecmd", - /* 340 */ "cmdlist ::= ecmd", - /* 341 */ "ecmd ::= SEMI", - /* 342 */ "ecmd ::= cmdx SEMI", - /* 343 */ "ecmd ::= explain cmdx SEMI", - /* 344 */ "trans_opt ::=", - /* 345 */ "trans_opt ::= TRANSACTION", - /* 346 */ "trans_opt ::= TRANSACTION nm", - /* 347 */ "savepoint_opt ::= SAVEPOINT", - /* 348 */ "savepoint_opt ::=", - /* 349 */ "cmd ::= create_table create_table_args", - /* 350 */ "table_option_set ::= table_option", - /* 351 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 352 */ "columnlist ::= columnname carglist", - /* 353 */ "nm ::= ID|INDEXED|JOIN_KW", - /* 354 */ "nm ::= STRING", - /* 355 */ "typetoken ::= typename", - /* 356 */ "typename ::= ID|STRING", - /* 357 */ "signed ::= plus_num", - /* 358 */ "signed ::= minus_num", - /* 359 */ "carglist ::= carglist ccons", - /* 360 */ "carglist ::=", - /* 361 */ "ccons ::= NULL onconf", - /* 362 */ "ccons ::= GENERATED ALWAYS AS generated", - /* 363 */ "ccons ::= AS generated", - /* 364 */ "conslist_opt ::= COMMA conslist", - /* 365 */ "conslist ::= conslist tconscomma tcons", - /* 366 */ "conslist ::= tcons", - /* 367 */ "tconscomma ::=", - /* 368 */ "defer_subclause_opt ::= defer_subclause", - /* 369 */ "resolvetype ::= raisetype", - /* 370 */ "selectnowith ::= oneselect", - /* 371 */ "oneselect ::= values", - /* 372 */ "sclp ::= selcollist COMMA", - /* 373 */ "as ::= ID|STRING", - /* 374 */ "indexed_opt ::= indexed_by", - /* 375 */ "returning ::=", - /* 376 */ "expr ::= term", - /* 377 */ "likeop ::= LIKE_KW|MATCH", - /* 378 */ "case_operand ::= expr", - /* 379 */ "exprlist ::= nexprlist", - /* 380 */ "nmnum ::= plus_num", - /* 381 */ "nmnum ::= nm", - /* 382 */ "nmnum ::= ON", - /* 383 */ "nmnum ::= DELETE", - /* 384 */ "nmnum ::= DEFAULT", - /* 385 */ "plus_num ::= INTEGER|FLOAT", - /* 386 */ "foreach_clause ::=", - /* 387 */ "foreach_clause ::= FOR EACH ROW", - /* 388 */ "trnm ::= nm", - /* 389 */ "tridxby ::=", - /* 390 */ "database_kw_opt ::= DATABASE", - /* 391 */ "database_kw_opt ::=", - /* 392 */ "kwcolumn_opt ::=", - /* 393 */ "kwcolumn_opt ::= COLUMNKW", - /* 394 */ "vtabarglist ::= vtabarg", - /* 395 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 396 */ "vtabarg ::= vtabarg vtabargtoken", - /* 397 */ "anylist ::=", - /* 398 */ "anylist ::= anylist LP anylist RP", - /* 399 */ "anylist ::= anylist ANY", - /* 400 */ "with ::=", - /* 401 */ "windowdefn_list ::= windowdefn", - /* 402 */ "window ::= frame_opt", + /* 188 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP", + /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", + /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", + /* 191 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over", + /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", + /* 193 */ "term ::= CTIME_KW", + /* 194 */ "expr ::= LP nexprlist COMMA expr RP", + /* 195 */ "expr ::= expr AND expr", + /* 196 */ "expr ::= expr OR expr", + /* 197 */ "expr ::= expr LT|GT|GE|LE expr", + /* 198 */ "expr ::= expr EQ|NE expr", + /* 199 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 200 */ "expr ::= expr PLUS|MINUS expr", + /* 201 */ "expr ::= expr STAR|SLASH|REM expr", + /* 202 */ "expr ::= expr CONCAT expr", + /* 203 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 204 */ "expr ::= expr likeop expr", + /* 205 */ "expr ::= expr likeop expr ESCAPE expr", + /* 206 */ "expr ::= expr ISNULL|NOTNULL", + /* 207 */ "expr ::= expr NOT NULL", + /* 208 */ "expr ::= expr IS expr", + /* 209 */ "expr ::= expr IS NOT expr", + /* 210 */ "expr ::= expr IS NOT DISTINCT FROM expr", + /* 211 */ "expr ::= expr IS DISTINCT FROM expr", + /* 212 */ "expr ::= NOT expr", + /* 213 */ "expr ::= BITNOT expr", + /* 214 */ "expr ::= PLUS|MINUS expr", + /* 215 */ "expr ::= expr PTR expr", + /* 216 */ "between_op ::= BETWEEN", + /* 217 */ "between_op ::= NOT BETWEEN", + /* 218 */ "expr ::= expr between_op expr AND expr", + /* 219 */ "in_op ::= IN", + /* 220 */ "in_op ::= NOT IN", + /* 221 */ "expr ::= expr in_op LP exprlist RP", + /* 222 */ "expr ::= LP select RP", + /* 223 */ "expr ::= expr in_op LP select RP", + /* 224 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 225 */ "expr ::= EXISTS LP select RP", + /* 226 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 227 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 228 */ "case_exprlist ::= WHEN expr THEN expr", + /* 229 */ "case_else ::= ELSE expr", + /* 230 */ "case_else ::=", + /* 231 */ "case_operand ::=", + /* 232 */ "exprlist ::=", + /* 233 */ "nexprlist ::= nexprlist COMMA expr", + /* 234 */ "nexprlist ::= expr", + /* 235 */ "paren_exprlist ::=", + /* 236 */ "paren_exprlist ::= LP exprlist RP", + /* 237 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 238 */ "uniqueflag ::= UNIQUE", + /* 239 */ "uniqueflag ::=", + /* 240 */ "eidlist_opt ::=", + /* 241 */ "eidlist_opt ::= LP eidlist RP", + /* 242 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 243 */ "eidlist ::= nm collate sortorder", + /* 244 */ "collate ::=", + /* 245 */ "collate ::= COLLATE ID|STRING", + /* 246 */ "cmd ::= DROP INDEX ifexists fullname", + /* 247 */ "cmd ::= VACUUM vinto", + /* 248 */ "cmd ::= VACUUM nm vinto", + /* 249 */ "vinto ::= INTO expr", + /* 250 */ "vinto ::=", + /* 251 */ "cmd ::= PRAGMA nm dbnm", + /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 256 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 257 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 258 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 260 */ "trigger_time ::= BEFORE|AFTER", + /* 261 */ "trigger_time ::= INSTEAD OF", + /* 262 */ "trigger_time ::=", + /* 263 */ "trigger_event ::= DELETE|INSERT", + /* 264 */ "trigger_event ::= UPDATE", + /* 265 */ "trigger_event ::= UPDATE OF idlist", + /* 266 */ "when_clause ::=", + /* 267 */ "when_clause ::= WHEN expr", + /* 268 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 269 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 270 */ "trnm ::= nm DOT nm", + /* 271 */ "tridxby ::= INDEXED BY nm", + /* 272 */ "tridxby ::= NOT INDEXED", + /* 273 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", + /* 274 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 275 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 276 */ "trigger_cmd ::= scanpt select scanpt", + /* 277 */ "expr ::= RAISE LP IGNORE RP", + /* 278 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 279 */ "raisetype ::= ROLLBACK", + /* 280 */ "raisetype ::= ABORT", + /* 281 */ "raisetype ::= FAIL", + /* 282 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 283 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 284 */ "cmd ::= DETACH database_kw_opt expr", + /* 285 */ "key_opt ::=", + /* 286 */ "key_opt ::= KEY expr", + /* 287 */ "cmd ::= REINDEX", + /* 288 */ "cmd ::= REINDEX nm dbnm", + /* 289 */ "cmd ::= ANALYZE", + /* 290 */ "cmd ::= ANALYZE nm dbnm", + /* 291 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 292 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 293 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 294 */ "add_column_fullname ::= fullname", + /* 295 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 296 */ "cmd ::= create_vtab", + /* 297 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 298 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 299 */ "vtabarg ::=", + /* 300 */ "vtabargtoken ::= ANY", + /* 301 */ "vtabargtoken ::= lp anylist RP", + /* 302 */ "lp ::= LP", + /* 303 */ "with ::= WITH wqlist", + /* 304 */ "with ::= WITH RECURSIVE wqlist", + /* 305 */ "wqas ::= AS", + /* 306 */ "wqas ::= AS MATERIALIZED", + /* 307 */ "wqas ::= AS NOT MATERIALIZED", + /* 308 */ "wqitem ::= nm eidlist_opt wqas LP select RP", + /* 309 */ "wqlist ::= wqitem", + /* 310 */ "wqlist ::= wqlist COMMA wqitem", + /* 311 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 312 */ "windowdefn ::= nm AS LP window RP", + /* 313 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 314 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 315 */ "window ::= ORDER BY sortlist frame_opt", + /* 316 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 317 */ "window ::= nm frame_opt", + /* 318 */ "frame_opt ::=", + /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 322 */ "frame_bound_s ::= frame_bound", + /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 324 */ "frame_bound_e ::= frame_bound", + /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 327 */ "frame_bound ::= CURRENT ROW", + /* 328 */ "frame_exclude_opt ::=", + /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 330 */ "frame_exclude ::= NO OTHERS", + /* 331 */ "frame_exclude ::= CURRENT ROW", + /* 332 */ "frame_exclude ::= GROUP|TIES", + /* 333 */ "window_clause ::= WINDOW windowdefn_list", + /* 334 */ "filter_over ::= filter_clause over_clause", + /* 335 */ "filter_over ::= over_clause", + /* 336 */ "filter_over ::= filter_clause", + /* 337 */ "over_clause ::= OVER LP window RP", + /* 338 */ "over_clause ::= OVER nm", + /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 340 */ "input ::= cmdlist", + /* 341 */ "cmdlist ::= cmdlist ecmd", + /* 342 */ "cmdlist ::= ecmd", + /* 343 */ "ecmd ::= SEMI", + /* 344 */ "ecmd ::= cmdx SEMI", + /* 345 */ "ecmd ::= explain cmdx SEMI", + /* 346 */ "trans_opt ::=", + /* 347 */ "trans_opt ::= TRANSACTION", + /* 348 */ "trans_opt ::= TRANSACTION nm", + /* 349 */ "savepoint_opt ::= SAVEPOINT", + /* 350 */ "savepoint_opt ::=", + /* 351 */ "cmd ::= create_table create_table_args", + /* 352 */ "table_option_set ::= table_option", + /* 353 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 354 */ "columnlist ::= columnname carglist", + /* 355 */ "nm ::= ID|INDEXED|JOIN_KW", + /* 356 */ "nm ::= STRING", + /* 357 */ "typetoken ::= typename", + /* 358 */ "typename ::= ID|STRING", + /* 359 */ "signed ::= plus_num", + /* 360 */ "signed ::= minus_num", + /* 361 */ "carglist ::= carglist ccons", + /* 362 */ "carglist ::=", + /* 363 */ "ccons ::= NULL onconf", + /* 364 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 365 */ "ccons ::= AS generated", + /* 366 */ "conslist_opt ::= COMMA conslist", + /* 367 */ "conslist ::= conslist tconscomma tcons", + /* 368 */ "conslist ::= tcons", + /* 369 */ "tconscomma ::=", + /* 370 */ "defer_subclause_opt ::= defer_subclause", + /* 371 */ "resolvetype ::= raisetype", + /* 372 */ "selectnowith ::= oneselect", + /* 373 */ "oneselect ::= values", + /* 374 */ "sclp ::= selcollist COMMA", + /* 375 */ "as ::= ID|STRING", + /* 376 */ "indexed_opt ::= indexed_by", + /* 377 */ "returning ::=", + /* 378 */ "expr ::= term", + /* 379 */ "likeop ::= LIKE_KW|MATCH", + /* 380 */ "case_operand ::= expr", + /* 381 */ "exprlist ::= nexprlist", + /* 382 */ "nmnum ::= plus_num", + /* 383 */ "nmnum ::= nm", + /* 384 */ "nmnum ::= ON", + /* 385 */ "nmnum ::= DELETE", + /* 386 */ "nmnum ::= DEFAULT", + /* 387 */ "plus_num ::= INTEGER|FLOAT", + /* 388 */ "foreach_clause ::=", + /* 389 */ "foreach_clause ::= FOR EACH ROW", + /* 390 */ "trnm ::= nm", + /* 391 */ "tridxby ::=", + /* 392 */ "database_kw_opt ::= DATABASE", + /* 393 */ "database_kw_opt ::=", + /* 394 */ "kwcolumn_opt ::=", + /* 395 */ "kwcolumn_opt ::= COLUMNKW", + /* 396 */ "vtabarglist ::= vtabarg", + /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 398 */ "vtabarg ::= vtabarg vtabargtoken", + /* 399 */ "anylist ::=", + /* 400 */ "anylist ::= anylist LP anylist RP", + /* 401 */ "anylist ::= anylist ANY", + /* 402 */ "with ::=", + /* 403 */ "windowdefn_list ::= windowdefn", + /* 404 */ "window ::= frame_opt", }; #endif /* NDEBUG */ @@ -172139,221 +173226,223 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 217, /* (185) expr ::= expr COLLATE ID|STRING */ 217, /* (186) expr ::= CAST LP expr AS typetoken RP */ 217, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ - 217, /* (188) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ - 217, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ - 217, /* (190) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ - 216, /* (191) term ::= CTIME_KW */ - 217, /* (192) expr ::= LP nexprlist COMMA expr RP */ - 217, /* (193) expr ::= expr AND expr */ - 217, /* (194) expr ::= expr OR expr */ - 217, /* (195) expr ::= expr LT|GT|GE|LE expr */ - 217, /* (196) expr ::= expr EQ|NE expr */ - 217, /* (197) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - 217, /* (198) expr ::= expr PLUS|MINUS expr */ - 217, /* (199) expr ::= expr STAR|SLASH|REM expr */ - 217, /* (200) expr ::= expr CONCAT expr */ - 274, /* (201) likeop ::= NOT LIKE_KW|MATCH */ - 217, /* (202) expr ::= expr likeop expr */ - 217, /* (203) expr ::= expr likeop expr ESCAPE expr */ - 217, /* (204) expr ::= expr ISNULL|NOTNULL */ - 217, /* (205) expr ::= expr NOT NULL */ - 217, /* (206) expr ::= expr IS expr */ - 217, /* (207) expr ::= expr IS NOT expr */ - 217, /* (208) expr ::= expr IS NOT DISTINCT FROM expr */ - 217, /* (209) expr ::= expr IS DISTINCT FROM expr */ - 217, /* (210) expr ::= NOT expr */ - 217, /* (211) expr ::= BITNOT expr */ - 217, /* (212) expr ::= PLUS|MINUS expr */ - 217, /* (213) expr ::= expr PTR expr */ - 275, /* (214) between_op ::= BETWEEN */ - 275, /* (215) between_op ::= NOT BETWEEN */ - 217, /* (216) expr ::= expr between_op expr AND expr */ - 276, /* (217) in_op ::= IN */ - 276, /* (218) in_op ::= NOT IN */ - 217, /* (219) expr ::= expr in_op LP exprlist RP */ - 217, /* (220) expr ::= LP select RP */ - 217, /* (221) expr ::= expr in_op LP select RP */ - 217, /* (222) expr ::= expr in_op nm dbnm paren_exprlist */ - 217, /* (223) expr ::= EXISTS LP select RP */ - 217, /* (224) expr ::= CASE case_operand case_exprlist case_else END */ - 279, /* (225) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - 279, /* (226) case_exprlist ::= WHEN expr THEN expr */ - 280, /* (227) case_else ::= ELSE expr */ - 280, /* (228) case_else ::= */ - 278, /* (229) case_operand ::= */ - 261, /* (230) exprlist ::= */ - 253, /* (231) nexprlist ::= nexprlist COMMA expr */ - 253, /* (232) nexprlist ::= expr */ - 277, /* (233) paren_exprlist ::= */ - 277, /* (234) paren_exprlist ::= LP exprlist RP */ - 190, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - 281, /* (236) uniqueflag ::= UNIQUE */ - 281, /* (237) uniqueflag ::= */ - 221, /* (238) eidlist_opt ::= */ - 221, /* (239) eidlist_opt ::= LP eidlist RP */ - 232, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ - 232, /* (241) eidlist ::= nm collate sortorder */ - 282, /* (242) collate ::= */ - 282, /* (243) collate ::= COLLATE ID|STRING */ - 190, /* (244) cmd ::= DROP INDEX ifexists fullname */ - 190, /* (245) cmd ::= VACUUM vinto */ - 190, /* (246) cmd ::= VACUUM nm vinto */ - 283, /* (247) vinto ::= INTO expr */ - 283, /* (248) vinto ::= */ - 190, /* (249) cmd ::= PRAGMA nm dbnm */ - 190, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ - 190, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - 190, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ - 190, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - 211, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ - 212, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ - 190, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - 285, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - 287, /* (258) trigger_time ::= BEFORE|AFTER */ - 287, /* (259) trigger_time ::= INSTEAD OF */ - 287, /* (260) trigger_time ::= */ - 288, /* (261) trigger_event ::= DELETE|INSERT */ - 288, /* (262) trigger_event ::= UPDATE */ - 288, /* (263) trigger_event ::= UPDATE OF idlist */ - 290, /* (264) when_clause ::= */ - 290, /* (265) when_clause ::= WHEN expr */ - 286, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - 286, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ - 292, /* (268) trnm ::= nm DOT nm */ - 293, /* (269) tridxby ::= INDEXED BY nm */ - 293, /* (270) tridxby ::= NOT INDEXED */ - 291, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - 291, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - 291, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - 291, /* (274) trigger_cmd ::= scanpt select scanpt */ - 217, /* (275) expr ::= RAISE LP IGNORE RP */ - 217, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ - 236, /* (277) raisetype ::= ROLLBACK */ - 236, /* (278) raisetype ::= ABORT */ - 236, /* (279) raisetype ::= FAIL */ - 190, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ - 190, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - 190, /* (282) cmd ::= DETACH database_kw_opt expr */ - 295, /* (283) key_opt ::= */ - 295, /* (284) key_opt ::= KEY expr */ - 190, /* (285) cmd ::= REINDEX */ - 190, /* (286) cmd ::= REINDEX nm dbnm */ - 190, /* (287) cmd ::= ANALYZE */ - 190, /* (288) cmd ::= ANALYZE nm dbnm */ - 190, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ - 190, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - 190, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - 296, /* (292) add_column_fullname ::= fullname */ - 190, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - 190, /* (294) cmd ::= create_vtab */ - 190, /* (295) cmd ::= create_vtab LP vtabarglist RP */ - 298, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 300, /* (297) vtabarg ::= */ - 301, /* (298) vtabargtoken ::= ANY */ - 301, /* (299) vtabargtoken ::= lp anylist RP */ - 302, /* (300) lp ::= LP */ - 266, /* (301) with ::= WITH wqlist */ - 266, /* (302) with ::= WITH RECURSIVE wqlist */ - 305, /* (303) wqas ::= AS */ - 305, /* (304) wqas ::= AS MATERIALIZED */ - 305, /* (305) wqas ::= AS NOT MATERIALIZED */ - 304, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ - 241, /* (307) wqlist ::= wqitem */ - 241, /* (308) wqlist ::= wqlist COMMA wqitem */ - 306, /* (309) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - 307, /* (310) windowdefn ::= nm AS LP window RP */ - 308, /* (311) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - 308, /* (312) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - 308, /* (313) window ::= ORDER BY sortlist frame_opt */ - 308, /* (314) window ::= nm ORDER BY sortlist frame_opt */ - 308, /* (315) window ::= nm frame_opt */ - 309, /* (316) frame_opt ::= */ - 309, /* (317) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - 309, /* (318) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - 313, /* (319) range_or_rows ::= RANGE|ROWS|GROUPS */ - 315, /* (320) frame_bound_s ::= frame_bound */ - 315, /* (321) frame_bound_s ::= UNBOUNDED PRECEDING */ - 316, /* (322) frame_bound_e ::= frame_bound */ - 316, /* (323) frame_bound_e ::= UNBOUNDED FOLLOWING */ - 314, /* (324) frame_bound ::= expr PRECEDING|FOLLOWING */ - 314, /* (325) frame_bound ::= CURRENT ROW */ - 317, /* (326) frame_exclude_opt ::= */ - 317, /* (327) frame_exclude_opt ::= EXCLUDE frame_exclude */ - 318, /* (328) frame_exclude ::= NO OTHERS */ - 318, /* (329) frame_exclude ::= CURRENT ROW */ - 318, /* (330) frame_exclude ::= GROUP|TIES */ - 251, /* (331) window_clause ::= WINDOW windowdefn_list */ - 273, /* (332) filter_over ::= filter_clause over_clause */ - 273, /* (333) filter_over ::= over_clause */ - 273, /* (334) filter_over ::= filter_clause */ - 312, /* (335) over_clause ::= OVER LP window RP */ - 312, /* (336) over_clause ::= OVER nm */ - 311, /* (337) filter_clause ::= FILTER LP WHERE expr RP */ - 185, /* (338) input ::= cmdlist */ - 186, /* (339) cmdlist ::= cmdlist ecmd */ - 186, /* (340) cmdlist ::= ecmd */ - 187, /* (341) ecmd ::= SEMI */ - 187, /* (342) ecmd ::= cmdx SEMI */ - 187, /* (343) ecmd ::= explain cmdx SEMI */ - 192, /* (344) trans_opt ::= */ - 192, /* (345) trans_opt ::= TRANSACTION */ - 192, /* (346) trans_opt ::= TRANSACTION nm */ - 194, /* (347) savepoint_opt ::= SAVEPOINT */ - 194, /* (348) savepoint_opt ::= */ - 190, /* (349) cmd ::= create_table create_table_args */ - 203, /* (350) table_option_set ::= table_option */ - 201, /* (351) columnlist ::= columnlist COMMA columnname carglist */ - 201, /* (352) columnlist ::= columnname carglist */ - 193, /* (353) nm ::= ID|INDEXED|JOIN_KW */ - 193, /* (354) nm ::= STRING */ - 208, /* (355) typetoken ::= typename */ - 209, /* (356) typename ::= ID|STRING */ - 210, /* (357) signed ::= plus_num */ - 210, /* (358) signed ::= minus_num */ - 207, /* (359) carglist ::= carglist ccons */ - 207, /* (360) carglist ::= */ - 215, /* (361) ccons ::= NULL onconf */ - 215, /* (362) ccons ::= GENERATED ALWAYS AS generated */ - 215, /* (363) ccons ::= AS generated */ - 202, /* (364) conslist_opt ::= COMMA conslist */ - 228, /* (365) conslist ::= conslist tconscomma tcons */ - 228, /* (366) conslist ::= tcons */ - 229, /* (367) tconscomma ::= */ - 233, /* (368) defer_subclause_opt ::= defer_subclause */ - 235, /* (369) resolvetype ::= raisetype */ - 239, /* (370) selectnowith ::= oneselect */ - 240, /* (371) oneselect ::= values */ - 254, /* (372) sclp ::= selcollist COMMA */ - 255, /* (373) as ::= ID|STRING */ - 264, /* (374) indexed_opt ::= indexed_by */ - 272, /* (375) returning ::= */ - 217, /* (376) expr ::= term */ - 274, /* (377) likeop ::= LIKE_KW|MATCH */ - 278, /* (378) case_operand ::= expr */ - 261, /* (379) exprlist ::= nexprlist */ - 284, /* (380) nmnum ::= plus_num */ - 284, /* (381) nmnum ::= nm */ - 284, /* (382) nmnum ::= ON */ - 284, /* (383) nmnum ::= DELETE */ - 284, /* (384) nmnum ::= DEFAULT */ - 211, /* (385) plus_num ::= INTEGER|FLOAT */ - 289, /* (386) foreach_clause ::= */ - 289, /* (387) foreach_clause ::= FOR EACH ROW */ - 292, /* (388) trnm ::= nm */ - 293, /* (389) tridxby ::= */ - 294, /* (390) database_kw_opt ::= DATABASE */ - 294, /* (391) database_kw_opt ::= */ - 297, /* (392) kwcolumn_opt ::= */ - 297, /* (393) kwcolumn_opt ::= COLUMNKW */ - 299, /* (394) vtabarglist ::= vtabarg */ - 299, /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ - 300, /* (396) vtabarg ::= vtabarg vtabargtoken */ - 303, /* (397) anylist ::= */ - 303, /* (398) anylist ::= anylist LP anylist RP */ - 303, /* (399) anylist ::= anylist ANY */ - 266, /* (400) with ::= */ - 306, /* (401) windowdefn_list ::= windowdefn */ - 308, /* (402) window ::= frame_opt */ + 217, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ + 217, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + 217, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + 217, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ + 217, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + 216, /* (193) term ::= CTIME_KW */ + 217, /* (194) expr ::= LP nexprlist COMMA expr RP */ + 217, /* (195) expr ::= expr AND expr */ + 217, /* (196) expr ::= expr OR expr */ + 217, /* (197) expr ::= expr LT|GT|GE|LE expr */ + 217, /* (198) expr ::= expr EQ|NE expr */ + 217, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 217, /* (200) expr ::= expr PLUS|MINUS expr */ + 217, /* (201) expr ::= expr STAR|SLASH|REM expr */ + 217, /* (202) expr ::= expr CONCAT expr */ + 274, /* (203) likeop ::= NOT LIKE_KW|MATCH */ + 217, /* (204) expr ::= expr likeop expr */ + 217, /* (205) expr ::= expr likeop expr ESCAPE expr */ + 217, /* (206) expr ::= expr ISNULL|NOTNULL */ + 217, /* (207) expr ::= expr NOT NULL */ + 217, /* (208) expr ::= expr IS expr */ + 217, /* (209) expr ::= expr IS NOT expr */ + 217, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */ + 217, /* (211) expr ::= expr IS DISTINCT FROM expr */ + 217, /* (212) expr ::= NOT expr */ + 217, /* (213) expr ::= BITNOT expr */ + 217, /* (214) expr ::= PLUS|MINUS expr */ + 217, /* (215) expr ::= expr PTR expr */ + 275, /* (216) between_op ::= BETWEEN */ + 275, /* (217) between_op ::= NOT BETWEEN */ + 217, /* (218) expr ::= expr between_op expr AND expr */ + 276, /* (219) in_op ::= IN */ + 276, /* (220) in_op ::= NOT IN */ + 217, /* (221) expr ::= expr in_op LP exprlist RP */ + 217, /* (222) expr ::= LP select RP */ + 217, /* (223) expr ::= expr in_op LP select RP */ + 217, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */ + 217, /* (225) expr ::= EXISTS LP select RP */ + 217, /* (226) expr ::= CASE case_operand case_exprlist case_else END */ + 279, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 279, /* (228) case_exprlist ::= WHEN expr THEN expr */ + 280, /* (229) case_else ::= ELSE expr */ + 280, /* (230) case_else ::= */ + 278, /* (231) case_operand ::= */ + 261, /* (232) exprlist ::= */ + 253, /* (233) nexprlist ::= nexprlist COMMA expr */ + 253, /* (234) nexprlist ::= expr */ + 277, /* (235) paren_exprlist ::= */ + 277, /* (236) paren_exprlist ::= LP exprlist RP */ + 190, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 281, /* (238) uniqueflag ::= UNIQUE */ + 281, /* (239) uniqueflag ::= */ + 221, /* (240) eidlist_opt ::= */ + 221, /* (241) eidlist_opt ::= LP eidlist RP */ + 232, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ + 232, /* (243) eidlist ::= nm collate sortorder */ + 282, /* (244) collate ::= */ + 282, /* (245) collate ::= COLLATE ID|STRING */ + 190, /* (246) cmd ::= DROP INDEX ifexists fullname */ + 190, /* (247) cmd ::= VACUUM vinto */ + 190, /* (248) cmd ::= VACUUM nm vinto */ + 283, /* (249) vinto ::= INTO expr */ + 283, /* (250) vinto ::= */ + 190, /* (251) cmd ::= PRAGMA nm dbnm */ + 190, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 190, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 190, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 190, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 211, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ + 212, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ + 190, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 285, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 287, /* (260) trigger_time ::= BEFORE|AFTER */ + 287, /* (261) trigger_time ::= INSTEAD OF */ + 287, /* (262) trigger_time ::= */ + 288, /* (263) trigger_event ::= DELETE|INSERT */ + 288, /* (264) trigger_event ::= UPDATE */ + 288, /* (265) trigger_event ::= UPDATE OF idlist */ + 290, /* (266) when_clause ::= */ + 290, /* (267) when_clause ::= WHEN expr */ + 286, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 286, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ + 292, /* (270) trnm ::= nm DOT nm */ + 293, /* (271) tridxby ::= INDEXED BY nm */ + 293, /* (272) tridxby ::= NOT INDEXED */ + 291, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + 291, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 291, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 291, /* (276) trigger_cmd ::= scanpt select scanpt */ + 217, /* (277) expr ::= RAISE LP IGNORE RP */ + 217, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ + 236, /* (279) raisetype ::= ROLLBACK */ + 236, /* (280) raisetype ::= ABORT */ + 236, /* (281) raisetype ::= FAIL */ + 190, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ + 190, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 190, /* (284) cmd ::= DETACH database_kw_opt expr */ + 295, /* (285) key_opt ::= */ + 295, /* (286) key_opt ::= KEY expr */ + 190, /* (287) cmd ::= REINDEX */ + 190, /* (288) cmd ::= REINDEX nm dbnm */ + 190, /* (289) cmd ::= ANALYZE */ + 190, /* (290) cmd ::= ANALYZE nm dbnm */ + 190, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 190, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 190, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 296, /* (294) add_column_fullname ::= fullname */ + 190, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 190, /* (296) cmd ::= create_vtab */ + 190, /* (297) cmd ::= create_vtab LP vtabarglist RP */ + 298, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 300, /* (299) vtabarg ::= */ + 301, /* (300) vtabargtoken ::= ANY */ + 301, /* (301) vtabargtoken ::= lp anylist RP */ + 302, /* (302) lp ::= LP */ + 266, /* (303) with ::= WITH wqlist */ + 266, /* (304) with ::= WITH RECURSIVE wqlist */ + 305, /* (305) wqas ::= AS */ + 305, /* (306) wqas ::= AS MATERIALIZED */ + 305, /* (307) wqas ::= AS NOT MATERIALIZED */ + 304, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ + 241, /* (309) wqlist ::= wqitem */ + 241, /* (310) wqlist ::= wqlist COMMA wqitem */ + 306, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 307, /* (312) windowdefn ::= nm AS LP window RP */ + 308, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 308, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 308, /* (315) window ::= ORDER BY sortlist frame_opt */ + 308, /* (316) window ::= nm ORDER BY sortlist frame_opt */ + 308, /* (317) window ::= nm frame_opt */ + 309, /* (318) frame_opt ::= */ + 309, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 309, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 313, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ + 315, /* (322) frame_bound_s ::= frame_bound */ + 315, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ + 316, /* (324) frame_bound_e ::= frame_bound */ + 316, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 314, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ + 314, /* (327) frame_bound ::= CURRENT ROW */ + 317, /* (328) frame_exclude_opt ::= */ + 317, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 318, /* (330) frame_exclude ::= NO OTHERS */ + 318, /* (331) frame_exclude ::= CURRENT ROW */ + 318, /* (332) frame_exclude ::= GROUP|TIES */ + 251, /* (333) window_clause ::= WINDOW windowdefn_list */ + 273, /* (334) filter_over ::= filter_clause over_clause */ + 273, /* (335) filter_over ::= over_clause */ + 273, /* (336) filter_over ::= filter_clause */ + 312, /* (337) over_clause ::= OVER LP window RP */ + 312, /* (338) over_clause ::= OVER nm */ + 311, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ + 185, /* (340) input ::= cmdlist */ + 186, /* (341) cmdlist ::= cmdlist ecmd */ + 186, /* (342) cmdlist ::= ecmd */ + 187, /* (343) ecmd ::= SEMI */ + 187, /* (344) ecmd ::= cmdx SEMI */ + 187, /* (345) ecmd ::= explain cmdx SEMI */ + 192, /* (346) trans_opt ::= */ + 192, /* (347) trans_opt ::= TRANSACTION */ + 192, /* (348) trans_opt ::= TRANSACTION nm */ + 194, /* (349) savepoint_opt ::= SAVEPOINT */ + 194, /* (350) savepoint_opt ::= */ + 190, /* (351) cmd ::= create_table create_table_args */ + 203, /* (352) table_option_set ::= table_option */ + 201, /* (353) columnlist ::= columnlist COMMA columnname carglist */ + 201, /* (354) columnlist ::= columnname carglist */ + 193, /* (355) nm ::= ID|INDEXED|JOIN_KW */ + 193, /* (356) nm ::= STRING */ + 208, /* (357) typetoken ::= typename */ + 209, /* (358) typename ::= ID|STRING */ + 210, /* (359) signed ::= plus_num */ + 210, /* (360) signed ::= minus_num */ + 207, /* (361) carglist ::= carglist ccons */ + 207, /* (362) carglist ::= */ + 215, /* (363) ccons ::= NULL onconf */ + 215, /* (364) ccons ::= GENERATED ALWAYS AS generated */ + 215, /* (365) ccons ::= AS generated */ + 202, /* (366) conslist_opt ::= COMMA conslist */ + 228, /* (367) conslist ::= conslist tconscomma tcons */ + 228, /* (368) conslist ::= tcons */ + 229, /* (369) tconscomma ::= */ + 233, /* (370) defer_subclause_opt ::= defer_subclause */ + 235, /* (371) resolvetype ::= raisetype */ + 239, /* (372) selectnowith ::= oneselect */ + 240, /* (373) oneselect ::= values */ + 254, /* (374) sclp ::= selcollist COMMA */ + 255, /* (375) as ::= ID|STRING */ + 264, /* (376) indexed_opt ::= indexed_by */ + 272, /* (377) returning ::= */ + 217, /* (378) expr ::= term */ + 274, /* (379) likeop ::= LIKE_KW|MATCH */ + 278, /* (380) case_operand ::= expr */ + 261, /* (381) exprlist ::= nexprlist */ + 284, /* (382) nmnum ::= plus_num */ + 284, /* (383) nmnum ::= nm */ + 284, /* (384) nmnum ::= ON */ + 284, /* (385) nmnum ::= DELETE */ + 284, /* (386) nmnum ::= DEFAULT */ + 211, /* (387) plus_num ::= INTEGER|FLOAT */ + 289, /* (388) foreach_clause ::= */ + 289, /* (389) foreach_clause ::= FOR EACH ROW */ + 292, /* (390) trnm ::= nm */ + 293, /* (391) tridxby ::= */ + 294, /* (392) database_kw_opt ::= DATABASE */ + 294, /* (393) database_kw_opt ::= */ + 297, /* (394) kwcolumn_opt ::= */ + 297, /* (395) kwcolumn_opt ::= COLUMNKW */ + 299, /* (396) vtabarglist ::= vtabarg */ + 299, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ + 300, /* (398) vtabarg ::= vtabarg vtabargtoken */ + 303, /* (399) anylist ::= */ + 303, /* (400) anylist ::= anylist LP anylist RP */ + 303, /* (401) anylist ::= anylist ANY */ + 266, /* (402) with ::= */ + 306, /* (403) windowdefn_list ::= windowdefn */ + 308, /* (404) window ::= frame_opt */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -172547,221 +173636,223 @@ static const signed char yyRuleInfoNRhs[] = { -3, /* (185) expr ::= expr COLLATE ID|STRING */ -6, /* (186) expr ::= CAST LP expr AS typetoken RP */ -5, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ - -4, /* (188) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ - -6, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ - -5, /* (190) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ - -1, /* (191) term ::= CTIME_KW */ - -5, /* (192) expr ::= LP nexprlist COMMA expr RP */ - -3, /* (193) expr ::= expr AND expr */ - -3, /* (194) expr ::= expr OR expr */ - -3, /* (195) expr ::= expr LT|GT|GE|LE expr */ - -3, /* (196) expr ::= expr EQ|NE expr */ - -3, /* (197) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - -3, /* (198) expr ::= expr PLUS|MINUS expr */ - -3, /* (199) expr ::= expr STAR|SLASH|REM expr */ - -3, /* (200) expr ::= expr CONCAT expr */ - -2, /* (201) likeop ::= NOT LIKE_KW|MATCH */ - -3, /* (202) expr ::= expr likeop expr */ - -5, /* (203) expr ::= expr likeop expr ESCAPE expr */ - -2, /* (204) expr ::= expr ISNULL|NOTNULL */ - -3, /* (205) expr ::= expr NOT NULL */ - -3, /* (206) expr ::= expr IS expr */ - -4, /* (207) expr ::= expr IS NOT expr */ - -6, /* (208) expr ::= expr IS NOT DISTINCT FROM expr */ - -5, /* (209) expr ::= expr IS DISTINCT FROM expr */ - -2, /* (210) expr ::= NOT expr */ - -2, /* (211) expr ::= BITNOT expr */ - -2, /* (212) expr ::= PLUS|MINUS expr */ - -3, /* (213) expr ::= expr PTR expr */ - -1, /* (214) between_op ::= BETWEEN */ - -2, /* (215) between_op ::= NOT BETWEEN */ - -5, /* (216) expr ::= expr between_op expr AND expr */ - -1, /* (217) in_op ::= IN */ - -2, /* (218) in_op ::= NOT IN */ - -5, /* (219) expr ::= expr in_op LP exprlist RP */ - -3, /* (220) expr ::= LP select RP */ - -5, /* (221) expr ::= expr in_op LP select RP */ - -5, /* (222) expr ::= expr in_op nm dbnm paren_exprlist */ - -4, /* (223) expr ::= EXISTS LP select RP */ - -5, /* (224) expr ::= CASE case_operand case_exprlist case_else END */ - -5, /* (225) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - -4, /* (226) case_exprlist ::= WHEN expr THEN expr */ - -2, /* (227) case_else ::= ELSE expr */ - 0, /* (228) case_else ::= */ - 0, /* (229) case_operand ::= */ - 0, /* (230) exprlist ::= */ - -3, /* (231) nexprlist ::= nexprlist COMMA expr */ - -1, /* (232) nexprlist ::= expr */ - 0, /* (233) paren_exprlist ::= */ - -3, /* (234) paren_exprlist ::= LP exprlist RP */ - -12, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - -1, /* (236) uniqueflag ::= UNIQUE */ - 0, /* (237) uniqueflag ::= */ - 0, /* (238) eidlist_opt ::= */ - -3, /* (239) eidlist_opt ::= LP eidlist RP */ - -5, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ - -3, /* (241) eidlist ::= nm collate sortorder */ - 0, /* (242) collate ::= */ - -2, /* (243) collate ::= COLLATE ID|STRING */ - -4, /* (244) cmd ::= DROP INDEX ifexists fullname */ - -2, /* (245) cmd ::= VACUUM vinto */ - -3, /* (246) cmd ::= VACUUM nm vinto */ - -2, /* (247) vinto ::= INTO expr */ - 0, /* (248) vinto ::= */ - -3, /* (249) cmd ::= PRAGMA nm dbnm */ - -5, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ - -6, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - -5, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ - -6, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - -2, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ - -2, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ - -5, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - -11, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - -1, /* (258) trigger_time ::= BEFORE|AFTER */ - -2, /* (259) trigger_time ::= INSTEAD OF */ - 0, /* (260) trigger_time ::= */ - -1, /* (261) trigger_event ::= DELETE|INSERT */ - -1, /* (262) trigger_event ::= UPDATE */ - -3, /* (263) trigger_event ::= UPDATE OF idlist */ - 0, /* (264) when_clause ::= */ - -2, /* (265) when_clause ::= WHEN expr */ - -3, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - -2, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ - -3, /* (268) trnm ::= nm DOT nm */ - -3, /* (269) tridxby ::= INDEXED BY nm */ - -2, /* (270) tridxby ::= NOT INDEXED */ - -9, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - -8, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - -6, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - -3, /* (274) trigger_cmd ::= scanpt select scanpt */ - -4, /* (275) expr ::= RAISE LP IGNORE RP */ - -6, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ - -1, /* (277) raisetype ::= ROLLBACK */ - -1, /* (278) raisetype ::= ABORT */ - -1, /* (279) raisetype ::= FAIL */ - -4, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ - -6, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - -3, /* (282) cmd ::= DETACH database_kw_opt expr */ - 0, /* (283) key_opt ::= */ - -2, /* (284) key_opt ::= KEY expr */ - -1, /* (285) cmd ::= REINDEX */ - -3, /* (286) cmd ::= REINDEX nm dbnm */ - -1, /* (287) cmd ::= ANALYZE */ - -3, /* (288) cmd ::= ANALYZE nm dbnm */ - -6, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ - -7, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - -6, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - -1, /* (292) add_column_fullname ::= fullname */ - -8, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - -1, /* (294) cmd ::= create_vtab */ - -4, /* (295) cmd ::= create_vtab LP vtabarglist RP */ - -8, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 0, /* (297) vtabarg ::= */ - -1, /* (298) vtabargtoken ::= ANY */ - -3, /* (299) vtabargtoken ::= lp anylist RP */ - -1, /* (300) lp ::= LP */ - -2, /* (301) with ::= WITH wqlist */ - -3, /* (302) with ::= WITH RECURSIVE wqlist */ - -1, /* (303) wqas ::= AS */ - -2, /* (304) wqas ::= AS MATERIALIZED */ - -3, /* (305) wqas ::= AS NOT MATERIALIZED */ - -6, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ - -1, /* (307) wqlist ::= wqitem */ - -3, /* (308) wqlist ::= wqlist COMMA wqitem */ - -3, /* (309) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - -5, /* (310) windowdefn ::= nm AS LP window RP */ - -5, /* (311) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - -6, /* (312) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - -4, /* (313) window ::= ORDER BY sortlist frame_opt */ - -5, /* (314) window ::= nm ORDER BY sortlist frame_opt */ - -2, /* (315) window ::= nm frame_opt */ - 0, /* (316) frame_opt ::= */ - -3, /* (317) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - -6, /* (318) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - -1, /* (319) range_or_rows ::= RANGE|ROWS|GROUPS */ - -1, /* (320) frame_bound_s ::= frame_bound */ - -2, /* (321) frame_bound_s ::= UNBOUNDED PRECEDING */ - -1, /* (322) frame_bound_e ::= frame_bound */ - -2, /* (323) frame_bound_e ::= UNBOUNDED FOLLOWING */ - -2, /* (324) frame_bound ::= expr PRECEDING|FOLLOWING */ - -2, /* (325) frame_bound ::= CURRENT ROW */ - 0, /* (326) frame_exclude_opt ::= */ - -2, /* (327) frame_exclude_opt ::= EXCLUDE frame_exclude */ - -2, /* (328) frame_exclude ::= NO OTHERS */ - -2, /* (329) frame_exclude ::= CURRENT ROW */ - -1, /* (330) frame_exclude ::= GROUP|TIES */ - -2, /* (331) window_clause ::= WINDOW windowdefn_list */ - -2, /* (332) filter_over ::= filter_clause over_clause */ - -1, /* (333) filter_over ::= over_clause */ - -1, /* (334) filter_over ::= filter_clause */ - -4, /* (335) over_clause ::= OVER LP window RP */ - -2, /* (336) over_clause ::= OVER nm */ - -5, /* (337) filter_clause ::= FILTER LP WHERE expr RP */ - -1, /* (338) input ::= cmdlist */ - -2, /* (339) cmdlist ::= cmdlist ecmd */ - -1, /* (340) cmdlist ::= ecmd */ - -1, /* (341) ecmd ::= SEMI */ - -2, /* (342) ecmd ::= cmdx SEMI */ - -3, /* (343) ecmd ::= explain cmdx SEMI */ - 0, /* (344) trans_opt ::= */ - -1, /* (345) trans_opt ::= TRANSACTION */ - -2, /* (346) trans_opt ::= TRANSACTION nm */ - -1, /* (347) savepoint_opt ::= SAVEPOINT */ - 0, /* (348) savepoint_opt ::= */ - -2, /* (349) cmd ::= create_table create_table_args */ - -1, /* (350) table_option_set ::= table_option */ - -4, /* (351) columnlist ::= columnlist COMMA columnname carglist */ - -2, /* (352) columnlist ::= columnname carglist */ - -1, /* (353) nm ::= ID|INDEXED|JOIN_KW */ - -1, /* (354) nm ::= STRING */ - -1, /* (355) typetoken ::= typename */ - -1, /* (356) typename ::= ID|STRING */ - -1, /* (357) signed ::= plus_num */ - -1, /* (358) signed ::= minus_num */ - -2, /* (359) carglist ::= carglist ccons */ - 0, /* (360) carglist ::= */ - -2, /* (361) ccons ::= NULL onconf */ - -4, /* (362) ccons ::= GENERATED ALWAYS AS generated */ - -2, /* (363) ccons ::= AS generated */ - -2, /* (364) conslist_opt ::= COMMA conslist */ - -3, /* (365) conslist ::= conslist tconscomma tcons */ - -1, /* (366) conslist ::= tcons */ - 0, /* (367) tconscomma ::= */ - -1, /* (368) defer_subclause_opt ::= defer_subclause */ - -1, /* (369) resolvetype ::= raisetype */ - -1, /* (370) selectnowith ::= oneselect */ - -1, /* (371) oneselect ::= values */ - -2, /* (372) sclp ::= selcollist COMMA */ - -1, /* (373) as ::= ID|STRING */ - -1, /* (374) indexed_opt ::= indexed_by */ - 0, /* (375) returning ::= */ - -1, /* (376) expr ::= term */ - -1, /* (377) likeop ::= LIKE_KW|MATCH */ - -1, /* (378) case_operand ::= expr */ - -1, /* (379) exprlist ::= nexprlist */ - -1, /* (380) nmnum ::= plus_num */ - -1, /* (381) nmnum ::= nm */ - -1, /* (382) nmnum ::= ON */ - -1, /* (383) nmnum ::= DELETE */ - -1, /* (384) nmnum ::= DEFAULT */ - -1, /* (385) plus_num ::= INTEGER|FLOAT */ - 0, /* (386) foreach_clause ::= */ - -3, /* (387) foreach_clause ::= FOR EACH ROW */ - -1, /* (388) trnm ::= nm */ - 0, /* (389) tridxby ::= */ - -1, /* (390) database_kw_opt ::= DATABASE */ - 0, /* (391) database_kw_opt ::= */ - 0, /* (392) kwcolumn_opt ::= */ - -1, /* (393) kwcolumn_opt ::= COLUMNKW */ - -1, /* (394) vtabarglist ::= vtabarg */ - -3, /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ - -2, /* (396) vtabarg ::= vtabarg vtabargtoken */ - 0, /* (397) anylist ::= */ - -4, /* (398) anylist ::= anylist LP anylist RP */ - -2, /* (399) anylist ::= anylist ANY */ - 0, /* (400) with ::= */ - -1, /* (401) windowdefn_list ::= windowdefn */ - -1, /* (402) window ::= frame_opt */ + -8, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ + -4, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + -6, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + -9, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ + -5, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + -1, /* (193) term ::= CTIME_KW */ + -5, /* (194) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (195) expr ::= expr AND expr */ + -3, /* (196) expr ::= expr OR expr */ + -3, /* (197) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (198) expr ::= expr EQ|NE expr */ + -3, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (200) expr ::= expr PLUS|MINUS expr */ + -3, /* (201) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (202) expr ::= expr CONCAT expr */ + -2, /* (203) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (204) expr ::= expr likeop expr */ + -5, /* (205) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (206) expr ::= expr ISNULL|NOTNULL */ + -3, /* (207) expr ::= expr NOT NULL */ + -3, /* (208) expr ::= expr IS expr */ + -4, /* (209) expr ::= expr IS NOT expr */ + -6, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */ + -5, /* (211) expr ::= expr IS DISTINCT FROM expr */ + -2, /* (212) expr ::= NOT expr */ + -2, /* (213) expr ::= BITNOT expr */ + -2, /* (214) expr ::= PLUS|MINUS expr */ + -3, /* (215) expr ::= expr PTR expr */ + -1, /* (216) between_op ::= BETWEEN */ + -2, /* (217) between_op ::= NOT BETWEEN */ + -5, /* (218) expr ::= expr between_op expr AND expr */ + -1, /* (219) in_op ::= IN */ + -2, /* (220) in_op ::= NOT IN */ + -5, /* (221) expr ::= expr in_op LP exprlist RP */ + -3, /* (222) expr ::= LP select RP */ + -5, /* (223) expr ::= expr in_op LP select RP */ + -5, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (225) expr ::= EXISTS LP select RP */ + -5, /* (226) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (228) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (229) case_else ::= ELSE expr */ + 0, /* (230) case_else ::= */ + 0, /* (231) case_operand ::= */ + 0, /* (232) exprlist ::= */ + -3, /* (233) nexprlist ::= nexprlist COMMA expr */ + -1, /* (234) nexprlist ::= expr */ + 0, /* (235) paren_exprlist ::= */ + -3, /* (236) paren_exprlist ::= LP exprlist RP */ + -12, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (238) uniqueflag ::= UNIQUE */ + 0, /* (239) uniqueflag ::= */ + 0, /* (240) eidlist_opt ::= */ + -3, /* (241) eidlist_opt ::= LP eidlist RP */ + -5, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (243) eidlist ::= nm collate sortorder */ + 0, /* (244) collate ::= */ + -2, /* (245) collate ::= COLLATE ID|STRING */ + -4, /* (246) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (247) cmd ::= VACUUM vinto */ + -3, /* (248) cmd ::= VACUUM nm vinto */ + -2, /* (249) vinto ::= INTO expr */ + 0, /* (250) vinto ::= */ + -3, /* (251) cmd ::= PRAGMA nm dbnm */ + -5, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (260) trigger_time ::= BEFORE|AFTER */ + -2, /* (261) trigger_time ::= INSTEAD OF */ + 0, /* (262) trigger_time ::= */ + -1, /* (263) trigger_event ::= DELETE|INSERT */ + -1, /* (264) trigger_event ::= UPDATE */ + -3, /* (265) trigger_event ::= UPDATE OF idlist */ + 0, /* (266) when_clause ::= */ + -2, /* (267) when_clause ::= WHEN expr */ + -3, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (270) trnm ::= nm DOT nm */ + -3, /* (271) tridxby ::= INDEXED BY nm */ + -2, /* (272) tridxby ::= NOT INDEXED */ + -9, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + -8, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (276) trigger_cmd ::= scanpt select scanpt */ + -4, /* (277) expr ::= RAISE LP IGNORE RP */ + -6, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ + -1, /* (279) raisetype ::= ROLLBACK */ + -1, /* (280) raisetype ::= ABORT */ + -1, /* (281) raisetype ::= FAIL */ + -4, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (284) cmd ::= DETACH database_kw_opt expr */ + 0, /* (285) key_opt ::= */ + -2, /* (286) key_opt ::= KEY expr */ + -1, /* (287) cmd ::= REINDEX */ + -3, /* (288) cmd ::= REINDEX nm dbnm */ + -1, /* (289) cmd ::= ANALYZE */ + -3, /* (290) cmd ::= ANALYZE nm dbnm */ + -6, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -6, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -1, /* (294) add_column_fullname ::= fullname */ + -8, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -1, /* (296) cmd ::= create_vtab */ + -4, /* (297) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (299) vtabarg ::= */ + -1, /* (300) vtabargtoken ::= ANY */ + -3, /* (301) vtabargtoken ::= lp anylist RP */ + -1, /* (302) lp ::= LP */ + -2, /* (303) with ::= WITH wqlist */ + -3, /* (304) with ::= WITH RECURSIVE wqlist */ + -1, /* (305) wqas ::= AS */ + -2, /* (306) wqas ::= AS MATERIALIZED */ + -3, /* (307) wqas ::= AS NOT MATERIALIZED */ + -6, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ + -1, /* (309) wqlist ::= wqitem */ + -3, /* (310) wqlist ::= wqlist COMMA wqitem */ + -3, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (312) windowdefn ::= nm AS LP window RP */ + -5, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (315) window ::= ORDER BY sortlist frame_opt */ + -5, /* (316) window ::= nm ORDER BY sortlist frame_opt */ + -2, /* (317) window ::= nm frame_opt */ + 0, /* (318) frame_opt ::= */ + -3, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (322) frame_bound_s ::= frame_bound */ + -2, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (324) frame_bound_e ::= frame_bound */ + -2, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (327) frame_bound ::= CURRENT ROW */ + 0, /* (328) frame_exclude_opt ::= */ + -2, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (330) frame_exclude ::= NO OTHERS */ + -2, /* (331) frame_exclude ::= CURRENT ROW */ + -1, /* (332) frame_exclude ::= GROUP|TIES */ + -2, /* (333) window_clause ::= WINDOW windowdefn_list */ + -2, /* (334) filter_over ::= filter_clause over_clause */ + -1, /* (335) filter_over ::= over_clause */ + -1, /* (336) filter_over ::= filter_clause */ + -4, /* (337) over_clause ::= OVER LP window RP */ + -2, /* (338) over_clause ::= OVER nm */ + -5, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (340) input ::= cmdlist */ + -2, /* (341) cmdlist ::= cmdlist ecmd */ + -1, /* (342) cmdlist ::= ecmd */ + -1, /* (343) ecmd ::= SEMI */ + -2, /* (344) ecmd ::= cmdx SEMI */ + -3, /* (345) ecmd ::= explain cmdx SEMI */ + 0, /* (346) trans_opt ::= */ + -1, /* (347) trans_opt ::= TRANSACTION */ + -2, /* (348) trans_opt ::= TRANSACTION nm */ + -1, /* (349) savepoint_opt ::= SAVEPOINT */ + 0, /* (350) savepoint_opt ::= */ + -2, /* (351) cmd ::= create_table create_table_args */ + -1, /* (352) table_option_set ::= table_option */ + -4, /* (353) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (354) columnlist ::= columnname carglist */ + -1, /* (355) nm ::= ID|INDEXED|JOIN_KW */ + -1, /* (356) nm ::= STRING */ + -1, /* (357) typetoken ::= typename */ + -1, /* (358) typename ::= ID|STRING */ + -1, /* (359) signed ::= plus_num */ + -1, /* (360) signed ::= minus_num */ + -2, /* (361) carglist ::= carglist ccons */ + 0, /* (362) carglist ::= */ + -2, /* (363) ccons ::= NULL onconf */ + -4, /* (364) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (365) ccons ::= AS generated */ + -2, /* (366) conslist_opt ::= COMMA conslist */ + -3, /* (367) conslist ::= conslist tconscomma tcons */ + -1, /* (368) conslist ::= tcons */ + 0, /* (369) tconscomma ::= */ + -1, /* (370) defer_subclause_opt ::= defer_subclause */ + -1, /* (371) resolvetype ::= raisetype */ + -1, /* (372) selectnowith ::= oneselect */ + -1, /* (373) oneselect ::= values */ + -2, /* (374) sclp ::= selcollist COMMA */ + -1, /* (375) as ::= ID|STRING */ + -1, /* (376) indexed_opt ::= indexed_by */ + 0, /* (377) returning ::= */ + -1, /* (378) expr ::= term */ + -1, /* (379) likeop ::= LIKE_KW|MATCH */ + -1, /* (380) case_operand ::= expr */ + -1, /* (381) exprlist ::= nexprlist */ + -1, /* (382) nmnum ::= plus_num */ + -1, /* (383) nmnum ::= nm */ + -1, /* (384) nmnum ::= ON */ + -1, /* (385) nmnum ::= DELETE */ + -1, /* (386) nmnum ::= DEFAULT */ + -1, /* (387) plus_num ::= INTEGER|FLOAT */ + 0, /* (388) foreach_clause ::= */ + -3, /* (389) foreach_clause ::= FOR EACH ROW */ + -1, /* (390) trnm ::= nm */ + 0, /* (391) tridxby ::= */ + -1, /* (392) database_kw_opt ::= DATABASE */ + 0, /* (393) database_kw_opt ::= */ + 0, /* (394) kwcolumn_opt ::= */ + -1, /* (395) kwcolumn_opt ::= COLUMNKW */ + -1, /* (396) vtabarglist ::= vtabarg */ + -3, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (398) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (399) anylist ::= */ + -4, /* (400) anylist ::= anylist LP anylist RP */ + -2, /* (401) anylist ::= anylist ANY */ + 0, /* (402) with ::= */ + -1, /* (403) windowdefn_list ::= windowdefn */ + -1, /* (404) window ::= frame_opt */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -172821,7 +173912,7 @@ static YYACTIONTYPE yy_reduce( case 5: /* transtype ::= DEFERRED */ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); - case 319: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==319); + case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321); {yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/} break; case 8: /* cmd ::= COMMIT|END trans_opt */ @@ -172858,7 +173949,7 @@ static YYACTIONTYPE yy_reduce( case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); case 81: /* ifexists ::= */ yytestcase(yyruleno==81); case 98: /* distinct ::= */ yytestcase(yyruleno==98); - case 242: /* collate ::= */ yytestcase(yyruleno==242); + case 244: /* collate ::= */ yytestcase(yyruleno==244); {yymsp[1].minor.yy394 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ @@ -173042,9 +174133,9 @@ static YYACTIONTYPE yy_reduce( break; case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); - case 215: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==215); - case 218: /* in_op ::= NOT IN */ yytestcase(yyruleno==218); - case 243: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==243); + case 217: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==217); + case 220: /* in_op ::= NOT IN */ yytestcase(yyruleno==220); + case 245: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==245); {yymsp[-1].minor.yy394 = 1;} break; case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ @@ -173193,9 +174284,9 @@ static YYACTIONTYPE yy_reduce( case 99: /* sclp ::= */ case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132); case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142); - case 230: /* exprlist ::= */ yytestcase(yyruleno==230); - case 233: /* paren_exprlist ::= */ yytestcase(yyruleno==233); - case 238: /* eidlist_opt ::= */ yytestcase(yyruleno==238); + case 232: /* exprlist ::= */ yytestcase(yyruleno==232); + case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235); + case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240); {yymsp[1].minor.yy322 = 0;} break; case 100: /* selcollist ::= sclp scanpt expr scanpt as */ @@ -173224,8 +174315,8 @@ static YYACTIONTYPE yy_reduce( break; case 103: /* as ::= AS nm */ case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115); - case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254); - case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255); + case 256: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==256); + case 257: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==257); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; case 105: /* from ::= */ @@ -173397,16 +174488,16 @@ static YYACTIONTYPE yy_reduce( case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); case 151: /* where_opt ::= */ yytestcase(yyruleno==151); case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); - case 228: /* case_else ::= */ yytestcase(yyruleno==228); - case 229: /* case_operand ::= */ yytestcase(yyruleno==229); - case 248: /* vinto ::= */ yytestcase(yyruleno==248); + case 230: /* case_else ::= */ yytestcase(yyruleno==230); + case 231: /* case_operand ::= */ yytestcase(yyruleno==231); + case 250: /* vinto ::= */ yytestcase(yyruleno==250); {yymsp[1].minor.yy528 = 0;} break; case 145: /* having_opt ::= HAVING expr */ case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152); case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154); - case 227: /* case_else ::= ELSE expr */ yytestcase(yyruleno==227); - case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247); + case 229: /* case_else ::= ELSE expr */ yytestcase(yyruleno==229); + case 249: /* vinto ::= INTO expr */ yytestcase(yyruleno==249); {yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;} break; case 147: /* limit_opt ::= LIMIT expr */ @@ -173592,33 +174683,48 @@ static YYACTIONTYPE yy_reduce( } yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 188: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + case 188: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ +{ + yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy322, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy394); + sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-1].minor.yy322); +} + yymsp[-7].minor.yy528 = yylhsminor.yy528; + break; + case 189: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ { yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } yymsp[-3].minor.yy528 = yylhsminor.yy528; break; - case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ { yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394); sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); } yymsp[-5].minor.yy528 = yylhsminor.yy528; break; - case 190: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + case 191: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ +{ + yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy322, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy394); + sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); + sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-2].minor.yy322); +} + yymsp[-8].minor.yy528 = yylhsminor.yy528; + break; + case 192: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ { yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); } yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 191: /* term ::= CTIME_KW */ + case 193: /* term ::= CTIME_KW */ { yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } yymsp[0].minor.yy528 = yylhsminor.yy528; break; - case 192: /* expr ::= LP nexprlist COMMA expr RP */ + case 194: /* expr ::= LP nexprlist COMMA expr RP */ { ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528); yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); @@ -173632,22 +174738,22 @@ static YYACTIONTYPE yy_reduce( } } break; - case 193: /* expr ::= expr AND expr */ + case 195: /* expr ::= expr AND expr */ {yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} break; - case 194: /* expr ::= expr OR expr */ - case 195: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==195); - case 196: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==196); - case 197: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==197); - case 198: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==198); - case 199: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==199); - case 200: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==200); + case 196: /* expr ::= expr OR expr */ + case 197: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==197); + case 198: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==198); + case 199: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==199); + case 200: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==200); + case 201: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==201); + case 202: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==202); {yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} break; - case 201: /* likeop ::= NOT LIKE_KW|MATCH */ + case 203: /* likeop ::= NOT LIKE_KW|MATCH */ {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} break; - case 202: /* expr ::= expr likeop expr */ + case 204: /* expr ::= expr likeop expr */ { ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; @@ -173659,7 +174765,7 @@ static YYACTIONTYPE yy_reduce( if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc; } break; - case 203: /* expr ::= expr likeop expr ESCAPE expr */ + case 205: /* expr ::= expr likeop expr ESCAPE expr */ { ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; @@ -173672,47 +174778,47 @@ static YYACTIONTYPE yy_reduce( if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc; } break; - case 204: /* expr ::= expr ISNULL|NOTNULL */ + case 206: /* expr ::= expr ISNULL|NOTNULL */ {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);} break; - case 205: /* expr ::= expr NOT NULL */ + case 207: /* expr ::= expr NOT NULL */ {yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);} break; - case 206: /* expr ::= expr IS expr */ + case 208: /* expr ::= expr IS expr */ { yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL); } break; - case 207: /* expr ::= expr IS NOT expr */ + case 209: /* expr ::= expr IS NOT expr */ { yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL); } break; - case 208: /* expr ::= expr IS NOT DISTINCT FROM expr */ + case 210: /* expr ::= expr IS NOT DISTINCT FROM expr */ { yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL); } break; - case 209: /* expr ::= expr IS DISTINCT FROM expr */ + case 211: /* expr ::= expr IS DISTINCT FROM expr */ { yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL); } break; - case 210: /* expr ::= NOT expr */ - case 211: /* expr ::= BITNOT expr */ yytestcase(yyruleno==211); + case 212: /* expr ::= NOT expr */ + case 213: /* expr ::= BITNOT expr */ yytestcase(yyruleno==213); {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/} break; - case 212: /* expr ::= PLUS|MINUS expr */ + case 214: /* expr ::= PLUS|MINUS expr */ { yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0); /*A-overwrites-B*/ } break; - case 213: /* expr ::= expr PTR expr */ + case 215: /* expr ::= expr PTR expr */ { ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528); pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528); @@ -173720,11 +174826,11 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy528 = yylhsminor.yy528; break; - case 214: /* between_op ::= BETWEEN */ - case 217: /* in_op ::= IN */ yytestcase(yyruleno==217); + case 216: /* between_op ::= BETWEEN */ + case 219: /* in_op ::= IN */ yytestcase(yyruleno==219); {yymsp[0].minor.yy394 = 0;} break; - case 216: /* expr ::= expr between_op expr AND expr */ + case 218: /* expr ::= expr between_op expr AND expr */ { ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); @@ -173737,7 +174843,7 @@ static YYACTIONTYPE yy_reduce( if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 219: /* expr ::= expr in_op LP exprlist RP */ + case 221: /* expr ::= expr in_op LP exprlist RP */ { if( yymsp[-1].minor.yy322==0 ){ /* Expressions of the form @@ -173783,20 +174889,20 @@ static YYACTIONTYPE yy_reduce( } } break; - case 220: /* expr ::= LP select RP */ + case 222: /* expr ::= LP select RP */ { yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47); } break; - case 221: /* expr ::= expr in_op LP select RP */ + case 223: /* expr ::= expr in_op LP select RP */ { yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47); if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 222: /* expr ::= expr in_op nm dbnm paren_exprlist */ + case 224: /* expr ::= expr in_op nm dbnm paren_exprlist */ { SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); @@ -173806,14 +174912,14 @@ static YYACTIONTYPE yy_reduce( if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 223: /* expr ::= EXISTS LP select RP */ + case 225: /* expr ::= EXISTS LP select RP */ { Expr *p; p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47); } break; - case 224: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 226: /* expr ::= CASE case_operand case_exprlist case_else END */ { yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0); if( yymsp[-4].minor.yy528 ){ @@ -173825,29 +174931,29 @@ static YYACTIONTYPE yy_reduce( } } break; - case 225: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 227: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528); } break; - case 226: /* case_exprlist ::= WHEN expr THEN expr */ + case 228: /* case_exprlist ::= WHEN expr THEN expr */ { yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528); } break; - case 231: /* nexprlist ::= nexprlist COMMA expr */ + case 233: /* nexprlist ::= nexprlist COMMA expr */ {yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);} break; - case 232: /* nexprlist ::= expr */ + case 234: /* nexprlist ::= expr */ {yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/} break; - case 234: /* paren_exprlist ::= LP exprlist RP */ - case 239: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==239); + case 236: /* paren_exprlist ::= LP exprlist RP */ + case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241); {yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;} break; - case 235: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + case 237: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394, @@ -173857,48 +174963,48 @@ static YYACTIONTYPE yy_reduce( } } break; - case 236: /* uniqueflag ::= UNIQUE */ - case 278: /* raisetype ::= ABORT */ yytestcase(yyruleno==278); + case 238: /* uniqueflag ::= UNIQUE */ + case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280); {yymsp[0].minor.yy394 = OE_Abort;} break; - case 237: /* uniqueflag ::= */ + case 239: /* uniqueflag ::= */ {yymsp[1].minor.yy394 = OE_None;} break; - case 240: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */ { yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); } break; - case 241: /* eidlist ::= nm collate sortorder */ + case 243: /* eidlist ::= nm collate sortorder */ { yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/ } break; - case 244: /* cmd ::= DROP INDEX ifexists fullname */ + case 246: /* cmd ::= DROP INDEX ifexists fullname */ {sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);} break; - case 245: /* cmd ::= VACUUM vinto */ + case 247: /* cmd ::= VACUUM vinto */ {sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);} break; - case 246: /* cmd ::= VACUUM nm vinto */ + case 248: /* cmd ::= VACUUM nm vinto */ {sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);} break; - case 249: /* cmd ::= PRAGMA nm dbnm */ + case 251: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 250: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 251: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 252: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 253: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; - case 256: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; @@ -173906,50 +175012,50 @@ static YYACTIONTYPE yy_reduce( sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all); } break; - case 257: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 259: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; - case 258: /* trigger_time ::= BEFORE|AFTER */ + case 260: /* trigger_time ::= BEFORE|AFTER */ { yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 259: /* trigger_time ::= INSTEAD OF */ + case 261: /* trigger_time ::= INSTEAD OF */ { yymsp[-1].minor.yy394 = TK_INSTEAD;} break; - case 260: /* trigger_time ::= */ + case 262: /* trigger_time ::= */ { yymsp[1].minor.yy394 = TK_BEFORE; } break; - case 261: /* trigger_event ::= DELETE|INSERT */ - case 262: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==262); + case 263: /* trigger_event ::= DELETE|INSERT */ + case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264); {yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;} break; - case 263: /* trigger_event ::= UPDATE OF idlist */ + case 265: /* trigger_event ::= UPDATE OF idlist */ {yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;} break; - case 264: /* when_clause ::= */ - case 283: /* key_opt ::= */ yytestcase(yyruleno==283); + case 266: /* when_clause ::= */ + case 285: /* key_opt ::= */ yytestcase(yyruleno==285); { yymsp[1].minor.yy528 = 0; } break; - case 265: /* when_clause ::= WHEN expr */ - case 284: /* key_opt ::= KEY expr */ yytestcase(yyruleno==284); + case 267: /* when_clause ::= WHEN expr */ + case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286); { yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; } break; - case 266: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { assert( yymsp[-2].minor.yy33!=0 ); yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33; yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33; } break; - case 267: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 269: /* trigger_cmd_list ::= trigger_cmd SEMI */ { assert( yymsp[-1].minor.yy33!=0 ); yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33; } break; - case 268: /* trnm ::= nm DOT nm */ + case 270: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -173957,39 +175063,39 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 269: /* tridxby ::= INDEXED BY nm */ + case 271: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 270: /* tridxby ::= NOT INDEXED */ + case 272: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 271: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ {yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);} yymsp[-8].minor.yy33 = yylhsminor.yy33; break; - case 272: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/ } yymsp[-7].minor.yy33 = yylhsminor.yy33; break; - case 273: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + case 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ {yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);} yymsp[-5].minor.yy33 = yylhsminor.yy33; break; - case 274: /* trigger_cmd ::= scanpt select scanpt */ + case 276: /* trigger_cmd ::= scanpt select scanpt */ {yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/} yymsp[-2].minor.yy33 = yylhsminor.yy33; break; - case 275: /* expr ::= RAISE LP IGNORE RP */ + case 277: /* expr ::= RAISE LP IGNORE RP */ { yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); if( yymsp[-3].minor.yy528 ){ @@ -173997,7 +175103,7 @@ static YYACTIONTYPE yy_reduce( } } break; - case 276: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */ { yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); if( yymsp[-5].minor.yy528 ) { @@ -174005,114 +175111,114 @@ static YYACTIONTYPE yy_reduce( } } break; - case 277: /* raisetype ::= ROLLBACK */ + case 279: /* raisetype ::= ROLLBACK */ {yymsp[0].minor.yy394 = OE_Rollback;} break; - case 279: /* raisetype ::= FAIL */ + case 281: /* raisetype ::= FAIL */ {yymsp[0].minor.yy394 = OE_Fail;} break; - case 280: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 282: /* cmd ::= DROP TRIGGER ifexists fullname */ { sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394); } break; - case 281: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528); } break; - case 282: /* cmd ::= DETACH database_kw_opt expr */ + case 284: /* cmd ::= DETACH database_kw_opt expr */ { sqlite3Detach(pParse, yymsp[0].minor.yy528); } break; - case 285: /* cmd ::= REINDEX */ + case 287: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 286: /* cmd ::= REINDEX nm dbnm */ + case 288: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 287: /* cmd ::= ANALYZE */ + case 289: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 288: /* cmd ::= ANALYZE nm dbnm */ + case 290: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 289: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0); } break; - case 290: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ { yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); } break; - case 291: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + case 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ { sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0); } break; - case 292: /* add_column_fullname ::= fullname */ + case 294: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131); } break; - case 293: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 294: /* cmd ::= create_vtab */ + case 296: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 295: /* cmd ::= create_vtab LP vtabarglist RP */ + case 297: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 296: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 298: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ { sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394); } break; - case 297: /* vtabarg ::= */ + case 299: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 298: /* vtabargtoken ::= ANY */ - case 299: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==299); - case 300: /* lp ::= LP */ yytestcase(yyruleno==300); + case 300: /* vtabargtoken ::= ANY */ + case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301); + case 302: /* lp ::= LP */ yytestcase(yyruleno==302); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 301: /* with ::= WITH wqlist */ - case 302: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==302); + case 303: /* with ::= WITH wqlist */ + case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304); { sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); } break; - case 303: /* wqas ::= AS */ + case 305: /* wqas ::= AS */ {yymsp[0].minor.yy516 = M10d_Any;} break; - case 304: /* wqas ::= AS MATERIALIZED */ + case 306: /* wqas ::= AS MATERIALIZED */ {yymsp[-1].minor.yy516 = M10d_Yes;} break; - case 305: /* wqas ::= AS NOT MATERIALIZED */ + case 307: /* wqas ::= AS NOT MATERIALIZED */ {yymsp[-2].minor.yy516 = M10d_No;} break; - case 306: /* wqitem ::= nm eidlist_opt wqas LP select RP */ + case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */ { yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/ } break; - case 307: /* wqlist ::= wqitem */ + case 309: /* wqlist ::= wqitem */ { yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/ } break; - case 308: /* wqlist ::= wqlist COMMA wqitem */ + case 310: /* wqlist ::= wqlist COMMA wqitem */ { yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385); } break; - case 309: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 311: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { assert( yymsp[0].minor.yy41!=0 ); sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41); @@ -174121,7 +175227,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy41 = yylhsminor.yy41; break; - case 310: /* windowdefn ::= nm AS LP window RP */ + case 312: /* windowdefn ::= nm AS LP window RP */ { if( ALWAYS(yymsp[-1].minor.yy41) ){ yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); @@ -174130,83 +175236,83 @@ static YYACTIONTYPE yy_reduce( } yymsp[-4].minor.yy41 = yylhsminor.yy41; break; - case 311: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + case 313: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ { yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0); } break; - case 312: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + case 314: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ { yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0); } yymsp[-5].minor.yy41 = yylhsminor.yy41; break; - case 313: /* window ::= ORDER BY sortlist frame_opt */ + case 315: /* window ::= ORDER BY sortlist frame_opt */ { yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0); } break; - case 314: /* window ::= nm ORDER BY sortlist frame_opt */ + case 316: /* window ::= nm ORDER BY sortlist frame_opt */ { yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); } yymsp[-4].minor.yy41 = yylhsminor.yy41; break; - case 315: /* window ::= nm frame_opt */ + case 317: /* window ::= nm frame_opt */ { yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0); } yymsp[-1].minor.yy41 = yylhsminor.yy41; break; - case 316: /* frame_opt ::= */ + case 318: /* frame_opt ::= */ { yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); } break; - case 317: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ { yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516); } yymsp[-2].minor.yy41 = yylhsminor.yy41; break; - case 318: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ { yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516); } yymsp[-5].minor.yy41 = yylhsminor.yy41; break; - case 320: /* frame_bound_s ::= frame_bound */ - case 322: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==322); + case 322: /* frame_bound_s ::= frame_bound */ + case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324); {yylhsminor.yy595 = yymsp[0].minor.yy595;} yymsp[0].minor.yy595 = yylhsminor.yy595; break; - case 321: /* frame_bound_s ::= UNBOUNDED PRECEDING */ - case 323: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==323); - case 325: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==325); + case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325); + case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327); {yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;} yymsp[-1].minor.yy595 = yylhsminor.yy595; break; - case 324: /* frame_bound ::= expr PRECEDING|FOLLOWING */ + case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */ {yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;} yymsp[-1].minor.yy595 = yylhsminor.yy595; break; - case 326: /* frame_exclude_opt ::= */ + case 328: /* frame_exclude_opt ::= */ {yymsp[1].minor.yy516 = 0;} break; - case 327: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ + case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ {yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;} break; - case 328: /* frame_exclude ::= NO OTHERS */ - case 329: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==329); + case 330: /* frame_exclude ::= NO OTHERS */ + case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331); {yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/} break; - case 330: /* frame_exclude ::= GROUP|TIES */ + case 332: /* frame_exclude ::= GROUP|TIES */ {yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/} break; - case 331: /* window_clause ::= WINDOW windowdefn_list */ + case 333: /* window_clause ::= WINDOW windowdefn_list */ { yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; } break; - case 332: /* filter_over ::= filter_clause over_clause */ + case 334: /* filter_over ::= filter_clause over_clause */ { if( yymsp[0].minor.yy41 ){ yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528; @@ -174217,13 +175323,13 @@ static YYACTIONTYPE yy_reduce( } yymsp[-1].minor.yy41 = yylhsminor.yy41; break; - case 333: /* filter_over ::= over_clause */ + case 335: /* filter_over ::= over_clause */ { yylhsminor.yy41 = yymsp[0].minor.yy41; } yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 334: /* filter_over ::= filter_clause */ + case 336: /* filter_over ::= filter_clause */ { yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( yylhsminor.yy41 ){ @@ -174235,13 +175341,13 @@ static YYACTIONTYPE yy_reduce( } yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 335: /* over_clause ::= OVER LP window RP */ + case 337: /* over_clause ::= OVER LP window RP */ { yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41; assert( yymsp[-3].minor.yy41!=0 ); } break; - case 336: /* over_clause ::= OVER nm */ + case 338: /* over_clause ::= OVER nm */ { yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( yymsp[-1].minor.yy41 ){ @@ -174249,75 +175355,75 @@ static YYACTIONTYPE yy_reduce( } } break; - case 337: /* filter_clause ::= FILTER LP WHERE expr RP */ + case 339: /* filter_clause ::= FILTER LP WHERE expr RP */ { yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; } break; default: - /* (338) input ::= cmdlist */ yytestcase(yyruleno==338); - /* (339) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==339); - /* (340) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=340); - /* (341) ecmd ::= SEMI */ yytestcase(yyruleno==341); - /* (342) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==342); - /* (343) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=343); - /* (344) trans_opt ::= */ yytestcase(yyruleno==344); - /* (345) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==345); - /* (346) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==346); - /* (347) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==347); - /* (348) savepoint_opt ::= */ yytestcase(yyruleno==348); - /* (349) cmd ::= create_table create_table_args */ yytestcase(yyruleno==349); - /* (350) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=350); - /* (351) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==351); - /* (352) columnlist ::= columnname carglist */ yytestcase(yyruleno==352); - /* (353) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==353); - /* (354) nm ::= STRING */ yytestcase(yyruleno==354); - /* (355) typetoken ::= typename */ yytestcase(yyruleno==355); - /* (356) typename ::= ID|STRING */ yytestcase(yyruleno==356); - /* (357) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=357); - /* (358) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=358); - /* (359) carglist ::= carglist ccons */ yytestcase(yyruleno==359); - /* (360) carglist ::= */ yytestcase(yyruleno==360); - /* (361) ccons ::= NULL onconf */ yytestcase(yyruleno==361); - /* (362) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==362); - /* (363) ccons ::= AS generated */ yytestcase(yyruleno==363); - /* (364) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==364); - /* (365) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==365); - /* (366) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=366); - /* (367) tconscomma ::= */ yytestcase(yyruleno==367); - /* (368) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=368); - /* (369) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=369); - /* (370) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=370); - /* (371) oneselect ::= values */ yytestcase(yyruleno==371); - /* (372) sclp ::= selcollist COMMA */ yytestcase(yyruleno==372); - /* (373) as ::= ID|STRING */ yytestcase(yyruleno==373); - /* (374) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=374); - /* (375) returning ::= */ yytestcase(yyruleno==375); - /* (376) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=376); - /* (377) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==377); - /* (378) case_operand ::= expr */ yytestcase(yyruleno==378); - /* (379) exprlist ::= nexprlist */ yytestcase(yyruleno==379); - /* (380) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=380); - /* (381) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=381); - /* (382) nmnum ::= ON */ yytestcase(yyruleno==382); - /* (383) nmnum ::= DELETE */ yytestcase(yyruleno==383); - /* (384) nmnum ::= DEFAULT */ yytestcase(yyruleno==384); - /* (385) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==385); - /* (386) foreach_clause ::= */ yytestcase(yyruleno==386); - /* (387) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==387); - /* (388) trnm ::= nm */ yytestcase(yyruleno==388); - /* (389) tridxby ::= */ yytestcase(yyruleno==389); - /* (390) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==390); - /* (391) database_kw_opt ::= */ yytestcase(yyruleno==391); - /* (392) kwcolumn_opt ::= */ yytestcase(yyruleno==392); - /* (393) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==393); - /* (394) vtabarglist ::= vtabarg */ yytestcase(yyruleno==394); - /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==395); - /* (396) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==396); - /* (397) anylist ::= */ yytestcase(yyruleno==397); - /* (398) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==398); - /* (399) anylist ::= anylist ANY */ yytestcase(yyruleno==399); - /* (400) with ::= */ yytestcase(yyruleno==400); - /* (401) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=401); - /* (402) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=402); + /* (340) input ::= cmdlist */ yytestcase(yyruleno==340); + /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341); + /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342); + /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343); + /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344); + /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345); + /* (346) trans_opt ::= */ yytestcase(yyruleno==346); + /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347); + /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348); + /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349); + /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350); + /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351); + /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352); + /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353); + /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354); + /* (355) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==355); + /* (356) nm ::= STRING */ yytestcase(yyruleno==356); + /* (357) typetoken ::= typename */ yytestcase(yyruleno==357); + /* (358) typename ::= ID|STRING */ yytestcase(yyruleno==358); + /* (359) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=359); + /* (360) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=360); + /* (361) carglist ::= carglist ccons */ yytestcase(yyruleno==361); + /* (362) carglist ::= */ yytestcase(yyruleno==362); + /* (363) ccons ::= NULL onconf */ yytestcase(yyruleno==363); + /* (364) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==364); + /* (365) ccons ::= AS generated */ yytestcase(yyruleno==365); + /* (366) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==366); + /* (367) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==367); + /* (368) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=368); + /* (369) tconscomma ::= */ yytestcase(yyruleno==369); + /* (370) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=370); + /* (371) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=371); + /* (372) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=372); + /* (373) oneselect ::= values */ yytestcase(yyruleno==373); + /* (374) sclp ::= selcollist COMMA */ yytestcase(yyruleno==374); + /* (375) as ::= ID|STRING */ yytestcase(yyruleno==375); + /* (376) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=376); + /* (377) returning ::= */ yytestcase(yyruleno==377); + /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378); + /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379); + /* (380) case_operand ::= expr */ yytestcase(yyruleno==380); + /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381); + /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382); + /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383); + /* (384) nmnum ::= ON */ yytestcase(yyruleno==384); + /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385); + /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386); + /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387); + /* (388) foreach_clause ::= */ yytestcase(yyruleno==388); + /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389); + /* (390) trnm ::= nm */ yytestcase(yyruleno==390); + /* (391) tridxby ::= */ yytestcase(yyruleno==391); + /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392); + /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393); + /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394); + /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395); + /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396); + /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397); + /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398); + /* (399) anylist ::= */ yytestcase(yyruleno==399); + /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400); + /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401); + /* (402) with ::= */ yytestcase(yyruleno==402); + /* (403) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=403); + /* (404) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=404); break; /********** End reduce actions ************************************************/ }; @@ -176441,7 +177547,9 @@ SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*); #ifdef SQLITE_ENABLE_STMTVTAB SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*); #endif - +#ifdef SQLITE_EXTRA_AUTOEXT +int SQLITE_EXTRA_AUTOEXT(sqlite3*); +#endif /* ** An array of pointers to extension initializer functions for ** built-in extensions. @@ -176475,6 +177583,9 @@ static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = { #ifdef SQLITE_ENABLE_BYTECODE_VTAB sqlite3VdbeBytecodeVtabInit, #endif +#ifdef SQLITE_EXTRA_AUTOEXT + SQLITE_EXTRA_AUTOEXT, +#endif }; #ifndef SQLITE_AMALGAMATION @@ -176548,6 +177659,32 @@ SQLITE_API char *sqlite3_temp_directory = 0; */ SQLITE_API char *sqlite3_data_directory = 0; +/* +** Determine whether or not high-precision (long double) floating point +** math works correctly on CPU currently running. +*/ +static SQLITE_NOINLINE int hasHighPrecisionDouble(int rc){ + if( sizeof(LONGDOUBLE_TYPE)<=8 ){ + /* If the size of "long double" is not more than 8, then + ** high-precision math is not possible. */ + return 0; + }else{ + /* Just because sizeof(long double)>8 does not mean that the underlying + ** hardware actually supports high-precision floating point. For example, + ** clearing the 0x100 bit in the floating-point control word on Intel + ** processors will make long double work like double, even though long + ** double takes up more space. The only way to determine if long double + ** actually works is to run an experiment. */ + LONGDOUBLE_TYPE a, b, c; + rc++; + a = 1.0+rc*0.1; + b = 1.0e+18+rc*25.0; + c = a+b; + return b!=c; + } +} + + /* ** Initialize SQLite. ** @@ -176743,6 +177880,12 @@ SQLITE_API int sqlite3_initialize(void){ } #endif + /* Experimentally determine if high-precision floating point is + ** available. */ +#ifndef SQLITE_OMIT_WSD + sqlite3Config.bUseLongDouble = hasHighPrecisionDouble(rc); +#endif + return rc; } @@ -177313,6 +178456,10 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(db->mutex); va_start(ap, op); switch( op ){ @@ -177642,6 +178789,14 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ } #endif + while( db->pDbData ){ + DbClientData *p = db->pDbData; + db->pDbData = p->pNext; + assert( p->pData!=0 ); + if( p->xDestructor ) p->xDestructor(p->pData); + sqlite3_free(p); + } + /* Convert the connection into a zombie and then close it. */ db->eOpenState = SQLITE_STATE_ZOMBIE; @@ -178716,6 +179871,12 @@ SQLITE_API void *sqlite3_preupdate_hook( void *pArg /* First callback argument */ ){ void *pRet; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 ){ + return 0; + } +#endif sqlite3_mutex_enter(db->mutex); pRet = db->pPreUpdateArg; db->xPreUpdateCallback = xCallback; @@ -178862,7 +180023,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( if( eModeSQLITE_CHECKPOINT_TRUNCATE ){ /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint ** mode: */ - return SQLITE_MISUSE; + return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(db->mutex); @@ -180099,6 +181260,69 @@ SQLITE_API int sqlite3_collation_needed16( } #endif /* SQLITE_OMIT_UTF16 */ +/* +** Find existing client data. +*/ +SQLITE_API void *sqlite3_get_clientdata(sqlite3 *db, const char *zName){ + DbClientData *p; + sqlite3_mutex_enter(db->mutex); + for(p=db->pDbData; p; p=p->pNext){ + if( strcmp(p->zName, zName)==0 ){ + void *pResult = p->pData; + sqlite3_mutex_leave(db->mutex); + return pResult; + } + } + sqlite3_mutex_leave(db->mutex); + return 0; +} + +/* +** Add new client data to a database connection. +*/ +SQLITE_API int sqlite3_set_clientdata( + sqlite3 *db, /* Attach client data to this connection */ + const char *zName, /* Name of the client data */ + void *pData, /* The client data itself */ + void (*xDestructor)(void*) /* Destructor */ +){ + DbClientData *p, **pp; + sqlite3_mutex_enter(db->mutex); + pp = &db->pDbData; + for(p=db->pDbData; p && strcmp(p->zName,zName); p=p->pNext){ + pp = &p->pNext; + } + if( p ){ + assert( p->pData!=0 ); + if( p->xDestructor ) p->xDestructor(p->pData); + if( pData==0 ){ + *pp = p->pNext; + sqlite3_free(p); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; + } + }else if( pData==0 ){ + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; + }else{ + size_t n = strlen(zName); + p = sqlite3_malloc64( sizeof(DbClientData)+n+1 ); + if( p==0 ){ + if( xDestructor ) xDestructor(pData); + sqlite3_mutex_leave(db->mutex); + return SQLITE_NOMEM; + } + memcpy(p->zName, zName, n+1); + p->pNext = db->pDbData; + db->pDbData = p; + } + p->pData = pData; + p->xDestructor = xDestructor; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + + #ifndef SQLITE_OMIT_DEPRECATED /* ** This function is now an anachronism. It used to be used to recover from a @@ -180448,6 +181672,28 @@ SQLITE_API int sqlite3_test_control(int op, ...){ } #endif + /* sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b); + ** + ** If b is true, then activate the SQLITE_FkNoAction setting. If b is + ** false then clearn that setting. If the SQLITE_FkNoAction setting is + ** abled, all foreign key ON DELETE and ON UPDATE actions behave as if + ** they were NO ACTION, regardless of how they are defined. + ** + ** NB: One must usually run "PRAGMA writable_schema=RESET" after + ** using this test-control, before it will take full effect. failing + ** to reset the schema can result in some unexpected behavior. + */ + case SQLITE_TESTCTRL_FK_NO_ACTION: { + sqlite3 *db = va_arg(ap, sqlite3*); + int b = va_arg(ap, int); + if( b ){ + db->flags |= SQLITE_FkNoAction; + }else{ + db->flags &= ~SQLITE_FkNoAction; + } + break; + } + /* ** sqlite3_test_control(BITVEC_TEST, size, program) ** @@ -180872,11 +182118,11 @@ SQLITE_API int sqlite3_test_control(int op, ...){ ** X<0 Make no changes to the bUseLongDouble. Just report value. ** X==0 Disable bUseLongDouble ** X==1 Enable bUseLongDouble - ** X==2 Set bUseLongDouble to its default value for this platform + ** X>=2 Set bUseLongDouble to its default value for this platform */ case SQLITE_TESTCTRL_USELONGDOUBLE: { int b = va_arg(ap, int); - if( b==2 ) b = sizeof(LONGDOUBLE_TYPE)>8; + if( b>=2 ) b = hasHighPrecisionDouble(b); if( b>=0 ) sqlite3Config.bUseLongDouble = b>0; rc = sqlite3Config.bUseLongDouble!=0; break; @@ -181290,7 +182536,7 @@ SQLITE_API int sqlite3_compileoption_used(const char *zOptName){ int nOpt; const char **azCompileOpt; -#if SQLITE_ENABLE_API_ARMOR +#ifdef SQLITE_ENABLE_API_ARMOR if( zOptName==0 ){ (void)SQLITE_MISUSE_BKPT; return 0; @@ -181485,6 +182731,9 @@ SQLITE_API int sqlite3_unlock_notify( ){ int rc = SQLITE_OK; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(db->mutex); enterMutex(); @@ -182506,6 +183755,7 @@ struct Fts3Table { int nPgsz; /* Page size for host database */ char *zSegmentsTbl; /* Name of %_segments table */ sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ + int iSavepoint; /* ** The following array of hash tables is used to buffer pending index @@ -183249,6 +184499,7 @@ static void fts3DeclareVtab(int *pRc, Fts3Table *p){ zLanguageid = (p->zLanguageid ? p->zLanguageid : "__langid"); sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(p->db, SQLITE_VTAB_INNOCUOUS); /* Create a list of user columns for the virtual table */ zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); @@ -186498,6 +187749,8 @@ static int fts3RenameMethod( rc = sqlite3Fts3PendingTermsFlush(p); } + p->bIgnoreSavepoint = 1; + if( p->zContentTbl==0 ){ fts3DbExec(&rc, db, "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", @@ -186525,6 +187778,8 @@ static int fts3RenameMethod( "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';", p->zDb, p->zName, zName ); + + p->bIgnoreSavepoint = 0; return rc; } @@ -186535,12 +187790,28 @@ static int fts3RenameMethod( */ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ int rc = SQLITE_OK; - UNUSED_PARAMETER(iSavepoint); - assert( ((Fts3Table *)pVtab)->inTransaction ); - assert( ((Fts3Table *)pVtab)->mxSavepoint <= iSavepoint ); - TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); - if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){ - rc = fts3SyncMethod(pVtab); + Fts3Table *pTab = (Fts3Table*)pVtab; + assert( pTab->inTransaction ); + assert( pTab->mxSavepoint<=iSavepoint ); + TESTONLY( pTab->mxSavepoint = iSavepoint ); + + if( pTab->bIgnoreSavepoint==0 ){ + if( fts3HashCount(&pTab->aIndex[0].hPending)>0 ){ + char *zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", + pTab->zDb, pTab->zName, pTab->zName + ); + if( zSql ){ + pTab->bIgnoreSavepoint = 1; + rc = sqlite3_exec(pTab->db, zSql, 0, 0, 0); + pTab->bIgnoreSavepoint = 0; + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint+1; + } } return rc; } @@ -186551,12 +187822,11 @@ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ ** This is a no-op. */ static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ - TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); - UNUSED_PARAMETER(iSavepoint); - UNUSED_PARAMETER(pVtab); - assert( p->inTransaction ); - assert( p->mxSavepoint >= iSavepoint ); - TESTONLY( p->mxSavepoint = iSavepoint-1 ); + Fts3Table *pTab = (Fts3Table*)pVtab; + assert( pTab->inTransaction ); + assert( pTab->mxSavepoint >= iSavepoint ); + TESTONLY( pTab->mxSavepoint = iSavepoint-1 ); + pTab->iSavepoint = iSavepoint; return SQLITE_OK; } @@ -186566,11 +187836,13 @@ static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ ** Discard the contents of the pending terms table. */ static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ - Fts3Table *p = (Fts3Table*)pVtab; + Fts3Table *pTab = (Fts3Table*)pVtab; UNUSED_PARAMETER(iSavepoint); - assert( p->inTransaction ); - TESTONLY( p->mxSavepoint = iSavepoint ); - sqlite3Fts3PendingTermsClear(p); + assert( pTab->inTransaction ); + TESTONLY( pTab->mxSavepoint = iSavepoint ); + if( (iSavepoint+1)<=pTab->iSavepoint ){ + sqlite3Fts3PendingTermsClear(pTab); + } return SQLITE_OK; } @@ -186589,8 +187861,49 @@ static int fts3ShadowName(const char *zName){ return 0; } +/* +** Implementation of the xIntegrity() method on the FTS3/FTS4 virtual +** table. +*/ +static int fts3Integrity( + sqlite3_vtab *pVtab, /* The virtual table to be checked */ + const char *zSchema, /* Name of schema in which pVtab lives */ + const char *zTabname, /* Name of the pVTab table */ + int isQuick, /* True if this is a quick_check */ + char **pzErr /* Write error message here */ +){ + Fts3Table *p = (Fts3Table*)pVtab; + char *zSql; + int rc; + char *zErr = 0; + + assert( pzErr!=0 ); + assert( *pzErr==0 ); + UNUSED_PARAMETER(isQuick); + zSql = sqlite3_mprintf( + "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", + zSchema, zTabname, zTabname); + if( zSql==0 ){ + return SQLITE_NOMEM; + } + rc = sqlite3_exec(p->db, zSql, 0, 0, &zErr); + sqlite3_free(zSql); + if( (rc&0xff)==SQLITE_CORRUPT ){ + *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", + p->bFts4 ? 4 : 3, zSchema, zTabname); + }else if( rc!=SQLITE_OK ){ + *pzErr = sqlite3_mprintf("unable to validate the inverted index for" + " FTS%d table %s.%s: %s", + p->bFts4 ? 4 : 3, zSchema, zTabname, zErr); + } + sqlite3_free(zErr); + return SQLITE_OK; +} + + + static const sqlite3_module fts3Module = { - /* iVersion */ 3, + /* iVersion */ 4, /* xCreate */ fts3CreateMethod, /* xConnect */ fts3ConnectMethod, /* xBestIndex */ fts3BestIndexMethod, @@ -186614,6 +187927,7 @@ static const sqlite3_module fts3Module = { /* xRelease */ fts3ReleaseMethod, /* xRollbackTo */ fts3RollbackToMethod, /* xShadowName */ fts3ShadowName, + /* xIntegrity */ fts3Integrity, }; /* @@ -189289,7 +190603,8 @@ SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc; /* Return code */ @@ -192855,7 +194170,8 @@ SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestr 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc; /* Return code */ @@ -196196,7 +197512,6 @@ SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); if( rc==SQLITE_DONE ) rc = SQLITE_OK; } - sqlite3Fts3PendingTermsClear(p); /* Determine the auto-incr-merge setting if unknown. If enabled, ** estimate the number of leaf blocks of content to be written @@ -196218,6 +197533,10 @@ SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ rc = sqlite3_reset(pStmt); } } + + if( rc==SQLITE_OK ){ + sqlite3Fts3PendingTermsClear(p); + } return rc; } @@ -196849,6 +198168,8 @@ static int fts3AppendToNode( blobGrowBuffer(pPrev, nTerm, &rc); if( rc!=SQLITE_OK ) return rc; + assert( pPrev!=0 ); + assert( pPrev->a!=0 ); nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm); nSuffix = nTerm - nPrefix; @@ -196905,9 +198226,13 @@ static int fts3IncrmergeAppend( nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; /* If the current block is not empty, and if adding this term/doclist - ** to the current block would make it larger than Fts3Table.nNodeSize - ** bytes, write this block out to the database. */ - if( pLeaf->block.n>0 && (pLeaf->block.n + nSpace)>p->nNodeSize ){ + ** to the current block would make it larger than Fts3Table.nNodeSize bytes, + ** and if there is still room for another leaf page, write this block out to + ** the database. */ + if( pLeaf->block.n>0 + && (pLeaf->block.n + nSpace)>p->nNodeSize + && pLeaf->iBlock < (pWriter->iStart + pWriter->nLeafEst) + ){ rc = fts3WriteSegment(p, pLeaf->iBlock, pLeaf->block.a, pLeaf->block.n); pWriter->nWork++; @@ -197239,7 +198564,7 @@ static int fts3IncrmergeLoad( rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0); blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc - ); + ); if( rc==SQLITE_OK ){ memcpy(pNode->block.a, aBlock, nBlock); pNode->block.n = nBlock; @@ -198304,8 +199629,11 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ rc = fts3DoIncrmerge(p, &zVal[6]); }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ rc = fts3DoAutoincrmerge(p, &zVal[10]); + }else if( nVal==5 && 0==sqlite3_strnicmp(zVal, "flush", 5) ){ + rc = sqlite3Fts3PendingTermsFlush(p); + } #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - }else{ + else{ int v; if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ v = atoi(&zVal[9]); @@ -198323,8 +199651,8 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v; rc = SQLITE_OK; } -#endif } +#endif return rc; } @@ -201837,7 +203165,7 @@ static void jsonResult(JsonString *p){ }else if( jsonForceRCStr(p) ){ sqlite3RCStrRef(p->zBuf); sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, - (void(*)(void*))sqlite3RCStrUnref, + sqlite3RCStrUnref, SQLITE_UTF8); } } @@ -203177,7 +204505,7 @@ static JsonParse *jsonParseCached( /* The input JSON was not found anywhere in the cache. We will need ** to parse it ourselves and generate a new JsonParse object. */ - bJsonRCStr = sqlite3ValueIsOfClass(pJson,(void(*)(void*))sqlite3RCStrUnref); + bJsonRCStr = sqlite3ValueIsOfClass(pJson,sqlite3RCStrUnref); p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) ); if( p==0 ){ sqlite3_result_error_nomem(pCtx); @@ -203391,6 +204719,7 @@ static JsonNode *jsonLookupStep( if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--; j += jsonNodeSize(&pRoot[j]); } + if( i==0 && j<=pRoot->n ) break; if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; if( pParse->useMod==0 ) break; assert( pRoot->eU==2 ); @@ -204078,11 +205407,13 @@ static void jsonReplaceNode( break; } if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){ - char *zCopy = sqlite3DbStrDup(0, z); + char *zCopy = sqlite3_malloc64( n+1 ); int k; if( zCopy ){ + memcpy(zCopy, z, n); + zCopy[n] = 0; jsonParseAddCleanup(p, sqlite3_free, zCopy); - }else{ + }else{ p->oom = 1; sqlite3_result_error_nomem(pCtx); } @@ -204359,7 +205690,7 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : - (void(*)(void*))sqlite3RCStrUnref); + sqlite3RCStrUnref); pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); @@ -204468,7 +205799,7 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : - (void(*)(void*))sqlite3RCStrUnref); + sqlite3RCStrUnref); pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); @@ -204900,7 +206231,7 @@ static int jsonEachFilter( if( z==0 ) return SQLITE_OK; memset(&p->sParse, 0, sizeof(p->sParse)); p->sParse.nJPRef = 1; - if( sqlite3ValueIsOfClass(argv[0], (void(*)(void*))sqlite3RCStrUnref) ){ + if( sqlite3ValueIsOfClass(argv[0], sqlite3RCStrUnref) ){ p->sParse.zJson = sqlite3RCStrRef((char*)z); }else{ n = sqlite3_value_bytes(argv[0]); @@ -204995,7 +206326,8 @@ static sqlite3_module jsonEachModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* The methods of the json_tree virtual table. */ @@ -205023,7 +206355,8 @@ static sqlite3_module jsonTreeModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ #endif /* !defined(SQLITE_OMIT_JSON) */ @@ -205258,6 +206591,7 @@ struct Rtree { int iDepth; /* Current depth of the r-tree structure */ char *zDb; /* Name of database containing r-tree table */ char *zName; /* Name of r-tree table */ + char *zNodeName; /* Name of the %_node table */ u32 nBusy; /* Current number of users of this structure */ i64 nRowEst; /* Estimated number of rows in this table */ u32 nCursor; /* Number of open cursors */ @@ -205270,7 +206604,6 @@ struct Rtree { ** headed by the node (leaf nodes have RtreeNode.iNode==0). */ RtreeNode *pDeleted; - int iReinsertHeight; /* Height of sub-trees Reinsert() has run on */ /* Blob I/O on xxx_node */ sqlite3_blob *pNodeBlob; @@ -205567,15 +206900,20 @@ struct RtreeMatchArg { ** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined ** at run-time. */ -#ifndef SQLITE_BYTEORDER -# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ +#ifndef SQLITE_BYTEORDER /* Replicate changes at tag-20230904a */ +# if defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ +# define SQLITE_BYTEORDER 4321 +# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ +# define SQLITE_BYTEORDER 1234 +# elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 +# define SQLITE_BYTEORDER 4321 +# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64) -# define SQLITE_BYTEORDER 1234 -# elif defined(sparc) || defined(__ppc__) || \ - defined(__ARMEB__) || defined(__AARCH64EB__) -# define SQLITE_BYTEORDER 4321 +# define SQLITE_BYTEORDER 1234 +# elif defined(sparc) || defined(__ARMEB__) || defined(__AARCH64EB__) +# define SQLITE_BYTEORDER 4321 # else # define SQLITE_BYTEORDER 0 # endif @@ -205824,11 +207162,9 @@ static int nodeAcquire( } } if( pRtree->pNodeBlob==0 ){ - char *zTab = sqlite3_mprintf("%s_node", pRtree->zName); - if( zTab==0 ) return SQLITE_NOMEM; - rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, zTab, "data", iNode, 0, + rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, pRtree->zNodeName, + "data", iNode, 0, &pRtree->pNodeBlob); - sqlite3_free(zTab); } if( rc ){ nodeBlobReset(pRtree); @@ -207169,8 +208505,12 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ pIdxInfo->idxNum = 2; pIdxInfo->needToFreeIdxStr = 1; - if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){ - return SQLITE_NOMEM; + if( iIdx>0 ){ + pIdxInfo->idxStr = sqlite3_malloc( iIdx+1 ); + if( pIdxInfo->idxStr==0 ){ + return SQLITE_NOMEM; + } + memcpy(pIdxInfo->idxStr, zIdxStr, iIdx+1); } nRow = pRtree->nRowEst >> (iIdx/2); @@ -207249,31 +208589,22 @@ static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ */ static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ int ii; - int isInt = (pRtree->eCoordType==RTREE_COORD_INT32); - for(ii=0; iinDim2; ii+=2){ - RtreeCoord *a1 = &p1->aCoord[ii]; - RtreeCoord *a2 = &p2->aCoord[ii]; - if( (!isInt && (a2[0].fa1[1].f)) - || ( isInt && (a2[0].ia1[1].i)) - ){ - return 0; + if( pRtree->eCoordType==RTREE_COORD_INT32 ){ + for(ii=0; iinDim2; ii+=2){ + RtreeCoord *a1 = &p1->aCoord[ii]; + RtreeCoord *a2 = &p2->aCoord[ii]; + if( a2[0].ia1[1].i ) return 0; + } + }else{ + for(ii=0; iinDim2; ii+=2){ + RtreeCoord *a1 = &p1->aCoord[ii]; + RtreeCoord *a2 = &p2->aCoord[ii]; + if( a2[0].fa1[1].f ) return 0; } } return 1; } -/* -** Return the amount cell p would grow by if it were unioned with pCell. -*/ -static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){ - RtreeDValue area; - RtreeCell cell; - memcpy(&cell, p, sizeof(RtreeCell)); - area = cellArea(pRtree, &cell); - cellUnion(pRtree, &cell, pCell); - return (cellArea(pRtree, &cell)-area); -} - static RtreeDValue cellOverlap( Rtree *pRtree, RtreeCell *p, @@ -207320,38 +208651,52 @@ static int ChooseLeaf( for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ int iCell; sqlite3_int64 iBest = 0; - + int bFound = 0; RtreeDValue fMinGrowth = RTREE_ZERO; RtreeDValue fMinArea = RTREE_ZERO; - int nCell = NCELL(pNode); - RtreeCell cell; RtreeNode *pChild = 0; - RtreeCell *aCell = 0; - - /* Select the child node which will be enlarged the least if pCell - ** is inserted into it. Resolve ties by choosing the entry with - ** the smallest area. + /* First check to see if there is are any cells in pNode that completely + ** contains pCell. If two or more cells in pNode completely contain pCell + ** then pick the smallest. */ for(iCell=0; iCell1 ){ - int iLeft = 0; - int iRight = 0; - - int nLeft = nIdx/2; - int nRight = nIdx-nLeft; - int *aLeft = aIdx; - int *aRight = &aIdx[nLeft]; - - SortByDistance(aLeft, nLeft, aDistance, aSpare); - SortByDistance(aRight, nRight, aDistance, aSpare); - - memcpy(aSpare, aLeft, sizeof(int)*nLeft); - aLeft = aSpare; - - while( iLeftnDim; iDim++){ - aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]); - aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]); - } - } - for(iDim=0; iDimnDim; iDim++){ - aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2)); - } - - for(ii=0; iinDim; iDim++){ - RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - - DCOORD(aCell[ii].aCoord[iDim*2])); - aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); - } - } - - SortByDistance(aOrder, nCell, aDistance, aSpare); - nodeZero(pRtree, pNode); - - for(ii=0; rc==SQLITE_OK && ii<(nCell-(RTREE_MINCELLS(pRtree)+1)); ii++){ - RtreeCell *p = &aCell[aOrder[ii]]; - nodeInsertCell(pRtree, pNode, p); - if( p->iRowid==pCell->iRowid ){ - if( iHeight==0 ){ - rc = rowidWrite(pRtree, p->iRowid, pNode->iNode); - }else{ - rc = parentWrite(pRtree, p->iRowid, pNode->iNode); - } - } - } - if( rc==SQLITE_OK ){ - rc = fixBoundingBox(pRtree, pNode); - } - for(; rc==SQLITE_OK && iiiNode currently contains - ** the height of the sub-tree headed by the cell. - */ - RtreeNode *pInsert; - RtreeCell *p = &aCell[aOrder[ii]]; - rc = ChooseLeaf(pRtree, p, iHeight, &pInsert); - if( rc==SQLITE_OK ){ - int rc2; - rc = rtreeInsertCell(pRtree, pInsert, p, iHeight); - rc2 = nodeRelease(pRtree, pInsert); - if( rc==SQLITE_OK ){ - rc = rc2; - } - } - } - - sqlite3_free(aCell); - return rc; -} - /* ** Insert cell pCell into node pNode. Node pNode is the head of a ** subtree iHeight high (leaf nodes have iHeight==0). @@ -208100,12 +209273,7 @@ static int rtreeInsertCell( } } if( nodeInsertCell(pRtree, pNode, pCell) ){ - if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ - rc = SplitNode(pRtree, pNode, pCell, iHeight); - }else{ - pRtree->iReinsertHeight = iHeight; - rc = Reinsert(pRtree, pNode, pCell, iHeight); - } + rc = SplitNode(pRtree, pNode, pCell, iHeight); }else{ rc = AdjustTree(pRtree, pNode, pCell); if( ALWAYS(rc==SQLITE_OK) ){ @@ -208448,7 +209616,6 @@ static int rtreeUpdate( } if( rc==SQLITE_OK ){ int rc2; - pRtree->iReinsertHeight = -1; rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); rc2 = nodeRelease(pRtree, pLeaf); if( rc==SQLITE_OK ){ @@ -208589,8 +209756,11 @@ static int rtreeShadowName(const char *zName){ return 0; } +/* Forward declaration */ +static int rtreeIntegrity(sqlite3_vtab*, const char*, const char*, int, char**); + static sqlite3_module rtreeModule = { - 3, /* iVersion */ + 4, /* iVersion */ rtreeCreate, /* xCreate - create a table */ rtreeConnect, /* xConnect - connect to an existing table */ rtreeBestIndex, /* xBestIndex - Determine search strategy */ @@ -208613,7 +209783,8 @@ static sqlite3_module rtreeModule = { rtreeSavepoint, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - rtreeShadowName /* xShadowName */ + rtreeShadowName, /* xShadowName */ + rtreeIntegrity /* xIntegrity */ }; static int rtreeSqlInit( @@ -208869,22 +210040,27 @@ static int rtreeInit( } sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + /* Allocate the sqlite3_vtab structure */ nDb = (int)strlen(argv[1]); nName = (int)strlen(argv[2]); - pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName*2+8); if( !pRtree ){ return SQLITE_NOMEM; } - memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); + memset(pRtree, 0, sizeof(Rtree)+nDb+nName*2+8); pRtree->nBusy = 1; pRtree->base.pModule = &rtreeModule; pRtree->zDb = (char *)&pRtree[1]; pRtree->zName = &pRtree->zDb[nDb+1]; + pRtree->zNodeName = &pRtree->zName[nName+1]; pRtree->eCoordType = (u8)eCoordType; memcpy(pRtree->zDb, argv[1], nDb); memcpy(pRtree->zName, argv[2], nName); + memcpy(pRtree->zNodeName, argv[2], nName); + memcpy(&pRtree->zNodeName[nName], "_node", 6); /* Create/Connect to the underlying relational database schema. If @@ -209381,7 +210557,6 @@ static int rtreeCheckTable( ){ RtreeCheck check; /* Common context for various routines */ sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */ - int bEnd = 0; /* True if transaction should be closed */ int nAux = 0; /* Number of extra columns. */ /* Initialize the context object */ @@ -209390,14 +210565,6 @@ static int rtreeCheckTable( check.zDb = zDb; check.zTab = zTab; - /* If there is not already an open transaction, open one now. This is - ** to ensure that the queries run as part of this integrity-check operate - ** on a consistent snapshot. */ - if( sqlite3_get_autocommit(db) ){ - check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0); - bEnd = 1; - } - /* Find the number of auxiliary columns */ if( check.rc==SQLITE_OK ){ pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); @@ -209438,15 +210605,34 @@ static int rtreeCheckTable( sqlite3_finalize(check.aCheckMapping[0]); sqlite3_finalize(check.aCheckMapping[1]); - /* If one was opened, close the transaction */ - if( bEnd ){ - int rc = sqlite3_exec(db, "END", 0, 0, 0); - if( check.rc==SQLITE_OK ) check.rc = rc; - } *pzReport = check.zReport; return check.rc; } +/* +** Implementation of the xIntegrity method for Rtree. +*/ +static int rtreeIntegrity( + sqlite3_vtab *pVtab, /* The virtual table to check */ + const char *zSchema, /* Schema in which the virtual table lives */ + const char *zName, /* Name of the virtual table */ + int isQuick, /* True for a quick_check */ + char **pzErr /* Write results here */ +){ + Rtree *pRtree = (Rtree*)pVtab; + int rc; + assert( pzErr!=0 && *pzErr==0 ); + UNUSED_PARAMETER(zSchema); + UNUSED_PARAMETER(zName); + UNUSED_PARAMETER(isQuick); + rc = rtreeCheckTable(pRtree->db, pRtree->zDb, pRtree->zName, pzErr); + if( rc==SQLITE_OK && *pzErr ){ + *pzErr = sqlite3_mprintf("In RTree %s.%s:\n%z", + pRtree->zDb, pRtree->zName, *pzErr); + } + return rc; +} + /* ** Usage: ** @@ -210768,24 +211954,28 @@ static int geopolyInit( (void)pAux; sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); /* Allocate the sqlite3_vtab structure */ nDb = strlen(argv[1]); nName = strlen(argv[2]); - pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName*2+8); if( !pRtree ){ return SQLITE_NOMEM; } - memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); + memset(pRtree, 0, sizeof(Rtree)+nDb+nName*2+8); pRtree->nBusy = 1; pRtree->base.pModule = &rtreeModule; pRtree->zDb = (char *)&pRtree[1]; pRtree->zName = &pRtree->zDb[nDb+1]; + pRtree->zNodeName = &pRtree->zName[nName+1]; pRtree->eCoordType = RTREE_COORD_REAL32; pRtree->nDim = 2; pRtree->nDim2 = 4; memcpy(pRtree->zDb, argv[1], nDb); memcpy(pRtree->zName, argv[2], nName); + memcpy(pRtree->zNodeName, argv[2], nName); + memcpy(&pRtree->zNodeName[nName], "_node", 6); /* Create/Connect to the underlying relational database schema. If @@ -211199,7 +212389,6 @@ static int geopolyUpdate( } if( rc==SQLITE_OK ){ int rc2; - pRtree->iReinsertHeight = -1; rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); rc2 = nodeRelease(pRtree, pLeaf); if( rc==SQLITE_OK ){ @@ -211296,7 +212485,8 @@ static sqlite3_module geopolyModule = { rtreeSavepoint, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - rtreeShadowName /* xShadowName */ + rtreeShadowName, /* xShadowName */ + rtreeIntegrity /* xIntegrity */ }; static int sqlite3_geopoly_init(sqlite3 *db){ @@ -219310,7 +220500,8 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; return sqlite3_create_module(db, "dbstat", &dbstat_module, 0); } @@ -219747,7 +220938,8 @@ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0); } @@ -219878,6 +221070,18 @@ struct sqlite3_changeset_iter { ** The data associated with each hash-table entry is a structure containing ** a subset of the initial values that the modified row contained at the ** start of the session. Or no initial values if the row was inserted. +** +** pDfltStmt: +** This is only used by the sqlite3changegroup_xxx() APIs, not by +** regular sqlite3_session objects. It is a SELECT statement that +** selects the default value for each table column. For example, +** if the table is +** +** CREATE TABLE xx(a DEFAULT 1, b, c DEFAULT 'abc') +** +** then this variable is the compiled version of: +** +** SELECT 1, NULL, 'abc' */ struct SessionTable { SessionTable *pNext; @@ -219886,10 +221090,12 @@ struct SessionTable { int bStat1; /* True if this is sqlite_stat1 */ int bRowid; /* True if this table uses rowid for PK */ const char **azCol; /* Column names */ + const char **azDflt; /* Default value expressions */ u8 *abPK; /* Array of primary key flags */ int nEntry; /* Total number of entries in hash table */ int nChange; /* Size of apChange[] array */ SessionChange **apChange; /* Hash table buckets */ + sqlite3_stmt *pDfltStmt; }; /* @@ -220058,6 +221264,7 @@ struct SessionTable { struct SessionChange { u8 op; /* One of UPDATE, DELETE, INSERT */ u8 bIndirect; /* True if this change is "indirect" */ + u16 nRecordField; /* Number of fields in aRecord[] */ int nMaxSize; /* Max size of eventual changeset record */ int nRecord; /* Number of bytes in buffer aRecord[] */ u8 *aRecord; /* Buffer containing old.* record */ @@ -220083,7 +221290,7 @@ static int sessionVarintLen(int iVal){ ** Read a varint value from aBuf[] into *piVal. Return the number of ** bytes read. */ -static int sessionVarintGet(u8 *aBuf, int *piVal){ +static int sessionVarintGet(const u8 *aBuf, int *piVal){ return getVarint32(aBuf, *piVal); } @@ -220346,9 +221553,11 @@ static int sessionPreupdateHash( ** Return the number of bytes of space occupied by the value (including ** the type byte). */ -static int sessionSerialLen(u8 *a){ - int e = *a; +static int sessionSerialLen(const u8 *a){ + int e; int n; + assert( a!=0 ); + e = *a; if( e==0 || e==0xFF ) return 1; if( e==SQLITE_NULL ) return 1; if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; @@ -220753,13 +221962,14 @@ static int sessionGrowHash( ** ** For example, if the table is declared as: ** -** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z)); +** CREATE TABLE tbl1(w, x DEFAULT 'abc', y, z, PRIMARY KEY(w, z)); ** -** Then the four output variables are populated as follows: +** Then the five output variables are populated as follows: ** ** *pnCol = 4 ** *pzTab = "tbl1" ** *pazCol = {"w", "x", "y", "z"} +** *pazDflt = {NULL, 'abc', NULL, NULL} ** *pabPK = {1, 0, 0, 1} ** ** All returned buffers are part of the same single allocation, which must @@ -220773,6 +221983,7 @@ static int sessionTableInfo( int *pnCol, /* OUT: number of columns */ const char **pzTab, /* OUT: Copy of zThis */ const char ***pazCol, /* OUT: Array of column names for table */ + const char ***pazDflt, /* OUT: Array of default value expressions */ u8 **pabPK, /* OUT: Array of booleans - true for PK col */ int *pbRowid /* OUT: True if only PK is a rowid */ ){ @@ -220785,11 +221996,18 @@ static int sessionTableInfo( int i; u8 *pAlloc = 0; char **azCol = 0; + char **azDflt = 0; u8 *abPK = 0; int bRowid = 0; /* Set to true to use rowid as PK */ assert( pazCol && pabPK ); + *pazCol = 0; + *pabPK = 0; + *pnCol = 0; + if( pzTab ) *pzTab = 0; + if( pazDflt ) *pazDflt = 0; + nThis = sqlite3Strlen30(zThis); if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){ rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0); @@ -220803,39 +222021,28 @@ static int sessionTableInfo( }else if( rc==SQLITE_ERROR ){ zPragma = sqlite3_mprintf(""); }else{ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; return rc; } }else{ zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); } if( !zPragma ){ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; return SQLITE_NOMEM; } rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); sqlite3_free(zPragma); if( rc!=SQLITE_OK ){ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; return rc; } nByte = nThis + 1; bRowid = (pbRowid!=0); while( SQLITE_ROW==sqlite3_step(pStmt) ){ - nByte += sqlite3_column_bytes(pStmt, 1); + nByte += sqlite3_column_bytes(pStmt, 1); /* name */ + nByte += sqlite3_column_bytes(pStmt, 4); /* dflt_value */ nDbCol++; - if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; + if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; /* pk */ } if( nDbCol==0 ) bRowid = 0; nDbCol += bRowid; @@ -220843,15 +222050,18 @@ static int sessionTableInfo( rc = sqlite3_reset(pStmt); if( rc==SQLITE_OK ){ - nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); + nByte += nDbCol * (sizeof(const char *)*2 + sizeof(u8) + 1 + 1); pAlloc = sessionMalloc64(pSession, nByte); if( pAlloc==0 ){ rc = SQLITE_NOMEM; + }else{ + memset(pAlloc, 0, nByte); } } if( rc==SQLITE_OK ){ azCol = (char **)pAlloc; - pAlloc = (u8 *)&azCol[nDbCol]; + azDflt = (char**)&azCol[nDbCol]; + pAlloc = (u8 *)&azDflt[nDbCol]; abPK = (u8 *)pAlloc; pAlloc = &abPK[nDbCol]; if( pzTab ){ @@ -220871,11 +222081,21 @@ static int sessionTableInfo( } while( SQLITE_ROW==sqlite3_step(pStmt) ){ int nName = sqlite3_column_bytes(pStmt, 1); + int nDflt = sqlite3_column_bytes(pStmt, 4); const unsigned char *zName = sqlite3_column_text(pStmt, 1); + const unsigned char *zDflt = sqlite3_column_text(pStmt, 4); + if( zName==0 ) break; memcpy(pAlloc, zName, nName+1); azCol[i] = (char *)pAlloc; pAlloc += nName+1; + if( zDflt ){ + memcpy(pAlloc, zDflt, nDflt+1); + azDflt[i] = (char *)pAlloc; + pAlloc += nDflt+1; + }else{ + azDflt[i] = 0; + } abPK[i] = sqlite3_column_int(pStmt, 5); i++; } @@ -220886,14 +222106,11 @@ static int sessionTableInfo( ** free any allocation made. An error code will be returned in this case. */ if( rc==SQLITE_OK ){ - *pazCol = (const char **)azCol; + *pazCol = (const char**)azCol; + if( pazDflt ) *pazDflt = (const char**)azDflt; *pabPK = abPK; *pnCol = nDbCol; }else{ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; sessionFree(pSession, azCol); } if( pbRowid ) *pbRowid = bRowid; @@ -220902,10 +222119,9 @@ static int sessionTableInfo( } /* -** This function is only called from within a pre-update handler for a -** write to table pTab, part of session pSession. If this is the first -** write to this table, initalize the SessionTable.nCol, azCol[] and -** abPK[] arrays accordingly. +** This function is called to initialize the SessionTable.nCol, azCol[] +** abPK[] and azDflt[] members of SessionTable object pTab. If these +** fields are already initilialized, this function is a no-op. ** ** If an error occurs, an error code is stored in sqlite3_session.rc and ** non-zero returned. Or, if no error occurs but the table has no primary @@ -220913,15 +222129,22 @@ static int sessionTableInfo( ** indicate that updates on this table should be ignored. SessionTable.abPK ** is set to NULL in this case. */ -static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ +static int sessionInitTable( + sqlite3_session *pSession, /* Optional session handle */ + SessionTable *pTab, /* Table object to initialize */ + sqlite3 *db, /* Database handle to read schema from */ + const char *zDb /* Name of db - "main", "temp" etc. */ +){ + int rc = SQLITE_OK; + if( pTab->nCol==0 ){ u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); - pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, - pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK, - (pSession->bImplicitPK ? &pTab->bRowid : 0) + rc = sessionTableInfo(pSession, db, zDb, + pTab->zName, &pTab->nCol, 0, &pTab->azCol, &pTab->azDflt, &abPK, + ((pSession==0 || pSession->bImplicitPK) ? &pTab->bRowid : 0) ); - if( pSession->rc==SQLITE_OK ){ + if( rc==SQLITE_OK ){ int i; for(i=0; inCol; i++){ if( abPK[i] ){ @@ -220933,14 +222156,321 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ pTab->bStat1 = 1; } - if( pSession->bEnableSize ){ + if( pSession && pSession->bEnableSize ){ pSession->nMaxChangesetSize += ( 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName)+1 ); } } } - return (pSession->rc || pTab->abPK==0); + + if( pSession ){ + pSession->rc = rc; + return (rc || pTab->abPK==0); + } + return rc; +} + +/* +** Re-initialize table object pTab. +*/ +static int sessionReinitTable(sqlite3_session *pSession, SessionTable *pTab){ + int nCol = 0; + const char **azCol = 0; + const char **azDflt = 0; + u8 *abPK = 0; + int bRowid = 0; + + assert( pSession->rc==SQLITE_OK ); + + pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, + pTab->zName, &nCol, 0, &azCol, &azDflt, &abPK, + (pSession->bImplicitPK ? &bRowid : 0) + ); + if( pSession->rc==SQLITE_OK ){ + if( pTab->nCol>nCol || pTab->bRowid!=bRowid ){ + pSession->rc = SQLITE_SCHEMA; + }else{ + int ii; + int nOldCol = pTab->nCol; + for(ii=0; iinCol ){ + if( pTab->abPK[ii]!=abPK[ii] ){ + pSession->rc = SQLITE_SCHEMA; + } + }else if( abPK[ii] ){ + pSession->rc = SQLITE_SCHEMA; + } + } + + if( pSession->rc==SQLITE_OK ){ + const char **a = pTab->azCol; + pTab->azCol = azCol; + pTab->nCol = nCol; + pTab->azDflt = azDflt; + pTab->abPK = abPK; + azCol = a; + } + if( pSession->bEnableSize ){ + pSession->nMaxChangesetSize += (nCol - nOldCol); + pSession->nMaxChangesetSize += sessionVarintLen(nCol); + pSession->nMaxChangesetSize -= sessionVarintLen(nOldCol); + } + } + } + + sqlite3_free((char*)azCol); + return pSession->rc; +} + +/* +** Session-change object (*pp) contains an old.* record with fewer than +** nCol fields. This function updates it with the default values for +** the missing fields. +*/ +static void sessionUpdateOneChange( + sqlite3_session *pSession, /* For memory accounting */ + int *pRc, /* IN/OUT: Error code */ + SessionChange **pp, /* IN/OUT: Change object to update */ + int nCol, /* Number of columns now in table */ + sqlite3_stmt *pDflt /* SELECT */ +){ + SessionChange *pOld = *pp; + + while( pOld->nRecordFieldnRecordField; + int eType = sqlite3_column_type(pDflt, iField); + switch( eType ){ + case SQLITE_NULL: + nIncr = 1; + break; + case SQLITE_INTEGER: + case SQLITE_FLOAT: + nIncr = 9; + break; + default: { + int n = sqlite3_column_bytes(pDflt, iField); + nIncr = 1 + sessionVarintLen(n) + n; + assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); + break; + } + } + + nByte = nIncr + (sizeof(SessionChange) + pOld->nRecord); + pNew = sessionMalloc64(pSession, nByte); + if( pNew==0 ){ + *pRc = SQLITE_NOMEM; + return; + }else{ + memcpy(pNew, pOld, sizeof(SessionChange)); + pNew->aRecord = (u8*)&pNew[1]; + memcpy(pNew->aRecord, pOld->aRecord, pOld->nRecord); + pNew->aRecord[pNew->nRecord++] = (u8)eType; + switch( eType ){ + case SQLITE_INTEGER: { + i64 iVal = sqlite3_column_int64(pDflt, iField); + sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal); + pNew->nRecord += 8; + break; + } + + case SQLITE_FLOAT: { + double rVal = sqlite3_column_double(pDflt, iField); + i64 iVal = 0; + memcpy(&iVal, &rVal, sizeof(rVal)); + sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal); + pNew->nRecord += 8; + break; + } + + case SQLITE_TEXT: { + int n = sqlite3_column_bytes(pDflt, iField); + const char *z = (const char*)sqlite3_column_text(pDflt, iField); + pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n); + memcpy(&pNew->aRecord[pNew->nRecord], z, n); + pNew->nRecord += n; + break; + } + + case SQLITE_BLOB: { + int n = sqlite3_column_bytes(pDflt, iField); + const u8 *z = (const u8*)sqlite3_column_blob(pDflt, iField); + pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n); + memcpy(&pNew->aRecord[pNew->nRecord], z, n); + pNew->nRecord += n; + break; + } + + default: + assert( eType==SQLITE_NULL ); + break; + } + + sessionFree(pSession, pOld); + *pp = pOld = pNew; + pNew->nRecordField++; + pNew->nMaxSize += nIncr; + if( pSession ){ + pSession->nMaxChangesetSize += nIncr; + } + } + } +} + +/* +** Ensure that there is room in the buffer to append nByte bytes of data. +** If not, use sqlite3_realloc() to grow the buffer so that there is. +** +** If successful, return zero. Otherwise, if an OOM condition is encountered, +** set *pRc to SQLITE_NOMEM and return non-zero. +*/ +static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){ +#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1) + i64 nReq = p->nBuf + nByte; + if( *pRc==SQLITE_OK && nReq>p->nAlloc ){ + u8 *aNew; + i64 nNew = p->nAlloc ? p->nAlloc : 128; + + do { + nNew = nNew*2; + }while( nNewSESSION_MAX_BUFFER_SZ ){ + nNew = SESSION_MAX_BUFFER_SZ; + if( nNewaBuf, nNew); + if( 0==aNew ){ + *pRc = SQLITE_NOMEM; + }else{ + p->aBuf = aNew; + p->nAlloc = nNew; + } + } + return (*pRc!=SQLITE_OK); +} + + +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. Otherwise, append a string to the buffer. All bytes in the string +** up to (but not including) the nul-terminator are written to the buffer. +** +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before +** returning. +*/ +static void sessionAppendStr( + SessionBuffer *p, + const char *zStr, + int *pRc +){ + int nStr = sqlite3Strlen30(zStr); + if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ + memcpy(&p->aBuf[p->nBuf], zStr, nStr); + p->nBuf += nStr; + p->aBuf[p->nBuf] = 0x00; + } +} + +/* +** Format a string using printf() style formatting and then append it to the +** buffer using sessionAppendString(). +*/ +static void sessionAppendPrintf( + SessionBuffer *p, /* Buffer to append to */ + int *pRc, + const char *zFmt, + ... +){ + if( *pRc==SQLITE_OK ){ + char *zApp = 0; + va_list ap; + va_start(ap, zFmt); + zApp = sqlite3_vmprintf(zFmt, ap); + if( zApp==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + sessionAppendStr(p, zApp, pRc); + } + va_end(ap); + sqlite3_free(zApp); + } +} + +/* +** Prepare a statement against database handle db that SELECTs a single +** row containing the default values for each column in table pTab. For +** example, if pTab is declared as: +** +** CREATE TABLE pTab(a PRIMARY KEY, b DEFAULT 123, c DEFAULT 'abcd'); +** +** Then this function prepares and returns the SQL statement: +** +** SELECT NULL, 123, 'abcd'; +*/ +static int sessionPrepareDfltStmt( + sqlite3 *db, /* Database handle */ + SessionTable *pTab, /* Table to prepare statement for */ + sqlite3_stmt **ppStmt /* OUT: Statement handle */ +){ + SessionBuffer sql = {0,0,0}; + int rc = SQLITE_OK; + const char *zSep = " "; + int ii = 0; + + *ppStmt = 0; + sessionAppendPrintf(&sql, &rc, "SELECT"); + for(ii=0; iinCol; ii++){ + const char *zDflt = pTab->azDflt[ii] ? pTab->azDflt[ii] : "NULL"; + sessionAppendPrintf(&sql, &rc, "%s%s", zSep, zDflt); + zSep = ", "; + } + if( rc==SQLITE_OK ){ + rc = sqlite3_prepare_v2(db, (const char*)sql.aBuf, -1, ppStmt, 0); + } + sqlite3_free(sql.aBuf); + + return rc; +} + +/* +** Table pTab has one or more existing change-records with old.* records +** with fewer than pTab->nCol columns. This function updates all such +** change-records with the default values for the missing columns. +*/ +static int sessionUpdateChanges(sqlite3_session *pSession, SessionTable *pTab){ + sqlite3_stmt *pStmt = 0; + int rc = pSession->rc; + + rc = sessionPrepareDfltStmt(pSession->db, pTab, &pStmt); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + int ii = 0; + SessionChange **pp = 0; + for(ii=0; iinChange; ii++){ + for(pp=&pTab->apChange[ii]; *pp; pp=&((*pp)->pNext)){ + if( (*pp)->nRecordField!=pTab->nCol ){ + sessionUpdateOneChange(pSession, &rc, pp, pTab->nCol, pStmt); + } + } + } + } + + pSession->rc = rc; + rc = sqlite3_finalize(pStmt); + if( pSession->rc==SQLITE_OK ) pSession->rc = rc; + return pSession->rc; } /* @@ -221103,16 +222633,22 @@ static void sessionPreupdateOneChange( int iHash; int bNull = 0; int rc = SQLITE_OK; + int nExpect = 0; SessionStat1Ctx stat1 = {{0,0,0,0,0},0}; if( pSession->rc ) return; /* Load table details if required */ - if( sessionInitTable(pSession, pTab) ) return; + if( sessionInitTable(pSession, pTab, pSession->db, pSession->zDb) ) return; /* Check the number of columns in this xPreUpdate call matches the ** number of columns in the table. */ - if( (pTab->nCol-pTab->bRowid)!=pSession->hook.xCount(pSession->hook.pCtx) ){ + nExpect = pSession->hook.xCount(pSession->hook.pCtx); + if( (pTab->nCol-pTab->bRowid)nCol-pTab->bRowid)!=nExpect ){ pSession->rc = SQLITE_SCHEMA; return; } @@ -221189,7 +222725,7 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pC = (SessionChange *)sessionMalloc64(pSession, nByte); + pC = (SessionChange*)sessionMalloc64(pSession, nByte); if( !pC ){ rc = SQLITE_NOMEM; goto error_out; @@ -221222,6 +222758,7 @@ static void sessionPreupdateOneChange( if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){ pC->bIndirect = 1; } + pC->nRecordField = pTab->nCol; pC->nRecord = nByte; pC->op = op; pC->pNext = pTab->apChange[iHash]; @@ -221601,7 +223138,7 @@ SQLITE_API int sqlite3session_diff( /* Locate and if necessary initialize the target table object */ rc = sessionFindTable(pSession, zTbl, &pTo); if( pTo==0 ) goto diff_out; - if( sessionInitTable(pSession, pTo) ){ + if( sessionInitTable(pSession, pTo, pSession->db, pSession->zDb) ){ rc = pSession->rc; goto diff_out; } @@ -221614,7 +223151,7 @@ SQLITE_API int sqlite3session_diff( int bRowid = 0; u8 *abPK; const char **azCol = 0; - rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK, + rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, 0, &abPK, pSession->bImplicitPK ? &bRowid : 0 ); if( rc==SQLITE_OK ){ @@ -221729,6 +223266,7 @@ static void sessionDeleteTable(sqlite3_session *pSession, SessionTable *pList){ sessionFree(pSession, p); } } + sqlite3_finalize(pTab->pDfltStmt); sessionFree(pSession, (char*)pTab->azCol); /* cast works around VC++ bug */ sessionFree(pSession, pTab->apChange); sessionFree(pSession, pTab); @@ -221763,7 +223301,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){ /* Assert that all allocations have been freed and then free the ** session object itself. */ - assert( pSession->nMalloc==0 ); + // assert( pSession->nMalloc==0 ); sqlite3_free(pSession); } @@ -221834,48 +223372,6 @@ SQLITE_API int sqlite3session_attach( return rc; } -/* -** Ensure that there is room in the buffer to append nByte bytes of data. -** If not, use sqlite3_realloc() to grow the buffer so that there is. -** -** If successful, return zero. Otherwise, if an OOM condition is encountered, -** set *pRc to SQLITE_NOMEM and return non-zero. -*/ -static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){ -#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1) - i64 nReq = p->nBuf + nByte; - if( *pRc==SQLITE_OK && nReq>p->nAlloc ){ - u8 *aNew; - i64 nNew = p->nAlloc ? p->nAlloc : 128; - - do { - nNew = nNew*2; - }while( nNewSESSION_MAX_BUFFER_SZ ){ - nNew = SESSION_MAX_BUFFER_SZ; - if( nNewaBuf, nNew); - if( 0==aNew ){ - *pRc = SQLITE_NOMEM; - }else{ - p->aBuf = aNew; - p->nAlloc = nNew; - } - } - return (*pRc!=SQLITE_OK); -} - /* ** Append the value passed as the second argument to the buffer passed ** as the first. @@ -221944,27 +223440,6 @@ static void sessionAppendBlob( } } -/* -** This function is a no-op if *pRc is other than SQLITE_OK when it is -** called. Otherwise, append a string to the buffer. All bytes in the string -** up to (but not including) the nul-terminator are written to the buffer. -** -** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before -** returning. -*/ -static void sessionAppendStr( - SessionBuffer *p, - const char *zStr, - int *pRc -){ - int nStr = sqlite3Strlen30(zStr); - if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ - memcpy(&p->aBuf[p->nBuf], zStr, nStr); - p->nBuf += nStr; - p->aBuf[p->nBuf] = 0x00; - } -} - /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is ** called. Otherwise, append the string representation of integer iVal @@ -221983,27 +223458,6 @@ static void sessionAppendInteger( sessionAppendStr(p, aBuf, pRc); } -static void sessionAppendPrintf( - SessionBuffer *p, /* Buffer to append to */ - int *pRc, - const char *zFmt, - ... -){ - if( *pRc==SQLITE_OK ){ - char *zApp = 0; - va_list ap; - va_start(ap, zFmt); - zApp = sqlite3_vmprintf(zFmt, ap); - if( zApp==0 ){ - *pRc = SQLITE_NOMEM; - }else{ - sessionAppendStr(p, zApp, pRc); - } - va_end(ap); - sqlite3_free(zApp); - } -} - /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is ** called. Otherwise, append the string zStr enclosed in quotes (") and @@ -222494,26 +223948,16 @@ static int sessionGenerateChangeset( for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ const char *zName = pTab->zName; - int nCol = 0; /* Number of columns in table */ - u8 *abPK = 0; /* Primary key array */ - const char **azCol = 0; /* Table columns */ int i; /* Used to iterate through hash buckets */ sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ int nRewind = buf.nBuf; /* Initial size of write buffer */ int nNoop; /* Size of buffer after writing tbl header */ - int bRowid = 0; + int nOldCol = pTab->nCol; /* Check the table schema is still Ok. */ - rc = sessionTableInfo( - 0, db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK, - (pSession->bImplicitPK ? &bRowid : 0) - ); - if( rc==SQLITE_OK && ( - pTab->nCol!=nCol - || pTab->bRowid!=bRowid - || memcmp(abPK, pTab->abPK, nCol) - )){ - rc = SQLITE_SCHEMA; + rc = sessionReinitTable(pSession, pTab); + if( rc==SQLITE_OK && pTab->nCol!=nOldCol ){ + rc = sessionUpdateChanges(pSession, pTab); } /* Write a table header */ @@ -222521,8 +223965,8 @@ static int sessionGenerateChangeset( /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ - rc = sessionSelectStmt( - db, 0, pSession->zDb, zName, bRowid, nCol, azCol, abPK, &pSel + rc = sessionSelectStmt(db, 0, pSession->zDb, + zName, pTab->bRowid, pTab->nCol, pTab->azCol, pTab->abPK, &pSel ); } @@ -222531,22 +223975,22 @@ static int sessionGenerateChangeset( SessionChange *p; /* Used to iterate through changes */ for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ - rc = sessionSelectBind(pSel, nCol, abPK, p); + rc = sessionSelectBind(pSel, pTab->nCol, pTab->abPK, p); if( rc!=SQLITE_OK ) continue; if( sqlite3_step(pSel)==SQLITE_ROW ){ if( p->op==SQLITE_INSERT ){ int iCol; sessionAppendByte(&buf, SQLITE_INSERT, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); - for(iCol=0; iColnCol; iCol++){ sessionAppendCol(&buf, pSel, iCol, &rc); } }else{ - assert( abPK!=0 ); /* Because sessionSelectStmt() returned ok */ - rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK); + assert( pTab->abPK!=0 ); + rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, pTab->abPK); } }else if( p->op!=SQLITE_INSERT ){ - rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK); + rc = sessionAppendDelete(&buf, bPatchset, p, pTab->nCol,pTab->abPK); } if( rc==SQLITE_OK ){ rc = sqlite3_reset(pSel); @@ -222571,7 +224015,6 @@ static int sessionGenerateChangeset( if( buf.nBuf==nNoop ){ buf.nBuf = nRewind; } - sqlite3_free((char*)azCol); /* cast works around VC++ bug */ } } @@ -224700,7 +226143,7 @@ static int sessionChangesetApply( sqlite3changeset_pk(pIter, &abPK, 0); rc = sessionTableInfo(0, db, "main", zNew, - &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK, &sApply.bRowid + &sApply.nCol, &zTab, &sApply.azCol, 0, &sApply.abPK, &sApply.bRowid ); if( rc!=SQLITE_OK ) break; for(i=0; iflags & SQLITE_FkNoAction; + + if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ + db->flags |= ((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } + if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags ); } + + if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ + assert( db->flags & SQLITE_FkNoAction ); + db->flags &= ~((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } return rc; } @@ -224924,6 +226380,9 @@ struct sqlite3_changegroup { int rc; /* Error code */ int bPatch; /* True to accumulate patchsets */ SessionTable *pList; /* List of tables in current patch */ + + sqlite3 *db; /* Configured by changegroup_schema() */ + char *zDb; /* Configured by changegroup_schema() */ }; /* @@ -224944,6 +226403,7 @@ static int sessionChangeMerge( ){ SessionChange *pNew = 0; int rc = SQLITE_OK; + assert( aRec!=0 ); if( !pExist ){ pNew = (SessionChange *)sqlite3_malloc64(sizeof(SessionChange) + nRec); @@ -225109,6 +226569,114 @@ static int sessionChangeMerge( return rc; } +/* +** Check if a changeset entry with nCol columns and the PK array passed +** as the final argument to this function is compatible with SessionTable +** pTab. If so, return 1. Otherwise, if they are incompatible in some way, +** return 0. +*/ +static int sessionChangesetCheckCompat( + SessionTable *pTab, + int nCol, + u8 *abPK +){ + if( pTab->azCol && nColnCol ){ + int ii; + for(ii=0; iinCol; ii++){ + u8 bPK = (ii < nCol) ? abPK[ii] : 0; + if( pTab->abPK[ii]!=bPK ) return 0; + } + return 1; + } + return (pTab->nCol==nCol && 0==memcmp(abPK, pTab->abPK, nCol)); +} + +static int sessionChangesetExtendRecord( + sqlite3_changegroup *pGrp, + SessionTable *pTab, + int nCol, + int op, + const u8 *aRec, + int nRec, + SessionBuffer *pOut +){ + int rc = SQLITE_OK; + int ii = 0; + + assert( pTab->azCol ); + assert( nColnCol ); + + pOut->nBuf = 0; + if( op==SQLITE_INSERT || (op==SQLITE_DELETE && pGrp->bPatch==0) ){ + /* Append the missing default column values to the record. */ + sessionAppendBlob(pOut, aRec, nRec, &rc); + if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){ + rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt); + } + for(ii=nCol; rc==SQLITE_OK && iinCol; ii++){ + int eType = sqlite3_column_type(pTab->pDfltStmt, ii); + sessionAppendByte(pOut, eType, &rc); + switch( eType ){ + case SQLITE_FLOAT: + case SQLITE_INTEGER: { + i64 iVal; + if( eType==SQLITE_INTEGER ){ + iVal = sqlite3_column_int64(pTab->pDfltStmt, ii); + }else{ + double rVal = sqlite3_column_int64(pTab->pDfltStmt, ii); + memcpy(&iVal, &rVal, sizeof(i64)); + } + if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ + sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); + } + break; + } + + case SQLITE_BLOB: + case SQLITE_TEXT: { + int n = sqlite3_column_bytes(pTab->pDfltStmt, ii); + sessionAppendVarint(pOut, n, &rc); + if( eType==SQLITE_TEXT ){ + const u8 *z = (const u8*)sqlite3_column_text(pTab->pDfltStmt, ii); + sessionAppendBlob(pOut, z, n, &rc); + }else{ + const u8 *z = (const u8*)sqlite3_column_blob(pTab->pDfltStmt, ii); + sessionAppendBlob(pOut, z, n, &rc); + } + break; + } + + default: + assert( eType==SQLITE_NULL ); + break; + } + } + }else if( op==SQLITE_UPDATE ){ + /* Append missing "undefined" entries to the old.* record. And, if this + ** is an UPDATE, to the new.* record as well. */ + int iOff = 0; + if( pGrp->bPatch==0 ){ + for(ii=0; iinCol-nCol); ii++){ + sessionAppendByte(pOut, 0x00, &rc); + } + } + + sessionAppendBlob(pOut, &aRec[iOff], nRec-iOff, &rc); + for(ii=0; ii<(pTab->nCol-nCol); ii++){ + sessionAppendByte(pOut, 0x00, &rc); + } + }else{ + assert( op==SQLITE_DELETE && pGrp->bPatch ); + sessionAppendBlob(pOut, aRec, nRec, &rc); + } + + return rc; +} + /* ** Add all changes in the changeset traversed by the iterator passed as ** the first argument to the changegroup hash tables. @@ -225122,6 +226690,7 @@ static int sessionChangesetToHash( int nRec; int rc = SQLITE_OK; SessionTable *pTab = 0; + SessionBuffer rec = {0, 0, 0}; while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){ const char *zNew; @@ -225133,6 +226702,9 @@ static int sessionChangesetToHash( SessionChange *pExist = 0; SessionChange **pp; + /* Ensure that only changesets, or only patchsets, but not a mixture + ** of both, are being combined. It is an error to try to combine a + ** changeset and a patchset. */ if( pGrp->pList==0 ){ pGrp->bPatch = pIter->bPatchset; }else if( pIter->bPatchset!=pGrp->bPatch ){ @@ -225165,18 +226737,38 @@ static int sessionChangesetToHash( pTab->zName = (char*)&pTab->abPK[nCol]; memcpy(pTab->zName, zNew, nNew+1); + if( pGrp->db ){ + pTab->nCol = 0; + rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); + if( rc ){ + assert( pTab->azCol==0 ); + sqlite3_free(pTab); + break; + } + } + /* The new object must be linked on to the end of the list, not ** simply added to the start of it. This is to ensure that the ** tables within the output of sqlite3changegroup_output() are in ** the right order. */ for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext); *ppTab = pTab; - }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){ + } + + if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ rc = SQLITE_SCHEMA; break; } } + if( nColnCol ){ + assert( pGrp->db ); + rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, &rec); + if( rc ) break; + aRec = rec.aBuf; + nRec = rec.nBuf; + } + if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; @@ -225214,6 +226806,7 @@ static int sessionChangesetToHash( } } + sqlite3_free(rec.aBuf); if( rc==SQLITE_OK ) rc = pIter->rc; return rc; } @@ -225300,6 +226893,31 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp){ return rc; } +/* +** Provide a database schema to the changegroup object. +*/ +SQLITE_API int sqlite3changegroup_schema( + sqlite3_changegroup *pGrp, + sqlite3 *db, + const char *zDb +){ + int rc = SQLITE_OK; + + if( pGrp->pList || pGrp->db ){ + /* Cannot add a schema after one or more calls to sqlite3changegroup_add(), + ** or after sqlite3changegroup_schema() has already been called. */ + rc = SQLITE_MISUSE; + }else{ + pGrp->zDb = sqlite3_mprintf("%s", zDb); + if( pGrp->zDb==0 ){ + rc = SQLITE_NOMEM; + }else{ + pGrp->db = db; + } + } + return rc; +} + /* ** Add the changeset currently stored in buffer pData, size nData bytes, ** to changeset-group p. @@ -225363,6 +226981,7 @@ SQLITE_API int sqlite3changegroup_output_strm( */ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ + sqlite3_free(pGrp->zDb); sessionDeleteTable(0, pGrp->pList); sqlite3_free(pGrp); } @@ -228868,15 +230487,19 @@ static int fts5CInstIterInit( */ typedef struct HighlightContext HighlightContext; struct HighlightContext { - CInstIter iter; /* Coalesced Instance Iterator */ - int iPos; /* Current token offset in zIn[] */ + /* Constant parameters to fts5HighlightCb() */ int iRangeStart; /* First token to include */ int iRangeEnd; /* If non-zero, last token to include */ const char *zOpen; /* Opening highlight */ const char *zClose; /* Closing highlight */ const char *zIn; /* Input text */ int nIn; /* Size of input text in bytes */ - int iOff; /* Current offset within zIn[] */ + + /* Variables modified by fts5HighlightCb() */ + CInstIter iter; /* Coalesced Instance Iterator */ + int iPos; /* Current token offset in zIn[] */ + int iOff; /* Have copied up to this offset in zIn[] */ + int bOpen; /* True if highlight is open */ char *zOut; /* Output value */ }; @@ -228909,8 +230532,8 @@ static int fts5HighlightCb( int tflags, /* Mask of FTS5_TOKEN_* flags */ const char *pToken, /* Buffer containing token */ int nToken, /* Size of token in bytes */ - int iStartOff, /* Start offset of token */ - int iEndOff /* End offset of token */ + int iStartOff, /* Start byte offset of token */ + int iEndOff /* End byte offset of token */ ){ HighlightContext *p = (HighlightContext*)pContext; int rc = SQLITE_OK; @@ -228926,30 +230549,47 @@ static int fts5HighlightCb( if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff; } - if( iPos==p->iter.iStart ){ + /* If the parenthesis is open, and this token is not part of the current + ** phrase, and the starting byte offset of this token is past the point + ** that has currently been copied into the output buffer, close the + ** parenthesis. */ + if( p->bOpen + && (iPos<=p->iter.iStart || p->iter.iStart<0) + && iStartOff>p->iOff + ){ + fts5HighlightAppend(&rc, p, p->zClose, -1); + p->bOpen = 0; + } + + /* If this is the start of a new phrase, and the highlight is not open: + ** + ** * copy text from the input up to the start of the phrase, and + ** * open the highlight. + */ + if( iPos==p->iter.iStart && p->bOpen==0 ){ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iStartOff - p->iOff); fts5HighlightAppend(&rc, p, p->zOpen, -1); p->iOff = iStartOff; + p->bOpen = 1; } if( iPos==p->iter.iEnd ){ - if( p->iRangeEnd>=0 && p->iter.iStartiRangeStart ){ + if( p->bOpen==0 ){ + assert( p->iRangeEnd>=0 ); fts5HighlightAppend(&rc, p, p->zOpen, -1); + p->bOpen = 1; } fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); - fts5HighlightAppend(&rc, p, p->zClose, -1); p->iOff = iEndOff; + if( rc==SQLITE_OK ){ rc = fts5CInstIterNext(&p->iter); } } - if( p->iRangeEnd>=0 && iPos==p->iRangeEnd ){ + if( iPos==p->iRangeEnd ){ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); p->iOff = iEndOff; - if( iPos>=p->iter.iStart && iPositer.iEnd ){ - fts5HighlightAppend(&rc, p, p->zClose, -1); - } } return rc; @@ -228990,6 +230630,9 @@ static void fts5HighlightFunction( if( rc==SQLITE_OK ){ rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); } + if( ctx.bOpen ){ + fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); + } fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff); if( rc==SQLITE_OK ){ @@ -229268,6 +230911,9 @@ static void fts5SnippetFunction( if( rc==SQLITE_OK ){ rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); } + if( ctx.bOpen ){ + fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); + } if( ctx.iRangeEnd>=(nColSize-1) ){ fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff); }else{ @@ -237539,7 +239185,6 @@ static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){ assert_nc( i2!=0 ); pRes->bTermEq = 1; if( p1->iRowid==p2->iRowid ){ - p1->bDel = p2->bDel; return i2; } res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : +1; @@ -237907,7 +239552,7 @@ static Fts5Iter *fts5MultiIterAlloc( int nSeg ){ Fts5Iter *pNew; - int nSlot; /* Power of two >= nSeg */ + i64 nSlot; /* Power of two >= nSeg */ for(nSlot=2; nSlotpLeaf->szLeaf; u64 iDelta = 0; - u64 iNextDelta = 0; int iNextOff = 0; int iOff = 0; int nIdx = 0; @@ -239691,7 +241335,6 @@ static void fts5DoSecureDelete( int bLastInDoclist = 0; int iIdx = 0; int iStart = 0; - int iKeyOff = 0; int iDelKeyOff = 0; /* Offset of deleted key, if any */ nIdx = nPg-iPgIdx; @@ -239716,10 +241359,21 @@ static void fts5DoSecureDelete( ** This block sets the following variables: ** ** iStart: + ** The offset of the first byte of the rowid or delta-rowid + ** value for the doclist entry being removed. + ** ** iDelta: + ** The value of the rowid or delta-rowid value for the doclist + ** entry being removed. + ** + ** iNextOff: + ** The offset of the next entry following the position list + ** for the one being removed. If the position list for this + ** entry overflows onto the next leaf page, this value will be + ** greater than pLeaf->szLeaf. */ { - int iSOP; + int iSOP; /* Start-Of-Position-list */ if( pSeg->iLeafPgno==pSeg->iTermLeafPgno ){ iStart = pSeg->iTermLeafOffset; }else{ @@ -239755,47 +241409,75 @@ static void fts5DoSecureDelete( } iOff = iStart; - if( iNextOff>=iPgIdx ){ - int pgno = pSeg->iLeafPgno+1; - fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); - iNextOff = iPgIdx; - }else{ - /* Set bLastInDoclist to true if the entry being removed is the last - ** in its doclist. */ - for(iIdx=0, iKeyOff=0; iIdxbDel==0 ){ + if( iNextOff>=iPgIdx ){ + int pgno = pSeg->iLeafPgno+1; + fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); + iNextOff = iPgIdx; + }else{ + /* Loop through the page-footer. If iNextOff (offset of the + ** entry following the one we are removing) is equal to the + ** offset of a key on this page, then the entry is the last + ** in its doclist. */ + int iKeyOff = 0; + for(iIdx=0; iIdxbDel ){ + iOff += sqlite3Fts5PutVarint(&aPg[iOff], iDelta); + aPg[iOff++] = 0x01; + }else if( bLastInDoclist==0 ){ if( iNextOff!=iPgIdx ){ + u64 iNextDelta = 0; iNextOff += fts5GetVarint(&aPg[iNextOff], &iNextDelta); iOff += sqlite3Fts5PutVarint(&aPg[iOff], iDelta + iNextDelta); } }else if( - iStart==pSeg->iTermLeafOffset && pSeg->iLeafPgno==pSeg->iTermLeafPgno + pSeg->iLeafPgno==pSeg->iTermLeafPgno + && iStart==pSeg->iTermLeafOffset ){ /* The entry being removed was the only position list in its ** doclist. Therefore the term needs to be removed as well. */ int iKey = 0; - for(iIdx=0, iKeyOff=0; iIdx(u32)iStart ) break; iKeyOff += iVal; } + assert_nc( iKey>=1 ); + /* Set iDelKeyOff to the value of the footer entry to remove from + ** the page. */ iDelKeyOff = iOff = iKeyOff; + if( iNextOff!=iPgIdx ){ + /* This is the only position-list associated with the term, and there + ** is another term following it on this page. So the subsequent term + ** needs to be moved to replace the term associated with the entry + ** being removed. */ int nPrefix = 0; int nSuffix = 0; int nPrefix2 = 0; @@ -239874,6 +241556,15 @@ static void fts5DoSecureDelete( } } + /* Assuming no error has occurred, this block does final edits to the + ** leaf page before writing it back to disk. Input variables are: + ** + ** nPg: Total initial size of leaf page. + ** iPgIdx: Initial offset of page footer. + ** + ** iOff: Offset to move data to + ** iNextOff: Offset to move data from + */ if( p->rc==SQLITE_OK ){ const int nMove = nPg - iNextOff; /* Number of bytes to move */ int nShift = iNextOff - iOff; /* Distance to move them */ @@ -240074,10 +241765,16 @@ static void fts5FlushOneHash(Fts5Index *p){ fts5WriteFlushLeaf(p, &writer); } }else{ - int bDummy; - int nPos; - int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy); - nCopy += nPos; + int bDel = 0; + int nPos = 0; + int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDel); + if( bDel && bSecureDelete ){ + fts5BufferAppendVarint(&p->rc, pBuf, nPos*2); + iOff += nCopy; + nCopy = nPos; + }else{ + nCopy += nPos; + } if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){ /* The entire poslist will fit on the current leaf. So copy ** it in one go. */ @@ -240115,7 +241812,6 @@ static void fts5FlushOneHash(Fts5Index *p){ assert( pBuf->n<=pBuf->nSpace ); if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash); } - sqlite3Fts5HashClear(pHash); fts5WriteFinish(p, &writer, &pgnoLast); assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 ); @@ -240148,7 +241844,6 @@ static void fts5FlushOneHash(Fts5Index *p){ fts5IndexCrisismerge(p, &pStruct); fts5StructureWrite(p, pStruct); fts5StructureRelease(pStruct); - p->nContentlessDelete = 0; } /* @@ -240159,8 +241854,12 @@ static void fts5IndexFlush(Fts5Index *p){ if( p->nPendingData || p->nContentlessDelete ){ assert( p->pHash ); fts5FlushOneHash(p); - p->nPendingData = 0; - p->nPendingRow = 0; + if( p->rc==SQLITE_OK ){ + sqlite3Fts5HashClear(p->pHash); + p->nPendingData = 0; + p->nPendingRow = 0; + p->nContentlessDelete = 0; + } } } @@ -242902,7 +244601,8 @@ static int sqlite3Fts5IndexInit(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; rc = sqlite3_create_module(db, "fts5_structure", &fts5structure_module, 0); } @@ -243041,6 +244741,8 @@ struct Fts5FullTable { Fts5Storage *pStorage; /* Document store */ Fts5Global *pGlobal; /* Global (connection wide) data */ Fts5Cursor *pSortCsr; /* Sort data from this cursor */ + int iSavepoint; /* Successful xSavepoint()+1 */ + int bInSavepoint; #ifdef SQLITE_DEBUG struct Fts5TransactionState ts; #endif @@ -243329,6 +245031,13 @@ static int fts5InitVtab( pConfig->pzErrmsg = 0; } + if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ + rc = sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, (int)1); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + } + if( rc!=SQLITE_OK ){ fts5FreeVtab(pTab); pTab = 0; @@ -244278,9 +245987,8 @@ static int fts5FilterMethod( pCsr->pExpr = pTab->pSortCsr->pExpr; rc = fts5CursorFirst(pTab, pCsr, bDesc); }else if( pCsr->pExpr ){ - if( rc==SQLITE_OK ){ - rc = fts5CursorParseRank(pConfig, pCsr, pRank); - } + assert( rc==SQLITE_OK ); + rc = fts5CursorParseRank(pConfig, pCsr, pRank); if( rc==SQLITE_OK ){ if( bOrderByRank ){ pCsr->ePlan = FTS5_PLAN_SORTED_MATCH; @@ -244451,6 +246159,7 @@ static int fts5SpecialInsert( Fts5Config *pConfig = pTab->p.pConfig; int rc = SQLITE_OK; int bError = 0; + int bLoadConfig = 0; if( 0==sqlite3_stricmp("delete-all", zCmd) ){ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ @@ -244462,6 +246171,7 @@ static int fts5SpecialInsert( }else{ rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage); } + bLoadConfig = 1; }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){ if( pConfig->eContent==FTS5_CONTENT_NONE ){ fts5SetVtabError(pTab, @@ -244471,6 +246181,7 @@ static int fts5SpecialInsert( }else{ rc = sqlite3Fts5StorageRebuild(pTab->pStorage); } + bLoadConfig = 1; }else if( 0==sqlite3_stricmp("optimize", zCmd) ){ rc = sqlite3Fts5StorageOptimize(pTab->pStorage); }else if( 0==sqlite3_stricmp("merge", zCmd) ){ @@ -244483,6 +246194,8 @@ static int fts5SpecialInsert( }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){ pConfig->bPrefixIndex = sqlite3_value_int(pVal); #endif + }else if( 0==sqlite3_stricmp("flush", zCmd) ){ + rc = sqlite3Fts5FlushToDisk(&pTab->p); }else{ rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); if( rc==SQLITE_OK ){ @@ -244496,6 +246209,12 @@ static int fts5SpecialInsert( } } } + + if( rc==SQLITE_OK && bLoadConfig ){ + pTab->p.pConfig->iCookie--; + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + } + return rc; } @@ -244614,7 +246333,7 @@ static int fts5UpdateMethod( assert( nArg!=1 || eType0==SQLITE_INTEGER ); /* Filter out attempts to run UPDATE or DELETE on contentless tables. - ** This is not suported. Except - DELETE is supported if the CREATE + ** This is not suported. Except - they are both supported if the CREATE ** VIRTUAL TABLE statement contained "contentless_delete=1". */ if( eType0==SQLITE_INTEGER && pConfig->eContent==FTS5_CONTENT_NONE @@ -244643,7 +246362,8 @@ static int fts5UpdateMethod( } else if( eType0!=SQLITE_INTEGER ){ - /* If this is a REPLACE, first remove the current entry (if any) */ + /* An INSERT statement. If the conflict-mode is REPLACE, first remove + ** the current entry (if any). */ if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); @@ -245517,8 +247237,12 @@ static int fts5RenameMethod( sqlite3_vtab *pVtab, /* Virtual table handle */ const char *zName /* New name of table */ ){ + int rc; Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - return sqlite3Fts5StorageRename(pTab->pStorage, zName); + pTab->bInSavepoint = 1; + rc = sqlite3Fts5StorageRename(pTab->pStorage, zName); + pTab->bInSavepoint = 0; + return rc; } static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ @@ -245532,9 +247256,29 @@ static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ ** Flush the contents of the pending-terms table to disk. */ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ - UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ - fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_SAVEPOINT, iSavepoint); - return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; + int rc = SQLITE_OK; + char *zSql = 0; + fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); + + if( pTab->bInSavepoint==0 ){ + zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", + pTab->p.pConfig->zDb, pTab->p.pConfig->zName, pTab->p.pConfig->zName + ); + if( zSql ){ + pTab->bInSavepoint = 1; + rc = sqlite3_exec(pTab->p.pConfig->db, zSql, 0, 0, 0); + pTab->bInSavepoint = 0; + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint+1; + } + } + + return rc; } /* @@ -245543,9 +247287,16 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ ** This is a no-op. */ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ - UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ - fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_RELEASE, iSavepoint); - return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; + int rc = SQLITE_OK; + fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint); + if( (iSavepoint+1)iSavepoint ){ + rc = sqlite3Fts5FlushToDisk(&pTab->p); + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint; + } + } + return rc; } /* @@ -245555,11 +247306,14 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ */ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ + int rc = SQLITE_OK; fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); fts5TripCursors(pTab); pTab->p.pConfig->pgsz = 0; - return sqlite3Fts5StorageRollback(pTab->pStorage); + if( (iSavepoint+1)<=pTab->iSavepoint ){ + rc = sqlite3Fts5StorageRollback(pTab->pStorage); + } + return rc; } /* @@ -245761,7 +247515,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2023-10-10 12:14:04 4310099cce5a487035fa535dd3002c59ac7f1d1bec68d7cf317fd3e769484790", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301", -1, SQLITE_TRANSIENT); } /* @@ -245779,9 +247533,46 @@ static int fts5ShadowName(const char *zName){ return 0; } +/* +** Run an integrity check on the FTS5 data structures. Return a string +** if anything is found amiss. Return a NULL pointer if everything is +** OK. +*/ +static int fts5Integrity( + sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */ + const char *zSchema, /* Name of schema in which this table lives */ + const char *zTabname, /* Name of the table itself */ + int isQuick, /* True if this is a quick-check */ + char **pzErr /* Write error message here */ +){ + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; + Fts5Config *pConfig = pTab->p.pConfig; + char *zSql; + char *zErr = 0; + int rc; + assert( pzErr!=0 && *pzErr==0 ); + UNUSED_PARAM(isQuick); + zSql = sqlite3_mprintf( + "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", + zSchema, zTabname, pConfig->zName); + if( zSql==0 ) return SQLITE_NOMEM; + rc = sqlite3_exec(pConfig->db, zSql, 0, 0, &zErr); + sqlite3_free(zSql); + if( (rc&0xff)==SQLITE_CORRUPT ){ + *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", + zSchema, zTabname); + }else if( rc!=SQLITE_OK ){ + *pzErr = sqlite3_mprintf("unable to validate the inverted index for" + " FTS5 table %s.%s: %s", + zSchema, zTabname, zErr); + } + sqlite3_free(zErr); + return SQLITE_OK; +} + static int fts5Init(sqlite3 *db){ static const sqlite3_module fts5Mod = { - /* iVersion */ 3, + /* iVersion */ 4, /* xCreate */ fts5CreateMethod, /* xConnect */ fts5ConnectMethod, /* xBestIndex */ fts5BestIndexMethod, @@ -245804,7 +247595,8 @@ static int fts5Init(sqlite3 *db){ /* xSavepoint */ fts5SavepointMethod, /* xRelease */ fts5ReleaseMethod, /* xRollbackTo */ fts5RollbackToMethod, - /* xShadowName */ fts5ShadowName + /* xShadowName */ fts5ShadowName, + /* xIntegrity */ fts5Integrity }; int rc; @@ -247081,7 +248873,9 @@ static int sqlite3Fts5StorageSync(Fts5Storage *p){ i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db); if( p->bTotalsValid ){ rc = fts5StorageSaveTotals(p); - p->bTotalsValid = 0; + if( rc==SQLITE_OK ){ + p->bTotalsValid = 0; + } } if( rc==SQLITE_OK ){ rc = sqlite3Fts5IndexSync(p->pIndex); @@ -250449,7 +252243,8 @@ static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){ /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; void *p = (void*)pGlobal; @@ -250778,6 +252573,7 @@ static sqlite3_module stmtModule = { 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index 037611348d0..d4f1c810cef 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.43.2" -#define SQLITE_VERSION_NUMBER 3043002 -#define SQLITE_SOURCE_ID "2023-10-10 12:14:04 4310099cce5a487035fa535dd3002c59ac7f1d1bec68d7cf317fd3e769484790" +#define SQLITE_VERSION "3.44.0" +#define SQLITE_VERSION_NUMBER 3044000 +#define SQLITE_SOURCE_ID "2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -2127,7 +2127,7 @@ struct sqlite3_mem_methods { ** is stored in each sorted record and the required column values loaded ** from the database as records are returned in sorted order. The default ** value for this option is to never use this optimization. Specifying a -** negative value for this option restores the default behaviour. +** negative value for this option restores the default behavior. ** This option is only available if SQLite is compiled with the ** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. ** @@ -2302,7 +2302,7 @@ struct sqlite3_mem_methods { ** database handle, SQLite checks if this will mean that there are now no ** connections at all to the database. If so, it performs a checkpoint ** operation before closing the connection. This option may be used to -** override this behaviour. The first parameter passed to this operation +** override this behavior. The first parameter passed to this operation ** is an integer - positive to disable checkpoints-on-close, or zero (the ** default) to enable them, and negative to leave the setting unchanged. ** The second parameter is a pointer to an integer @@ -3955,6 +3955,7 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** text that describes the error, as either UTF-8 or UTF-16 respectively. +** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by @@ -5325,6 +5326,7 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); */ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); + /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines} @@ -5879,32 +5881,32 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to -** associate metadata with argument values. If the same value is passed to -** multiple invocations of the same SQL function during query execution, under -** some circumstances the associated metadata may be preserved. An example -** of where this might be useful is in a regular-expression matching -** function. The compiled version of the regular expression can be stored as -** metadata associated with the pattern string. +** associate auxiliary data with argument values. If the same argument +** value is passed to multiple invocations of the same SQL function during +** query execution, under some circumstances the associated auxiliary data +** might be preserved. An example of where this might be useful is in a +** regular-expression matching function. The compiled version of the regular +** expression can be stored as auxiliary data associated with the pattern string. ** Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data ** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument ** value to the application-defined function. ^N is zero for the left-most -** function argument. ^If there is no metadata +** function argument. ^If there is no auxiliary data ** associated with the function argument, the sqlite3_get_auxdata(C,N) interface ** returns a NULL pointer. ** -** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th -** argument of the application-defined function. ^Subsequent +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the +** N-th argument of the application-defined function. ^Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent -** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or -** NULL if the metadata has been discarded. +** sqlite3_set_auxdata(C,N,P,X) call if the auxiliary data is still valid or +** NULL if the auxiliary data has been discarded. ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, ** SQLite will invoke the destructor function X with parameter P exactly -** once, when the metadata is discarded. -** SQLite is free to discard the metadata at any time, including:
      +** once, when the auxiliary data is discarded. +** SQLite is free to discard the auxiliary data at any time, including:
        **
      • ^(when the corresponding function parameter changes)^, or **
      • ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the ** SQL statement)^, or @@ -5920,7 +5922,7 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** function implementation should not make any use of P after ** sqlite3_set_auxdata() has been called. ** -** ^(In practice, metadata is preserved between function calls for +** ^(In practice, auxiliary data is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** @@ -5930,10 +5932,67 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** ** These routines must be called from the same thread in which ** the SQL function is running. +** +** See also: [sqlite3_get_clientdata()] and [sqlite3_set_clientdata()]. */ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); +/* +** CAPI3REF: Database Connection Client Data +** METHOD: sqlite3 +** +** These functions are used to associate one or more named pointers +** with a [database connection]. +** A call to sqlite3_set_clientdata(D,N,P,X) causes the pointer P +** to be attached to [database connection] D using name N. Subsequent +** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P +** or a NULL pointer if there were no prior calls to +** sqlite3_set_clientdata() with the same values of D and N. +** Names are compared using strcmp() and are thus case sensitive. +** +** If P and X are both non-NULL, then the destructor X is invoked with +** argument P on the first of the following occurrences: +**
          +**
        • An out-of-memory error occurs during the call to +** sqlite3_set_clientdata() which attempts to register pointer P. +**
        • A subsequent call to sqlite3_set_clientdata(D,N,P,X) is made +** with the same D and N parameters. +**
        • The database connection closes. SQLite does not make any guarantees +** about the order in which destructors are called, only that all +** destructors will be called exactly once at some point during the +** database connection closing process. +**
        +** +** SQLite does not do anything with client data other than invoke +** destructors on the client data at the appropriate time. The intended +** use for client data is to provide a mechanism for wrapper libraries +** to store additional information about an SQLite database connection. +** +** There is no limit (other than available memory) on the number of different +** client data pointers (with different names) that can be attached to a +** single database connection. However, the implementation is optimized +** for the case of having only one or two different client data names. +** Applications and wrapper libraries are discouraged from using more than +** one client data name each. +** +** There is no way to enumerate the client data pointers +** associated with a database connection. The N parameter can be thought +** of as a secret key such that only code that knows the secret key is able +** to access the associated data. +** +** Security Warning: These interfaces should not be exposed in scripting +** languages or in other circumstances where it might be possible for an +** an attacker to invoke them. Any agent that can invoke these interfaces +** can probably also take control of the process. +** +** Database connection client data is only available for SQLite +** version 3.44.0 ([dateof:3.44.0]) and later. +** +** See also: [sqlite3_set_auxdata()] and [sqlite3_get_auxdata()]. +*/ +SQLITE_API void *sqlite3_get_clientdata(sqlite3*,const char*); +SQLITE_API int sqlite3_set_clientdata(sqlite3*, const char*, void*, void(*)(void*)); /* ** CAPI3REF: Constants Defining Special Destructor Behavior @@ -6566,7 +6625,7 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); /* -** CAPI3REF: Allowed return values from [sqlite3_txn_state()] +** CAPI3REF: Allowed return values from sqlite3_txn_state() ** KEYWORDS: {transaction state} ** ** These constants define the current transaction state of a database file. @@ -6698,7 +6757,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** ^Each call to the sqlite3_autovacuum_pages() interface overrides all ** previous invocations for that database connection. ^If the callback ** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer, -** then the autovacuum steps callback is cancelled. The return value +** then the autovacuum steps callback is canceled. The return value ** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might ** be some other error code if something goes wrong. The current ** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other @@ -7217,6 +7276,10 @@ struct sqlite3_module { /* The methods above are in versions 1 and 2 of the sqlite_module object. ** Those below are for version 3 and greater. */ int (*xShadowName)(const char*); + /* The methods above are in versions 1 through 3 of the sqlite_module object. + ** Those below are for version 4 and greater. */ + int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema, + const char *zTabName, int mFlags, char **pzErr); }; /* @@ -7704,7 +7767,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); ** code is returned and the transaction rolled back. ** ** Calling this function with an argument that is not a NULL pointer or an -** open blob handle results in undefined behaviour. ^Calling this routine +** open blob handle results in undefined behavior. ^Calling this routine ** with a null pointer (such as would be returned by a failed call to ** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function ** is passed a valid open blob handle, the values returned by the @@ -8184,6 +8247,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */ +#define SQLITE_TESTCTRL_FK_NO_ACTION 7 #define SQLITE_TESTCTRL_BITVEC_TEST 8 #define SQLITE_TESTCTRL_FAULT_INSTALL 9 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 @@ -9245,8 +9309,8 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is cancelled. ^The blocked connections -** unlock-notify callback may also be cancelled by closing the blocked +** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** ** The unlock-notify callback is not reentrant. If an application invokes @@ -10549,6 +10613,13 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy ** of the database exists. ** +** After the call, if the SQLITE_SERIALIZE_NOCOPY bit had been set, +** the returned buffer content will remain accessible and unchanged +** until either the next write operation on the connection or when +** the connection is closed, and applications must not modify the +** buffer. If the bit had been clear, the returned buffer will not +** be accessed by SQLite after the call. +** ** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the ** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory ** allocation error occurs. @@ -10597,6 +10668,9 @@ SQLITE_API unsigned char *sqlite3_serialize( ** SQLite will try to increase the buffer size using sqlite3_realloc64() ** if writes on the database cause it to grow larger than M bytes. ** +** Applications must not modify the buffer P or invalidate it before +** the database connection D is closed. +** ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. @@ -10605,6 +10679,13 @@ SQLITE_API unsigned char *sqlite3_serialize( ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. ** +** The deserialized database should not be in [WAL mode]. If the database +** is in WAL mode, then any attempt to use the database file will result +** in an [SQLITE_CANTOPEN] error. The application can set the +** [file format version numbers] (bytes 18 and 19) of the input database P +** to 0x01 prior to invoking sqlite3_deserialize(D,S,P,N,M,F) to force the +** database file into rollback mode and work around this limitation. +** ** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then ** [sqlite3_free()] is invoked on argument P prior to returning. @@ -11677,6 +11758,18 @@ SQLITE_API int sqlite3changeset_concat( ); +/* +** CAPI3REF: Upgrade the Schema of a Changeset/Patchset +*/ +SQLITE_API int sqlite3changeset_upgrade( + sqlite3 *db, + const char *zDb, + int nIn, const void *pIn, /* Input changeset */ + int *pnOut, void **ppOut /* OUT: Inverse of input */ +); + + + /* ** CAPI3REF: Changegroup Handle ** @@ -11723,6 +11816,38 @@ typedef struct sqlite3_changegroup sqlite3_changegroup; */ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); +/* +** CAPI3REF: Add a Schema to a Changegroup +** METHOD: sqlite3_changegroup_schema +** +** This method may be used to optionally enforce the rule that the changesets +** added to the changegroup handle must match the schema of database zDb +** ("main", "temp", or the name of an attached database). If +** sqlite3changegroup_add() is called to add a changeset that is not compatible +** with the configured schema, SQLITE_SCHEMA is returned and the changegroup +** object is left in an undefined state. +** +** A changeset schema is considered compatible with the database schema in +** the same way as for sqlite3changeset_apply(). Specifically, for each +** table in the changeset, there exists a database table with: +** +**
          +**
        • The name identified by the changeset, and +**
        • at least as many columns as recorded in the changeset, and +**
        • the primary key columns in the same position as recorded in +** the changeset. +**
        +** +** The output of the changegroup object always has the same schema as the +** database nominated using this function. In cases where changesets passed +** to sqlite3changegroup_add() have fewer columns than the corresponding table +** in the database schema, these are filled in using the default column +** values from the database schema. This makes it possible to combined +** changesets that have different numbers of columns for a single table +** within a changegroup, provided that they are otherwise compatible. +*/ +SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb); + /* ** CAPI3REF: Add A Changeset To A Changegroup ** METHOD: sqlite3_changegroup @@ -11791,13 +11916,18 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); ** If the new changeset contains changes to a table that is already present ** in the changegroup, then the number of columns and the position of the ** primary key columns for the table must be consistent. If this is not the -** case, this function fails with SQLITE_SCHEMA. If the input changeset -** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is -** returned. Or, if an out-of-memory condition occurs during processing, this -** function returns SQLITE_NOMEM. In all cases, if an error occurs the state -** of the final contents of the changegroup is undefined. +** case, this function fails with SQLITE_SCHEMA. Except, if the changegroup +** object has been configured with a database schema using the +** sqlite3changegroup_schema() API, then it is possible to combine changesets +** with different numbers of columns for a single table, provided that +** they are otherwise compatible. ** -** If no error occurs, SQLITE_OK is returned. +** If the input changeset appears to be corrupt and the corruption is +** detected, SQLITE_CORRUPT is returned. Or, if an out-of-memory condition +** occurs during processing, this function returns SQLITE_NOMEM. +** +** In all cases, if an error occurs the state of the final contents of the +** changegroup is undefined. If no error occurs, SQLITE_OK is returned. */ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); @@ -12062,10 +12192,17 @@ SQLITE_API int sqlite3changeset_apply_v2( **
      • an insert change if all fields of the conflicting row match ** the row being inserted. **
      +** +**
      SQLITE_CHANGESETAPPLY_FKNOACTION
      +** If this flag it set, then all foreign key constraints in the target +** database behave as if they were declared with "ON UPDATE NO ACTION ON +** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL +** or SET DEFAULT. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 +#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 /* ** CAPI3REF: Constants Passed To The Conflict Handler From 63a58e072020ba97e73d3030e270a5871c38e49f Mon Sep 17 00:00:00 2001 From: Vladimir Belyavsky Date: Sun, 12 Nov 2023 12:04:12 +0300 Subject: [PATCH 04/58] QSystemTrayIcon: properly disconnect old menu in setContextMenu() Amends 121a30ccef3b6306c1da4f415fe1305dbf2dd901 Fix the unfortunate mistake where oldMenu was not properly disconnected from the contextMenuRequested() signal. This could lead to a situation when several menus are displayed at the same time. Fixes: QTBUG-78737 Change-Id: Ice59841724207192eacd5a52b644f83159e09913 Reviewed-by: Volker Hilsheimer (cherry picked from commit b71aa3c661797a916effd29171665ea838816595) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 7ea394eed6f70d4fb9b8a094db7bff40ea04f6bd) (cherry picked from commit 08dfed7e1cd2224e4bdcbe7fb275418eb8458ee6) (cherry picked from commit 3db07109309ee18cc60dc09e4dcc10d9d5df69d5) --- src/widgets/util/qsystemtrayicon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index 47e60d0f901..9918bed72e5 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -208,7 +208,7 @@ void QSystemTrayIcon::setContextMenu(QMenu *menu) if (oldMenu != menu && d->qpa_sys) { // Show the QMenu-based menu for QPA plugins that do not provide native menus if (oldMenu && !oldMenu->platformMenu()) - QObject::disconnect(d->qpa_sys, &QPlatformSystemTrayIcon::contextMenuRequested, menu, nullptr); + QObject::disconnect(d->qpa_sys, &QPlatformSystemTrayIcon::contextMenuRequested, oldMenu, nullptr); if (menu && !menu->platformMenu()) { QObject::connect(d->qpa_sys, &QPlatformSystemTrayIcon::contextMenuRequested, menu, From 165daa88c1e5a768cce18c10bf570fe22a741411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 9 Nov 2023 13:11:35 +0100 Subject: [PATCH 05/58] Fix compilation with MSVC 17.8 stdext is deprecated, slated for removal. The macros were used to work around a compiler warning generated when using the 3-arg overload of certain STL algorithms even when the 4-arg version (added in C++14) was not available. These deprecation warnings seem to have been discontinued as of MSVC++ 14.15 _MSC_VER == 1915 (Visual Studio 2017 version 15.8) so making the macros no-ops from VS 2022 17.8 onward is not expected to trigger these warnings again. Fixes: QTBUG-118993 Change-Id: I2c3b69d46d13f6fcccf0ffce186b984b7758f287 Reviewed-by: Marc Mutz (cherry picked from commit 52b6258ec846cc53ebdb1c8167edd30db39c7891) (cherry picked from commit 24ca6bd117648e28d8b966d97c0a76036cf57345) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 2723b03120e066e56ac94fc578ca4dea2f271ea3) (cherry picked from commit 521e059cdddd4a67babc49921ddd9969724c0fb9) --- src/corelib/global/qcompilerdetection.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index f374c531e56..07964bbed74 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -110,8 +110,10 @@ # endif # define Q_DECL_EXPORT __declspec(dllexport) # define Q_DECL_IMPORT __declspec(dllimport) -# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) stdext::make_unchecked_array_iterator(x) // Since _MSC_VER >= 1800 -# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) stdext::make_checked_array_iterator(x, size_t(N)) // Since _MSC_VER >= 1500 +# if _MSC_VER < 1938 // stdext is deprecated since VS 2022 17.8 +# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) stdext::make_unchecked_array_iterator(x) // Since _MSC_VER >= 1800 +# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) stdext::make_checked_array_iterator(x, size_t(N)) // Since _MSC_VER >= 1500 +# endif /* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */ # if defined(__INTEL_COMPILER) # undef Q_CC_MSVC_ONLY From ae62bd02f1c92350a8838f1b1d1ad3e8ce9db924 Mon Sep 17 00:00:00 2001 From: Ahmad Samir Date: Sat, 8 Apr 2023 13:38:49 +0200 Subject: [PATCH 06/58] QStringList: improve benchmark code Make the strings in the stringlist-to-be-joined unique, which matches actual use-cases better than joining a list of identical strings, especially with QString's implicit sharing, if it's copies of the same QString, it's sharing the underlying data. Manual conflict resolutions: - Removed C++14 digit separators to restore C++11 compatibility Task-number: QTBUG-116859 Change-Id: I1da93885e938045322ba8337df5e4e96985f892f Reviewed-by: Thiago Macieira (cherry picked from commit e1dcc858b2a0ac2b359cdbf7e07e70c1237daef0) Reviewed-by: Marc Mutz (cherry picked from commit e1fe8963a78fd91a1307b3c302c69cc74136aee7) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit ea5035bfb4e69ffd3792a093128e418b38d07ad1) Reviewed-by: Volker Hilsheimer (cherry picked from commit 0d3585447467f1e437827e6d63ff69ee4114a9d5) --- tests/benchmarks/corelib/text/qstringlist/main.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/benchmarks/corelib/text/qstringlist/main.cpp b/tests/benchmarks/corelib/text/qstringlist/main.cpp index 9f184d0cf58..0d41e934415 100644 --- a/tests/benchmarks/corelib/text/qstringlist/main.cpp +++ b/tests/benchmarks/corelib/text/qstringlist/main.cpp @@ -68,9 +68,9 @@ private: QStringList tst_QStringList::populateList(const int count, const QString &unit) { QStringList retval; - + retval.reserve(count); for (int i = 0; i < count; ++i) - retval.append(unit); + retval.append(unit + QString::number(i)); return retval; } @@ -102,19 +102,19 @@ void tst_QStringList::join_data() const QTest::addColumn("input"); QTest::addColumn("separator"); - QTest::newRow("") + QTest::newRow("100") << populateList(100, QLatin1String("unit")) << QString(); - QTest::newRow("") + QTest::newRow("1000") << populateList(1000, QLatin1String("unit")) << QString(); - QTest::newRow("") + QTest::newRow("10000") << populateList(10000, QLatin1String("unit")) << QString(); - QTest::newRow("") + QTest::newRow("100000") << populateList(100000, QLatin1String("unit")) << QString(); } From 24ab27d5d06cab6181c2066517c6056424c21817 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 15 Nov 2023 14:58:42 +0100 Subject: [PATCH 07/58] Upgrade to Harfbuzz 8.3.0 Fixes: QTBUG-119150 Change-Id: I80f21f6f27cce14a1e91e822c3681ec491491ff1 Reviewed-by: Qt CI Bot Reviewed-by: Volker Hilsheimer (cherry picked from commit 98ca28f7a65b2d4e0a90e2d74448ad6992260a1c) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 67637f2c4056bccf71a880253eaaaa5f09494cf9) (cherry picked from commit be62459ee5281b1bd323ef1346ef5051ed75d2bb) (cherry picked from commit 9e802b62a0595a31ab14c7df957ac3417822468c) --- src/3rdparty/harfbuzz-ng/README.md | 6 +- src/3rdparty/harfbuzz-ng/qt_attribution.json | 2 +- .../harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh | 6 + .../harfbuzz-ng/src/OT/Color/COLR/COLR.hh | 17 +- .../harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh | 8 + .../harfbuzz-ng/src/OT/Color/sbix/sbix.hh | 1 + .../harfbuzz-ng/src/OT/Color/svg/svg.hh | 1 + .../src/OT/Layout/Common/Coverage.hh | 1 + .../harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh | 59 ++++++- .../harfbuzz-ng/src/OT/Layout/GPOS/Anchor.hh | 1 + .../src/OT/Layout/GPOS/AnchorFormat3.hh | 6 + .../src/OT/Layout/GPOS/AnchorMatrix.hh | 10 +- .../harfbuzz-ng/src/OT/Layout/GPOS/Common.hh | 2 +- .../src/OT/Layout/GPOS/CursivePosFormat1.hh | 14 +- .../src/OT/Layout/GPOS/MarkMarkPosFormat1.hh | 1 + .../src/OT/Layout/GPOS/PairPosFormat1.hh | 44 +++-- .../src/OT/Layout/GPOS/PairPosFormat2.hh | 39 +++-- .../harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh | 8 +- .../src/OT/Layout/GPOS/PairValueRecord.hh | 4 +- .../src/OT/Layout/GPOS/SinglePos.hh | 12 +- .../src/OT/Layout/GPOS/SinglePosFormat1.hh | 29 +++- .../src/OT/Layout/GPOS/SinglePosFormat2.hh | 40 ++++- .../src/OT/Layout/GPOS/ValueFormat.hh | 83 +++++++--- .../GSUB/ReverseChainSingleSubstFormat1.hh | 8 +- .../harfbuzz-ng/src/OT/Layout/types.hh | 8 +- src/3rdparty/harfbuzz-ng/src/OT/name/name.hh | 5 +- .../harfbuzz-ng/src/graph/classdef-graph.hh | 3 + .../harfbuzz-ng/src/graph/coverage-graph.hh | 3 + src/3rdparty/harfbuzz-ng/src/graph/graph.hh | 2 + .../harfbuzz-ng/src/graph/gsubgpos-graph.hh | 4 + .../src/graph/markbasepos-graph.hh | 3 + .../harfbuzz-ng/src/graph/pairpos-graph.hh | 3 + .../src/hb-aat-layout-ankr-table.hh | 1 + .../src/hb-aat-layout-bsln-table.hh | 1 + .../harfbuzz-ng/src/hb-aat-layout-common.hh | 6 + .../src/hb-aat-layout-feat-table.hh | 2 + .../src/hb-aat-layout-just-table.hh | 3 + .../src/hb-aat-layout-kerx-table.hh | 25 ++- .../src/hb-aat-layout-morx-table.hh | 41 +++-- .../src/hb-aat-layout-opbd-table.hh | 1 + .../src/hb-aat-layout-trak-table.hh | 2 + src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h | 4 +- .../harfbuzz-ng/src/hb-aat-ltag-table.hh | 5 +- src/3rdparty/harfbuzz-ng/src/hb-array.hh | 2 + src/3rdparty/harfbuzz-ng/src/hb-atomic.hh | 10 +- .../harfbuzz-ng/src/hb-bit-set-invertible.hh | 4 +- src/3rdparty/harfbuzz-ng/src/hb-deprecated.h | 11 +- src/3rdparty/harfbuzz-ng/src/hb-ft.cc | 4 +- src/3rdparty/harfbuzz-ng/src/hb-map.hh | 31 +++- src/3rdparty/harfbuzz-ng/src/hb-open-file.hh | 6 + src/3rdparty/harfbuzz-ng/src/hb-open-type.hh | 60 ++++--- .../harfbuzz-ng/src/hb-ot-cff-common.hh | 31 +++- .../harfbuzz-ng/src/hb-ot-cff1-table.hh | 23 ++- .../harfbuzz-ng/src/hb-ot-cff2-table.hh | 12 +- .../harfbuzz-ng/src/hb-ot-cmap-table.hh | 14 +- .../harfbuzz-ng/src/hb-ot-hdmx-table.hh | 2 + .../harfbuzz-ng/src/hb-ot-head-table.hh | 1 + .../harfbuzz-ng/src/hb-ot-hhea-table.hh | 4 +- .../harfbuzz-ng/src/hb-ot-kern-table.hh | 9 +- .../src/hb-ot-layout-base-table.hh | 2 + .../harfbuzz-ng/src/hb-ot-layout-common.hh | 155 ++++++++++++++---- .../harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh | 21 ++- .../src/hb-ot-layout-jstf-table.hh | 1 + .../harfbuzz-ng/src/hb-ot-math-table.hh | 3 + .../harfbuzz-ng/src/hb-ot-maxp-table.hh | 3 +- .../harfbuzz-ng/src/hb-ot-meta-table.hh | 2 + .../harfbuzz-ng/src/hb-ot-os2-table.hh | 24 +++ .../harfbuzz-ng/src/hb-ot-post-table.hh | 18 +- .../harfbuzz-ng/src/hb-ot-stat-table.hh | 3 + .../harfbuzz-ng/src/hb-ot-var-avar-table.hh | 3 + .../harfbuzz-ng/src/hb-ot-var-common.hh | 77 +++++---- .../harfbuzz-ng/src/hb-ot-var-cvar-table.hh | 3 +- .../harfbuzz-ng/src/hb-ot-var-fvar-table.hh | 3 + .../harfbuzz-ng/src/hb-ot-var-gvar-table.hh | 11 +- .../harfbuzz-ng/src/hb-ot-var-hvar-table.hh | 1 + .../harfbuzz-ng/src/hb-ot-var-mvar-table.hh | 2 + .../harfbuzz-ng/src/hb-ot-vorg-table.hh | 1 + .../harfbuzz-ng/src/hb-priority-queue.hh | 3 + src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh | 5 +- src/3rdparty/harfbuzz-ng/src/hb-set.hh | 2 + .../harfbuzz-ng/src/hb-subset-cff1.cc | 55 ++++--- .../harfbuzz-ng/src/hb-subset-cff2.cc | 56 ++++--- .../harfbuzz-ng/src/hb-subset-input.cc | 6 + .../src/hb-subset-instancer-solver.cc | 8 +- .../src/hb-subset-plan-member-list.hh | 12 ++ .../harfbuzz-ng/src/hb-subset-plan.cc | 91 +++++++--- .../harfbuzz-ng/src/hb-subset-plan.hh | 3 + src/3rdparty/harfbuzz-ng/src/hb-subset.cc | 3 +- src/3rdparty/harfbuzz-ng/src/hb-subset.h | 6 + src/3rdparty/harfbuzz-ng/src/hb-vector.hh | 7 +- src/3rdparty/harfbuzz-ng/src/hb-version.h | 6 +- 91 files changed, 1017 insertions(+), 327 deletions(-) diff --git a/src/3rdparty/harfbuzz-ng/README.md b/src/3rdparty/harfbuzz-ng/README.md index 099d4b7719c..33165091a8b 100644 --- a/src/3rdparty/harfbuzz-ng/README.md +++ b/src/3rdparty/harfbuzz-ng/README.md @@ -13,8 +13,10 @@ HarfBuzz is a text shaping engine. It primarily supports [OpenType][1], but also [Apple Advanced Typography][2]. HarfBuzz is used in Android, Chrome, ChromeOS, Firefox, GNOME, GTK+, KDE, Qt, LibreOffice, OpenJDK, XeTeX, -PlayStation, Microsoft Edge, Photoshop, Illustrator, InDesign, -and other places. +PlayStation, Microsoft Edge, Adobe Photoshop, Illustrator, InDesign, +Godot Engine, and other places. + +[![xkcd-derived image](xkcd.png)](https://xkcd.com/2347/) For bug reports, mailing list, and other information please visit: diff --git a/src/3rdparty/harfbuzz-ng/qt_attribution.json b/src/3rdparty/harfbuzz-ng/qt_attribution.json index ab283a6f7db..26ef2e30e6a 100644 --- a/src/3rdparty/harfbuzz-ng/qt_attribution.json +++ b/src/3rdparty/harfbuzz-ng/qt_attribution.json @@ -7,7 +7,7 @@ "Description": "HarfBuzz is an OpenType text shaping engine.", "Homepage": "http://harfbuzz.org", - "Version": "8.2.2", + "Version": "8.3.0", "License": "MIT License", "LicenseId": "MIT", "LicenseFile": "COPYING", diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh index 457039bfc6c..bcf1848f498 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh @@ -204,6 +204,7 @@ struct IndexSubtable { TRACE_SANITIZE (this); if (!u.header.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.header.indexFormat) { case 1: return_trace (u.format1.sanitize (c, glyph_count)); @@ -378,6 +379,7 @@ struct IndexSubtableRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && firstGlyphIndex <= lastGlyphIndex && offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1)); } @@ -635,6 +637,7 @@ struct BitmapSizeTable { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) && horizontal.sanitize (c) && vertical.sanitize (c)); @@ -738,7 +741,9 @@ struct CBLC { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2 || version.major == 3) && + hb_barrier () && sizeTables.sanitize (c, this)); } @@ -975,6 +980,7 @@ struct CBDT { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2 || version.major == 3)); } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh index 60b094ecbc8..b632a1d9eba 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh @@ -1948,10 +1948,11 @@ struct COLR bool has_v0_data () const { return numBaseGlyphs; } bool has_v1_data () const { - if (version == 1) - return (this+baseGlyphList).len > 0; + if (version != 1) + return false; + hb_barrier (); - return false; + return (this+baseGlyphList).len > 0; } unsigned int get_glyph_layers (hb_codepoint_t glyph, @@ -2032,6 +2033,8 @@ struct COLR hb_set_t *palette_indices) const { if (version != 1) return; + hb_barrier (); + hb_set_t visited_glyphs; hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices); @@ -2058,10 +2061,12 @@ struct COLR { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) && (this+layersZ).sanitize (c, numLayers) && (version == 0 || - (version == 1 && + (hb_barrier () && + version == 1 && baseGlyphList.sanitize (c, this) && layerList.sanitize (c, this) && clipList.sanitize (c, this) && @@ -2284,6 +2289,8 @@ struct COLR { if (version == 1) { + hb_barrier (); + const Paint *paint = get_base_glyph_paint (glyph); return paint != nullptr; @@ -2313,6 +2320,8 @@ struct COLR if (version == 1) { + hb_barrier (); + const Paint *paint = get_base_glyph_paint (glyph); if (paint) { diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh index c07716c1c98..2821334db7c 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh @@ -214,13 +214,17 @@ struct CPAL hb_set_t *nameids_to_retain /* OUT */) const { if (version == 1) + { + hb_barrier (); v1 ().collect_name_ids (this, numPalettes, numColors, color_index_map, nameids_to_retain); + } } private: const CPALV1Tail& v1 () const { if (version == 0) return Null (CPALV1Tail); + hb_barrier (); return StructAfter (*this); } @@ -312,7 +316,10 @@ struct CPAL return_trace (false); if (version == 1) + { + hb_barrier (); return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map)); + } return_trace (true); } @@ -321,6 +328,7 @@ struct CPAL { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && (this+colorRecordsZ).sanitize (c, numColorRecords) && colorRecordIndicesZ.sanitize (c, numPalettes) && (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors))); diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh index ce8693cfb16..51ae1a9c63b 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh @@ -368,6 +368,7 @@ struct sbix { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version >= 1 && strikes.sanitize (c, this))); } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh index c7d91b88ee0..2e1f935109d 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh @@ -56,6 +56,7 @@ struct SVGDocumentIndexEntry { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && svgDoc.sanitize (c, base, svgDocLength)); } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh index 25056c9bc35..344e87afb30 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh @@ -64,6 +64,7 @@ struct Coverage { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh index dd025c1284d..14a9b5e5cd8 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh @@ -291,6 +291,7 @@ struct CaretValue { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -441,6 +442,20 @@ struct MarkGlyphSetsFormat1 bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; } + void collect_used_mark_sets (const hb_set_t& glyph_set, + hb_set_t& used_mark_sets /* OUT */) const + { + unsigned i = 0; + for (const auto &offset : coverage) + { + const auto &cov = this+offset; + if (cov.intersects (&glyph_set)) + used_mark_sets.add (i); + + i++; + } + } + template void collect_coverage (hb_vector_t &sets) const { @@ -461,6 +476,7 @@ struct MarkGlyphSetsFormat1 bool ret = true; for (const Offset32To& offset : coverage.iter ()) { + auto snap = c->serializer->snapshot (); auto *o = out->coverage.serialize_append (c->serializer); if (unlikely (!o)) { @@ -468,11 +484,17 @@ struct MarkGlyphSetsFormat1 break; } - //not using o->serialize_subset (c, offset, this, out) here because - //OTS doesn't allow null offset. - //See issue: https://github.com/khaledhosny/ots/issues/172 + //skip empty coverage c->serializer->push (); - c->dispatch (this+offset); + bool res = false; + if (offset) res = c->dispatch (this+offset); + if (!res) + { + c->serializer->pop_discard (); + c->serializer->revert (snap); + (out->coverage.len)--; + continue; + } c->serializer->add_link (*o, c->serializer->pop_pack ()); } @@ -513,6 +535,15 @@ struct MarkGlyphSets } } + void collect_used_mark_sets (const hb_set_t& glyph_set, + hb_set_t& used_mark_sets /* OUT */) const + { + switch (u.format) { + case 1: u.format1.collect_used_mark_sets (glyph_set, used_mark_sets); return; + default:return; + } + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -526,6 +557,7 @@ struct MarkGlyphSets { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); default:return_trace (true); @@ -600,6 +632,7 @@ struct GDEFVersion1_2 attachList.sanitize (c, this) && ligCaretList.sanitize (c, this) && markAttachClassDef.sanitize (c, this) && + hb_barrier () && (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) && (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); } @@ -627,23 +660,28 @@ struct GDEFVersion1_2 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - auto *out = c->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->version.major = version.major; + out->version.minor = version.minor; bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); - bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); bool subset_markglyphsetsdef = false; + auto snapshot_version0 = c->serializer->snapshot (); if (version.to_int () >= 0x00010002u) { + if (unlikely (!c->serializer->embed (markGlyphSetsDef))) return_trace (false); subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); } bool subset_varstore = false; + auto snapshot_version2 = c->serializer->snapshot (); if (version.to_int () >= 0x00010003u) { + if (unlikely (!c->serializer->embed (varStore))) return_trace (false); if (c->plan->all_axes_pinned) out->varStore = 0; else if (c->plan->normalized_coords) @@ -666,15 +704,21 @@ struct GDEFVersion1_2 subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ()); } + if (subset_varstore) { out->version.minor = 3; + c->plan->has_gdef_varstore = true; } else if (subset_markglyphsetsdef) { out->version.minor = 2; + c->serializer->revert (snapshot_version2); } else { out->version.minor = 0; + c->serializer->revert (snapshot_version0); } + bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); + return_trace (subset_glyphclassdef || subset_attachlist || subset_ligcaretlist || subset_markattachclassdef || (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) || @@ -709,6 +753,7 @@ struct GDEF { TRACE_SANITIZE (this); if (unlikely (!u.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.version.major) { case 1: return_trace (u.version1.sanitize (c)); #ifndef HB_NO_BEYOND_64K diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Anchor.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Anchor.hh index 49e76e77509..7802e397f4c 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Anchor.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Anchor.hh @@ -25,6 +25,7 @@ struct Anchor { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat3.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat3.hh index 56eda4a5778..b5422652c4e 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat3.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat3.hh @@ -38,9 +38,15 @@ struct AnchorFormat3 *y = font->em_fscale_y (yCoordinate); if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) + { + hb_barrier (); *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); + } if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) + { + hb_barrier (); *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); + } } bool subset (hb_subset_context_t *c) const diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh index 37ba7916f2a..2557e9a7231 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh @@ -8,7 +8,7 @@ namespace GPOS_impl { struct AnchorMatrix { HBUINT16 rows; /* Number of rows */ - UnsizedArrayOf> + UnsizedArrayOf> matrixZ; /* Matrix of offsets to Anchor tables-- * from beginning of AnchorMatrix table */ public: @@ -18,6 +18,7 @@ struct AnchorMatrix { TRACE_SANITIZE (this); if (!c->check_struct (this)) return_trace (false); + hb_barrier (); if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false); unsigned int count = rows * cols; if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false); @@ -25,6 +26,7 @@ struct AnchorMatrix if (c->lazy_some_gpos) return_trace (true); + hb_barrier (); for (unsigned int i = 0; i < count; i++) if (!matrixZ[i].sanitize (c, this)) return_trace (false); return_trace (true); @@ -38,6 +40,7 @@ struct AnchorMatrix if (unlikely (row >= rows || col >= cols)) return Null (Anchor); auto &offset = matrixZ[row * cols + col]; if (unlikely (!offset.sanitize (&c->sanitizer, this))) return Null (Anchor); + hb_barrier (); *found = !offset.is_null (); return this+offset; } @@ -65,15 +68,14 @@ struct AnchorMatrix if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->rows = num_rows; - bool ret = false; for (const unsigned i : index_iter) { auto *offset = c->serializer->embed (matrixZ[i]); if (!offset) return_trace (false); - ret |= offset->serialize_subset (c, matrixZ[i], this); + offset->serialize_subset (c, matrixZ[i], this); } - return_trace (ret); + return_trace (true); } }; diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Common.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Common.hh index 408197454f1..696d25d75c8 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Common.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Common.hh @@ -23,7 +23,7 @@ static void SinglePos_serialize (hb_serialize_context_t *c, const SrcLookup *src, Iterator it, const hb_hashmap_t> *layout_variation_idx_delta_map, - bool all_axes_pinned); + unsigned new_format); } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh index 7c42c3f777a..6b019ac513b 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh @@ -11,21 +11,21 @@ struct EntryExitRecord { friend struct CursivePosFormat1; - bool sanitize (hb_sanitize_context_t *c, const void *base) const + bool sanitize (hb_sanitize_context_t *c, const struct CursivePosFormat1 *base) const { TRACE_SANITIZE (this); return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); } void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const void *src_base) const + const struct CursivePosFormat1 *src_base) const { (src_base+entryAnchor).collect_variation_indices (c); (src_base+exitAnchor).collect_variation_indices (c); } bool subset (hb_subset_context_t *c, - const void *src_base) const + const struct CursivePosFormat1 *src_base) const { TRACE_SERIALIZE (this); auto *out = c->serializer->embed (this); @@ -38,11 +38,11 @@ struct EntryExitRecord } protected: - Offset16To + Offset16To entryAnchor; /* Offset to EntryAnchor table--from * beginning of CursivePos * subtable--may be NULL */ - Offset16To + Offset16To exitAnchor; /* Offset to ExitAnchor table--from * beginning of CursivePos * subtable--may be NULL */ @@ -128,6 +128,7 @@ struct CursivePosFormat1 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; if (!this_record.entryAnchor || unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false); + hb_barrier (); hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); @@ -145,6 +146,7 @@ struct CursivePosFormat1 buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); return_trace (false); } + hb_barrier (); unsigned int i = skippy_iter.idx; unsigned int j = buffer->idx; @@ -262,7 +264,7 @@ struct CursivePosFormat1 hb_requires (hb_is_iterator (Iterator))> void serialize (hb_subset_context_t *c, Iterator it, - const void *src_base) + const struct CursivePosFormat1 *src_base) { if (unlikely (!c->serializer->extend_min ((*this)))) return; this->format = 1; diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh index 70cf071668e..57eb782a958 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -42,6 +42,7 @@ struct MarkMarkPosFormat1_2 mark1Coverage.sanitize (c, this) && mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) && + hb_barrier () && mark2Array.sanitize (c, this, (unsigned int) classCount)); } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh index e4a2006fb98..ac2774a76fb 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh @@ -36,6 +36,7 @@ struct PairPosFormat1_3 TRACE_SANITIZE (this); if (!c->check_struct (this)) return_trace (false); + hb_barrier (); unsigned int len1 = valueFormat[0].get_len (); unsigned int len2 = valueFormat[1].get_len (); @@ -131,20 +132,33 @@ struct PairPosFormat1_3 auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->format = format; - out->valueFormat[0] = valueFormat[0]; - out->valueFormat[1] = valueFormat[1]; - if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) - { - hb_pair_t newFormats = compute_effective_value_formats (glyphset); - out->valueFormat[0] = newFormats.first; - out->valueFormat[1] = newFormats.second; - } - if (c->plan->all_axes_pinned) + hb_pair_t newFormats = hb_pair (valueFormat[0], valueFormat[1]); + + if (c->plan->normalized_coords) { - out->valueFormat[0] = out->valueFormat[0].drop_device_table_flags (); - out->valueFormat[1] = out->valueFormat[1].drop_device_table_flags (); + /* all device flags will be dropped when full instancing, no need to strip + * hints, also do not strip emtpy cause we don't compute the new default + * value during stripping */ + newFormats = compute_effective_value_formats (glyphset, false, false, &c->plan->layout_variation_idx_delta_map); } + /* do not strip hints for VF */ + else if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + { + hb_blob_t* blob = hb_face_reference_table (c->plan->source, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + bool strip = !has_fvar; + /* special case: strip hints when a VF has no GDEF varstore after + * subsetting*/ + if (has_fvar && !c->plan->has_gdef_varstore) + strip = true; + newFormats = compute_effective_value_formats (glyphset, strip, true); + } + + out->valueFormat[0] = newFormats.first; + out->valueFormat[1] = newFormats.second; hb_sorted_vector_t new_coverage; @@ -175,7 +189,9 @@ struct PairPosFormat1_3 } - hb_pair_t compute_effective_value_formats (const hb_set_t& glyphset) const + hb_pair_t compute_effective_value_formats (const hb_set_t& glyphset, + bool strip_hints, bool strip_empty, + const hb_hashmap_t> *varidx_delta_map = nullptr) const { unsigned record_size = PairSet::get_size (valueFormat); @@ -195,8 +211,8 @@ struct PairPosFormat1_3 { if (record->intersects (glyphset)) { - format1 = format1 | valueFormat[0].get_effective_format (record->get_values_1 ()); - format2 = format2 | valueFormat[1].get_effective_format (record->get_values_2 (valueFormat[0])); + format1 = format1 | valueFormat[0].get_effective_format (record->get_values_1 (), strip_hints, strip_empty, &set, varidx_delta_map); + format2 = format2 | valueFormat[1].get_effective_format (record->get_values_2 (valueFormat[0]), strip_hints, strip_empty, &set, varidx_delta_map); } record = &StructAtOffset (record, record_size); } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh index 4adb1ef606c..dd02da887d4 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -8,7 +8,7 @@ namespace Layout { namespace GPOS_impl { template -struct PairPosFormat2_4 +struct PairPosFormat2_4 : ValueBase { protected: HBUINT16 format; /* Format identifier--format = 2 */ @@ -287,18 +287,31 @@ struct PairPosFormat2_4 unsigned len2 = valueFormat2.get_len (); hb_pair_t newFormats = hb_pair (valueFormat1, valueFormat2); - if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) - newFormats = compute_effective_value_formats (klass1_map, klass2_map); + + if (c->plan->normalized_coords) + { + /* in case of full instancing, all var device flags will be dropped so no + * need to strip hints here */ + newFormats = compute_effective_value_formats (klass1_map, klass2_map, false, false, &c->plan->layout_variation_idx_delta_map); + } + /* do not strip hints for VF */ + else if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + { + hb_blob_t* blob = hb_face_reference_table (c->plan->source, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + bool strip = !has_fvar; + /* special case: strip hints when a VF has no GDEF varstore after + * subsetting*/ + if (has_fvar && !c->plan->has_gdef_varstore) + strip = true; + newFormats = compute_effective_value_formats (klass1_map, klass2_map, strip, true); + } out->valueFormat1 = newFormats.first; out->valueFormat2 = newFormats.second; - if (c->plan->all_axes_pinned) - { - out->valueFormat1 = out->valueFormat1.drop_device_table_flags (); - out->valueFormat2 = out->valueFormat2.drop_device_table_flags (); - } - unsigned total_len = len1 + len2; hb_vector_t class2_idxs (+ hb_range ((unsigned) class2Count) | hb_filter (klass2_map)); for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map)) @@ -326,7 +339,9 @@ struct PairPosFormat2_4 hb_pair_t compute_effective_value_formats (const hb_map_t& klass1_map, - const hb_map_t& klass2_map) const + const hb_map_t& klass2_map, + bool strip_hints, bool strip_empty, + const hb_hashmap_t> *varidx_delta_map = nullptr) const { unsigned len1 = valueFormat1.get_len (); unsigned len2 = valueFormat2.get_len (); @@ -340,8 +355,8 @@ struct PairPosFormat2_4 for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map)) { unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_size; - format1 = format1 | valueFormat1.get_effective_format (&values[idx]); - format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]); + format1 = format1 | valueFormat1.get_effective_format (&values[idx], strip_hints, strip_empty, this, varidx_delta_map); + format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1], strip_hints, strip_empty, this, varidx_delta_map); } if (format1 == valueFormat1 && format2 == valueFormat2) diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh index db301bb8160..5560fab1743 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh @@ -9,7 +9,7 @@ namespace GPOS_impl { template -struct PairSet +struct PairSet : ValueBase { template friend struct PairPosFormat1_3; @@ -45,10 +45,12 @@ struct PairSet bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const { TRACE_SANITIZE (this); - if (!(c->check_struct (this) - && c->check_range (&firstPairValueRecord, + if (!(c->check_struct (this) && + hb_barrier () && + c->check_range (&firstPairValueRecord, len, closure->stride))) return_trace (false); + hb_barrier (); unsigned int count = len; const PairValueRecord *record = &firstPairValueRecord; diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairValueRecord.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairValueRecord.hh index 72bf0e99b53..d00618b763b 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairValueRecord.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairValueRecord.hh @@ -29,7 +29,7 @@ struct PairValueRecord struct context_t { - const void *base; + const ValueBase *base; const ValueFormat *valueFormats; const ValueFormat *newFormats; unsigned len1; /* valueFormats[0].get_len() */ @@ -62,7 +62,7 @@ struct PairValueRecord void collect_variation_indices (hb_collect_variation_indices_context_t *c, const ValueFormat *valueFormats, - const void *base) const + const ValueBase *base) const { unsigned record1_len = valueFormats[0].get_len (); unsigned record2_len = valueFormats[1].get_len (); diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePos.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePos.hh index 3af6c499659..a0243a218c5 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePos.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePos.hh @@ -39,14 +39,12 @@ struct SinglePos const SrcLookup* src, Iterator glyph_val_iter_pairs, const hb_hashmap_t> *layout_variation_idx_delta_map, - bool all_axes_pinned) + unsigned newFormat) { if (unlikely (!c->extend_min (u.format))) return; unsigned format = 2; - ValueFormat new_format = src->get_value_format (); - - if (all_axes_pinned) - new_format = new_format.drop_device_table_flags (); + ValueFormat new_format; + new_format = newFormat; if (glyph_val_iter_pairs) format = get_format (glyph_val_iter_pairs); @@ -89,8 +87,8 @@ SinglePos_serialize (hb_serialize_context_t *c, const SrcLookup *src, Iterator it, const hb_hashmap_t> *layout_variation_idx_delta_map, - bool all_axes_pinned) -{ c->start_embed ()->serialize (c, src, it, layout_variation_idx_delta_map, all_axes_pinned); } + unsigned new_format) +{ c->start_embed ()->serialize (c, src, it, layout_variation_idx_delta_map, new_format); } } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat1.hh index dff1f7316d5..b2d151d4461 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -8,7 +8,7 @@ namespace OT { namespace Layout { namespace GPOS_impl { -struct SinglePosFormat1 +struct SinglePosFormat1 : ValueBase { protected: HBUINT16 format; /* Format identifier--format = 1 */ @@ -28,6 +28,7 @@ struct SinglePosFormat1 TRACE_SANITIZE (this); return_trace (c->check_struct (this) && coverage.sanitize (c, this) && + hb_barrier () && /* The coverage table may use a range to represent a set * of glyphs, which means a small number of bytes can * generate a large glyph set. Manually modify the @@ -146,6 +147,30 @@ struct SinglePosFormat1 hb_set_t intersection; (this+coverage).intersect_set (glyphset, intersection); + unsigned new_format = valueFormat; + + if (c->plan->normalized_coords) + { + new_format = valueFormat.get_effective_format (values.arrayZ, false, false, this, &c->plan->layout_variation_idx_delta_map); + } + /* do not strip hints for VF */ + else if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + { + hb_blob_t* blob = hb_face_reference_table (c->plan->source, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + bool strip = !has_fvar; + /* special case: strip hints when a VF has no GDEF varstore after + * subsetting*/ + if (has_fvar && !c->plan->has_gdef_varstore) + strip = true; + new_format = valueFormat.get_effective_format (values.arrayZ, + strip, /* strip hints */ + true, /* strip empty */ + this, nullptr); + } + auto it = + hb_iter (intersection) | hb_map_retains_sorting (glyph_map) @@ -153,7 +178,7 @@ struct SinglePosFormat1 ; bool ret = bool (it); - SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned); + SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, new_format); return_trace (ret); } }; diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat2.hh index 168ad3bb8c8..ae4a5ed7561 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat2.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat2.hh @@ -7,7 +7,7 @@ namespace OT { namespace Layout { namespace GPOS_impl { -struct SinglePosFormat2 +struct SinglePosFormat2 : ValueBase { protected: HBUINT16 format; /* Format identifier--format = 2 */ @@ -143,6 +143,37 @@ struct SinglePosFormat2 coverage.serialize_serialize (c, glyphs); } + template + unsigned compute_effective_format (const hb_face_t *face, + Iterator it, + bool is_instancing, bool strip_hints, + bool has_gdef_varstore, + const hb_hashmap_t> *varidx_delta_map) const + { + hb_blob_t* blob = hb_face_reference_table (face, HB_TAG ('f','v','a','r')); + bool has_fvar = (blob != hb_blob_get_empty ()); + hb_blob_destroy (blob); + + unsigned new_format = 0; + if (is_instancing) + { + new_format = new_format | valueFormat.get_effective_format (+ it | hb_map (hb_second), false, false, this, varidx_delta_map); + } + /* do not strip hints for VF */ + else if (strip_hints) + { + bool strip = !has_fvar; + if (has_fvar && !has_gdef_varstore) + strip = true; + new_format = new_format | valueFormat.get_effective_format (+ it | hb_map (hb_second), strip, true, this, nullptr); + } + else + new_format = valueFormat; + + return new_format; + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -163,8 +194,13 @@ struct SinglePosFormat2 }) ; + unsigned new_format = compute_effective_format (c->plan->source, it, + bool (c->plan->normalized_coords), + bool (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING), + c->plan->has_gdef_varstore, + &c->plan->layout_variation_idx_delta_map); bool ret = bool (it); - SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned); + SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, new_format); return_trace (ret); } }; diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh index 461a13d4b70..17f57db1f5f 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh @@ -9,6 +9,8 @@ namespace GPOS_impl { typedef HBUINT16 Value; +struct ValueBase {}; // Dummy base class tag for OffsetTo bases. + typedef UnsizedArrayOf ValueRecord; struct ValueFormat : HBUINT16 @@ -78,7 +80,7 @@ struct ValueFormat : HBUINT16 } bool apply_value (hb_ot_apply_context_t *c, - const void *base, + const ValueBase *base, const Value *values, hb_glyph_position_t &glyph_pos) const { @@ -142,11 +144,29 @@ struct ValueFormat : HBUINT16 return ret; } - unsigned int get_effective_format (const Value *values) const + unsigned int get_effective_format (const Value *values, bool strip_hints, bool strip_empty, const ValueBase *base, + const hb_hashmap_t> *varidx_delta_map) const { unsigned int format = *this; for (unsigned flag = xPlacement; flag <= yAdvDevice; flag = flag << 1) { - if (format & flag) should_drop (*values++, (Flags) flag, &format); + if (format & flag) + { + if (strip_hints && flag >= xPlaDevice) + { + format = format & ~flag; + values++; + continue; + } + if (varidx_delta_map && flag >= xPlaDevice) + { + update_var_flag (values++, (Flags) flag, &format, base, varidx_delta_map); + continue; + } + /* do not strip empty when instancing, cause we don't know whether the new + * default value is 0 or not */ + if (strip_empty) should_drop (*values, (Flags) flag, &format); + values++; + } } return format; @@ -154,18 +174,19 @@ struct ValueFormat : HBUINT16 template - unsigned int get_effective_format (Iterator it) const { + unsigned int get_effective_format (Iterator it, bool strip_hints, bool strip_empty, const ValueBase *base, + const hb_hashmap_t> *varidx_delta_map) const { unsigned int new_format = 0; for (const hb_array_t& values : it) - new_format = new_format | get_effective_format (&values); + new_format = new_format | get_effective_format (&values, strip_hints, strip_empty, base, varidx_delta_map); return new_format; } void copy_values (hb_serialize_context_t *c, unsigned int new_format, - const void *base, + const ValueBase *base, const Value *values, const hb_hashmap_t> *layout_variation_idx_delta_map) const { @@ -217,7 +238,7 @@ struct ValueFormat : HBUINT16 } void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const void *base, + const ValueBase *base, const hb_array_t& values) const { unsigned format = *this; @@ -251,17 +272,8 @@ struct ValueFormat : HBUINT16 } } - unsigned drop_device_table_flags () const - { - unsigned format = *this; - for (unsigned flag = xPlaDevice; flag <= yAdvDevice; flag = flag << 1) - format = format & ~flag; - - return format; - } - private: - bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const + bool sanitize_value_devices (hb_sanitize_context_t *c, const ValueBase *base, const Value *values) const { unsigned int format = *this; @@ -278,17 +290,17 @@ struct ValueFormat : HBUINT16 return true; } - static inline Offset16To& get_device (Value* value) + static inline Offset16To& get_device (Value* value) { - return *static_cast *> (value); + return *static_cast *> (value); } - static inline const Offset16To& get_device (const Value* value) + static inline const Offset16To& get_device (const Value* value) { - return *static_cast *> (value); + return *static_cast *> (value); } static inline const Device& get_device (const Value* value, bool *worked, - const void *base, + const ValueBase *base, hb_sanitize_context_t &c) { if (worked) *worked |= bool (*value); @@ -296,12 +308,13 @@ struct ValueFormat : HBUINT16 if (unlikely (!offset.sanitize (&c, base))) return Null(Device); + hb_barrier (); return base + offset; } void add_delta_to_value (HBINT16 *value, - const void *base, + const ValueBase *base, const Value *src_value, const hb_hashmap_t> *layout_variation_idx_delta_map) const { @@ -313,7 +326,8 @@ struct ValueFormat : HBUINT16 *value += hb_second (*varidx_delta); } - bool copy_device (hb_serialize_context_t *c, const void *base, + bool copy_device (hb_serialize_context_t *c, + const ValueBase *base, const Value *src_value, const hb_hashmap_t> *layout_variation_idx_delta_map, unsigned int new_format, Flags flag) const @@ -354,7 +368,7 @@ struct ValueFormat : HBUINT16 return (format & devices) != 0; } - bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const + bool sanitize_value (hb_sanitize_context_t *c, const ValueBase *base, const Value *values) const { TRACE_SANITIZE (this); @@ -366,7 +380,7 @@ struct ValueFormat : HBUINT16 return_trace (!has_device () || sanitize_value_devices (c, base, values)); } - bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const + bool sanitize_values (hb_sanitize_context_t *c, const ValueBase *base, const Value *values, unsigned int count) const { TRACE_SANITIZE (this); unsigned size = get_size (); @@ -376,11 +390,12 @@ struct ValueFormat : HBUINT16 if (c->lazy_some_gpos) return_trace (true); + hb_barrier (); return_trace (sanitize_values_stride_unsafe (c, base, values, count, size)); } /* Just sanitize referenced Device tables. Doesn't check the values themselves. */ - bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const + bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const ValueBase *base, const Value *values, unsigned int count, unsigned int stride) const { TRACE_SANITIZE (this); @@ -403,6 +418,20 @@ struct ValueFormat : HBUINT16 *format = *format & ~flag; } + void update_var_flag (const Value* value, Flags flag, + unsigned int* format, const ValueBase *base, + const hb_hashmap_t> *varidx_delta_map) const + { + if (*value) + { + unsigned varidx = (base + get_device (value)).get_variation_index (); + hb_pair_t *varidx_delta; + if (varidx_delta_map->has (varidx, &varidx_delta) && + varidx_delta->first != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + return; + } + *format = *format & ~flag; + } }; } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh index 916fa281b32..ec374f2f022 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh @@ -33,9 +33,11 @@ struct ReverseChainSingleSubstFormat1 TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &lookahead = StructAfter (backtrack); if (!lookahead.sanitize (c, this)) return_trace (false); + hb_barrier (); const auto &substitute = StructAfter (lookahead); return_trace (substitute.sanitize (c)); } @@ -109,12 +111,12 @@ struct ReverseChainSingleSubstFormat1 bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); - if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL)) - return_trace (false); /* No chaining to this type */ - unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); + if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL)) + return_trace (false); /* No chaining to this type */ + const auto &lookahead = StructAfter (backtrack); const auto &substitute = StructAfter (lookahead); diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh index 6a43403e94b..3840db05986 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh @@ -38,8 +38,8 @@ struct SmallTypes { using HBUINT = HBUINT16; using HBGlyphID = HBGlyphID16; using Offset = Offset16; - template - using OffsetTo = OT::Offset16To; + template + using OffsetTo = OT::Offset16To; template using ArrayOf = OT::Array16Of; template @@ -52,8 +52,8 @@ struct MediumTypes { using HBUINT = HBUINT24; using HBGlyphID = HBGlyphID24; using Offset = Offset24; - template - using OffsetTo = OT::Offset24To; + template + using OffsetTo = OT::Offset24To; template using ArrayOf = OT::Array24Of; template diff --git a/src/3rdparty/harfbuzz-ng/src/OT/name/name.hh b/src/3rdparty/harfbuzz-ng/src/OT/name/name.hh index c8de1013456..e2a25d4a0f0 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/name/name.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/name/name.hh @@ -242,7 +242,9 @@ struct NameRecord bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && offset.sanitize (c, base, length)); + return_trace (c->check_struct (this) && + hb_barrier () && + offset.sanitize (c, base, length)); } HBUINT16 platformID; /* Platform ID. */ @@ -465,6 +467,7 @@ struct name { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (format == 0 || format == 1) && c->check_array (nameRecordZ.arrayZ, count) && c->check_range (this, stringOffset) && diff --git a/src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh index c1432883ffa..9cf845a82d2 100644 --- a/src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh +++ b/src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh @@ -39,6 +39,7 @@ struct ClassDefFormat1 : public OT::ClassDefFormat1_3 int64_t vertex_len = vertex.obj.tail - vertex.obj.head; constexpr unsigned min_size = OT::ClassDefFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + classValue.get_size () - classValue.len.get_size (); } }; @@ -50,6 +51,7 @@ struct ClassDefFormat2 : public OT::ClassDefFormat2_4 int64_t vertex_len = vertex.obj.tail - vertex.obj.head; constexpr unsigned min_size = OT::ClassDefFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); } }; @@ -114,6 +116,7 @@ struct ClassDef : public OT::ClassDef { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::ClassDef::min_size) return false; + hb_barrier (); switch (u.format) { case 1: return ((ClassDefFormat1*)this)->sanitize (vertex); diff --git a/src/3rdparty/harfbuzz-ng/src/graph/coverage-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/coverage-graph.hh index 4f44e076d1f..61ca063e345 100644 --- a/src/3rdparty/harfbuzz-ng/src/graph/coverage-graph.hh +++ b/src/3rdparty/harfbuzz-ng/src/graph/coverage-graph.hh @@ -39,6 +39,7 @@ struct CoverageFormat1 : public OT::Layout::Common::CoverageFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + glyphArray.get_size () - glyphArray.len.get_size (); } }; @@ -50,6 +51,7 @@ struct CoverageFormat2 : public OT::Layout::Common::CoverageFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); } }; @@ -138,6 +140,7 @@ struct Coverage : public OT::Layout::Common::Coverage { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::Layout::Common::Coverage::min_size) return false; + hb_barrier (); switch (u.format) { case 1: return ((CoverageFormat1*)this)->sanitize (vertex); diff --git a/src/3rdparty/harfbuzz-ng/src/graph/graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/graph.hh index 2b4e1b2d3f3..26ad00bdd98 100644 --- a/src/3rdparty/harfbuzz-ng/src/graph/graph.hh +++ b/src/3rdparty/harfbuzz-ng/src/graph/graph.hh @@ -567,6 +567,7 @@ struct graph_t update_distances (); hb_priority_queue_t queue; + queue.alloc (vertices_.length); hb_vector_t &sorted_graph = vertices_scratch_; if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; hb_vector_t id_map; @@ -1370,6 +1371,7 @@ struct graph_t vertices_.tail ().distance = 0; hb_priority_queue_t queue; + queue.alloc (count); queue.insert (0, vertices_.length - 1); hb_vector_t visited; diff --git a/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-graph.hh index 12fcbdc497f..0f6d5662e03 100644 --- a/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-graph.hh +++ b/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-graph.hh @@ -76,6 +76,7 @@ struct Lookup : public OT::Lookup { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::Lookup::min_size) return false; + hb_barrier (); return vertex_len >= this->get_size (); } @@ -351,6 +352,7 @@ struct LookupList : public OT::LookupList { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::LookupList::min_size) return false; + hb_barrier (); return vertex_len >= OT::LookupList::item_size * this->len; } }; @@ -364,6 +366,7 @@ struct GSTAR : public OT::GSUBGPOS GSTAR* gstar = (GSTAR*) r.obj.head; if (!gstar || !gstar->sanitize (r)) return nullptr; + hb_barrier (); return gstar; } @@ -383,6 +386,7 @@ struct GSTAR : public OT::GSUBGPOS { int64_t len = vertex.obj.tail - vertex.obj.head; if (len < OT::GSUBGPOS::min_size) return false; + hb_barrier (); return len >= get_size (); } diff --git a/src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh index ae5ebd0d167..fb4166128a9 100644 --- a/src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh +++ b/src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh @@ -40,6 +40,7 @@ struct AnchorMatrix : public OT::Layout::GPOS_impl::AnchorMatrix { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < AnchorMatrix::min_size) return false; + hb_barrier (); return vertex_len >= AnchorMatrix::min_size + OT::Offset16::static_size * class_count * this->rows; @@ -128,6 +129,7 @@ struct MarkArray : public OT::Layout::GPOS_impl::MarkArray int64_t vertex_len = vertex.obj.tail - vertex.obj.head; unsigned min_size = MarkArray::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= get_size (); } @@ -495,6 +497,7 @@ struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < u.format.get_size ()) return false; + hb_barrier (); switch (u.format) { case 1: diff --git a/src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh index ad158cc9e8f..f7f74b18c9c 100644 --- a/src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh +++ b/src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh @@ -42,6 +42,7 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3::min_size; if (vertex_len < min_size) return false; + hb_barrier (); return vertex_len >= min_size + pairSet.get_size () - pairSet.len.get_size(); @@ -198,6 +199,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4::min_size; if (vertex_len < min_size) return false; + hb_barrier (); const unsigned class1_count = class1Count; return vertex_len >= @@ -625,6 +627,7 @@ struct PairPos : public OT::Layout::GPOS_impl::PairPos { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < u.format.get_size ()) return false; + hb_barrier (); switch (u.format) { case 1: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh index 63fac84524f..dbb38b1bc07 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh @@ -75,6 +75,7 @@ struct ankr { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version == 0 && c->check_range (this, anchorData) && lookupTable.sanitize (c, this, &(this+anchorData)))); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh index bf12d2e699f..8e42fab2e04 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh @@ -123,6 +123,7 @@ struct bsln TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && defaultBaseline < 32))) return_trace (false); + hb_barrier (); switch (format) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh index 672f80e0db8..05dd58c6df6 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh @@ -191,6 +191,7 @@ struct LookupSegmentArray { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && first <= last && valuesZ.sanitize (c, base, last - first + 1)); } @@ -199,6 +200,7 @@ struct LookupSegmentArray { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && first <= last && valuesZ.sanitize (c, base, last - first + 1, std::forward (ds)...)); } @@ -360,6 +362,7 @@ struct LookupFormat10 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && valueSize <= 4 && valueArrayZ.sanitize (c, glyphCount * valueSize)); } @@ -415,6 +418,7 @@ struct Lookup { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 0: return_trace (u.format0.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -429,6 +433,7 @@ struct Lookup { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 0: return_trace (u.format0.sanitize (c, base)); case 2: return_trace (u.format2.sanitize (c, base)); @@ -558,6 +563,7 @@ struct StateTable { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && + hb_barrier () && nClasses >= 4 /* Ensure pre-defined classes fit. */ && classTable.sanitize (c, this)))) return_trace (false); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh index 815a1fd2aa9..4fbec332eb7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh @@ -138,6 +138,7 @@ struct FeatureName { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && (base+settingTableZ).sanitize (c, nSettings))); } @@ -200,6 +201,7 @@ struct feat { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && namesZ.sanitize (c, featureNameCount, this))); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh index 8fd3990f887..ee08da172ea 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh @@ -185,6 +185,7 @@ struct ActionSubrecord TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (u.header.actionType) { @@ -220,6 +221,7 @@ struct PostcompensationActionChain TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); unsigned int offset = min_size; for (unsigned int i = 0; i < count; i++) @@ -389,6 +391,7 @@ struct just TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && horizData.sanitize (c, this, this) && vertData.sanitize (c, this, this))); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh index 35d7c84c2bc..0de54e0a022 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh @@ -54,6 +54,7 @@ kerxTupleKern (int value, unsigned int offset = value; const FWORD *pv = &StructAtOffset (base, offset); if (unlikely (!c->sanitizer.check_array (pv, tupleCount))) return 0; + hb_barrier (); return *pv; } @@ -259,6 +260,7 @@ struct KerxSubTableFormat1 depth = 0; return; } + hb_barrier (); hb_mask_t kern_mask = c->plan->kern_mask; @@ -389,6 +391,7 @@ struct KerxSubTableFormat2 kern_idx = Types::offsetToIndex (kern_idx, this, arrayZ.arrayZ); const FWORD *v = &arrayZ[kern_idx]; if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), this, c); } @@ -429,6 +432,7 @@ struct KerxSubTableFormat2 return_trace (likely (c->check_struct (this) && leftClassTable.sanitize (c, this) && rightClassTable.sanitize (c, this) && + hb_barrier () && c->check_range (this, array))); } @@ -509,6 +513,7 @@ struct KerxSubTableFormat4 double the ankrActionIndex to get the correct offset here. */ const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2]; if (!c->sanitizer.check_array (data, 2)) return; + hb_barrier (); unsigned int markControlPoint = *data++; unsigned int currControlPoint = *data++; hb_position_t markX = 0; @@ -537,6 +542,7 @@ struct KerxSubTableFormat4 double the ankrActionIndex to get the correct offset here. */ const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2]; if (!c->sanitizer.check_array (data, 2)) return; + hb_barrier (); unsigned int markAnchorPoint = *data++; unsigned int currAnchorPoint = *data++; const Anchor &markAnchor = c->ankr_table->get_anchor (c->buffer->info[mark].codepoint, @@ -557,6 +563,7 @@ struct KerxSubTableFormat4 by 4 to get the correct offset for the given action. */ const FWORD *data = (const FWORD *) &ankrData[entry.data.ankrActionIndex * 4]; if (!c->sanitizer.check_array (data, 4)) return; + hb_barrier (); int markX = *data++; int markY = *data++; int currX = *data++; @@ -639,6 +646,7 @@ struct KerxSubTableFormat6 if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; const FWORD32 *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD32)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c); } else @@ -649,6 +657,7 @@ struct KerxSubTableFormat6 unsigned int offset = l + r; const FWORD *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + hb_barrier (); return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c); } } @@ -674,6 +683,7 @@ struct KerxSubTableFormat6 { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && (is_long () ? ( u.l.rowIndexTable.sanitize (c, this) && @@ -787,9 +797,10 @@ struct KerxSubTable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.header.sanitize (c) || - u.header.length <= u.header.static_size || - !c->check_range (this, u.header.length)) + if (!(u.header.sanitize (c) && + hb_barrier () && + u.header.length >= u.header.static_size && + c->check_range (this, u.header.length))) return_trace (false); return_trace (dispatch (c)); @@ -936,9 +947,10 @@ struct KerxTable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!thiz()->version.sanitize (c) || - (unsigned) thiz()->version < (unsigned) T::minVersion || - !thiz()->tableCount.sanitize (c))) + if (unlikely (!(thiz()->version.sanitize (c) && + hb_barrier () && + (unsigned) thiz()->version >= (unsigned) T::minVersion && + thiz()->tableCount.sanitize (c)))) return_trace (false); typedef typename T::SubTable SubTable; @@ -949,6 +961,7 @@ struct KerxTable { if (unlikely (!st->u.header.sanitize (c))) return_trace (false); + hb_barrier (); /* OpenType kern table has 2-byte subtable lengths. That's limiting. * MS implementation also only supports one subtable, of format 0, * anyway. Certain versions of some fonts, like Calibry, contain diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh index f41ecc197fb..06c9334b370 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh @@ -259,7 +259,9 @@ struct ContextualSubtable unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint; const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; - if (!replacement->sanitize (&c->sanitizer) || !*replacement) + if (!(replacement->sanitize (&c->sanitizer) && + hb_barrier () && + *replacement)) replacement = nullptr; } if (replacement) @@ -287,7 +289,9 @@ struct ContextualSubtable unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint; const UnsizedArrayOf &subs_old = (const UnsizedArrayOf &) subs; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; - if (!replacement->sanitize (&c->sanitizer) || !*replacement) + if (!(replacement->sanitize (&c->sanitizer) && + hb_barrier () && + *replacement)) replacement = nullptr; } if (replacement) @@ -315,7 +319,7 @@ struct ContextualSubtable bool has_glyph_classes; unsigned int mark; const ContextualSubtable *table; - const UnsizedListOfOffset16To, HBUINT, false> &subs; + const UnsizedListOfOffset16To, HBUINT, void, false> &subs; }; bool apply (hb_aat_apply_context_t *c) const @@ -336,6 +340,7 @@ struct ContextualSubtable unsigned int num_entries = 0; if (unlikely (!machine.sanitize (c, &num_entries))) return_trace (false); + hb_barrier (); if (!Types::extended) return_trace (substitutionTables.sanitize (c, this, 0)); @@ -359,7 +364,7 @@ struct ContextualSubtable protected: StateTable machine; - NNOffsetTo, HBUINT, false>, HBUINT> + NNOffsetTo, HBUINT, void, false>, HBUINT> substitutionTables; public: DEFINE_SIZE_STATIC (20); @@ -513,6 +518,7 @@ struct LigatureSubtable if (unlikely (!buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]))) return; if (unlikely (!actionData->sanitize (&c->sanitizer))) break; + hb_barrier (); action = *actionData; uint32_t uoffset = action & LigActionOffset; @@ -523,6 +529,7 @@ struct LigatureSubtable component_idx = Types::wordOffsetToIndex (component_idx, table, component.arrayZ); const HBUINT16 &componentData = component[component_idx]; if (unlikely (!componentData.sanitize (&c->sanitizer))) break; + hb_barrier (); ligature_idx += componentData; DEBUG_MSG (APPLY, nullptr, "Action store %d last %d", @@ -533,6 +540,7 @@ struct LigatureSubtable ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ); const HBGlyphID16 &ligatureData = ligature[ligature_idx]; if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break; + hb_barrier (); hb_codepoint_t lig = ligatureData; DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig); @@ -587,6 +595,7 @@ struct LigatureSubtable TRACE_SANITIZE (this); /* The rest of array sanitizations are done at run-time. */ return_trace (c->check_struct (this) && machine.sanitize (c) && + hb_barrier () && ligAction && component && ligature); } @@ -765,6 +774,7 @@ struct InsertionSubtable unsigned int start = entry.data.markedInsertIndex; const HBGlyphID16 *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; + hb_barrier (); bool before = flags & MarkedInsertBefore; @@ -793,6 +803,7 @@ struct InsertionSubtable unsigned int start = entry.data.currentInsertIndex; const HBGlyphID16 *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; + hb_barrier (); bool before = flags & CurrentInsertBefore; @@ -849,6 +860,7 @@ struct InsertionSubtable TRACE_SANITIZE (this); /* The rest of array sanitizations are done at run-time. */ return_trace (c->check_struct (this) && machine.sanitize (c) && + hb_barrier () && insertionAction); } @@ -944,9 +956,10 @@ struct ChainSubtable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!length.sanitize (c) || - length <= min_size || - !c->check_range (this, length)) + if (!(length.sanitize (c) && + hb_barrier () && + length >= min_size && + c->check_range (this, length))) return_trace (false); hb_sanitize_with_object_t with (c, this); @@ -1089,9 +1102,10 @@ struct Chain bool sanitize (hb_sanitize_context_t *c, unsigned int version HB_UNUSED) const { TRACE_SANITIZE (this); - if (!length.sanitize (c) || - length < min_size || - !c->check_range (this, length)) + if (!(length.sanitize (c) && + hb_barrier () && + length >= min_size && + c->check_range (this, length))) return_trace (false); if (!c->check_array (featureZ.arrayZ, featureCount)) @@ -1103,6 +1117,7 @@ struct Chain { if (!subtable->sanitize (c)) return_trace (false); + hb_barrier (); subtable = &StructAfter> (*subtable); } @@ -1173,7 +1188,10 @@ struct mortmorx bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!version.sanitize (c) || !version || !chainCount.sanitize (c)) + if (!(version.sanitize (c) && + hb_barrier () && + version && + chainCount.sanitize (c))) return_trace (false); const Chain *chain = &firstChain; @@ -1182,6 +1200,7 @@ struct mortmorx { if (!chain->sanitize (c, version)) return_trace (false); + hb_barrier (); chain = &StructAfter> (*chain); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh index 51b650fc33c..9840d3a5541 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh @@ -144,6 +144,7 @@ struct opbd TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this) || version.major != 1)) return_trace (false); + hb_barrier (); switch (format) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh index c72c0865d3e..345a236e95e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh @@ -134,6 +134,7 @@ struct TrackData { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && sizeTable.sanitize (c, base, nSizes) && trackTable.sanitize (c, nTracks, base, nSizes))); } @@ -203,6 +204,7 @@ struct trak TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && horizData.sanitize (c, this, this) && vertData.sanitize (c, this, this))); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h index 9af27400886..c682a2f6d78 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h @@ -40,7 +40,7 @@ HB_BEGIN_DECLS * @HB_AAT_LAYOUT_FEATURE_TYPE_INVALID: Initial, unset feature type * @HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC: [All Typographic Features](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type0) * @HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES: [Ligatures](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type1) - * @HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION: [Cursive Connection](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type2) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION: [Cursive Connection](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type2) * @HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE: [Letter Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type3) * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION: [Vertical Substitution](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type4) * @HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT: [Linguistic Rearrangement](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type5) @@ -88,7 +88,7 @@ typedef enum HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC = 0, HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, - HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION = 2, + HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION = 2, HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT = 5, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-ltag-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-ltag-table.hh index 6d771e1513e..c974025d446 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-ltag-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-ltag-table.hh @@ -46,7 +46,9 @@ struct FTStringRange bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && (base+tag).sanitize (c, length)); + return_trace (c->check_struct (this) && + hb_barrier () && + (base+tag).sanitize (c, length)); } protected: @@ -73,6 +75,7 @@ struct ltag { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version >= 1 && tagRanges.sanitize (c, this))); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-array.hh b/src/3rdparty/harfbuzz-ng/src/hb-array.hh index 760f90259c8..9037179bc51 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-array.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-array.hh @@ -47,6 +47,8 @@ enum hb_not_found_t template struct hb_array_t : hb_iter_with_fallback_t, Type&> { + static constexpr bool realloc_move = true; + /* * Constructors. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh index 303dfe6d047..366fb32b7de 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh @@ -118,12 +118,12 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) */ #ifndef _hb_compiler_memory_r_barrier #if defined(__ATOMIC_ACQUIRE) // gcc-like -#define _hb_compiler_memory_r_barrier() asm volatile("": : :"memory") +static inline void _hb_compiler_memory_r_barrier () { asm volatile("": : :"memory"); } #elif !defined(_MSC_VER) #include #define _hb_compiler_memory_r_barrier() std::atomic_signal_fence (std::memory_order_acquire) #else -#define _hb_compiler_memory_r_barrier() do {} while (0) +static inline void _hb_compiler_memory_r_barrier () {} #endif #endif @@ -218,5 +218,11 @@ struct hb_atomic_ptr_t T *v = nullptr; }; +static inline bool hb_barrier () +{ + _hb_compiler_memory_r_barrier (); + return true; +} + #endif /* HB_ATOMIC_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh b/src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh index e765a479ae6..26262518070 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh @@ -359,8 +359,8 @@ struct hb_bit_set_invertible_t typedef hb_codepoint_t __item_t__; hb_codepoint_t __item__ () const { return v; } bool __more__ () const { return v != INVALID; } - void __next__ () { s->next (&v); if (l) l--; } - void __prev__ () { s->previous (&v); } + void __next__ () { s->next (&v); if (likely (l)) l--; } + void __prev__ () { s->previous (&v); l++; } unsigned __len__ () const { return l; } iter_t end () const { return iter_t (*s, false); } bool operator != (const iter_t& o) const diff --git a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h index 9fcce6d9ac4..ad19f9a3e94 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h @@ -56,7 +56,7 @@ HB_BEGIN_DECLS /** * HB_SCRIPT_CANADIAN_ABORIGINAL: * - * Use #HB_SCRIPT_CANADIAN_SYLLABICS instead: + * Use #HB_SCRIPT_CANADIAN_SYLLABICS instead. * * Deprecated: 0.9.20 */ @@ -301,6 +301,15 @@ hb_font_get_glyph_shape (hb_font_t *font, hb_draw_funcs_t *dfuncs, void *draw_data); +/** + * HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION: + * + * Use #HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION instead. + * + * Deprecated: 8.3.0 + */ +#define HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION + #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc b/src/3rdparty/harfbuzz-ng/src/hb-ft.cc index 6ca3f854655..955a9081e09 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ft.cc @@ -225,7 +225,7 @@ _hb_ft_hb_font_check_changed (hb_font_t *font, * Sets the FT_Load_Glyph load flags for the specified #hb_font_t. * * For more information, see - * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx + * * * This function works with #hb_font_t objects created by * hb_ft_font_create() or hb_ft_font_create_referenced(). @@ -253,7 +253,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) * Fetches the FT_Load_Glyph load flags of the specified #hb_font_t. * * For more information, see - * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx + * * * This function works with #hb_font_t objects created by * hb_ft_font_create() or hb_ft_font_create_referenced(). diff --git a/src/3rdparty/harfbuzz-ng/src/hb-map.hh b/src/3rdparty/harfbuzz-ng/src/hb-map.hh index 13d62054c11..45a02b830c3 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-map.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-map.hh @@ -42,10 +42,34 @@ template struct hb_hashmap_t { + static constexpr bool realloc_move = true; + hb_hashmap_t () { init (); } ~hb_hashmap_t () { fini (); } - hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { alloc (o.population); hb_copy (o, *this); } + hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () + { + if (unlikely (!o.mask)) return; + + if (item_t::is_trivial) + { + items = (item_t *) hb_malloc (sizeof (item_t) * (o.mask + 1)); + if (unlikely (!items)) + { + successful = false; + return; + } + population = o.population; + occupancy = o.occupancy; + mask = o.mask; + prime = o.prime; + max_chain_length = o.max_chain_length; + memcpy (items, o.items, sizeof (item_t) * (mask + 1)); + return; + } + + alloc (o.population); hb_copy (o, *this); + } hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); } hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); alloc (o.population); hb_copy (o, *this); return *this; } hb_hashmap_t& operator= (hb_hashmap_t&& o) { hb_swap (*this, o); return *this; } @@ -209,9 +233,10 @@ struct hb_hashmap_t old_items[i].hash, std::move (old_items[i].value)); } - if (!item_t::is_trivial) - old_items[i].~item_t (); } + if (!item_t::is_trivial) + for (unsigned int i = 0; i < old_size; i++) + old_items[i].~item_t (); hb_free (old_items); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-file.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-file.hh index 04f144a72c7..1157ea46d0d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-file.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-file.hh @@ -267,6 +267,7 @@ struct TTCHeader { TRACE_SANITIZE (this); if (unlikely (!u.header.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.header.version.major) { case 2: /* version 2 is compatible with version 1 */ case 1: return_trace (u.version1.sanitize (c)); @@ -302,6 +303,7 @@ struct ResourceRecord TRACE_SANITIZE (this); return_trace (c->check_struct (this) && offset.sanitize (c, data_base) && + hb_barrier () && get_face (data_base).sanitize (c)); } @@ -337,6 +339,7 @@ struct ResourceTypeRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && resourcesZ.sanitize (c, type_base, get_resource_count (), data_base)); @@ -385,6 +388,7 @@ struct ResourceMap { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && typeList.sanitize (c, this, &(this+typeList), data_base)); @@ -428,6 +432,7 @@ struct ResourceForkHeader { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && data.sanitize (c, this, dataLen) && map.sanitize (c, this, &(this+data))); } @@ -508,6 +513,7 @@ struct OpenTypeFontFile { TRACE_SANITIZE (this); if (unlikely (!u.tag.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.tag) { case CFFTag: /* All the non-collection tags */ case TrueTag: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh index d3fdd1caf52..6967bca3d4b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh @@ -309,7 +309,7 @@ struct _hb_has_null static Type *get_crap () { return &Crap (Type); } }; -template +template struct OffsetTo : Offset { using target_t = Type; @@ -335,22 +335,22 @@ struct OffsetTo : Offset } template + hb_enable_if (hb_is_convertible (const Base, const BaseType *))> friend const Type& operator + (const Base &base, const OffsetTo &offset) { return offset ((const void *) base); } template + hb_enable_if (hb_is_convertible (const Base, const BaseType *))> friend const Type& operator + (const OffsetTo &offset, const Base &base) { return offset ((const void *) base); } template + hb_enable_if (hb_is_convertible (Base, BaseType *))> friend Type& operator + (Base &&base, OffsetTo &offset) { return offset ((void *) base); } template + hb_enable_if (hb_is_convertible (Base, BaseType *))> friend Type& operator + (OffsetTo &offset, Base &&base) { return offset ((void *) base); } - template + template bool serialize_subset (hb_subset_context_t *c, const OffsetTo& src, - const void *src_base, Ts&&... ds) + const Base *src_base, Ts&&... ds) { *this = 0; if (src.is_null ()) @@ -414,10 +414,11 @@ struct OffsetTo : Offset const void *src_base, unsigned dst_bias = 0) { return serialize_copy (c, src, src_base, dst_bias, hb_serialize_context_t::Head); } - bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const + bool sanitize_shallow (hb_sanitize_context_t *c, const BaseType *base) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); //if (unlikely (this->is_null ())) return_trace (true); if (unlikely ((const char *) base + (unsigned) *this < (const char *) base)) return_trace (false); return_trace (true); @@ -427,10 +428,11 @@ struct OffsetTo : Offset #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE #endif - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const + bool sanitize (hb_sanitize_context_t *c, const BaseType *base, Ts&&... ds) const { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && + hb_barrier () && (this->is_null () || c->dispatch (StructAtOffset (base, *this), std::forward (ds)...) || neuter (c))); @@ -445,14 +447,14 @@ struct OffsetTo : Offset DEFINE_SIZE_STATIC (sizeof (OffsetType)); }; /* Partial specializations. */ -template using Offset16To = OffsetTo; -template using Offset24To = OffsetTo; -template using Offset32To = OffsetTo; +template using Offset16To = OffsetTo; +template using Offset24To = OffsetTo; +template using Offset32To = OffsetTo; -template using NNOffsetTo = OffsetTo; -template using NNOffset16To = Offset16To; -template using NNOffset24To = Offset24To; -template using NNOffset32To = Offset32To; +template using NNOffsetTo = OffsetTo; +template using NNOffset16To = Offset16To; +template using NNOffset24To = Offset24To; +template using NNOffset32To = Offset32To; /* @@ -536,6 +538,7 @@ struct UnsizedArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) return_trace (false); @@ -555,17 +558,17 @@ struct UnsizedArrayOf }; /* Unsized array of offset's */ -template -using UnsizedArray16OfOffsetTo = UnsizedArrayOf>; +template +using UnsizedArray16OfOffsetTo = UnsizedArrayOf>; /* Unsized array of offsets relative to the beginning of the array itself. */ -template -struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo +template +struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo { const Type& operator [] (int i_) const { unsigned int i = (unsigned int) i_; - const OffsetTo *p = &this->arrayZ[i]; + const OffsetTo *p = &this->arrayZ[i]; if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Null (Type); /* Overflowed. */ _hb_compiler_memory_r_barrier (); return this+*p; @@ -573,7 +576,7 @@ struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo *p = &this->arrayZ[i]; + const OffsetTo *p = &this->arrayZ[i]; if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Crap (Type); /* Overflowed. */ _hb_compiler_memory_r_barrier (); return this+*p; @@ -583,7 +586,7 @@ struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo + return_trace ((UnsizedArray16OfOffsetTo ::sanitize (c, count, this, std::forward (ds)...))); } }; @@ -725,6 +728,7 @@ struct ArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -735,7 +739,9 @@ struct ArrayOf bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (len.sanitize (c) && c->check_array_sized (arrayZ, len, sizeof (LenType))); + return_trace (len.sanitize (c) && + hb_barrier () && + c->check_array_sized (arrayZ, len, sizeof (LenType))); } public: @@ -866,6 +872,7 @@ struct HeadlessArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -878,6 +885,7 @@ struct HeadlessArrayOf { TRACE_SANITIZE (this); return_trace (lenP1.sanitize (c) && + hb_barrier () && (!lenP1 || c->check_array_sized (arrayZ, lenP1 - 1, sizeof (LenType)))); } @@ -919,6 +927,7 @@ struct ArrayOfM1 TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], std::forward (ds)...))) @@ -931,6 +940,7 @@ struct ArrayOfM1 { TRACE_SANITIZE (this); return_trace (lenM1.sanitize (c) && + hb_barrier () && (c->check_array_sized (arrayZ, lenM1 + 1, sizeof (LenType)))); } @@ -1104,6 +1114,7 @@ struct VarSizedBinSearchArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true); + hb_barrier (); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, std::forward (ds)...))) @@ -1130,6 +1141,7 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); return_trace (header.sanitize (c) && + hb_barrier () && Type::static_size <= header.unitSize && c->check_range (bytesZ.arrayZ, header.nUnits, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh index 923a32b26f8..4fdba197ac7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh @@ -78,7 +78,8 @@ struct CFFIndex hb_requires (hb_is_iterable (Iterable))> bool serialize (hb_serialize_context_t *c, const Iterable &iterable, - const unsigned *p_data_size = nullptr) + const unsigned *p_data_size = nullptr, + unsigned min_off_size = 0) { TRACE_SERIALIZE (this); unsigned data_size; @@ -88,7 +89,7 @@ struct CFFIndex total_size (iterable, &data_size); auto it = hb_iter (iterable); - if (unlikely (!serialize_header (c, +it, data_size))) return_trace (false); + if (unlikely (!serialize_header (c, +it, data_size, min_off_size))) return_trace (false); unsigned char *ret = c->allocate_size (data_size, false); if (unlikely (!ret)) return_trace (false); for (const auto &_ : +it) @@ -111,11 +112,13 @@ struct CFFIndex hb_requires (hb_is_iterator (Iterator))> bool serialize_header (hb_serialize_context_t *c, Iterator it, - unsigned data_size) + unsigned data_size, + unsigned min_off_size = 0) { TRACE_SERIALIZE (this); unsigned off_size = (hb_bit_storage (data_size + 1) + 7) / 8; + off_size = hb_max(min_off_size, off_size); /* serialize CFFIndex header */ if (unlikely (!c->extend_min (this))) return_trace (false); @@ -195,7 +198,7 @@ struct CFFIndex template - static unsigned total_size (const Iterable &iterable, unsigned *data_size = nullptr) + static unsigned total_size (const Iterable &iterable, unsigned *data_size = nullptr, unsigned min_off_size = 0) { auto it = + hb_iter (iterable); if (!it) @@ -211,6 +214,7 @@ struct CFFIndex if (data_size) *data_size = total; unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8; + off_size = hb_max(min_off_size, off_size); return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total; } @@ -274,8 +278,10 @@ struct CFFIndex { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && (count == 0 || /* empty INDEX */ (count < count + 1u && + hb_barrier () && c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 && c->check_array (offsets, offSize, count + 1u) && c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count)))))); @@ -412,6 +418,7 @@ struct FDSelect0 { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this)))) return_trace (false); + hb_barrier (); if (unlikely (!c->check_array (fds, c->get_num_glyphs ()))) return_trace (false); @@ -438,7 +445,9 @@ struct FDSelect3_4_Range bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const { TRACE_SANITIZE (this); - return_trace (first < c->get_num_glyphs () && (fd < fdcount)); + return_trace (c->check_struct (this) && + hb_barrier () && + first < c->get_num_glyphs () && (fd < fdcount)); } GID_TYPE first; @@ -456,15 +465,20 @@ struct FDSelect3_4 bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this) || !ranges.sanitize (c, nullptr, fdcount) || - (nRanges () == 0) || ranges[0].first != 0)) + if (unlikely (!(c->check_struct (this) && + ranges.sanitize (c, nullptr, fdcount) && + hb_barrier () && + (nRanges () != 0) && + ranges[0].first == 0))) return_trace (false); for (unsigned int i = 1; i < nRanges (); i++) if (unlikely (ranges[i - 1].first >= ranges[i].first)) return_trace (false); - if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ()))) + if (unlikely (!(sentinel().sanitize (c) && + hb_barrier () && + (sentinel() == c->get_num_glyphs ())))) return_trace (false); return_trace (true); @@ -559,6 +573,7 @@ struct FDSelect TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh index 1e81dcb5e3a..c869e90554b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh @@ -275,6 +275,7 @@ struct Encoding TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (table_format ()) { @@ -376,13 +377,13 @@ struct Charset1_2 { bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) - return_trace (false); num_glyphs--; unsigned i; for (i = 0; num_glyphs > 0; i++) { - if (unlikely (!ranges[i].sanitize (c) || (num_glyphs < ranges[i].nLeft + 1))) + if (unlikely (!(ranges[i].sanitize (c) && + hb_barrier () && + (num_glyphs >= ranges[i].nLeft + 1)))) return_trace (false); num_glyphs -= (ranges[i].nLeft + 1); } @@ -615,6 +616,7 @@ struct Charset TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { @@ -1055,6 +1057,7 @@ struct cff1 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 1)); } @@ -1085,14 +1088,17 @@ struct cff1 nameIndex = &cff->nameIndex (cff); if ((nameIndex == &Null (CFF1NameIndex)) || !nameIndex->sanitize (&sc)) goto fail; + hb_barrier (); topDictIndex = &StructAtOffset (nameIndex, nameIndex->get_size ()); if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0)) goto fail; + hb_barrier (); { /* parse top dict */ const hb_ubytes_t topDictStr = (*topDictIndex)[0]; if (unlikely (!topDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff1_top_dict_interp_env_t env (topDictStr); cff1_top_dict_interpreter_t top_interp (env); if (unlikely (!top_interp.interpret (topDict))) goto fail; @@ -1104,6 +1110,7 @@ struct cff1 { charset = &StructAtOffsetOrNull (cff, topDict.CharsetOffset); if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc, &num_charset_entries))) goto fail; + hb_barrier (); } fdCount = 1; @@ -1114,6 +1121,7 @@ struct cff1 if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) || (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count))) goto fail; + hb_barrier (); fdCount = fdArray->count; } @@ -1134,21 +1142,25 @@ struct cff1 { encoding = &StructAtOffsetOrNull (cff, topDict.EncodingOffset); if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) goto fail; + hb_barrier (); } } stringIndex = &StructAtOffset (topDictIndex, topDictIndex->get_size ()); if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc)) goto fail; + hb_barrier (); globalSubrs = &StructAtOffset (stringIndex, stringIndex->get_size ()); if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc)) goto fail; + hb_barrier (); charStrings = &StructAtOffsetOrNull (cff, topDict.charStringsOffset); if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc))) goto fail; + hb_barrier (); num_glyphs = charStrings->count; if (num_glyphs != sc.get_num_glyphs ()) @@ -1166,6 +1178,7 @@ struct cff1 { hb_ubytes_t fontDictStr = (*fdArray)[i]; if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff1_font_dict_values_t *font; cff1_top_dict_interp_env_t env (fontDictStr); cff1_font_dict_interpreter_t font_interp (env); @@ -1177,6 +1190,7 @@ struct cff1 PRIVDICTVAL *priv = &privateDicts[i]; const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + hb_barrier (); num_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); priv->init (); @@ -1186,6 +1200,7 @@ struct cff1 if (priv->localSubrs != &Null (CFF1Subrs) && unlikely (!priv->localSubrs->sanitize (&sc))) goto fail; + hb_barrier (); } } else /* non-CID */ @@ -1195,6 +1210,7 @@ struct cff1 const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + hb_barrier (); num_interp_env_t env (privDictStr); dict_interpreter_t priv_interp (env); priv->init (); @@ -1204,6 +1220,7 @@ struct cff1 if (priv->localSubrs != &Null (CFF1Subrs) && unlikely (!priv->localSubrs->sanitize (&sc))) goto fail; + hb_barrier (); } return; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh index af24bb9986f..652748b7375 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh @@ -90,6 +90,7 @@ struct CFF2FDSelect TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (format) { @@ -115,7 +116,10 @@ struct CFF2VariationStore bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this)) && c->check_range (&varStore, size) && varStore.sanitize (c)); + return_trace (c->check_struct (this) && + hb_barrier () && + c->check_range (&varStore, size) && + varStore.sanitize (c)); } bool serialize (hb_serialize_context_t *c, const CFF2VariationStore *varStore) @@ -384,6 +388,7 @@ struct cff2 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version.major == 2)); } @@ -414,6 +419,7 @@ struct cff2 { /* parse top dict */ hb_ubytes_t topDictStr = (cff2 + cff2->topDict).as_ubytes (cff2->topDictSize); if (unlikely (!topDictStr.sanitize (&sc))) goto fail; + hb_barrier (); num_interp_env_t env (topDictStr); cff2_top_dict_interpreter_t top_interp (env); topDict.init (); @@ -430,6 +436,7 @@ struct cff2 (charStrings == &Null (CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) || (globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) || (fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) || + !hb_barrier () || (((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count))))) goto fail; @@ -446,6 +453,7 @@ struct cff2 { const hb_ubytes_t fontDictStr = (*fdArray)[i]; if (unlikely (!fontDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff2_font_dict_values_t *font; num_interp_env_t env (fontDictStr); cff2_font_dict_interpreter_t font_interp (env); @@ -456,6 +464,7 @@ struct cff2 const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff2, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); if (unlikely (!privDictStr.sanitize (&sc))) goto fail; + hb_barrier (); cff2_priv_dict_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); privateDicts[i].init (); @@ -465,6 +474,7 @@ struct cff2 if (privateDicts[i].localSubrs != &Null (CFF2Subrs) && unlikely (!privateDicts[i].localSubrs->sanitize (&sc))) goto fail; + hb_barrier (); } return; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh index 30401b1926e..e2e25818557 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh @@ -556,6 +556,7 @@ struct CmapSubtableFormat4 TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); if (unlikely (!c->check_range (this, length))) { @@ -742,10 +743,11 @@ struct CmapSubtableLongSegmented unsigned num_glyphs) const { hb_codepoint_t last_end = 0; - for (unsigned i = 0; i < this->groups.len; i++) + unsigned count = this->groups.len; + for (unsigned i = 0; i < count; i++) { - hb_codepoint_t start = this->groups[i].startCharCode; - hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups[i].endCharCode, + hb_codepoint_t start = this->groups.arrayZ[i].startCharCode; + hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups.arrayZ[i].endCharCode, (hb_codepoint_t) HB_UNICODE_MAX); if (unlikely (start > end || start < last_end)) { // Range is not in order and is invalid, skip it. @@ -754,7 +756,7 @@ struct CmapSubtableLongSegmented last_end = end; - hb_codepoint_t gid = this->groups[i].glyphID; + hb_codepoint_t gid = this->groups.arrayZ[i].glyphID; if (!gid) { if (T::formatNumber == 13) continue; @@ -767,9 +769,9 @@ struct CmapSubtableLongSegmented mapping->alloc (mapping->get_population () + end - start + 1); + unicodes->add_range (start, end); for (unsigned cp = start; cp <= end; cp++) { - unicodes->add (cp); mapping->set (cp, gid); gid += T::increment; } @@ -1427,6 +1429,7 @@ struct CmapSubtable { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 0: return_trace (u.format0 .sanitize (c)); case 4: return_trace (u.format4 .sanitize (c)); @@ -2060,6 +2063,7 @@ struct cmap { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && likely (version == 0) && encodingRecord.sanitize (c, this)); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh index cbcf6f5f22f..8582dbe27da 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh @@ -71,6 +71,7 @@ struct DeviceRecord { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && c->check_range (this, sizeDeviceRecord))); } @@ -152,6 +153,7 @@ struct hdmx { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) && min_size + numRecords * sizeDeviceRecord > numRecords * sizeDeviceRecord && sizeDeviceRecord >= DeviceRecord::min_size && diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh index 770cf52d173..4cb6c15c677 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh @@ -103,6 +103,7 @@ struct head { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && version.major == 1 && magicNumber == 0x5F0F3CF5u); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh index d9c9bd35377..27becfda3d4 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh @@ -50,7 +50,9 @@ struct _hea bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && likely (version.major == 1)); + return_trace (c->check_struct (this) && + hb_barrier () && + likely (version.major == 1)); } public: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh index ffa11bc2496..39444d803f0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh @@ -79,6 +79,7 @@ struct KernSubTableFormat3 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_range (kernValueZ, kernValueCount * sizeof (FWORD) + glyphCount * 2 + @@ -147,9 +148,10 @@ struct KernSubTable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.header.sanitize (c) || - u.header.length < u.header.min_size || - !c->check_range (this, u.header.length))) return_trace (false); + if (unlikely (!(u.header.sanitize (c) && + hb_barrier () && + u.header.length >= u.header.min_size && + c->check_range (this, u.header.length)))) return_trace (false); return_trace (dispatch (c)); } @@ -337,6 +339,7 @@ struct kern { TRACE_SANITIZE (this); if (!u.version32.sanitize (c)) return_trace (false); + hb_barrier (); return_trace (dispatch (c)); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh index 2b7e9e4b184..a23b6377d19 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh @@ -135,6 +135,7 @@ struct BaseCoord { TRACE_SANITIZE (this); if (unlikely (!u.format.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -496,6 +497,7 @@ struct BASE { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && likely (version.major == 1) && hAxis.sanitize (c, this) && vAxis.sanitize (c, this) && diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh index e869d8eceab..6b359cceb72 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh @@ -64,7 +64,7 @@ struct hb_collect_feature_substitutes_with_var_context_t const hb_hashmap_t *axes_location; hb_hashmap_t> *record_cond_idx_map; hb_hashmap_t *feature_substitutes_map; - bool& insert_catch_all_feature_variation_record; + hb_set_t& catch_all_record_feature_idxes; // not stored in subset_plan hb_set_t *feature_indices; @@ -142,6 +142,8 @@ struct hb_subset_layout_context_t : const hb_map_t *feature_index_map; const hb_hashmap_t *feature_substitutes_map; hb_hashmap_t> *feature_record_cond_idx_map; + const hb_set_t *catch_all_record_feature_idxes; + const hb_hashmap_t> *feature_idx_tag_map; unsigned cur_script_index; unsigned cur_feature_var_record_idx; @@ -164,6 +166,8 @@ struct hb_subset_layout_context_t : feature_index_map = &c_->plan->gsub_features; feature_substitutes_map = &c_->plan->gsub_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gsub_feature_record_cond_idx_map; + catch_all_record_feature_idxes = &c_->plan->gsub_old_features; + feature_idx_tag_map = &c_->plan->gsub_old_feature_idx_tag_map; } else { @@ -172,6 +176,8 @@ struct hb_subset_layout_context_t : feature_index_map = &c_->plan->gpos_features; feature_substitutes_map = &c_->plan->gpos_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gpos_feature_record_cond_idx_map; + catch_all_record_feature_idxes = &c_->plan->gpos_old_features; + feature_idx_tag_map = &c_->plan->gpos_old_feature_idx_tag_map; } } @@ -454,6 +460,7 @@ struct FeatureParamsSize { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); /* This subtable has some "history", if you will. Some earlier versions of * Adobe tools calculated the offset of the FeatureParams subtable from the @@ -820,6 +827,7 @@ struct Feature TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) return_trace (false); + hb_barrier (); /* Some earlier versions of Adobe tools calculated the offset of the * FeatureParams subtable from the beginning of the FeatureList table! @@ -838,6 +846,7 @@ struct Feature unsigned int orig_offset = featureParams; if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) return_trace (false); + hb_barrier (); if (featureParams == 0 && closure && closure->tag == HB_TAG ('s','i','z','e') && @@ -900,7 +909,8 @@ struct Record { TRACE_SANITIZE (this); const Record_sanitize_closure_t closure = {tag, base}; - return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure)); + return_trace (c->check_struct (this) && + offset.sanitize (c, base, &closure)); } Tag tag; /* 4-byte Tag identifier */ @@ -1371,10 +1381,20 @@ struct Lookup if (lookupFlag & LookupFlag::UseMarkFilteringSet) { - if (unlikely (!c->serializer->extend (out))) return_trace (false); const HBUINT16 &markFilteringSet = StructAfter (subTable); - HBUINT16 &outMarkFilteringSet = StructAfter (out->subTable); - outMarkFilteringSet = markFilteringSet; + hb_codepoint_t *idx; + if (!c->plan->used_mark_sets_map.has (markFilteringSet, &idx)) + { + unsigned new_flag = lookupFlag; + new_flag &= ~LookupFlag::UseMarkFilteringSet; + out->lookupFlag = new_flag; + } + else + { + if (unlikely (!c->serializer->extend (out))) return_trace (false); + HBUINT16 &outMarkFilteringSet = StructAfter (out->subTable); + outMarkFilteringSet = *idx; + } } // Always keep the lookup even if it's empty. The rest of layout subsetting depends on lookup @@ -1391,6 +1411,7 @@ struct Lookup { TRACE_SANITIZE (this); if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); + hb_barrier (); unsigned subtables = get_subtable_count (); if (unlikely (!c->visit_subtables (subtables))) return_trace (false); @@ -1406,6 +1427,8 @@ struct Lookup if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ())) { + hb_barrier (); + /* The spec says all subtables of an Extension lookup should * have the same type, which shall not be the Extension type * itself (but we already checked for that). @@ -2156,6 +2179,7 @@ struct ClassDef { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -2534,7 +2558,9 @@ struct VarRegionList bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount)); + return_trace (c->check_struct (this) && + hb_barrier () && + axesZ.sanitize (c, axisCount * regionCount)); } bool serialize (hb_serialize_context_t *c, @@ -2728,6 +2754,7 @@ struct VarData TRACE_SANITIZE (this); return_trace (c->check_struct (this) && regionIndices.sanitize (c) && + hb_barrier () && wordCount () <= regionIndices.len && c->check_range (get_delta_bytes (), itemCount, @@ -3077,6 +3104,7 @@ struct VariationStore TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && format == 1 && regions.sanitize (c, this) && dataSets.sanitize (c, this)); @@ -3330,8 +3358,12 @@ struct ConditionFormat1 Triple axis_range (-1.f, 0.f, 1.f); Triple *axis_limit; + bool axis_set_by_user = false; if (c->axes_location->has (axis_tag, &axis_limit)) + { axis_range = *axis_limit; + axis_set_by_user = true; + } float axis_min_val = axis_range.minimum; float axis_default_val = axis_range.middle; @@ -3350,8 +3382,7 @@ struct ConditionFormat1 return DROP_RECORD_WITH_VAR; //condition met and axis pinned, drop the condition - if (c->axes_location->has (axis_tag) && - c->axes_location->get (axis_tag).is_point ()) + if (axis_set_by_user && axis_range.is_point ()) return DROP_COND_WITH_VAR; if (filter_max_val != axis_max_val || filter_min_val != axis_min_val) @@ -3365,7 +3396,6 @@ struct ConditionFormat1 condition_map->set (axisIndex, val); return KEEP_COND_WITH_VAR; } - return KEEP_RECORD_WITH_VAR; } @@ -3424,6 +3454,7 @@ struct Condition { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); default:return_trace (true); @@ -3497,12 +3528,15 @@ struct ConditionSet } bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const + hb_subset_layout_context_t *l, + bool insert_catch_all) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + if (insert_catch_all) return_trace (true); + hb_set_t *retained_cond_set = nullptr; if (l->feature_record_cond_idx_map != nullptr) retained_cond_set = l->feature_record_cond_idx_map->get (l->cur_feature_var_record_idx); @@ -3548,27 +3582,51 @@ struct FeatureTableSubstitutionRecord } void collect_feature_substitutes_with_variations (hb_hashmap_t *feature_substitutes_map, + hb_set_t& catch_all_record_feature_idxes, const hb_set_t *feature_indices, const void *base) const { if (feature_indices->has (featureIndex)) + { feature_substitutes_map->set (featureIndex, &(base+feature)); + catch_all_record_feature_idxes.add (featureIndex); + } + } + + bool serialize (hb_subset_layout_context_t *c, + unsigned feature_index, + const Feature *f, const Tag *tag) + { + TRACE_SERIALIZE (this); + hb_serialize_context_t *s = c->subset_context->serializer; + if (unlikely (!s->extend_min (this))) return_trace (false); + + uint32_t *new_feature_idx; + if (!c->feature_index_map->has (feature_index, &new_feature_idx)) + return_trace (false); + + if (!s->check_assign (featureIndex, *new_feature_idx, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + + s->push (); + bool ret = f->subset (c->subset_context, c, tag); + if (ret) s->add_link (feature, s->pop_pack ()); + else s->pop_discard (); + + return_trace (ret); } bool subset (hb_subset_layout_context_t *c, const void *base) const { TRACE_SUBSET (this); - if (!c->feature_index_map->has (featureIndex) || - c->feature_substitutes_map->has (featureIndex)) { - // Feature that is being substituted is not being retained, so we don't - // need this. + uint32_t *new_feature_index; + if (!c->feature_index_map->has (featureIndex, &new_feature_index)) return_trace (false); - } auto *out = c->subset_context->serializer->embed (this); if (unlikely (!out)) return_trace (false); - out->featureIndex = c->feature_index_map->get (featureIndex); + out->featureIndex = *new_feature_index; return_trace (out->feature.serialize_subset (c->subset_context, feature, base, c)); } @@ -3600,16 +3658,10 @@ struct FeatureTableSubstitution } void collect_lookups (const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, hb_set_t *lookup_indexes /* OUT */) const { + hb_iter (substitutions) | hb_filter (feature_indexes, &FeatureTableSubstitutionRecord::featureIndex) - | hb_filter ([feature_substitutes_map] (const FeatureTableSubstitutionRecord& record) - { - if (feature_substitutes_map == nullptr) return true; - return !feature_substitutes_map->has (record.featureIndex); - }) | hb_apply ([this, lookup_indexes] (const FeatureTableSubstitutionRecord& r) { r.collect_lookups (this, lookup_indexes); }) ; @@ -3634,11 +3686,14 @@ struct FeatureTableSubstitution void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const { for (const FeatureTableSubstitutionRecord& record : substitutions) - record.collect_feature_substitutes_with_variations (c->feature_substitutes_map, c->feature_indices, this); + record.collect_feature_substitutes_with_variations (c->feature_substitutes_map, + c->catch_all_record_feature_idxes, + c->feature_indices, this); } bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const + hb_subset_layout_context_t *l, + bool insert_catch_all) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); @@ -3647,6 +3702,22 @@ struct FeatureTableSubstitution out->version.major = version.major; out->version.minor = version.minor; + if (insert_catch_all) + { + for (unsigned feature_index : *(l->catch_all_record_feature_idxes)) + { + hb_pair_t *p; + if (!l->feature_idx_tag_map->has (feature_index, &p)) + return_trace (false); + auto *o = out->substitutions.serialize_append (c->serializer); + if (!o->serialize (l, feature_index, + reinterpret_cast (p->first), + reinterpret_cast (p->second))) + return_trace (false); + } + return_trace (true); + } + + substitutions.iter () | hb_apply (subset_record_array (l, &(out->substitutions), this)) ; @@ -3658,6 +3729,7 @@ struct FeatureTableSubstitution { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && substitutions.sanitize (c, this)); } @@ -3676,10 +3748,9 @@ struct FeatureVariationRecord void collect_lookups (const void *base, const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, hb_set_t *lookup_indexes /* OUT */) const { - return (base+substitutions).collect_lookups (feature_indexes, feature_substitutes_map, lookup_indexes); + return (base+substitutions).collect_lookups (feature_indexes, lookup_indexes); } void closure_features (const void *base, @@ -3705,14 +3776,15 @@ struct FeatureVariationRecord } } - bool subset (hb_subset_layout_context_t *c, const void *base) const + bool subset (hb_subset_layout_context_t *c, const void *base, + bool insert_catch_all = false) const { TRACE_SUBSET (this); auto *out = c->subset_context->serializer->embed (this); if (unlikely (!out)) return_trace (false); - out->conditions.serialize_subset (c->subset_context, conditions, base, c); - out->substitutions.serialize_subset (c->subset_context, substitutions, base, c); + out->conditions.serialize_subset (c->subset_context, conditions, base, c, insert_catch_all); + out->substitutions.serialize_subset (c->subset_context, substitutions, base, c, insert_catch_all); return_trace (true); } @@ -3771,9 +3843,8 @@ struct FeatureVariations if (c->universal) break; } - if (c->variation_applied && !c->universal && - !c->record_cond_idx_map->is_empty ()) - c->insert_catch_all_feature_variation_record = true; + if (c->universal || c->record_cond_idx_map->is_empty ()) + c->catch_all_record_feature_idxes.reset (); } FeatureVariations* copy (hb_serialize_context_t *c) const @@ -3783,11 +3854,17 @@ struct FeatureVariations } void collect_lookups (const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, + const hb_hashmap_t> *feature_record_cond_idx_map, hb_set_t *lookup_indexes /* OUT */) const { - for (const FeatureVariationRecord& r : varRecords) - r.collect_lookups (this, feature_indexes, feature_substitutes_map, lookup_indexes); + unsigned count = varRecords.len; + for (unsigned int i = 0; i < count; i++) + { + if (feature_record_cond_idx_map && + !feature_record_cond_idx_map->has (i)) + continue; + varRecords[i].collect_lookups (this, feature_indexes, lookup_indexes); + } } void closure_features (const hb_map_t *lookup_indexes, @@ -3832,6 +3909,13 @@ struct FeatureVariations l->cur_feature_var_record_idx = i; subset_record_array (l, &(out->varRecords), this) (varRecords[i]); } + + if (out->varRecords.len && !l->catch_all_record_feature_idxes->is_empty ()) + { + bool insert_catch_all_record = true; + subset_record_array (l, &(out->varRecords), this, insert_catch_all_record) (varRecords[0]); + } + return_trace (bool (out->varRecords)); } @@ -3839,6 +3923,7 @@ struct FeatureVariations { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && varRecords.sanitize (c, this)); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh index 662ec9d3e8c..499ad673e42 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh @@ -2051,6 +2051,7 @@ struct Rule { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_range (inputZ.arrayZ, inputZ.item_size * (inputCount ? inputCount - 1 : 0) + LookupRecord::static_size * lookupCount)); @@ -2826,6 +2827,7 @@ struct ContextFormat3 { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); unsigned int count = glyphCount; if (unlikely (!count)) return_trace (false); /* We want to access coverageZ[0] freely. */ if (unlikely (!c->check_array (coverageZ.arrayZ, count))) return_trace (false); @@ -3219,10 +3221,13 @@ struct ChainRule TRACE_SANITIZE (this); /* Hyper-optimized sanitized because this is really hot. */ if (unlikely (!backtrack.len.sanitize (c))) return_trace (false); + hb_barrier (); const auto &input = StructAfter (backtrack); if (unlikely (!input.lenP1.sanitize (c))) return_trace (false); + hb_barrier (); const auto &lookahead = StructAfter (input); if (unlikely (!lookahead.len.sanitize (c))) return_trace (false); + hb_barrier (); const auto &lookup = StructAfter (lookahead); return_trace (likely (lookup.sanitize (c))); } @@ -4121,11 +4126,14 @@ struct ChainContextFormat3 { TRACE_SANITIZE (this); if (unlikely (!backtrack.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &input = StructAfter (backtrack); if (unlikely (!input.sanitize (c, this))) return_trace (false); + hb_barrier (); if (unlikely (!input.len)) return_trace (false); /* To be consistent with Context. */ const auto &lookahead = StructAfter (input); if (unlikely (!lookahead.sanitize (c, this))) return_trace (false); + hb_barrier (); const auto &lookup = StructAfter (lookahead); return_trace (likely (lookup.sanitize (c))); } @@ -4209,6 +4217,7 @@ struct ExtensionFormat1 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && extensionLookupType != T::SubTable::Extension); } @@ -4472,13 +4481,6 @@ struct GSUBGPOSVersion1_2 if (!c->subset_context->serializer->extend_min (&out->featureVars)) return_trace (false); - // TODO(qxliu76): the current implementation doesn't correctly handle feature variations - // that are dropped by instancing when the associated conditions don't trigger. - // Since partial instancing isn't yet supported this isn't an issue yet but will - // need to be fixed for partial instancing. - - - // if all axes are pinned all feature vars are dropped. bool ret = !c->subset_context->plan->all_axes_pinned && out->featureVars.serialize_subset (c->subset_context, featureVars, this, c); @@ -4513,6 +4515,7 @@ struct GSUBGPOS { TRACE_SANITIZE (this); if (unlikely (!u.version.sanitize (c))) return_trace (false); + hb_barrier (); switch (u.version.major) { case 1: return_trace (u.version1.sanitize (c)); #ifndef HB_NO_BEYOND_64K @@ -4638,11 +4641,11 @@ struct GSUBGPOS } void feature_variation_collect_lookups (const hb_set_t *feature_indexes, - const hb_hashmap_t *feature_substitutes_map, + const hb_hashmap_t> *feature_record_cond_idx_map, hb_set_t *lookup_indexes /* OUT */) const { #ifndef HB_NO_VAR - get_feature_variations ().collect_lookups (feature_indexes, feature_substitutes_map, lookup_indexes); + get_feature_variations ().collect_lookups (feature_indexes, feature_record_cond_idx_map, lookup_indexes); #endif } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh index a1c125b11b6..0ba7eaa2c5f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh @@ -214,6 +214,7 @@ struct JSTF { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && scriptList.sanitize (c, this)); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh index b11da464b22..32e497aef60 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh @@ -333,6 +333,7 @@ struct MathKern { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_array (mathValueRecordsZ.arrayZ, 2 * heightCount + 1) && sanitize_math_value_records (c)); } @@ -984,6 +985,7 @@ struct MathVariants return_trace (c->check_struct (this) && vertGlyphCoverage.sanitize (c, this) && horizGlyphCoverage.sanitize (c, this) && + hb_barrier () && c->check_array (glyphConstruction.arrayZ, vertGlyphCount + horizGlyphCount) && sanitize_offsets (c)); } @@ -1103,6 +1105,7 @@ struct MATH TRACE_SANITIZE (this); return_trace (version.sanitize (c) && likely (version.major == 1) && + hb_barrier () && mathConstants.sanitize (c, this) && mathGlyphInfo.sanitize (c, this) && mathVariants.sanitize (c, this)); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh index 0f4cc414ef8..8f000526b96 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh @@ -85,7 +85,7 @@ struct maxp TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); - + hb_barrier (); if (version.major == 1) { const maxpV1Tail &v1 = StructAfter (*this); @@ -103,6 +103,7 @@ struct maxp maxp_prime->numGlyphs = hb_min (c->plan->num_output_glyphs (), 0xFFFFu); if (maxp_prime->version.major == 1) { + hb_barrier (); const maxpV1Tail *src_v1 = &StructAfter (*this); maxpV1Tail *dest_v1 = c->serializer->embed (src_v1); if (unlikely (!dest_v1)) return_trace (false); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh index e1b68bcf91d..658db584c7d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh @@ -51,6 +51,7 @@ struct DataMap { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && dataZ.sanitize (c, base, dataLength))); } @@ -101,6 +102,7 @@ struct meta { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version == 1 && dataMaps.sanitize (c, this))); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh index 19330b9bd4e..8c2e696f56c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh @@ -209,6 +209,23 @@ struct OS2 return ret; } + static unsigned calc_avg_char_width (const hb_hashmap_t>& hmtx_map) + { + unsigned num = 0; + unsigned total_width = 0; + for (const auto& _ : hmtx_map.values_ref ()) + { + unsigned width = _.first; + if (width) + { + total_width += width; + num++; + } + } + + return num ? (unsigned) roundf (total_width / num) : 0; + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -239,10 +256,16 @@ struct OS2 if (os2_prime->version >= 2) { + hb_barrier (); auto *table = & const_cast (os2_prime->v2 ()); HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_X_HEIGHT, sxHeight); HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_CAP_HEIGHT, sCapHeight); } + + unsigned avg_char_width = calc_avg_char_width (c->plan->hmtx_map); + if (!c->serializer->check_assign (os2_prime->xAvgCharWidth, avg_char_width, + HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); } #endif @@ -334,6 +357,7 @@ struct OS2 { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); if (unlikely (version >= 1 && !v1X.sanitize (c))) return_trace (false); if (unlikely (version >= 2 && !v2X.sanitize (c))) return_trace (false); if (unlikely (version >= 5 && !v5X.sanitize (c))) return_trace (false); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh index aaecc348ee1..8132dcfb91b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh @@ -122,7 +122,10 @@ struct post } if (glyph_names && version.major == 2) + { + hb_barrier (); return_trace (v2X.subset (c)); + } return_trace (true); } @@ -138,6 +141,7 @@ struct post version = table->version.to_int (); if (version != 0x00020000) return; + hb_barrier (); const postV2Tail &v2 = table->v2X; @@ -217,10 +221,16 @@ struct post unsigned int get_glyph_count () const { if (version == 0x00010000) + { + hb_barrier (); return format1_names_length; + } if (version == 0x00020000) + { + hb_barrier (); return glyphNameIndex->len; + } return 0; } @@ -245,13 +255,18 @@ struct post { if (version == 0x00010000) { + hb_barrier (); if (glyph >= format1_names_length) return hb_bytes_t (); return format1_names (glyph); } - if (version != 0x00020000 || glyph >= glyphNameIndex->len) + if (version != 0x00020000) + return hb_bytes_t (); + hb_barrier (); + + if (glyph >= glyphNameIndex->len) return hb_bytes_t (); unsigned int index = glyphNameIndex->arrayZ[glyph]; @@ -284,6 +299,7 @@ struct post { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && (version.to_int () == 0x00010000 || (version.to_int () == 0x00020000 && v2X.sanitize (c)) || version.to_int () == 0x00030000)); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh index f7bb3791cab..58b3cd74dff 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh @@ -327,6 +327,7 @@ struct AxisValueFormat4 { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && axisValues.sanitize (c, axisCount))); } @@ -416,6 +417,7 @@ struct AxisValue TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); + hb_barrier (); switch (u.format) { @@ -560,6 +562,7 @@ struct STAT { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + hb_barrier () && version.major == 1 && version.minor > 0 && designAxesOffset.sanitize (c, this, designAxisCount) && diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh index f3754aa6b8f..b2e5d87a3cf 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh @@ -273,6 +273,7 @@ struct avar { TRACE_SANITIZE (this); if (!(version.sanitize (c) && + hb_barrier () && (version.major == 1 #ifndef HB_NO_AVAR2 || version.major == 2 @@ -293,6 +294,7 @@ struct avar #ifndef HB_NO_AVAR2 if (version.major < 2) return_trace (true); + hb_barrier (); const auto &v2 = * (const avarV2Tail *) map; if (unlikely (!v2.sanitize (c, this))) @@ -316,6 +318,7 @@ struct avar #ifndef HB_NO_AVAR2 if (version.major < 2) return; + hb_barrier (); for (; count < axisCount; count++) map = &StructAfter (*map); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh index b6fe13f1137..eff6df380f8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh @@ -119,6 +119,7 @@ struct DeltaSetIndexMapFormat01 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_range (mapDataZ.arrayZ, mapCount, get_width ())); @@ -191,6 +192,7 @@ struct DeltaSetIndexMap { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return_trace (false); + hb_barrier (); switch (u.format) { case 0: return_trace (u.format0.sanitize (c)); case 1: return_trace (u.format1.sanitize (c)); @@ -434,6 +436,8 @@ enum packed_delta_flag_t struct tuple_delta_t { + static constexpr bool realloc_move = true; // Watch out when adding new members! + public: hb_hashmap_t axis_tuples; @@ -514,14 +518,19 @@ struct tuple_delta_t return *this; unsigned num = indices.length; - for (unsigned i = 0; i < num; i++) - { - if (!indices.arrayZ[i]) continue; - - deltas_x[i] *= scalar; - if (deltas_y) - deltas_y[i] *= scalar; - } + if (deltas_y) + for (unsigned i = 0; i < num; i++) + { + if (!indices.arrayZ[i]) continue; + deltas_x[i] *= scalar; + deltas_y[i] *= scalar; + } + else + for (unsigned i = 0; i < num; i++) + { + if (!indices.arrayZ[i]) continue; + deltas_x[i] *= scalar; + } return *this; } @@ -767,7 +776,7 @@ struct tuple_delta_t unsigned encoded_len = 0; while (i < num_deltas) { - int val = deltas[i]; + int val = deltas.arrayZ[i]; if (val == 0) encoded_len += encode_delta_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), deltas); else if (val >= -128 && val <= 127) @@ -786,7 +795,7 @@ struct tuple_delta_t unsigned run_length = 0; auto it = encoded_bytes.iter (); unsigned encoded_len = 0; - while (i < num_deltas && deltas[i] == 0) + while (i < num_deltas && deltas.arrayZ[i] == 0) { i++; run_length++; @@ -815,13 +824,13 @@ struct tuple_delta_t unsigned num_deltas = deltas.length; while (i < num_deltas) { - int val = deltas[i]; + int val = deltas.arrayZ[i]; if (val > 127 || val < -128) break; /* from fonttools: if there're 2 or more zeros in a sequence, * it is better to start a new run to save bytes. */ - if (val == 0 && i + 1 < num_deltas && deltas[i+1] == 0) + if (val == 0 && i + 1 < num_deltas && deltas.arrayZ[i+1] == 0) break; i++; @@ -838,7 +847,7 @@ struct tuple_delta_t for (unsigned j = 0; j < 64; j++) { - *it++ = static_cast (deltas[start + j]); + *it++ = static_cast (deltas.arrayZ[start + j]); encoded_len++; } @@ -853,7 +862,7 @@ struct tuple_delta_t while (start < i) { - *it++ = static_cast (deltas[start++]); + *it++ = static_cast (deltas.arrayZ[start++]); encoded_len++; } } @@ -869,8 +878,8 @@ struct tuple_delta_t unsigned num_deltas = deltas.length; while (i < num_deltas) { - int val = deltas[i]; - + int val = deltas.arrayZ[i]; + /* start a new run for a single zero value*/ if (val == 0) break; @@ -879,7 +888,7 @@ struct tuple_delta_t * Only start a new run when there're 2 continuous such values. */ if (val >= -128 && val <= 127 && i + 1 < num_deltas && - deltas[i+1] >= -128 && deltas[i+1] <= 127) + deltas.arrayZ[i+1] >= -128 && deltas.arrayZ[i+1] <= 127) break; i++; @@ -895,7 +904,7 @@ struct tuple_delta_t for (unsigned j = 0; j < 64; j++) { - int16_t delta_val = deltas[start + j]; + int16_t delta_val = deltas.arrayZ[start + j]; *it++ = static_cast (delta_val >> 8); *it++ = static_cast (delta_val & 0xFF); @@ -912,7 +921,7 @@ struct tuple_delta_t encoded_len++; while (start < i) { - int16_t delta_val = deltas[start++]; + int16_t delta_val = deltas.arrayZ[start++]; *it++ = static_cast (delta_val >> 8); *it++ = static_cast (delta_val & 0xFF); @@ -1175,6 +1184,7 @@ struct TupleVariationData bool create_from_item_var_data (const VarData &var_data, const hb_vector_t>& regions, const hb_map_t& axes_old_index_tag_map, + unsigned& item_count, const hb_inc_bimap_t* inner_map = nullptr) { /* NULL offset, to keep original varidx valid, just return */ @@ -1184,7 +1194,8 @@ struct TupleVariationData unsigned num_regions = var_data.get_region_index_count (); if (!tuple_vars.alloc (num_regions)) return false; - unsigned item_count = inner_map ? inner_map->get_population () : var_data.get_item_count (); + item_count = inner_map ? inner_map->get_population () : var_data.get_item_count (); + if (!item_count) return true; unsigned row_size = var_data.get_row_size (); const HBUINT8 *delta_bytes = var_data.get_delta_bytes (); @@ -1775,6 +1786,14 @@ struct item_variations_t * have the same num of deltas (rows) */ hb_vector_t vars; + /* num of retained rows for each subtable, there're 2 cases when var_data is empty: + * 1. retained item_count is zero + * 2. regions is empty and item_count is non-zero. + * when converting to tuples, both will be dropped because the tuple is empty, + * however, we need to retain 2. as all-zero rows to keep original varidx + * valid, so we need a way to remember the num of rows for each subtable */ + hb_vector_t var_data_num_rows; + /* original region list, decompiled from item varstore, used when rebuilding * region list after instantiation */ hb_vector_t> orig_region_list; @@ -1836,22 +1855,26 @@ struct item_variations_t unsigned num_var_data = varStore.get_sub_table_count (); if (inner_maps && inner_maps.length != num_var_data) return false; - if (!vars.alloc (num_var_data)) return false; + if (!vars.alloc (num_var_data) || + !var_data_num_rows.alloc (num_var_data)) return false; for (unsigned i = 0; i < num_var_data; i++) { if (inner_maps && !inner_maps.arrayZ[i].get_population ()) continue; tuple_variations_t var_data_tuples; + unsigned item_count = 0; if (!var_data_tuples.create_from_item_var_data (varStore.get_sub_table (i), orig_region_list, axes_old_index_tag_map, + item_count, inner_maps ? &(inner_maps.arrayZ[i]) : nullptr)) return false; + var_data_num_rows.push (item_count); vars.push (std::move (var_data_tuples)); } - return !vars.in_error (); + return !vars.in_error () && !var_data_num_rows.in_error () && vars.length == var_data_num_rows.length; } bool instantiate_tuple_vars (const hb_hashmap_t& normalized_axes_location, @@ -1973,12 +1996,8 @@ struct item_variations_t unsigned num_cols = region_list.length; /* pre-alloc a 2D vector for all sub_table's VarData rows */ unsigned total_rows = 0; - for (unsigned major = 0; major < vars.length; major++) - { - const tuple_variations_t& tuples = vars[major]; - /* all tuples in each sub_table should have same num of deltas(num rows) */ - total_rows += tuples.tuple_vars[0].deltas_x.length; - } + for (unsigned major = 0; major < var_data_num_rows.length; major++) + total_rows += var_data_num_rows[major]; if (!delta_rows.resize (total_rows)) return false; /* init all rows to [0]*num_cols */ @@ -1998,7 +2017,7 @@ struct item_variations_t /* deltas are stored in tuples(column based), convert them back into items * (row based) delta */ const tuple_variations_t& tuples = vars[major]; - unsigned num_rows = tuples.tuple_vars[0].deltas_x.length; + unsigned num_rows = var_data_num_rows[major]; for (const tuple_delta_t& tuple: tuples.tuple_vars) { if (tuple.deltas_x.length != num_rows) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh index 381ae3c616b..3798ad3e3e5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh @@ -45,7 +45,8 @@ struct cvar { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - version.sanitize (c) && likely (version.major == 1) && + hb_barrier () && + likely (version.major == 1) && tupleVariationData.sanitize (c)); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh index 4c4957bd711..07d7586baac 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh @@ -131,6 +131,7 @@ struct InstanceRecord { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && c->check_array (coordinatesZ.arrayZ, axis_count)); } @@ -277,8 +278,10 @@ struct fvar { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && c->check_struct (this) && + hb_barrier () && axisSize == 20 && /* Assumed in our code. */ instanceSize >= axisCount * 4 + 4 && get_axes ().sanitize (c) && diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh index 8ef9f0ec45c..1c7a1f6c1e9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh @@ -296,7 +296,9 @@ struct gvar bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && (version.major == 1) && + return_trace (c->check_struct (this) && + hb_barrier () && + (version.major == 1) && sharedTuples.sanitize (c, this, axisCount * sharedTupleCount) && (is_long_offset () ? c->check_array (get_long_offset_array (), c->get_num_glyphs () + 1) : @@ -426,7 +428,10 @@ struct gvar subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length; } - bool long_offset = subset_data_size & ~0xFFFFu; + bool long_offset = (subset_data_size & ~0xFFFFu); + #ifdef HB_EXPERIMENTAL_API + long_offset = long_offset || (c->plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS); +#endif out->flags = long_offset ? 1 : 0; HBUINT8 *subset_offsets = c->serializer->allocate_size ((long_offset ? 4 : 2) * (num_glyphs + 1), false); @@ -444,6 +449,8 @@ struct gvar hb_memcpy (tuples, this+sharedTuples, shared_tuple_size); } + /* This ordering relative to the shared tuples array, which puts the glyphVariationData + last in the table, is required when HB_SUBSET_FLAGS_IFTB_REQUIREMENTS is set */ char *subset_data = c->serializer->allocate_size (subset_data_size, false); if (!subset_data) return_trace (false); out->dataZ = subset_data - (char *) out; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh index ca1ea1ca8c2..53a4642d383 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh @@ -288,6 +288,7 @@ struct HVARVVAR { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && varStore.sanitize (c, this) && advMap.sanitize (c, this) && diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh index ceabc9a3e29..6d697776189 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh @@ -77,8 +77,10 @@ struct MVAR { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && + hb_barrier () && likely (version.major == 1) && c->check_struct (this) && + hb_barrier () && valueRecordSize >= VariationValueRecord::static_size && varStore.sanitize (c, this) && c->check_range (valuesZ.arrayZ, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh index 671b6d2c290..95ae8ef5590 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh @@ -117,6 +117,7 @@ struct VORG { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && + hb_barrier () && version.major == 1 && vertYOrigins.sanitize (c)); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh b/src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh index 2c8ccbfb688..9b962a29d9b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh @@ -55,6 +55,9 @@ struct hb_priority_queue_t bool in_error () const { return heap.in_error (); } + bool alloc (unsigned size) + { return heap.alloc (size); } + #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh b/src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh index f2b7da1674b..408649c7689 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh @@ -134,7 +134,10 @@ struct hb_sanitize_context_t : const char *get_name () { return "SANITIZE"; } template bool may_dispatch (const T *obj HB_UNUSED, const F *format) - { return format->sanitize (this); } + { + return format->sanitize (this) && + hb_barrier (); + } static return_t default_return_value () { return true; } static return_t no_dispatch_return_value () { return false; } bool stop_sublookup_iteration (const return_t r) const { return !r; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.hh b/src/3rdparty/harfbuzz-ng/src/hb-set.hh index 7d1c941e4dc..ff2a170d2d1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-set.hh @@ -35,6 +35,8 @@ template struct hb_sparseset_t { + static constexpr bool realloc_move = true; + hb_object_header_t header; impl_t s; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc index 872cba66725..e9dd5d6427b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc @@ -620,6 +620,12 @@ struct cff1_subset_plan drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING; desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE; + #ifdef HB_EXPERIMENTAL_API + min_charstrings_off_size = (plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS) ? 4 : 0; + #else + min_charstrings_off_size = 0; + #endif + subset_charset = !acc.is_predef_charset (); if (!subset_charset) /* check whether the subset renumbers any glyph IDs */ @@ -778,13 +784,43 @@ struct cff1_subset_plan unsigned int topDictModSIDs[name_dict_values_t::ValCount]; bool desubroutinize = false; + + unsigned min_charstrings_off_size = 0; }; } // namespace OT +static bool _serialize_cff1_charstrings (hb_serialize_context_t *c, + struct OT::cff1_subset_plan &plan, + const OT::cff1::accelerator_subset_t &acc) +{ + c->push (); + + unsigned data_size = 0; + unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings, &data_size, plan.min_charstrings_off_size); + if (unlikely (!c->start_zerocopy (total_size))) + return false; + + auto *cs = c->start_embed (); + if (unlikely (!cs->serialize (c, plan.subset_charstrings, &data_size, plan.min_charstrings_off_size))) { + c->pop_discard (); + return false; + } + + plan.info.char_strings_link = c->pop_pack (false); + return true; +} + bool OT::cff1::accelerator_subset_t::serialize (hb_serialize_context_t *c, struct OT::cff1_subset_plan &plan) const { + /* push charstrings onto the object stack first which will ensure it packs as the last + object in the table. Keeping the chastrings last satisfies the requirements for patching + via IFTB. If this ordering needs to be changed in the future, charstrings should be left + at the end whenever HB_SUBSET_FLAGS_ITFB_REQUIREMENTS is enabled. */ + if (!_serialize_cff1_charstrings(c, plan, *this)) + return false; + /* private dicts & local subrs */ for (int i = (int) privateDicts.length; --i >= 0 ;) { @@ -823,25 +859,6 @@ OT::cff1::accelerator_subset_t::serialize (hb_serialize_context_t *c, if (!is_CID ()) plan.info.privateDictInfo = plan.fontdicts_mod[0].privateDictInfo; - /* CharStrings */ - { - c->push (); - - unsigned data_size = 0; - unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings, &data_size); - if (unlikely (!c->start_zerocopy (total_size))) - return false; - - auto *cs = c->start_embed (); - if (likely (cs->serialize (c, plan.subset_charstrings, &data_size))) - plan.info.char_strings_link = c->pop_pack (false); - else - { - c->pop_discard (); - return false; - } - } - /* FDArray (FD Index) */ if (fdArray != &Null (CFF1FDArray)) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc index 3c52fb9c2c3..abc108e5715 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc @@ -439,6 +439,12 @@ struct cff2_subset_plan desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE || pinned; // For instancing we need this path + #ifdef HB_EXPERIMENTAL_API + min_charstrings_off_size = (plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS) ? 4 : 0; + #else + min_charstrings_off_size = 0; + #endif + if (desubroutinize) { /* Flatten global & local subrs */ @@ -510,14 +516,45 @@ struct cff2_subset_plan bool drop_hints = false; bool desubroutinize = false; + + unsigned min_charstrings_off_size = 0; }; } // namespace OT +static bool _serialize_cff2_charstrings (hb_serialize_context_t *c, + cff2_subset_plan &plan, + const OT::cff2::accelerator_subset_t &acc) +{ + c->push (); + + unsigned data_size = 0; + unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings, &data_size, plan.min_charstrings_off_size); + if (unlikely (!c->start_zerocopy (total_size))) + return false; + + auto *cs = c->start_embed (); + if (unlikely (!cs->serialize (c, plan.subset_charstrings, &data_size, plan.min_charstrings_off_size))) + { + c->pop_discard (); + return false; + } + + plan.info.char_strings_link = c->pop_pack (false); + return true; +} + bool OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c, struct cff2_subset_plan &plan, hb_array_t normalized_coords) const { + /* push charstrings onto the object stack first which will ensure it packs as the last + object in the table. Keeping the chastrings last satisfies the requirements for patching + via IFTB. If this ordering needs to be changed in the future, charstrings should be left + at the end whenever HB_SUBSET_FLAGS_ITFB_REQUIREMENTS is enabled. */ + if (!_serialize_cff2_charstrings(c, plan, *this)) + return false; + /* private dicts & local subrs */ hb_vector_t private_dict_infos; if (unlikely (!private_dict_infos.resize (plan.subset_fdcount))) return false; @@ -556,25 +593,6 @@ OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c, } } - /* CharStrings */ - { - c->push (); - - unsigned data_size = 0; - unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings, &data_size); - if (unlikely (!c->start_zerocopy (total_size))) - return false; - - auto *cs = c->start_embed (); - if (likely (cs->serialize (c, plan.subset_charstrings, &data_size))) - plan.info.char_strings_link = c->pop_pack (false); - else - { - c->pop_discard (); - return false; - } - } - /* FDSelect */ if (fdSelect != &Null (CFF2FDSelect)) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc index 0277d3d3d6a..1e0a89a630d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc @@ -123,6 +123,12 @@ hb_subset_input_t::hb_subset_input_t () //justify HB_TAG ('j', 'a', 'l', 't'), // HarfBuzz doesn't use; others might + //East Asian spacing + HB_TAG ('c', 'h', 'w', 's'), + HB_TAG ('v', 'c', 'h', 'w'), + HB_TAG ('h', 'a', 'l', 't'), + HB_TAG ('v', 'h', 'a', 'l'), + //private HB_TAG ('H', 'a', 'r', 'f'), HB_TAG ('H', 'A', 'R', 'F'), diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc index 4cb3f8a4852..4876bc43797 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc @@ -168,12 +168,14 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) * | * crossing */ - if (gain > outGain) + if (gain >= outGain) { + // Note that this is the branch taken if both gain and outGain are 0. + // Crossing point on the axis. float crossing = peak + (1 - gain) * (upper - peak); - Triple loc{axisDef, peak, crossing}; + Triple loc{hb_max (lower, axisDef), peak, crossing}; float scalar = 1.f; // The part before the crossing point. @@ -253,7 +255,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) * axisDef axisMax */ float newUpper = peak + (1 - gain) * (upper - peak); - assert (axisMax <= newUpper); // Because outGain >= gain + assert (axisMax <= newUpper); // Because outGain > gain if (newUpper <= axisDef + (axisMax - axisDef) * 2) { upper = newUpper; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh index 8bc1fcb5682..71da80e3875 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh @@ -70,6 +70,9 @@ HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_colred) HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_lookups) HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_lookups) +//use_mark_sets mapping: old->new +HB_SUBSET_PLAN_MEMBER (hb_map_t, used_mark_sets_map) + //active langsys we'd like to retain HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gsub_langsys) HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpos_langsys) @@ -87,6 +90,15 @@ HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpo HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), gsub_feature_substitutes_map) HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), gpos_feature_substitutes_map) +// old feature_indexes set, used to reinstate the old features +HB_SUBSET_PLAN_MEMBER (hb_set_t, gsub_old_features) +HB_SUBSET_PLAN_MEMBER (hb_set_t, gpos_old_features) + +//feature_index->pair of (address of old feature, feature tag), used for inserting a catch all record +//if necessary +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E()>), gsub_old_feature_idx_tag_map) +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E()>), gpos_old_feature_idx_tag_map) + //active layers/palettes we'd like to retain HB_SUBSET_PLAN_MEMBER (hb_map_t, colrv1_layers) HB_SUBSET_PLAN_MEMBER (hb_map_t, colr_palettes) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc index c688b7187b2..5786223196d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc @@ -150,7 +150,8 @@ static void _collect_layout_indices (hb_subset_plan_t *plan, hb_set_t *feature_indices, /* OUT */ hb_hashmap_t> *feature_record_cond_idx_map, /* OUT */ hb_hashmap_t *feature_substitutes_map, /* OUT */ - bool& insert_catch_all_feature_variation_record) + hb_set_t& catch_all_record_feature_idxes, /* OUT */ + hb_hashmap_t>& catch_all_record_idx_feature_map /* OUT */) { unsigned num_features = table.get_feature_count (); hb_vector_t features; @@ -186,7 +187,7 @@ static void _collect_layout_indices (hb_subset_plan_t *plan, &plan->axes_location, feature_record_cond_idx_map, feature_substitutes_map, - insert_catch_all_feature_variation_record, + catch_all_record_feature_idxes, feature_indices, false, false, @@ -208,17 +209,25 @@ static void _collect_layout_indices (hb_subset_plan_t *plan, f->add_lookup_indexes_to (lookup_indices); } +#ifndef HB_NO_VAR + if (catch_all_record_feature_idxes) + { + for (unsigned feature_index : catch_all_record_feature_idxes) + { + const OT::Feature& f = table.get_feature (feature_index); + f.add_lookup_indexes_to (lookup_indices); + const void *tag = reinterpret_cast (&(table.get_feature_list ().get_tag (feature_index))); + catch_all_record_idx_feature_map.set (feature_index, hb_pair (&f, tag)); + } + } + // If all axes are pinned then all feature variations will be dropped so there's no need // to collect lookups from them. if (!plan->all_axes_pinned) - { - // TODO(qxliu76): this collection doesn't work correctly for feature variations that are dropped - // but not applied. The collection will collect and retain the lookup indices - // associated with those dropped but not activated rules. Since partial instancing - // isn't yet supported this isn't an issue yet but will need to be fixed for - // partial instancing. - table.feature_variation_collect_lookups (feature_indices, feature_substitutes_map, lookup_indices); - } + table.feature_variation_collect_lookups (feature_indices, + plan->user_axes_location.is_empty () ? nullptr: feature_record_cond_idx_map, + lookup_indices); +#endif } @@ -302,7 +311,8 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, script_langsys_map *langsys_map, hb_hashmap_t> *feature_record_cond_idx_map, hb_hashmap_t *feature_substitutes_map, - bool& insert_catch_all_feature_variation_record) + hb_set_t &catch_all_record_feature_idxes, + hb_hashmap_t>& catch_all_record_idx_feature_map) { hb_blob_ptr_t table = plan->source_table (); hb_tag_t table_tag = table->tableTag; @@ -313,7 +323,8 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, &feature_indices, feature_record_cond_idx_map, feature_substitutes_map, - insert_catch_all_feature_variation_record); + catch_all_record_feature_idxes, + catch_all_record_idx_feature_map); if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE)) hb_ot_layout_lookups_substitute_closure (plan->source, @@ -465,6 +476,24 @@ _math_closure (hb_subset_plan_t *plan, math.destroy (); } +static inline void +_remap_used_mark_sets (hb_subset_plan_t *plan, + hb_map_t& used_mark_sets_map) +{ + hb_blob_ptr_t gdef = plan->source_table (); + + if (!gdef->has_data () || !gdef->has_mark_glyph_sets ()) + { + gdef.destroy (); + return; + } + + hb_set_t used_mark_sets; + gdef->get_mark_glyph_sets ().collect_used_mark_sets (plan->_glyphset_gsub, used_mark_sets); + gdef.destroy (); + + _remap_indexes (&used_mark_sets, &used_mark_sets_map); +} static inline void _remove_invalid_gids (hb_set_t *glyphs, @@ -578,14 +607,18 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, else { plan->codepoint_to_glyph->alloc (cmap_unicodes->get_population ()); - for (hb_codepoint_t cp : *cmap_unicodes) + hb_codepoint_t first = HB_SET_VALUE_INVALID, last = HB_SET_VALUE_INVALID; + for (; cmap_unicodes->next_range (&first, &last); ) { - hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; - if (!unicodes->has (cp) && !glyphs->has (gid)) - continue; + for (unsigned cp = first; cp <= last; cp++) + { + hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; + if (!unicodes->has (cp) && !glyphs->has (gid)) + continue; - plan->codepoint_to_glyph->set (cp, gid); - plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); + plan->codepoint_to_glyph->set (cp, gid); + plan->unicode_to_new_gid_list.push (hb_pair (cp, gid)); + } } } @@ -714,7 +747,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, &plan->gsub_langsys, &plan->gsub_feature_record_cond_idx_map, &plan->gsub_feature_substitutes_map, - plan->gsub_insert_catch_all_feature_variation_rec); + plan->gsub_old_features, + plan->gsub_old_feature_idx_tag_map); if (!drop_tables->has (HB_OT_TAG_GPOS)) _closure_glyphs_lookups_features ( @@ -725,7 +759,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, &plan->gpos_langsys, &plan->gpos_feature_record_cond_idx_map, &plan->gpos_feature_substitutes_map, - plan->gpos_insert_catch_all_feature_variation_rec); + plan->gpos_old_features, + plan->gpos_old_feature_idx_tag_map); #endif _remove_invalid_gids (&plan->_glyphset_gsub, plan->source->get_num_glyphs ()); @@ -814,12 +849,12 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, if (retain_gids) { - DEBUG_MSG (SUBSET, nullptr, + DEBUG_MSG (SUBSET, nullptr, "HB_SUBSET_FLAGS_RETAIN_GIDS cannot be set if " "a custom glyph mapping has been provided."); return false; } - + hb_codepoint_t max_glyph = 0; hb_set_t remaining; for (auto old_gid : all_gids_to_retain->iter ()) @@ -871,9 +906,11 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, *num_glyphs = max_glyph + 1; } + reverse_glyph_map->alloc (reverse_glyph_map->get_population () + new_to_old_gid_list->length); + hb_iter (new_to_old_gid_list) | hb_sink (reverse_glyph_map) ; + glyph_map->alloc (glyph_map->get_population () + new_to_old_gid_list->length); + hb_iter (new_to_old_gid_list) | hb_map (&hb_codepoint_pair_t::reverse) | hb_sink (glyph_map) @@ -969,7 +1006,7 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) float *hvar_store_cache = nullptr; if (_hmtx.has_data () && _hmtx.var_table.get_length ()) hvar_store_cache = _hmtx.var_table->get_var_store ().create_cache (); - + OT::vmtx_accelerator_t _vmtx (plan->source); float *vvar_store_cache = nullptr; if (_vmtx.has_data () && _vmtx.var_table.get_length ()) @@ -1093,6 +1130,7 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, user_axes_location = input->axes_location; all_axes_pinned = false; pinned_at_default = true; + has_gdef_varstore = false; #ifdef HB_EXPERIMENTAL_API for (auto _ : input->name_table_overrides) @@ -1112,6 +1150,10 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, attach_accelerator_data = input->attach_accelerator_data; force_long_loca = input->force_long_loca; +#ifdef HB_EXPERIMENTAL_API + force_long_loca = force_long_loca || (flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS); +#endif + if (accel) accelerator = (hb_subset_accelerator_t*) accel; @@ -1160,6 +1202,9 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, for (auto &v : bounds_height_vec) v = 0xFFFFFFFF; + if (!drop_tables.has (HB_OT_TAG_GDEF)) + _remap_used_mark_sets (this, used_mark_sets_map); + if (unlikely (in_error ())) return; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh index a05d1d1a620..1f19a58c1ed 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh @@ -147,6 +147,9 @@ struct hb_subset_plan_t bool gsub_insert_catch_all_feature_variation_rec; bool gpos_insert_catch_all_feature_variation_rec; + // whether GDEF VarStore is retained + mutable bool has_gdef_varstore; + #define HB_SUBSET_PLAN_MEMBER(Type, Name) Type Name; #include "hb-subset-plan-member-list.hh" #undef HB_SUBSET_PLAN_MEMBER diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc index 229b1c30884..06e77dd8eb5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc @@ -460,9 +460,10 @@ _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, case HB_OT_TAG_hmtx: case HB_OT_TAG_vmtx: case HB_OT_TAG_maxp: + case HB_OT_TAG_OS2: return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf); case HB_OT_TAG_GPOS: - return !plan->normalized_coords || plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF); + return plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF); default: return true; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.h b/src/3rdparty/harfbuzz-ng/src/hb-subset.h index 4c356997f12..d79e7f762a0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.h @@ -73,6 +73,9 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; * OS/2 will not be recalculated. * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set don't perform glyph closure on layout * substitution rules (GSUB). Since: 7.2.0. + * @HB_SUBSET_FLAGS_IFTB_REQUIREMENTS: If set enforce requirements on the output subset + * to allow it to be used with incremental font transfer IFTB patches. Primarily, + * this forces all outline data to use long (32 bit) offsets. Since: EXPERIMENTAL * * List of boolean properties that can be configured on the subset input. * @@ -90,6 +93,9 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_GLYPH_NAMES = 0x00000080u, HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u, HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE = 0x00000200u, +#ifdef HB_EXPERIMENTAL_API + HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00000400u, +#endif } hb_subset_flags_t; /** diff --git a/src/3rdparty/harfbuzz-ng/src/hb-vector.hh b/src/3rdparty/harfbuzz-ng/src/hb-vector.hh index 13cfe56b59f..dfe1b7d1c7e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-vector.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-vector.hh @@ -37,6 +37,8 @@ template struct hb_vector_t { + static constexpr bool realloc_move = true; + typedef Type item_t; static constexpr unsigned item_size = hb_static_size (Type); using array_t = typename std::conditional, hb_array_t>::type; @@ -268,10 +270,9 @@ struct hb_vector_t } return new_array; } - /* Specialization for hb_vector_t> to speed up. */ + /* Specialization for types that can be moved using realloc(). */ template ) || - hb_is_same (T, hb_array_t ))> + hb_enable_if (T::realloc_move)> Type * realloc_vector (unsigned new_allocated, hb_priority<1>) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h index cd7257e45cf..b08dd1f09f4 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-version.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h @@ -47,20 +47,20 @@ HB_BEGIN_DECLS * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 2 +#define HB_VERSION_MINOR 3 /** * HB_VERSION_MICRO: * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 2 +#define HB_VERSION_MICRO 0 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "8.2.2" +#define HB_VERSION_STRING "8.3.0" /** * HB_VERSION_ATLEAST: From 94cf6e79dbbdf1bf6b363622832838a1e0f86d86 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 15 Nov 2023 14:43:46 +0100 Subject: [PATCH 08/58] xcb: make QXcbWindow inherit QObject MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pick-to: 5.15 Change-Id: I418305f1e66bdf90b8bda724976916e320012961 Reviewed-by: Tor Arne Vestbø (cherry picked from commit 5896314ff3e46849b6ff7e1069f2273cc6508cf7) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 42338ad4b90b9784b774d6c8654d90985a40f7d9) (cherry picked from commit 4b60a9bbbe12fe5fdd313d6de1dafac331a9e3d9) Reviewed-by: Liang Qi (cherry picked from commit f8e589c8d5c10d0734058086a21b0af3bfccddf4) --- src/plugins/platforms/xcb/qxcbdrag.cpp | 2 +- src/plugins/platforms/xcb/qxcbwindow.cpp | 30 ++++++++++++------------ src/plugins/platforms/xcb/qxcbwindow.h | 4 +++- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 5cfb252d042..7e05097cda9 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -1294,7 +1294,7 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event bool QXcbDrag::dndEnable(QXcbWindow *w, bool on) { - qCDebug(lcQpaXDnd) << "dndEnable" << w << on; + qCDebug(lcQpaXDnd) << "dndEnable" << static_cast(w) << on; // Windows announce that they support the XDND protocol by creating a window property XdndAware. if (on) { QXcbWindow *window = nullptr; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 039803f6580..7721b45950a 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -129,7 +129,7 @@ const quint32 XEMBED_VERSION = 0; QXcbScreen *QXcbWindow::parentScreen() { - return parent() ? static_cast(parent())->parentScreen() : xcbScreen(); + return QPlatformWindow::parent() ? static_cast(QPlatformWindow::parent())->parentScreen() : xcbScreen(); } //QPlatformWindow::screenForGeometry version that uses deviceIndependentGeometry @@ -275,8 +275,8 @@ void QXcbWindow::create() Qt::WindowType type = window()->type(); QXcbScreen *currentScreen = xcbScreen(); - QXcbScreen *platformScreen = parent() ? parentScreen() : initialScreen(); - QRect rect = parent() + QXcbScreen *platformScreen = QPlatformWindow::parent() ? parentScreen() : initialScreen(); + QRect rect = QPlatformWindow::parent() ? QHighDpi::toNativeLocalPosition(window()->geometry(), platformScreen) : QHighDpi::toNativePixels(window()->geometry(), platformScreen); @@ -316,11 +316,11 @@ void QXcbWindow::create() QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen()); xcb_window_t xcb_parent_id = platformScreen->root(); - if (parent()) { - xcb_parent_id = static_cast(parent())->xcb_window(); - m_embedded = parent()->isForeignWindow(); + if (QPlatformWindow::parent()) { + xcb_parent_id = static_cast(QPlatformWindow::parent())->xcb_window(); + m_embedded = QPlatformWindow::parent()->isForeignWindow(); - QSurfaceFormat parentFormat = parent()->window()->requestedFormat(); + QSurfaceFormat parentFormat = QPlatformWindow::parent()->window()->requestedFormat(); if (window()->surfaceType() != QSurface::OpenGLSurface && parentFormat.hasAlpha()) { window()->setFormat(parentFormat); } @@ -338,16 +338,16 @@ void QXcbWindow::create() qWarning() << "Failed to use requested visual id."; } - if (parent()) { + if (QPlatformWindow::parent()) { // When using a Vulkan QWindow via QWidget::createWindowContainer() we // must make sure the visuals are compatible. Now, the parent will be // of RasterGLSurface which typically chooses a GLX/EGL compatible // visual which may not be what the Vulkan window would choose. // Therefore, take the parent's visual. if (window()->surfaceType() == QSurface::VulkanSurface - && parent()->window()->surfaceType() != QSurface::VulkanSurface) + && QPlatformWindow::parent()->window()->surfaceType() != QSurface::VulkanSurface) { - visual = platformScreen->visualForId(static_cast(parent())->visualId()); + visual = platformScreen->visualForId(static_cast(QPlatformWindow::parent())->visualId()); } } @@ -570,7 +570,7 @@ void QXcbWindow::setGeometry(const QRect &rect) propagateSizeHints(); QXcbScreen *currentScreen = xcbScreen(); - QXcbScreen *newScreen = parent() ? parentScreen() : static_cast(screenForGeometry(rect)); + QXcbScreen *newScreen = QPlatformWindow::parent() ? parentScreen() : static_cast(screenForGeometry(rect)); if (!newScreen) newScreen = xcbScreen(); @@ -1794,7 +1794,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * { bool fromSendEvent = (event->response_type & 0x80); QPoint pos(event->x, event->y); - if (!parent() && !fromSendEvent) { + if (!QPlatformWindow::parent() && !fromSendEvent) { // Do not trust the position, query it instead. auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(), xcb_window(), xcbScreen()->root(), 0, 0); @@ -1805,7 +1805,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * } const QRect actualGeometry = QRect(pos, QSize(event->width, event->height)); - QPlatformScreen *newScreen = parent() ? parent()->screen() : screenForGeometry(actualGeometry); + QPlatformScreen *newScreen = QPlatformWindow::parent() ? QPlatformWindow::parent()->screen() : screenForGeometry(actualGeometry); if (!newScreen) return; @@ -1915,7 +1915,7 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in if (m_embedded && !m_trayIconWindow) { if (window() != QGuiApplication::focusWindow()) { - const QXcbWindow *container = static_cast(parent()); + const QXcbWindow *container = static_cast(QPlatformWindow::parent()); Q_ASSERT(container != nullptr); sendXEmbedMessage(container->xcb_window(), XEMBED_REQUEST_FOCUS); @@ -2363,7 +2363,7 @@ bool QXcbWindow::windowEvent(QEvent *event) case Qt::BacktabFocusReason: { const QXcbWindow *container = - static_cast(parent()); + static_cast(QPlatformWindow::parent()); sendXEmbedMessage(container->xcb_window(), focusEvent->reason() == Qt::TabFocusReason ? XEMBED_FOCUS_NEXT : XEMBED_FOCUS_PREV); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 9cefe1f4b91..f2338d8be17 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -41,6 +41,7 @@ #define QXCBWINDOW_H #include +#include #include #include @@ -57,8 +58,9 @@ class QXcbScreen; class QXcbSyncWindowRequest; class QIcon; -class Q_XCB_EXPORT QXcbWindow : public QXcbObject, public QXcbWindowEventListener, public QPlatformWindow +class Q_XCB_EXPORT QXcbWindow : public QObject, public QXcbObject, public QXcbWindowEventListener, public QPlatformWindow { + Q_OBJECT public: enum NetWmState { NetWmStateAbove = 0x1, From 2c2b74f1bd9bab8b170cca7c96b0e77023058d64 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 28 Jun 2023 11:34:01 +0200 Subject: [PATCH 09/58] xcb: update WM_TRANSIENT_FOR on transientParent native window recreation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It follows f9e4402ffeef791e66b7b2f2cc332000df7f5cd4. Fixes: QTBUG-105395 Change-Id: I399c448517b7dbdc28ba33f75ae43102836a8998 Reviewed-by: Tor Arne Vestbø (cherry picked from commit f2c5b846e092270e1f43b0625db26789a5f77ba6) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit eb7df2d77b0ee13b8d751be64ff606dd9d5cdf6d) Reviewed-by: Liang Qi (cherry picked from commit 98ee3222b48fc974f4565007c953728d34408941) --- src/plugins/platforms/xcb/qxcbwindow.cpp | 69 ++++++++++++++++++------ src/plugins/platforms/xcb/qxcbwindow.h | 5 ++ 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 7721b45950a..97b7e23ad50 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -94,6 +94,7 @@ enum { QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window"); +Q_LOGGING_CATEGORY(lcQpaXcbWindow, "qt.qpa.xcb.window"); Q_DECLARE_TYPEINFO(xcb_rectangle_t, Q_PRIMITIVE_TYPE); @@ -267,6 +268,7 @@ enum : quint32 { void QXcbWindow::create() { + xcb_window_t old_m_window = m_window; destroy(); m_windowState = Qt::WindowNoState; @@ -515,6 +517,17 @@ void QXcbWindow::create() if (m_trayIconWindow) m_embedded = requestSystemTrayWindowDock(); + + if (m_window != old_m_window) { + if (!m_wmTransientForChildren.isEmpty()) { + QList> transientChildren = m_wmTransientForChildren; + m_wmTransientForChildren.clear(); + for (auto transientChild : transientChildren) { + if (transientChild) + transientChild->updateWmTransientFor(); + } + } + } } QXcbWindow::~QXcbWindow() @@ -689,6 +702,44 @@ void QXcbWindow::setVisible(bool visible) hide(); } +void QXcbWindow::updateWmTransientFor() +{ + xcb_window_t transientXcbParent = XCB_NONE; + if (isTransient(window())) { + QWindow *tp = window()->transientParent(); + if (tp && tp->handle()) { + QXcbWindow *handle = static_cast(tp->handle()); + transientXcbParent = tp->handle()->winId(); + if (transientXcbParent) { + handle->registerWmTransientForChild(this); + qCDebug(lcQpaXcbWindow) << Q_FUNC_INFO << static_cast(handle) + << " registerWmTransientForChild " << static_cast(this); + } + } + // Default to client leader if there is no transient parent, else modal dialogs can + // be hidden by their parents. + if (!transientXcbParent) + transientXcbParent = connection()->clientLeader(); + if (transientXcbParent) { // ICCCM 4.1.2.6 + xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, + XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, + 1, &transientXcbParent); + qCDebug(lcQpaXcbWindow, "0x%x added XCB_ATOM_WM_TRANSIENT_FOR 0x%x", m_window, transientXcbParent); + } + } + if (!transientXcbParent) + xcb_delete_property(xcb_connection(), m_window, XCB_ATOM_WM_TRANSIENT_FOR); +} + +void QXcbWindow::registerWmTransientForChild(QXcbWindow *child) +{ + if (!child) + return; + + if (!m_wmTransientForChildren.contains(child)) + m_wmTransientForChildren.append(child); +} + void QXcbWindow::show() { if (window()->isTopLevel()) { @@ -702,23 +753,7 @@ void QXcbWindow::show() propagateSizeHints(); // update WM_TRANSIENT_FOR - xcb_window_t transientXcbParent = 0; - if (isTransient(window())) { - const QWindow *tp = window()->transientParent(); - if (tp && tp->handle()) - transientXcbParent = tp->handle()->winId(); - // Default to client leader if there is no transient parent, else modal dialogs can - // be hidden by their parents. - if (!transientXcbParent) - transientXcbParent = connection()->clientLeader(); - if (transientXcbParent) { // ICCCM 4.1.2.6 - xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, - XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, - 1, &transientXcbParent); - } - } - if (!transientXcbParent) - xcb_delete_property(xcb_connection(), m_window, XCB_ATOM_WM_TRANSIENT_FOR); + updateWmTransientFor(); // update _NET_WM_STATE setNetWmStateOnUnmappedWindow(); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index f2338d8be17..e784c3ddc39 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -156,6 +157,8 @@ public: Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source); void updateNetWmUserTime(xcb_timestamp_t timestamp); + void updateWmTransientFor(); + void registerWmTransientForChild(QXcbWindow *); static void setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes); static void setWmWindowRoleStatic(QWindow *window, const QByteArray &role); @@ -292,6 +295,8 @@ protected: qreal m_sizeHintsScaleFactor = 1.0; RecreationReasons m_recreationReasons = RecreationNotNeeded; + + QList> m_wmTransientForChildren; }; class QXcbForeignWindow : public QXcbWindow From 8da943f25f85f78d07f026ead21629797b722451 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 15 Nov 2023 10:52:25 +0100 Subject: [PATCH 10/58] [doc] QBENCHMARK_ONCE: fix typos ... and remove a prematurely-ending parenthesized remark. Change-Id: If0a2f482c45128739ed6cea1d8385ea34f45b094 Reviewed-by: Isak Fyksen Reviewed-by: Jason McDonald (cherry picked from commit e6febd05d963939a354162bf647b939ad7aca64f) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit d1d8d03b7dcaa3dbfd22797822cb9acbd0843229) (cherry picked from commit d6053ba84ec7ae5bb7958538fd4e3ee15252ec2e) (cherry picked from commit fbe43489ca337587b8871903c6d6971dcd8f5863) --- src/testlib/qtestcase.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/testlib/qtestcase.qdoc b/src/testlib/qtestcase.qdoc index dd5ec762a71..73d1cc850b1 100644 --- a/src/testlib/qtestcase.qdoc +++ b/src/testlib/qtestcase.qdoc @@ -617,8 +617,8 @@ this macro. Unlike QBENCHMARK, the contents of the contained code block is only run - once. The elapsed time will be reported as "0" if it's to short to - be measured by the selected backend. (Use) + once. The elapsed time will be reported as "0" if it's too short to + be measured by the selected backend. \sa {Qt Test Overview#Creating a Benchmark}{Creating a Benchmark}, {Chapter 5: Writing a Benchmark}{Writing a Benchmark} From a71a8c6c7d106159fbeb096be26f187737b1383d Mon Sep 17 00:00:00 2001 From: Tarja Sundqvist Date: Fri, 24 Nov 2023 17:06:16 +0200 Subject: [PATCH 11/58] Bump version to 5.15.17 Change-Id: I79a0f305807bd786f8d7187d6d9e84758feae957 --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index fe958c0b81c..860495581e1 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -6,4 +6,4 @@ DEFINES += QT_NO_JAVA_STYLE_ITERATORS QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) -MODULE_VERSION = 5.15.16 +MODULE_VERSION = 5.15.17 From 396e8cc57db3bc44d421fe35dd956a258aa5239c Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 23 Nov 2023 18:47:39 +0100 Subject: [PATCH 12/58] SQLite: Update SQLite to v3.44.1 [ChangeLog][Third-Party Code] Updated SQLite to v3.44.1 Change-Id: I156472b14dcf37b8632b948118ef95e62cf0118e Reviewed-by: Volker Hilsheimer (cherry picked from commit 11d82002491ab0b1499aa715382928db7d52cff8) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 59a2d5bdbab64ea5816c566902c070f3ed323987) (cherry picked from commit dbd2d1a31fbf595b05a6cfffb194e760fd6fde97) (cherry picked from commit 0fa011fe2c30270772873b53e0b258084708d23d) --- src/3rdparty/sqlite/qt_attribution.json | 4 +- src/3rdparty/sqlite/sqlite3.c | 255 ++++++++++++++++-------- src/3rdparty/sqlite/sqlite3.h | 67 +++++-- 3 files changed, 233 insertions(+), 93 deletions(-) diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json index 5d16c702117..2dea4e71c07 100644 --- a/src/3rdparty/sqlite/qt_attribution.json +++ b/src/3rdparty/sqlite/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Homepage": "https://www.sqlite.org/", - "Version": "3.44.0", - "DownloadLocation": "https://sqlite.org/2023/sqlite-amalgamation-3440000.zip", + "Version": "3.44.1", + "DownloadLocation": "https://sqlite.org/2023/sqlite-amalgamation-3440100.zip", "License": "Public Domain", "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." } diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 8f9309a8ba7..7d61daa8062 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.44.0. By combining all the individual C code files into this +** version 3.44.1. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** 17129ba1ff7f0daf37100ee82d507aef7827. +** d295f48e8f367b066b881780c98bdf980a1d. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -459,9 +459,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.0" -#define SQLITE_VERSION_NUMBER 3044000 -#define SQLITE_SOURCE_ID "2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301" +#define SQLITE_VERSION "3.44.1" +#define SQLITE_VERSION_NUMBER 3044001 +#define SQLITE_SOURCE_ID "2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -5886,13 +5886,27 @@ SQLITE_API int sqlite3_create_window_function( **
      ** ** [[SQLITE_SUBTYPE]]
      SQLITE_SUBTYPE
      -** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call +** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. -** Specifying this flag makes no difference for scalar or aggregate user -** functions. However, if it is not specified for a user-defined window -** function, then any sub-types belonging to arguments passed to the window -** function may be discarded before the window function is called (i.e. -** sqlite3_value_subtype() will always return 0). +** This flag instructs SQLite to omit some corner-case optimizations that +** might disrupt the operation of the [sqlite3_value_subtype()] function, +** causing it to return zero rather than the correct subtype(). +** SQL functions that invokes [sqlite3_value_subtype()] should have this +** property. If the SQLITE_SUBTYPE property is omitted, then the return +** value from [sqlite3_value_subtype()] might sometimes be zero even though +** a non-zero subtype was specified by the function argument expression. +** +** [[SQLITE_RESULT_SUBTYPE]]
      SQLITE_RESULT_SUBTYPE
      +** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call +** [sqlite3_result_subtype()] to cause a sub-type to be associated with its +** result. +** Every function that invokes [sqlite3_result_subtype()] should have this +** property. If it does not, then the call to [sqlite3_result_subtype()] +** might become a no-op if the function is used as term in an +** [expression index]. On the other hand, SQL functions that never invoke +** [sqlite3_result_subtype()] should avoid setting this property, as the +** purpose of this property is to disable certain optimizations that are +** incompatible with subtypes. **
      ** */ @@ -5900,6 +5914,7 @@ SQLITE_API int sqlite3_create_window_function( #define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 +#define SQLITE_RESULT_SUBTYPE 0x001000000 /* ** CAPI3REF: Deprecated Functions @@ -6096,6 +6111,12 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*); ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. +** +** Every [application-defined SQL function] that invoke this interface +** should include the [SQLITE_SUBTYPE] property in the text +** encoding argument when the function is [sqlite3_create_function|registered]. +** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() +** might return zero instead of the upstream subtype in some corner cases. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); @@ -6226,14 +6247,22 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); **
    • ^(when sqlite3_set_auxdata() is invoked again on the same ** parameter)^, or **
    • ^(during the original sqlite3_set_auxdata() call when a memory -** allocation error occurs.)^
    +** allocation error occurs.)^ +**
  • ^(during the original sqlite3_set_auxdata() call if the function +** is evaluated during query planning instead of during query execution, +** as sometimes happens with [SQLITE_ENABLE_STAT4].)^
** -** Note the last bullet in particular. The destructor X in +** Note the last two bullets in particular. The destructor X in ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the ** function implementation should not make any use of P after -** sqlite3_set_auxdata() has been called. +** sqlite3_set_auxdata() has been called. Furthermore, a call to +** sqlite3_get_auxdata() that occurs immediately after a corresponding call +** to sqlite3_set_auxdata() might still return NULL if an out-of-memory +** condition occurred during the sqlite3_set_auxdata() call or if the +** function is being evaluated during query planning rather than during +** query execution. ** ** ^(In practice, auxiliary data is preserved between function calls for ** function parameters that are compile-time constants, including literal @@ -6507,6 +6536,20 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); ** higher order bits are discarded. ** The number of subtype bytes preserved by SQLite might increase ** in future releases of SQLite. +** +** Every [application-defined SQL function] that invokes this interface +** should include the [SQLITE_RESULT_SUBTYPE] property in its +** text encoding argument when the SQL function is +** [sqlite3_create_function|registered]. If the [SQLITE_RESULT_SUBTYPE] +** property is omitted from the function that invokes sqlite3_result_subtype(), +** then in some cases the sqlite3_result_subtype() might fail to set +** the result subtype. +** +** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any +** SQL function that invokes the sqlite3_result_subtype() interface +** and that does not have the SQLITE_RESULT_SUBTYPE property will raise +** an error. Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1 +** by default. */ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); @@ -17811,14 +17854,15 @@ struct FuncDestructor { #define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a ** single query - might change over time */ #define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */ -/* 0x8000 -- available for reuse */ +#define SQLITE_FUNC_RUNONLY 0x8000 /* Cannot be used by valueFromFunction */ #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ -#define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ +/* SQLITE_SUBTYPE 0x00100000 // Consumer of subtypes */ #define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */ #define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */ #define SQLITE_FUNC_BUILTIN 0x00800000 /* This is a built-in function */ +/* SQLITE_RESULT_SUBTYPE 0x01000000 // Generator of subtypes */ #define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */ /* Identifier numbers for each in-line function */ @@ -17910,9 +17954,10 @@ struct FuncDestructor { #define MFUNCTION(zName, nArg, xPtr, xFunc) \ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } -#define JFUNCTION(zName, nArg, iArg, xFunc) \ - {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|\ - SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ +#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, iArg, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\ + SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\ + ((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_FUNC_BUILTIN|\ @@ -29453,7 +29498,7 @@ SQLITE_PRIVATE void sqlite3MemoryBarrier(void){ SQLITE_MEMORY_BARRIER; #elif defined(__GNUC__) __sync_synchronize(); -#elif MSVC_VERSION>=1300 +#elif MSVC_VERSION>=1400 _ReadWriteBarrier(); #elif defined(MemoryBarrier) MemoryBarrier(); @@ -61447,10 +61492,13 @@ act_like_temp_file: */ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){ Pager *pPager; + const char *p; while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){ zName--; } - pPager = *(Pager**)(zName - 4 - sizeof(Pager*)); + p = zName - 4 - sizeof(Pager*); + assert( EIGHT_BYTE_ALIGNMENT(p) ); + pPager = *(Pager**)p; return pPager->fd; } @@ -83411,7 +83459,7 @@ static int valueFromFunction( #endif assert( pFunc ); if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 - || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) + || (pFunc->funcFlags & (SQLITE_FUNC_NEEDCOLL|SQLITE_FUNC_RUNONLY))!=0 ){ return SQLITE_OK; } @@ -89952,6 +90000,18 @@ SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubt #ifdef SQLITE_ENABLE_API_ARMOR if( pCtx==0 ) return; #endif +#if defined(SQLITE_STRICT_SUBTYPE) && SQLITE_STRICT_SUBTYPE+0!=0 + if( pCtx->pFunc!=0 + && (pCtx->pFunc->funcFlags & SQLITE_RESULT_SUBTYPE)==0 + ){ + char zErr[200]; + sqlite3_snprintf(sizeof(zErr), zErr, + "misuse of sqlite3_result_subtype() by %s()", + pCtx->pFunc->zName); + sqlite3_result_error(pCtx, zErr, -1); + return; + } +#endif /* SQLITE_STRICT_SUBTYPE */ pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); pOut->eSubtype = eSubtype & 0xff; @@ -100321,7 +100381,7 @@ case OP_VCheck: { /* out2 */ pTab = pOp->p4.pTab; assert( pTab!=0 ); assert( IsVirtual(pTab) ); - assert( pTab->u.vtab.p!=0 ); + if( pTab->u.vtab.p==0 ) break; pVtab = pTab->u.vtab.p->pVtab; assert( pVtab!=0 ); pModule = pVtab->pModule; @@ -113917,8 +113977,8 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB */ SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){ return sqlite3ExprCompare(0, - sqlite3ExprSkipCollateAndLikely(pA), - sqlite3ExprSkipCollateAndLikely(pB), + sqlite3ExprSkipCollate(pA), + sqlite3ExprSkipCollate(pB), iTab); } @@ -147605,10 +147665,11 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ SrcList *pTabList; SrcItem *pFrom; - assert( p->selFlags & SF_Resolved ); if( p->selFlags & SF_HasTypeInfo ) return; p->selFlags |= SF_HasTypeInfo; pParse = pWalker->pParse; + testcase( (p->selFlags & SF_Resolved)==0 ); + assert( (p->selFlags & SF_Resolved) || IN_RENAME_OBJECT ); pTabList = p->pSrc; for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ Table *pTab = pFrom->pTab; @@ -148630,6 +148691,7 @@ SQLITE_PRIVATE int sqlite3Select( TREETRACE(0x1000,pParse,p, ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); + unsetJoinExpr(p->pWhere, pItem->iCursor, 0); } } if( pItem->fg.jointype & JT_LTORJ ){ @@ -148644,17 +148706,15 @@ SQLITE_PRIVATE int sqlite3Select( TREETRACE(0x1000,pParse,p, ("RIGHT-JOIN simplifies to JOIN on term %d\n",j)); pI2->fg.jointype &= ~(JT_RIGHT|JT_OUTER); + unsetJoinExpr(p->pWhere, pI2->iCursor, 1); } } } - for(j=pTabList->nSrc-1; j>=i; j--){ + for(j=pTabList->nSrc-1; j>=0; j--){ pTabList->a[j].fg.jointype &= ~JT_LTORJ; if( pTabList->a[j].fg.jointype & JT_RIGHT ) break; } } - assert( pItem->iCursor>=0 ); - unsetJoinExpr(p->pWhere, pItem->iCursor, - pTabList->a[0].fg.jointype & JT_LTORJ); } /* No further action if this term of the FROM clause is not a subquery */ @@ -166058,6 +166118,20 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( continue; } if( sqlite3ExprIsConstant(pExpr) ) continue; + if( pExpr->op==TK_FUNCTION ){ + /* Functions that might set a subtype should not be replaced by the + ** value taken from an expression index since the index omits the + ** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */ + int n; + FuncDef *pDef; + sqlite3 *db = pParse->db; + assert( ExprUseXList(pExpr) ); + n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; + pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); + if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ + continue; + } + } p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); if( p==0 ) break; p->pIENext = pParse->pIdxEpr; @@ -168240,7 +168314,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ assert( ExprUseXList(pWin->pOwner) ); assert( pWin->pWFunc!=0 ); pArgs = pWin->pOwner->x.pList; - if( pWin->pWFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){ + if( pWin->pWFunc->funcFlags & SQLITE_SUBTYPE ){ selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); pWin->bExprArgs = 1; @@ -179414,7 +179488,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc( assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| - SQLITE_SUBTYPE|SQLITE_INNOCUOUS); + SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But @@ -202995,13 +203069,19 @@ static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){ zIn++; N -= 2; while( N>0 ){ - for(i=0; i0 ){ jsonAppendRawNZ(p, zIn, i); zIn += i; N -= i; if( N==0 ) break; } + if( zIn[0]=='"' ){ + jsonAppendRawNZ(p, "\\\"", 2); + zIn++; + N--; + continue; + } assert( zIn[0]=='\\' ); switch( (u8)zIn[1] ){ case '\'': @@ -203396,7 +203476,8 @@ static void jsonReturnJson( JsonParse *pParse, /* The complete JSON */ JsonNode *pNode, /* Node to return */ sqlite3_context *pCtx, /* Return value for this function */ - int bGenerateAlt /* Also store the rendered text in zAlt */ + int bGenerateAlt, /* Also store the rendered text in zAlt */ + int omitSubtype /* Do not call sqlite3_result_subtype() */ ){ JsonString s; if( pParse->oom ){ @@ -203411,7 +203492,7 @@ static void jsonReturnJson( pParse->nAlt = s.nUsed; } jsonResult(&s); - sqlite3_result_subtype(pCtx, JSON_SUBTYPE); + if( !omitSubtype ) sqlite3_result_subtype(pCtx, JSON_SUBTYPE); } } @@ -203452,7 +203533,8 @@ static u32 jsonHexToInt4(const char *z){ static void jsonReturn( JsonParse *pParse, /* Complete JSON parse tree */ JsonNode *pNode, /* Node to return */ - sqlite3_context *pCtx /* Return value for this function */ + sqlite3_context *pCtx, /* Return value for this function */ + int omitSubtype /* Do not call sqlite3_result_subtype() */ ){ switch( pNode->eType ){ default: { @@ -203598,7 +203680,7 @@ static void jsonReturn( } case JSON_ARRAY: case JSON_OBJECT: { - jsonReturnJson(pParse, pNode, pCtx, 0); + jsonReturnJson(pParse, pNode, pCtx, 0, omitSubtype); break; } } @@ -204950,7 +205032,7 @@ static void jsonParseFunc( printf("iSubst = %u\n", p->iSubst); printf("iHold = %u\n", p->iHold); jsonDebugPrintNodeEntries(p->aNode, p->nNode); - jsonReturnJson(p, p->aNode, ctx, 1); + jsonReturnJson(p, p->aNode, ctx, 1, 0); } /* @@ -205136,15 +205218,14 @@ static void jsonExtractFunc( } if( pNode ){ if( flags & JSON_JSON ){ - jsonReturnJson(p, pNode, ctx, 0); + jsonReturnJson(p, pNode, ctx, 0, 0); }else{ - jsonReturn(p, pNode, ctx); - sqlite3_result_subtype(ctx, 0); + jsonReturn(p, pNode, ctx, 1); } } }else{ pNode = jsonLookup(p, zPath, 0, ctx); - if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx); + if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx, 0); } }else{ /* Two or more PATH arguments results in a JSON array with each @@ -205270,7 +205351,7 @@ static void jsonPatchFunc( if( pResult && pX->oom==0 ){ jsonDebugPrintParse(pX); jsonDebugPrintNode(pResult); - jsonReturnJson(pX, pResult, ctx, 0); + jsonReturnJson(pX, pResult, ctx, 0, 0); }else{ sqlite3_result_error_nomem(ctx); } @@ -205349,7 +205430,7 @@ static void jsonRemoveFunc( } } if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){ - jsonReturnJson(pParse, pParse->aNode, ctx, 1); + jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); } remove_done: jsonDebugPrintParse(p); @@ -205478,7 +205559,7 @@ static void jsonReplaceFunc( jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); } } - jsonReturnJson(pParse, pParse->aNode, ctx, 1); + jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); replace_err: jsonDebugPrintParse(pParse); jsonParseFree(pParse); @@ -205532,7 +205613,7 @@ static void jsonSetFunc( } } jsonDebugPrintParse(pParse); - jsonReturnJson(pParse, pParse->aNode, ctx, 1); + jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); jsonSetDone: jsonParseFree(pParse); } @@ -206047,7 +206128,7 @@ static int jsonEachColumn( case JEACH_KEY: { if( p->i==0 ) break; if( p->eType==JSON_OBJECT ){ - jsonReturn(&p->sParse, pThis, ctx); + jsonReturn(&p->sParse, pThis, ctx, 0); }else if( p->eType==JSON_ARRAY ){ u32 iKey; if( p->bRecursive ){ @@ -206063,7 +206144,7 @@ static int jsonEachColumn( } case JEACH_VALUE: { if( pThis->jnFlags & JNODE_LABEL ) pThis++; - jsonReturn(&p->sParse, pThis, ctx); + jsonReturn(&p->sParse, pThis, ctx, 0); break; } case JEACH_TYPE: { @@ -206074,7 +206155,7 @@ static int jsonEachColumn( case JEACH_ATOM: { if( pThis->jnFlags & JNODE_LABEL ) pThis++; if( pThis->eType>=JSON_ARRAY ) break; - jsonReturn(&p->sParse, pThis, ctx); + jsonReturn(&p->sParse, pThis, ctx, 0); break; } case JEACH_ID: { @@ -206367,34 +206448,43 @@ static sqlite3_module jsonTreeModule = { SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ #ifndef SQLITE_OMIT_JSON static FuncDef aJsonFunc[] = { - JFUNCTION(json, 1, 0, jsonRemoveFunc), - JFUNCTION(json_array, -1, 0, jsonArrayFunc), - JFUNCTION(json_array_length, 1, 0, jsonArrayLengthFunc), - JFUNCTION(json_array_length, 2, 0, jsonArrayLengthFunc), - JFUNCTION(json_error_position,1, 0, jsonErrorFunc), - JFUNCTION(json_extract, -1, 0, jsonExtractFunc), - JFUNCTION(->, 2, JSON_JSON, jsonExtractFunc), - JFUNCTION(->>, 2, JSON_SQL, jsonExtractFunc), - JFUNCTION(json_insert, -1, 0, jsonSetFunc), - JFUNCTION(json_object, -1, 0, jsonObjectFunc), - JFUNCTION(json_patch, 2, 0, jsonPatchFunc), - JFUNCTION(json_quote, 1, 0, jsonQuoteFunc), - JFUNCTION(json_remove, -1, 0, jsonRemoveFunc), - JFUNCTION(json_replace, -1, 0, jsonReplaceFunc), - JFUNCTION(json_set, -1, JSON_ISSET, jsonSetFunc), - JFUNCTION(json_type, 1, 0, jsonTypeFunc), - JFUNCTION(json_type, 2, 0, jsonTypeFunc), - JFUNCTION(json_valid, 1, 0, jsonValidFunc), -#if SQLITE_DEBUG - JFUNCTION(json_parse, 1, 0, jsonParseFunc), - JFUNCTION(json_test1, 1, 0, jsonTest1Func), + /* calls sqlite3_result_subtype() */ + /* | */ + /* Uses cache ______ | __ calls sqlite3_value_subtype() */ + /* | | | */ + /* Num args _________ | | | ___ Flags */ + /* | | | | | */ + /* | | | | | */ + JFUNCTION(json, 1, 1, 1, 0, 0, jsonRemoveFunc), + JFUNCTION(json_array, -1, 0, 1, 1, 0, jsonArrayFunc), + JFUNCTION(json_array_length, 1, 1, 0, 0, 0, jsonArrayLengthFunc), + JFUNCTION(json_array_length, 2, 1, 0, 0, 0, jsonArrayLengthFunc), + JFUNCTION(json_error_position,1, 1, 0, 0, 0, jsonErrorFunc), + JFUNCTION(json_extract, -1, 1, 1, 0, 0, jsonExtractFunc), + JFUNCTION(->, 2, 1, 1, 0, JSON_JSON, jsonExtractFunc), + JFUNCTION(->>, 2, 1, 0, 0, JSON_SQL, jsonExtractFunc), + JFUNCTION(json_insert, -1, 1, 1, 1, 0, jsonSetFunc), + JFUNCTION(json_object, -1, 0, 1, 1, 0, jsonObjectFunc), + JFUNCTION(json_patch, 2, 1, 1, 0, 0, jsonPatchFunc), + JFUNCTION(json_quote, 1, 0, 1, 1, 0, jsonQuoteFunc), + JFUNCTION(json_remove, -1, 1, 1, 0, 0, jsonRemoveFunc), + JFUNCTION(json_replace, -1, 1, 1, 1, 0, jsonReplaceFunc), + JFUNCTION(json_set, -1, 1, 1, 1, JSON_ISSET, jsonSetFunc), + JFUNCTION(json_type, 1, 1, 0, 0, 0, jsonTypeFunc), + JFUNCTION(json_type, 2, 1, 0, 0, 0, jsonTypeFunc), + JFUNCTION(json_valid, 1, 1, 0, 0, 0, jsonValidFunc), +#ifdef SQLITE_DEBUG + JFUNCTION(json_parse, 1, 1, 1, 0, 0, jsonParseFunc), + JFUNCTION(json_test1, 1, 1, 0, 1, 0, jsonTest1Func), #endif WAGGREGATE(json_group_array, 1, 0, 0, jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, - SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| + SQLITE_DETERMINISTIC), WAGGREGATE(json_group_object, 2, 0, 0, jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, - SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC) + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| + SQLITE_DETERMINISTIC) }; sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); #endif @@ -236131,10 +236221,8 @@ static Fts5HashEntry *fts5HashEntryMerge( } /* -** Extract all tokens from hash table iHash and link them into a list -** in sorted order. The hash table is cleared before returning. It is -** the responsibility of the caller to free the elements of the returned -** list. +** Link all tokens from hash table iHash into a list in sorted order. The +** tokens are not removed from the hash table. */ static int fts5HashEntrySort( Fts5Hash *pHash, @@ -239000,6 +239088,14 @@ static void fts5SegIterHashInit( pLeaf->p = (u8*)pList; } } + + /* The call to sqlite3Fts5HashScanInit() causes the hash table to + ** fill the size field of all existing position lists. This means they + ** can no longer be appended to. Since the only scenario in which they + ** can be appended to is if the previous operation on this table was + ** a DELETE, by clearing the Fts5Index.bDelete flag we can avoid this + ** possibility altogether. */ + p->bDelete = 0; }else{ p->rc = sqlite3Fts5HashQuery(p->pHash, sizeof(Fts5Data), (const char*)pTerm, nTerm, (void**)&pLeaf, &nList @@ -240677,7 +240773,7 @@ static void fts5WriteAppendPoslistData( const u8 *a = aData; int n = nData; - assert( p->pConfig->pgsz>0 ); + assert( p->pConfig->pgsz>0 || p->rc!=SQLITE_OK ); while( p->rc==SQLITE_OK && (pPage->buf.n + pPage->pgidx.n + n)>=p->pConfig->pgsz ){ @@ -241937,8 +242033,9 @@ static int sqlite3Fts5IndexOptimize(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); - assert( p->nContentlessDelete==0 ); + assert( p->rc!=SQLITE_OK || p->nContentlessDelete==0 ); pStruct = fts5StructureRead(p); + assert( p->rc!=SQLITE_OK || pStruct!=0 ); fts5StructureInvalidate(p); if( pStruct ){ @@ -247515,7 +247612,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4", -1, SQLITE_TRANSIENT); } /* diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index d4f1c810cef..fce162d697a 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.0" -#define SQLITE_VERSION_NUMBER 3044000 -#define SQLITE_SOURCE_ID "2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301" +#define SQLITE_VERSION "3.44.1" +#define SQLITE_VERSION_NUMBER 3044001 +#define SQLITE_SOURCE_ID "2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -5573,13 +5573,27 @@ SQLITE_API int sqlite3_create_window_function( ** ** ** [[SQLITE_SUBTYPE]]
SQLITE_SUBTYPE
-** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call +** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. -** Specifying this flag makes no difference for scalar or aggregate user -** functions. However, if it is not specified for a user-defined window -** function, then any sub-types belonging to arguments passed to the window -** function may be discarded before the window function is called (i.e. -** sqlite3_value_subtype() will always return 0). +** This flag instructs SQLite to omit some corner-case optimizations that +** might disrupt the operation of the [sqlite3_value_subtype()] function, +** causing it to return zero rather than the correct subtype(). +** SQL functions that invokes [sqlite3_value_subtype()] should have this +** property. If the SQLITE_SUBTYPE property is omitted, then the return +** value from [sqlite3_value_subtype()] might sometimes be zero even though +** a non-zero subtype was specified by the function argument expression. +** +** [[SQLITE_RESULT_SUBTYPE]]
SQLITE_RESULT_SUBTYPE
+** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call +** [sqlite3_result_subtype()] to cause a sub-type to be associated with its +** result. +** Every function that invokes [sqlite3_result_subtype()] should have this +** property. If it does not, then the call to [sqlite3_result_subtype()] +** might become a no-op if the function is used as term in an +** [expression index]. On the other hand, SQL functions that never invoke +** [sqlite3_result_subtype()] should avoid setting this property, as the +** purpose of this property is to disable certain optimizations that are +** incompatible with subtypes. **
** */ @@ -5587,6 +5601,7 @@ SQLITE_API int sqlite3_create_window_function( #define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 +#define SQLITE_RESULT_SUBTYPE 0x001000000 /* ** CAPI3REF: Deprecated Functions @@ -5783,6 +5798,12 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*); ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. +** +** Every [application-defined SQL function] that invoke this interface +** should include the [SQLITE_SUBTYPE] property in the text +** encoding argument when the function is [sqlite3_create_function|registered]. +** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() +** might return zero instead of the upstream subtype in some corner cases. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); @@ -5913,14 +5934,22 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); **
  • ^(when sqlite3_set_auxdata() is invoked again on the same ** parameter)^, or **
  • ^(during the original sqlite3_set_auxdata() call when a memory -** allocation error occurs.)^ +** allocation error occurs.)^ +**
  • ^(during the original sqlite3_set_auxdata() call if the function +** is evaluated during query planning instead of during query execution, +** as sometimes happens with [SQLITE_ENABLE_STAT4].)^ ** -** Note the last bullet in particular. The destructor X in +** Note the last two bullets in particular. The destructor X in ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the ** function implementation should not make any use of P after -** sqlite3_set_auxdata() has been called. +** sqlite3_set_auxdata() has been called. Furthermore, a call to +** sqlite3_get_auxdata() that occurs immediately after a corresponding call +** to sqlite3_set_auxdata() might still return NULL if an out-of-memory +** condition occurred during the sqlite3_set_auxdata() call or if the +** function is being evaluated during query planning rather than during +** query execution. ** ** ^(In practice, auxiliary data is preserved between function calls for ** function parameters that are compile-time constants, including literal @@ -6194,6 +6223,20 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); ** higher order bits are discarded. ** The number of subtype bytes preserved by SQLite might increase ** in future releases of SQLite. +** +** Every [application-defined SQL function] that invokes this interface +** should include the [SQLITE_RESULT_SUBTYPE] property in its +** text encoding argument when the SQL function is +** [sqlite3_create_function|registered]. If the [SQLITE_RESULT_SUBTYPE] +** property is omitted from the function that invokes sqlite3_result_subtype(), +** then in some cases the sqlite3_result_subtype() might fail to set +** the result subtype. +** +** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any +** SQL function that invokes the sqlite3_result_subtype() interface +** and that does not have the SQLITE_RESULT_SUBTYPE property will raise +** an error. Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1 +** by default. */ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); From 4d160930bd89560e60ffbff921039403d0b1afa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 29 Nov 2023 15:40:07 +0100 Subject: [PATCH 13/58] Bump supported macOS SDK version to version 14 Change-Id: I2da3a132f557285db9353a3dd5ff0e475c4aceb7 Reviewed-by: Alexandru Croitor --- mkspecs/common/macx.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/common/macx.conf b/mkspecs/common/macx.conf index 00b8713e76a..a57c702a067 100644 --- a/mkspecs/common/macx.conf +++ b/mkspecs/common/macx.conf @@ -11,7 +11,7 @@ QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.13 # older SDKs we have to keep this. QT_MAC_SDK_VERSION_MIN = 10.14 -QT_MAC_SDK_VERSION_MAX = 13 +QT_MAC_SDK_VERSION_MAX = 14 device.sdk = macosx device.target = device From 7cfc621aa049be666c08e94dd23fb82f8b0caffe Mon Sep 17 00:00:00 2001 From: Lauri Pohjanheimo Date: Mon, 6 Nov 2023 16:45:24 +0200 Subject: [PATCH 14/58] Fix Japan locale not showing japanese fonts correctly Fallback font determination did not take locale into account when Japanese locale was used. Android devices show Chinese fonts instead. Fixes the problem by prepending japanese defaut "Noto Sans Mono CJK ..." type font before other fonts. Does same for Chinese and Korean locales. Fixes: QTBUG-111528 Change-Id: I70994c0059c3819eeb09dacb9bbe6634490ecf37 Reviewed-by: Edward Welbourne Reviewed-by: Assam Boudjelthia (cherry picked from commit 476e8f8aef52592d3908b9d5cf6711af7a7d631d) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit c6a86b61642e2e8ab20e51e28079a83dd7547772) (cherry picked from commit c549a12839dae8aec094a67ccc7d93226c31ec68) (cherry picked from commit 72d6c295663e6cb9c2792ced5344347b745d419b) --- .../android/qandroidplatformfontdatabase.cpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp index e594257a4e1..ccc5ea81d04 100644 --- a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp +++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include +#include #include "qandroidplatformfontdatabase.h" @@ -76,6 +77,38 @@ QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &fami QChar::Script script) const { QStringList result; + + // Prepend CJK fonts by the locale. + QLocale locale = QLocale::system(); + switch (locale.language()) { + case QLocale::Chinese: { + switch (locale.country()) { + case QLocale::China: + case QLocale::Singapore: + result.append(QStringLiteral("Noto Sans Mono CJK SC")); + break; + case QLocale::Taiwan: + case QLocale::HongKong: + case QLocale::Macau: + result.append(QStringLiteral("Noto Sans Mono CJK TC")); + break; + default: + // no modifications. + break; + } + break; + } + case QLocale::Japanese: + result.append(QStringLiteral("Noto Sans Mono CJK JP")); + break; + case QLocale::Korean: + result.append(QStringLiteral("Noto Sans Mono CJK KR")); + break; + default: + // no modifications. + break; + } + if (styleHint == QFont::Monospace || styleHint == QFont::Courier) result.append(QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(QLatin1Char(';'))); else if (styleHint == QFont::Serif) From d369389a3f09bfc221a34e124239847e369d4862 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 2 Dec 2023 15:34:38 +0100 Subject: [PATCH 15/58] SQLite: Update SQLite to v3.44.2 [ChangeLog][Third-Party Code] Updated SQLite to v3.44.2 Change-Id: I4da6370cf1e320813b9ba807101ce188d3a09fa0 Reviewed-by: Andy Shaw Reviewed-by: Volker Hilsheimer (cherry picked from commit 8220173b020fd28fdf9635fbd46c9505b9d9442a) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 5c8e47d2dd5b4304320f0f541f7241cd3b345e4e) (cherry picked from commit dd5980a4508fd6b04476fc62e56c2cf663742cd0) (cherry picked from commit a5408f4c95ad4ee5ff337544ffa3f895eddfb0fa) --- src/3rdparty/sqlite/qt_attribution.json | 4 +-- src/3rdparty/sqlite/sqlite3.c | 43 +++++++++++++++---------- src/3rdparty/sqlite/sqlite3.h | 6 ++-- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json index 2dea4e71c07..8b8622548f3 100644 --- a/src/3rdparty/sqlite/qt_attribution.json +++ b/src/3rdparty/sqlite/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Homepage": "https://www.sqlite.org/", - "Version": "3.44.1", - "DownloadLocation": "https://sqlite.org/2023/sqlite-amalgamation-3440100.zip", + "Version": "3.44.2", + "DownloadLocation": "https://www.sqlite.org/2023/sqlite-amalgamation-3440200.zip", "License": "Public Domain", "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." } diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 7d61daa8062..9443127f46e 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.44.1. By combining all the individual C code files into this +** version 3.44.2. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** d295f48e8f367b066b881780c98bdf980a1d. +** ebead0e7230cd33bcec9f95d2183069565b9. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -459,9 +459,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.1" -#define SQLITE_VERSION_NUMBER 3044001 -#define SQLITE_SOURCE_ID "2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4" +#define SQLITE_VERSION "3.44.2" +#define SQLITE_VERSION_NUMBER 3044002 +#define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -84183,10 +84183,11 @@ static int growOpArray(Vdbe *v, int nOp){ ** sqlite3CantopenError(lineno) */ static void test_addop_breakpoint(int pc, Op *pOp){ - static int n = 0; + static u64 n = 0; (void)pc; (void)pOp; n++; + if( n==LARGEST_UINT64 ) abort(); /* so that n is used, preventing a warning */ } #endif @@ -92330,11 +92331,12 @@ SQLITE_API int sqlite3_found_count = 0; ** sqlite3CantopenError(lineno) */ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ - static int n = 0; + static u64 n = 0; (void)pc; (void)pOp; (void)v; n++; + if( n==LARGEST_UINT64 ) abort(); /* So that n is used, preventing a warning */ } #endif @@ -143612,7 +143614,8 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( NameContext sNC; assert( pSelect!=0 ); - assert( (pSelect->selFlags & SF_Resolved)!=0 ); + testcase( (pSelect->selFlags & SF_Resolved)==0 ); + assert( (pSelect->selFlags & SF_Resolved)!=0 || IN_RENAME_OBJECT ); assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 ); assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB ); if( db->mallocFailed || IN_RENAME_OBJECT ) return; @@ -241506,18 +241509,24 @@ static void fts5DoSecureDelete( iOff = iStart; - /* Set variable bLastInDoclist to true if this entry happens to be - ** the last rowid in the doclist for its term. */ + /* If the position-list for the entry being removed flows over past + ** the end of this page, delete the portion of the position-list on the + ** next page and beyond. + ** + ** Set variable bLastInDoclist to true if this entry happens + ** to be the last rowid in the doclist for its term. */ + if( iNextOff>=iPgIdx ){ + int pgno = pSeg->iLeafPgno+1; + fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); + iNextOff = iPgIdx; + } + if( pSeg->bDel==0 ){ - if( iNextOff>=iPgIdx ){ - int pgno = pSeg->iLeafPgno+1; - fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); - iNextOff = iPgIdx; - }else{ + if( iNextOff!=iPgIdx ){ /* Loop through the page-footer. If iNextOff (offset of the ** entry following the one we are removing) is equal to the ** offset of a key on this page, then the entry is the last - ** in its doclist. */ + ** in its doclist. */ int iKeyOff = 0; for(iIdx=0; iIdx Date: Fri, 10 Nov 2023 22:19:15 +0100 Subject: [PATCH 16/58] tst_QString: explain TransientDefaultLocale better A default-constructed QLocale gets initialized with the currently-active default locale, and apparently retains that setting henceforth. That is why the `prior` member is not explicitly initialized, which is confusing at face value. Explain the mechanism better, and explicitly default-initialize the member, so the next reader of the code saves the time to research this. Amends 76dfda1ad12cc42cdd832aed1edbe5f76b0cbb2d. Change-Id: I1d1171f8564c70a971938b92b809f63ba5637d3a Reviewed-by: Edward Welbourne (cherry picked from commit 6c60117d0140e5b70ced78f4dc246ed285273f8c) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 0b73a078057d1d5c2f2eec5c01ee066fa3e95c26) (cherry picked from commit 0e337f6d99816e30eeb084c19386d742275acbc9) (cherry picked from commit 8a99e34a5e88ccf784e8b7f43be911647693d715) --- tests/auto/corelib/text/qstring/tst_qstring.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index 90f7f63192e..e32d54e878c 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -323,7 +323,8 @@ class tst_QString : public QObject class TransientDefaultLocale { - const QLocale prior; // Records what *was* the default before we set it. + // This default-constructed QLocale records what *was* the default before we changed it: + const QLocale prior = {}; public: TransientDefaultLocale(const QLocale &transient) { revise(transient); } void revise(const QLocale &transient) { QLocale::setDefault(transient); } From 5cacae8c7cc3cebcc7f0217c67abebf404089564 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 8 Nov 2023 17:18:42 +0100 Subject: [PATCH 17/58] Rename QImageReader benchmark to tst_bench_ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Helps finding it, e.g. in QtCreator, as it's now disambiguated from tst_QImageReader, the auto-test. As a drive-by, remove all empty functions. Task-number: QTBUG-114253 Change-Id: Icb0a3627488bbf4cb0c9d6bc9890f31a88096afd Reviewed-by: Thiago Macieira (cherry picked from commit 47325e01b72dca38d315a4b955085a4295772e11) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 07ee02f3f6454f95d9e9d88125c0321bdcf84f6d) (cherry picked from commit 6a18ccff2c44dce86d320309033d7de7b4a6c77f) Reviewed-by: Mårten Nordheim Reviewed-by: Ivan Solovev (cherry picked from commit f512fa658e130342cf0a3f08f2e4a15b5fba5577) Reviewed-by: Marc Mutz --- .../gui/image/qimagereader/qimagereader.pro | 2 +- ...ereader.cpp => tst_bench_qimagereader.cpp} | 45 +++++++------------ 2 files changed, 17 insertions(+), 30 deletions(-) rename tests/benchmarks/gui/image/qimagereader/{tst_qimagereader.cpp => tst_bench_qimagereader.cpp} (89%) diff --git a/tests/benchmarks/gui/image/qimagereader/qimagereader.pro b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro index 3454cf1474d..4ad41f66f6b 100644 --- a/tests/benchmarks/gui/image/qimagereader/qimagereader.pro +++ b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro @@ -4,7 +4,7 @@ QT_FOR_CONFIG += gui-private TEMPLATE = app TARGET = tst_bench_qimagereader -SOURCES += tst_qimagereader.cpp +SOURCES += tst_bench_qimagereader.cpp qtConfig(gif): DEFINES += QTEST_HAVE_GIF qtConfig(jpeg): DEFINES += QTEST_HAVE_JPEG diff --git a/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp b/tests/benchmarks/gui/image/qimagereader/tst_bench_qimagereader.cpp similarity index 89% rename from tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp rename to tests/benchmarks/gui/image/qimagereader/tst_bench_qimagereader.cpp index 48e838148fb..2903d5d9edb 100644 --- a/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/benchmarks/gui/image/qimagereader/tst_bench_qimagereader.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ #include + #include #include #include @@ -34,6 +35,7 @@ #include #include #include + #include #include @@ -42,18 +44,15 @@ typedef QList QIntList; Q_DECLARE_METATYPE(QStringMap) Q_DECLARE_METATYPE(QIntList) -class tst_QImageReader : public QObject +class tst_bench_QImageReader : public QObject { Q_OBJECT public: - tst_QImageReader(); - virtual ~tst_QImageReader(); + tst_bench_QImageReader(); public slots: void initTestCase(); - void init(); - void cleanup(); private slots: void readImage_data(); @@ -73,7 +72,7 @@ private: QString prefix; }; -tst_QImageReader::tst_QImageReader() +tst_bench_QImageReader::tst_bench_QImageReader() { images << QPair(QLatin1String("colorful.bmp"), QByteArray("bmp")); images << QPair(QLatin1String("font.bmp"), QByteArray("bmp")); @@ -100,26 +99,14 @@ tst_QImageReader::tst_QImageReader() #endif } -tst_QImageReader::~tst_QImageReader() -{ -} - -void tst_QImageReader::initTestCase() +void tst_bench_QImageReader::initTestCase() { prefix = QFINDTESTDATA("images/"); if (prefix.isEmpty()) QFAIL("Can't find images directory!"); } -void tst_QImageReader::init() -{ -} - -void tst_QImageReader::cleanup() -{ -} - -void tst_QImageReader::readImage_data() +void tst_bench_QImageReader::readImage_data() { QTest::addColumn("fileName"); QTest::addColumn("format"); @@ -131,7 +118,7 @@ void tst_QImageReader::readImage_data() } } -void tst_QImageReader::readImage() +void tst_bench_QImageReader::readImage() { QFETCH(QString, fileName); QFETCH(QByteArray, format); @@ -143,7 +130,7 @@ void tst_QImageReader::readImage() } } -void tst_QImageReader::setScaledSize_data() +void tst_bench_QImageReader::setScaledSize_data() { QTest::addColumn("fileName"); QTest::addColumn("format"); @@ -161,7 +148,7 @@ void tst_QImageReader::setScaledSize_data() } } -void tst_QImageReader::setScaledSize() +void tst_bench_QImageReader::setScaledSize() { QFETCH(QString, fileName); QFETCH(QSize, newSize); @@ -175,7 +162,7 @@ void tst_QImageReader::setScaledSize() } } -void tst_QImageReader::setClipRect_data() +void tst_bench_QImageReader::setClipRect_data() { QTest::addColumn("fileName"); QTest::addColumn("format"); @@ -188,7 +175,7 @@ void tst_QImageReader::setClipRect_data() } } -void tst_QImageReader::setClipRect() +void tst_bench_QImageReader::setClipRect() { QFETCH(QString, fileName); QFETCH(QRect, newRect); @@ -202,12 +189,12 @@ void tst_QImageReader::setClipRect() } } -void tst_QImageReader::setScaledClipRect_data() +void tst_bench_QImageReader::setScaledClipRect_data() { setClipRect_data(); } -void tst_QImageReader::setScaledClipRect() +void tst_bench_QImageReader::setScaledClipRect() { QFETCH(QString, fileName); QFETCH(QRect, newRect); @@ -222,5 +209,5 @@ void tst_QImageReader::setScaledClipRect() } } -QTEST_MAIN(tst_QImageReader) -#include "tst_qimagereader.moc" +QTEST_MAIN(tst_bench_QImageReader) +#include "tst_bench_qimagereader.moc" From ea63c28efc1d2ecb467b83a34923d12462efa96f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 12 Dec 2023 20:51:56 +0100 Subject: [PATCH 18/58] HPack: fix a Yoda Condition Putting the variable on the LHS of a relational operation makes the expression easier to read. In this case, we find that the whole expression is nonsensical as an overflow protection, because if name.size() + value.size() overflows, the result will exactly _not_ be > max() - 32, because UB will have happened. To be fixed in a follow-up commit. As a drive-by, add parentheses around the RHS. Change-Id: I35ce598884c37c51b74756b3bd2734b9aad63c09 Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit 658607a34ead214fbacbc2cca44915655c318ea9) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 4f7efd41740107f90960116700e3134f5e433867) (cherry picked from commit 13c16b756900fe524f6d9534e8a07aa003c05e0c) (cherry picked from commit 1d4788a39668fb2dc5912a8d9c4272dc40e99f92) (cherry picked from commit 87de75b5cc946d196decaa6aef4792a6cac0b6db) --- src/network/access/http2/hpacktable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/http2/hpacktable.cpp b/src/network/access/http2/hpacktable.cpp index 834214ffa2c..ab166a6f753 100644 --- a/src/network/access/http2/hpacktable.cpp +++ b/src/network/access/http2/hpacktable.cpp @@ -63,7 +63,7 @@ HeaderSize entry_size(const QByteArray &name, const QByteArray &value) // 32 octets of overhead." const unsigned sum = unsigned(name.size() + value.size()); - if (std::numeric_limits::max() - 32 < sum) + if (sum > (std::numeric_limits::max() - 32)) return HeaderSize(); return HeaderSize(true, quint32(sum + 32)); } From 23c3fc483e8b6e21012a61f0bea884446f727776 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 12 Dec 2023 22:08:07 +0100 Subject: [PATCH 19/58] HPack: fix incorrect integer overflow check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This code never worked: For the comparison with max() - 32 to trigger, on 32-bit platforms (or Qt 5) signed interger overflow would have had to happen in the addition of the two sizes. The compiler can therefore remove the overflow check as dead code. On Qt 6 and 64-bit platforms, the signed integer addition would be very unlikely to overflow, but the following truncation to uint32 would yield the correct result only in a narrow 32-value window just below UINT_MAX, if even that. Fix by using the proper tool, qAddOverflow. Manual conflict resolutions: - qAddOverflow doesn't exist in Qt 5, use private add_overflow predecessor API instead Change-Id: I7599f2e75ff7f488077b0c60b81022591005661c Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit ee5da1f2eaf8932aeca02ffea6e4c618585e29e3) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit debeb8878da2dc706ead04b6072ecbe7e5313860) Reviewed-by: Thiago Macieira Reviewed-by: Marc Mutz (cherry picked from commit 811b9eef6d08d929af8708adbf2a5effb0eb62d7) (cherry picked from commit f931facd077ce945f1e42eaa3bead208822d3e00) (cherry picked from commit 9ef4ca5ecfed771dab890856130e93ef5ceabef5) Reviewed-by: Mårten Nordheim --- src/network/access/http2/hpacktable.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/network/access/http2/hpacktable.cpp b/src/network/access/http2/hpacktable.cpp index ab166a6f753..de91fc05bbb 100644 --- a/src/network/access/http2/hpacktable.cpp +++ b/src/network/access/http2/hpacktable.cpp @@ -40,6 +40,7 @@ #include "hpacktable_p.h" #include +#include #include #include @@ -62,7 +63,9 @@ HeaderSize entry_size(const QByteArray &name, const QByteArray &value) // for counting the number of references to the name and value would have // 32 octets of overhead." - const unsigned sum = unsigned(name.size() + value.size()); + size_t sum; + if (add_overflow(size_t(name.size()), size_t(value.size()), &sum)) + return HeaderSize(); if (sum > (std::numeric_limits::max() - 32)) return HeaderSize(); return HeaderSize(true, quint32(sum + 32)); From 7d405fb7143b05a6c6cae207a2bbeb35774f0a95 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Thu, 16 Nov 2023 11:57:15 +0100 Subject: [PATCH 20/58] xcb: only set base size when it's valid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In rare situation, base size could be (-1,-1) or (-2,-2) for high dpi, it will be converted into huge positive numbers. https://tronche.com/gui/x/icccm/sec-4.html If a base size is not provided, the minimum size is to be used in its place and vice versa. Task-number: QTBUG-117702 Change-Id: I900ed82f2291fb454d7e34a0dee27459d0a57240 Reviewed-by: Qt CI Bot Reviewed-by: Tor Arne Vestbø Reviewed-by: Axel Spoerl (cherry picked from commit 25720f5a6365125d77400a26f11dbcfc950e5c5f) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 0abe21de9d15b7ee5fa2383d4f4f675df9a8d893) Reviewed-by: Liang Qi (cherry picked from commit df43394df200fde86d912f84a881fc751a15ffbf) (cherry picked from commit b08f33441241a660935825eccf8fab07490aea34) --- src/plugins/platforms/xcb/qxcbwindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 97b7e23ad50..875517fe5fc 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1453,7 +1453,8 @@ void QXcbWindow::propagateSizeHints() qMin(XCOORD_MAX, maximumSize.height())); if (sizeIncrement.width() > 0 || sizeIncrement.height() > 0) { - xcb_icccm_size_hints_set_base_size(&hints, baseSize.width(), baseSize.height()); + if (!baseSize.isNull() && baseSize.isValid()) + xcb_icccm_size_hints_set_base_size(&hints, baseSize.width(), baseSize.height()); xcb_icccm_size_hints_set_resize_inc(&hints, sizeIncrement.width(), sizeIncrement.height()); } From 83c03b640e6ed2a37aa063ed054459a309d392b3 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 5 Jan 2024 11:12:46 +0100 Subject: [PATCH 21/58] QObject: Make it clear we don't install duplicated event filters Change-Id: I3048b50700880dd2445a5a65823fef02b196ce7d Reviewed-by: Paul Wicking Reviewed-by: Marc Mutz (cherry picked from commit 43de84644292978f2b8bce209830cf14d5384904) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 31a94ee00dbe95217b3b5ec4267f2304ec2b5631) (cherry picked from commit b06525ddbbe018f3b2dbd51a5c22c68c86b38d4e) (cherry picked from commit 11526a5413f2723e651b23f0f6bc2571249ff066) (cherry picked from commit 3095d7288fe80cc6ce1a74186d2857af788c2594) --- src/corelib/kernel/qobject.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 85221e8170b..fb790ea42ac 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2220,6 +2220,9 @@ void QObjectPrivate::setParent_helper(QObject *o) If multiple event filters are installed on a single object, the filter that was installed last is activated first. + If \a filterObj has already been installed for this object, + this function moves it so it acts as if it was installed last. + Here's a \c KeyPressEater class that eats the key presses of its monitored objects: From 22d259b0f0d806d4fa34d7f9fc89de52b0f63a4d Mon Sep 17 00:00:00 2001 From: Safiyyah Moosa Date: Wed, 24 Jan 2024 16:13:01 +0100 Subject: [PATCH 22/58] Doc: Replace 'saveFile' with 'saveFileContent' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The example snippet for QFileDialog::saveFileContent, displayed the incorrect and non-existent function, QFileDialog::saveFile. This issue fixes this error, and replaces 'saveFile' with 'saveFileContent'. The order of the input arguments (for SaveFileContent) were incorrect. This issue also fixes the order of the input arguments. Fixes: Change-Id: I31d103288f1341cd0b0b1c7344d72aaeddc23482 Reviewed-by: Topi Reiniö --- src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp index ed6043564bd..dd73f048c75 100644 --- a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp +++ b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp @@ -157,5 +157,5 @@ QFileDialog::getOpenFileContent("Images (*.png *.xpm *.jpg)", fileContentReady) //! [16] QByteArray imageData; // obtained from e.g. QImage::save() -QFileDialog::saveFile("myimage.png", imageData); +QFileDialog::saveFileContent(imageData, "myimage.png"); //! [16] From 03508e193c41ad78633c52070bb8501e32623cae Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 21 Dec 2023 07:03:41 +0100 Subject: [PATCH 23/58] [docs] Remove references to C++11 feature availability QVersionNumber, e.g., was added for Qt 5.6, the last Qt version that didn't require C++11. So it made sense that the original documentation stated that certain functions were only available in C++11 mode. But already Qt 5.7 required C++11, so these historical anecdotes are no longer pertient to today's Qt users, so remove them from the docs. Change-Id: I5c732d3b9b33e1fb6947eff4fac546476c8379f2 Reviewed-by: Thiago Macieira (cherry picked from commit 4f3142bfce0c64d023299f142d14e60ec577b698) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 5b856ba18f0316e9886a0d1048c9e1bb5e2b9fa1) (cherry picked from commit e98f7b448dbe438c547f4d4d3647a3ef08a44bc4) (cherry picked from commit d2d88cfa2e018d034789303ed82af56a133d03e8) (cherry picked from commit 9b5a83109f7023df2a1b8445a63070b633b43e72) --- src/corelib/global/qendian.cpp | 4 ++-- src/corelib/thread/qatomic.cpp | 4 ++-- src/corelib/tools/qcommandlineoption.cpp | 6 ++---- src/corelib/tools/qhash.cpp | 3 --- src/corelib/tools/qsharedpointer.cpp | 5 ++--- src/corelib/tools/qvarlengtharray.qdoc | 6 ------ src/corelib/tools/qversionnumber.cpp | 5 ----- src/gui/painting/qregion.cpp | 2 +- 8 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/corelib/global/qendian.cpp b/src/corelib/global/qendian.cpp index 9c4326f6706..692cb8fda4e 100644 --- a/src/corelib/global/qendian.cpp +++ b/src/corelib/global/qendian.cpp @@ -480,8 +480,8 @@ QT_BEGIN_NAMESPACE The template parameter \c T must be a C++ integer type: \list \li 8-bit: char, signed char, unsigned char, qint8, quint8 - \li 16-bit: short, unsigned short, qint16, quint16, char16_t (C++11) - \li 32-bit: int, unsigned int, qint32, quint32, char32_t (C++11) + \li 16-bit: short, unsigned short, qint16, quint16, char16_t + \li 32-bit: int, unsigned int, qint32, quint32, char32_t \li 64-bit: long long, unsigned long long, qint64, quint64 \li platform-specific size: long, unsigned long \li pointer size: qintptr, quintptr, qptrdiff diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp index 98d8f24ec05..ff7a1513dce 100644 --- a/src/corelib/thread/qatomic.cpp +++ b/src/corelib/thread/qatomic.cpp @@ -68,8 +68,8 @@ The template parameter \c T must be a C++ integer type: \list \li 8-bit: bool, char, signed char, unsigned char, qint8, quint8, char8_t (C++20) - \li 16-bit: short, unsigned short, qint16, quint16, char16_t (C++11) - \li 32-bit: int, unsigned int, qint32, quint32, char32_t (C++11) + \li 16-bit: short, unsigned short, qint16, quint16, char16_t + \li 32-bit: int, unsigned int, qint32, quint32, char32_t \li 64-bit: long long, unsigned long long, qint64, quint64 \li platform-specific size: long, unsigned long \li pointer size: qintptr, quintptr, qptrdiff diff --git a/src/corelib/tools/qcommandlineoption.cpp b/src/corelib/tools/qcommandlineoption.cpp index 3a2894fc504..ffffcd53ed6 100644 --- a/src/corelib/tools/qcommandlineoption.cpp +++ b/src/corelib/tools/qcommandlineoption.cpp @@ -151,8 +151,7 @@ QCommandLineOption::QCommandLineOption(const QStringList &names) The default value for the option is set to \a defaultValue. In Qt versions before 5.4, this constructor was \c explicit. In Qt 5.4 - and later, it no longer is and can be used for C++11-style uniform - initialization: + and later, it no longer is and can be used for uniform initialization: \snippet code/src_corelib_tools_qcommandlineoption.cpp cxx11-init @@ -187,8 +186,7 @@ QCommandLineOption::QCommandLineOption(const QString &name, const QString &descr The default value for the option is set to \a defaultValue. In Qt versions before 5.4, this constructor was \c explicit. In Qt 5.4 - and later, it no longer is and can be used for C++11-style uniform - initialization: + and later, it no longer is and can be used for uniform initialization: \snippet code/src_corelib_tools_qcommandlineoption.cpp cxx11-init-list diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index b075da0198a..aecd4aa0f54 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -2593,9 +2593,6 @@ uint qHash(long double key, uint seed) noexcept Constructs a multi-hash with a copy of each of the elements in the initializer list \a list. - - This function is only available if the program is being - compiled in C++11 mode. */ /*! \fn template QMultiHash::QMultiHash(const QHash &other) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index a0cfa0768da..ccf671d5838 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -211,7 +211,7 @@ last QSharedPointer instance had. This class is never instantiated directly: the constructors and - destructor are private and, in C++11, deleted. Only the create() function + destructor are deleted. Only the create() function may be called to return an object of this type. See below for construction details. @@ -250,8 +250,7 @@ Like ExternalRefCountWithCustomDeleter, this class is never instantiated directly. This class also provides a create() member that returns the - pointer, and hides its constructors and destructor. With C++11, they're - deleted. + pointer, and deletes its constructors and destructor. The size of this class depends on the size of \tt T. diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc index 30f12478aa0..21b65f2b750 100644 --- a/src/corelib/tools/qvarlengtharray.qdoc +++ b/src/corelib/tools/qvarlengtharray.qdoc @@ -110,9 +110,6 @@ \since 5.5 Constructs an array from the std::initializer_list given by \a args. - - This constructor is only enabled if the compiler supports C++11 initializer - lists. */ /*! \fn template template QVarLengthArray::QVarLengthArray(InputIterator first, InputIterator last) @@ -413,9 +410,6 @@ \since 5.5 Assigns the values of \a list to this array, and returns a reference to this array. - - This constructor is only enabled if the compiler supports C++11 initializer - lists. */ /*! \fn template QVarLengthArray::QVarLengthArray(const QVarLengthArray &other) diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp index 5d0d2fd52a1..e8171e1993a 100644 --- a/src/corelib/tools/qversionnumber.cpp +++ b/src/corelib/tools/qversionnumber.cpp @@ -105,8 +105,6 @@ QT_BEGIN_NAMESPACE \fn QVersionNumber::QVersionNumber(QVector &&seg) Move-constructs a version number from the list of numbers contained in \a seg. - - This constructor is only enabled if the compiler supports C++11 move semantics. */ /*! @@ -114,9 +112,6 @@ QT_BEGIN_NAMESPACE Construct a version number from the std::initializer_list specified by \a args. - - This constructor is only enabled if the compiler supports C++11 initializer - lists. */ /*! diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index 1d9a4e5a9e1..f71b58526ae 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -82,7 +82,7 @@ QT_BEGIN_NAMESPACE contains() a QPoint or QRect. The bounding rectangle can be found with boundingRect(). - Iteration over the region (with begin(), end(), or C++11 + Iteration over the region (with begin(), end(), or ranged-for loops) gives a decomposition of the region into rectangles. From f52617f1212cd14747bdb17f4d11843927381973 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 9 Jan 2024 13:03:47 +0100 Subject: [PATCH 24/58] tst_moc: DRY QProcess success verification While the code that checked that exitCode() == 0 was still consistent between all the callers, when it comes to checking stderr, there were several competing implementations, incl. checking the exitCode and dumping stderr to qDebug(), and using QCOMPARE to QByteArray(), presumably in order to get more detailed output on error. Alas, QCOMPARE's toString() truncates output pretty early, making it impossible to see what's going on on failure. So write a small macro that checks the exitCode _after_ it checked that stderr was empty (printing it in full if it was not), so we consistently get the error message instead of a truncated version, or just "exitCode() != 0" without further details. Change-Id: Ic8547fda3b02c645901962887c6ed7aad01f6ea4 Reviewed-by: Thiago Macieira Reviewed-by: Fabian Kosmale (cherry picked from commit 93af86bad566bf4c2c0a5fa7f64e84daaa20a311) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 22f0d3164e5358ae0d0c089160a0a42de38a0915) (cherry picked from commit 239ded94d670ed9d32f2299ef879e6bb2d39054b) (cherry picked from commit 113da02f5ef1e12881fb034c38d3eaf29b42b67c) (cherry picked from commit 678254c99d736715786af3ef8842d9c7e2351ea2) --- tests/auto/tools/moc/tst_moc.cpp | 59 +++++++++++++------------------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index cc465a213ae..26e74e2fc7c 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -758,6 +758,14 @@ private: }; +#define VERIFY_NO_ERRORS(proc) do { \ + auto &&p = proc; \ + const QByteArray stderr = p.readAllStandardError(); \ + QVERIFY2(stderr.isEmpty(), stderr.data()); \ + QCOMPARE(p.exitCode(), 0); \ + } while (false) + + void tst_Moc::initTestCase() { QString binpath = QLibraryInfo::location(QLibraryInfo::BinariesPath); @@ -771,10 +779,9 @@ void tst_Moc::initTestCase() QProcess proc; proc.start(qmake, QStringList() << "-query" << "QT_INSTALL_HEADERS"); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QByteArray output = proc.readAllStandardOutput(); QVERIFY(!output.isEmpty()); - QCOMPARE(proc.readAllStandardError(), QByteArray()); qtIncludePath = QString::fromLocal8Bit(output).trimmed(); QFileInfo fi(qtIncludePath); QVERIFY(fi.exists()); @@ -809,10 +816,9 @@ void tst_Moc::oldStyleCasts() QProcess proc; proc.start(m_moc, QStringList(m_sourceDirectory + QStringLiteral("/oldstyle-casts.h"))); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); - QCOMPARE(proc.readAllStandardError(), QByteArray()); QStringList args; args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "." @@ -823,8 +829,7 @@ void tst_Moc::oldStyleCasts() proc.closeWriteChannel(); QVERIFY(proc.waitForFinished()); - QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); #else QSKIP("Only tested on linux/gcc"); #endif @@ -879,10 +884,9 @@ void tst_Moc::inputFileNameWithDotsButNoExtension() proc.setWorkingDirectory(m_sourceDirectory + QStringLiteral("/task71021")); proc.start(m_moc, QStringList("../Header")); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); - QCOMPARE(proc.readAllStandardError(), QByteArray()); QStringList args; args << "-c" << "-x" << "c++" << "-I" << ".." @@ -893,8 +897,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension() proc.closeWriteChannel(); QVERIFY(proc.waitForFinished()); - QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); #else QSKIP("Only tested on linux/gcc"); #endif @@ -1155,11 +1158,7 @@ void tst_Moc::ignoreOptionClashes() if (!finished) qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error()); QVERIFY(finished); - if (proc.exitCode() != 0) { - qDebug() << proc.readAllStandardError(); - } - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); // If -pthread wasn't ignored, it was parsed as a prefix of "thread/", which breaks compilation. @@ -1173,7 +1172,7 @@ void tst_Moc::ignoreOptionClashes() proc.closeWriteChannel(); QVERIFY(proc.waitForFinished()); - QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString()); + VERIFY_NO_ERRORS(proc); #else QSKIP("Only tested on linux/gcc"); #endif @@ -1278,11 +1277,7 @@ void tst_Moc::frameworkSearchPath() if (!finished) qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error()); QVERIFY(finished); - if (proc.exitCode() != 0) { - qDebug() << proc.readAllStandardError(); - } - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); #else QSKIP("Only tested/relevant on unixy platforms"); #endif @@ -1314,11 +1309,9 @@ void tst_Moc::templateGtGt() QProcess proc; proc.start(m_moc, QStringList(m_sourceDirectory + QStringLiteral("/template-gtgt.h"))); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); - QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError()); - QVERIFY(mocWarning.isEmpty()); #else QSKIP("Only tested on linux/gcc"); #endif @@ -1335,8 +1328,7 @@ void tst_Moc::defineMacroViaCmdline() proc.start(m_moc, args); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); #else @@ -1355,8 +1347,7 @@ void tst_Moc::defineMacroViaForcedInclude() proc.start(m_moc, args); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); #else @@ -1375,8 +1366,7 @@ void tst_Moc::defineMacroViaForcedIncludeRelative() proc.start(m_moc, args); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); #else @@ -1421,8 +1411,7 @@ void tst_Moc::environmentIncludePaths() proc.setProcessEnvironment(env); proc.start(m_moc, args); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); #else @@ -1851,11 +1840,10 @@ void tst_Moc::notifyError() const QString header = m_sourceDirectory + QStringLiteral("/error-on-wrong-notify.h"); proc.start(m_moc, QStringList(header)); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QCOMPARE(proc.exitStatus(), QProcess::NormalExit); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); - QCOMPARE(proc.readAllStandardError(), QByteArray()); QStringList args; args << "-c" << "-x" << "c++" << "-I" << "." @@ -3560,10 +3548,9 @@ void tst_Moc::preprocessorOnly() QProcess proc; proc.start(m_moc, QStringList() << "-E" << m_sourceDirectory + QStringLiteral("/pp-dollar-signs.h")); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); - QCOMPARE(proc.readAllStandardError(), QByteArray()); QVERIFY(mocOut.contains("$$ = parser->createFoo()")); #else From 2cb26f7b6b07e2e8ed9de2b1dedc12364d0a04eb Mon Sep 17 00:00:00 2001 From: Ziming Song Date: Tue, 6 Dec 2022 16:30:40 +0800 Subject: [PATCH 25/58] QTextEngine: also round x-offset for non-subpixel text render If horizontal subpixel is not supported, both glyph advance and x-offset should be rounded. Or the position of rendered glyph might be fraction number. Fixes: QTBUG-104895 Fixes: QTBUG-120554 Change-Id: Ia572764bb87db9712847ceea532d8d424ec7704b (cherry picked from commit 6b1044cc3f79736b9d707d7f9f3cc8c3eae65193) Reviewed-by: Volker Hilsheimer (cherry picked from commit 97ca6c2a51b1c8ed7c9ce8499881e3f9029abbab) --- src/gui/text/qtextengine.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index f4540a7a931..7d8b70b48c3 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1807,8 +1807,10 @@ QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED if (!actualFontEngine->supportsSubPixelPositions() || (actualFontEngine->fontDef.styleStrategy & QFont::ForceIntegerMetrics)) { QT_WARNING_POP - for (uint i = 0; i < num_glyphs; ++i) + for (uint i = 0; i < num_glyphs; ++i) { g.advances[i] = g.advances[i].round(); + g.offsets[i].x = g.offsets[i].x.round(); + } } glyphs_shaped += num_glyphs; From dd0977e36d08e7467376c0c6dd4ad4fa5ee7b4c4 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 24 Jan 2024 10:43:50 +0100 Subject: [PATCH 26/58] [docs] QVersionNumber: fix a typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use "Constructs" instead of "Construct" in the initializer_list ctor docs, because it's what all other ctor docs also use. Change-Id: Ie84d208b81a062851d95fb336553e8e7c57d4b73 Reviewed-by: Mårten Nordheim Reviewed-by: Fabian Kosmale (cherry picked from commit 6147b3f5b2da44b26ff736e3ec850f7cd4cd2ccf) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 463e6698da63d453f0745e6f4fdf4ba417647ff2) (cherry picked from commit c5348ed844479c92470c318868e1cd8447280332) (cherry picked from commit 2a57ad881cba3505a721a9bfbe711c4b13148ed6) (cherry picked from commit 0815cf3f7b0c12e7118f5ba04613b5ca1b9b224f) --- src/corelib/tools/qversionnumber.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp index e8171e1993a..c5adfd40f0a 100644 --- a/src/corelib/tools/qversionnumber.cpp +++ b/src/corelib/tools/qversionnumber.cpp @@ -110,7 +110,7 @@ QT_BEGIN_NAMESPACE /*! \fn QVersionNumber::QVersionNumber(std::initializer_list args) - Construct a version number from the std::initializer_list specified by + Constructs a version number from the std::initializer_list specified by \a args. */ From 043fdbad5539fb0ca7417d790ab8e5c204de947f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 23 Jan 2024 16:37:12 +0100 Subject: [PATCH 27/58] Update Zlib to 1.3.1 [ChangeLog][Third-Party Code] zlib was updated to version 1.3.1. Task-number: QTBUG-121325 Fixes: QTBUG-121444 Change-Id: I0a72b7966916ccb825c7a8ae251e09b2914f0cf4 Reviewed-by: Volker Hilsheimer Reviewed-by: Dennis Oberst (cherry picked from commit 1579f19cf71aa220da3e8f7417a22baeb87a0f65) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit af9bf8712e48b6da4e56d7b189e63b3e44cd5fb2) (cherry picked from commit 1772c99267988366c68bc35fcdd3a238619dd675) (cherry picked from commit 605d1b3e289b75e8d3a85d9a66d545b666017e29) (cherry picked from commit 472ad5938ed5516f157ef0537549b124bc6ac172) --- src/3rdparty/zlib/qt_attribution.json | 6 ++-- src/3rdparty/zlib/qtpatches.diff | 42 +++++++++--------------- src/3rdparty/zlib/src/ChangeLog | 12 ++++++- src/3rdparty/zlib/src/README | 6 ++-- src/3rdparty/zlib/src/deflate.c | 47 ++++++++++++++++++++------- src/3rdparty/zlib/src/deflate.h | 35 ++++++++++++++++++-- src/3rdparty/zlib/src/gzguts.h | 8 ++--- src/3rdparty/zlib/src/gzlib.c | 12 +++---- src/3rdparty/zlib/src/inflate.c | 2 +- src/3rdparty/zlib/src/inftrees.c | 6 ++-- src/3rdparty/zlib/src/inftrees.h | 4 +-- src/3rdparty/zlib/src/trees.c | 20 ++++++++++-- src/3rdparty/zlib/src/zconf.h | 10 +----- src/3rdparty/zlib/src/zlib.h | 22 ++++++------- src/3rdparty/zlib/src/zutil.h | 32 ++---------------- 15 files changed, 147 insertions(+), 117 deletions(-) diff --git a/src/3rdparty/zlib/qt_attribution.json b/src/3rdparty/zlib/qt_attribution.json index 4106ab3cb73..7806aef31c7 100644 --- a/src/3rdparty/zlib/qt_attribution.json +++ b/src/3rdparty/zlib/qt_attribution.json @@ -6,11 +6,11 @@ "Description": "zlib is a general purpose data compression library.", "Homepage": "https://zlib.net/", - "Version": "1.3", - "DownloadLocation": "https://www.zlib.net/zlib-1.3.tar.gz", + "Version": "1.3.1", + "DownloadLocation": "https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz", "License": "zlib License", "LicenseId": "Zlib", "LicenseFile": "LICENSE", - "Copyright": "(C) 1995-2023 Jean-loup Gailly and Mark Adler" + "Copyright": "(C) 1995-2024 Jean-loup Gailly and Mark Adler" } diff --git a/src/3rdparty/zlib/qtpatches.diff b/src/3rdparty/zlib/qtpatches.diff index 20e2b10aa7f..b8efa5199e8 100644 --- a/src/3rdparty/zlib/qtpatches.diff +++ b/src/3rdparty/zlib/qtpatches.diff @@ -1,20 +1,20 @@ diff --git a/src/ChangeLog b/src/ChangeLog -index 8707988ac1..c107a78b5d 100644 +index b801a1031ec..686283a2aec 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,6 +1,10 @@ ChangeLog file for zlib -+Changes in 1.3 (Qt) (23 Aug 2023) ++Changes in 1.3.1 (Qt) (23 Jan 2024) +- This is a stripped down copy of zlib that contains patches to + make it compile as part of Qt. See also "qtpatches.diff". + - Changes in 1.3 (18 Aug 2023) - - Remove K&R function definitions and zlib2ansi - - Fix bug in deflateBound() for level 0 and memLevel 9 + Changes in 1.3.1 (22 Jan 2024) + - Reject overflows of zip header fields in minizip + - Fix bug in inflateSync() for data held in bit buffer diff --git a/src/README b/src/README -index e02fc5aa20..f9c16220b2 100644 +index c5f917540b6..af6b4f32bf5 100644 --- a/src/README +++ b/src/README @@ -6,6 +6,9 @@ thread safe. The data format used by the zlib library is described by RFCs @@ -28,7 +28,7 @@ index e02fc5aa20..f9c16220b2 100644 (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example of the library is given in the file test/example.c which also tests that diff --git a/src/gzguts.h b/src/gzguts.h -index f9375047e8..4c7c9f1225 100644 +index eba72085bb7..5bf6b7d4813 100644 --- a/src/gzguts.h +++ b/src/gzguts.h @@ -3,6 +3,12 @@ @@ -45,7 +45,7 @@ index f9375047e8..4c7c9f1225 100644 # ifndef _LARGEFILE_SOURCE # define _LARGEFILE_SOURCE 1 diff --git a/src/zconf.h b/src/zconf.h -index fb76ffe312..18be576f50 100644 +index 62adc8d8431..4e14507a22d 100644 --- a/src/zconf.h +++ b/src/zconf.h @@ -8,6 +8,9 @@ @@ -66,7 +66,7 @@ index fb76ffe312..18be576f50 100644 /* all zlib typedefs in zlib.h and zconf.h */ # define Byte z_Byte -@@ -441,7 +445,7 @@ typedef uLong FAR uLongf; +@@ -433,7 +437,7 @@ typedef uLong FAR uLongf; typedef unsigned long z_crc_t; #endif @@ -76,7 +76,7 @@ index fb76ffe312..18be576f50 100644 #endif diff --git a/src/zlib.h b/src/zlib.h -index 6b7244f994..ffe3b177e2 100644 +index 8d4b932eaf6..2cff72ee865 100644 --- a/src/zlib.h +++ b/src/zlib.h @@ -33,11 +33,15 @@ @@ -91,13 +91,13 @@ index 6b7244f994..ffe3b177e2 100644 extern "C" { #endif --#define ZLIB_VERSION "1.3" -+#define ZLIB_VERSION "1.3 (Qt)" - #define ZLIB_VERNUM 0x1300 +-#define ZLIB_VERSION "1.3.1" ++#define ZLIB_VERSION "1.3.1 (Qt)" + #define ZLIB_VERNUM 0x1310 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 3 diff --git a/src/zutil.h b/src/zutil.h -index 902a304cc2..3ea777b0f4 100644 +index 48dd7febae6..71dd616ab8d 100644 --- a/src/zutil.h +++ b/src/zutil.h @@ -13,6 +13,12 @@ @@ -113,19 +113,7 @@ index 902a304cc2..3ea777b0f4 100644 #ifdef HAVE_HIDDEN # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) #else -@@ -143,6 +149,11 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ - # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os - # include /* for fdopen */ - # else -+// We need to include stdio.h here because zlib.h will include TargetConditionals.h -+// This will define TARGET_OS_MAC that leads to this check. -+// Since zutil.h will include gzguts.h and gzguts.h includes stdio.h -+// AFTER check for fdopen we need to include stdio.h directly -+# include - # ifndef fdopen - # define fdopen(fd,mode) NULL /* No fdopen() */ - # endif -@@ -166,7 +177,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +@@ -157,7 +163,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 18 #endif diff --git a/src/3rdparty/zlib/src/ChangeLog b/src/3rdparty/zlib/src/ChangeLog index c107a78b5da..26541ea7928 100644 --- a/src/3rdparty/zlib/src/ChangeLog +++ b/src/3rdparty/zlib/src/ChangeLog @@ -1,10 +1,20 @@ ChangeLog file for zlib -Changes in 1.3 (Qt) (23 Aug 2023) +Changes in 1.3.1 (Qt) (23 Jan 2024) - This is a stripped down copy of zlib that contains patches to make it compile as part of Qt. See also "qtpatches.diff". +Changes in 1.3.1 (22 Jan 2024) +- Reject overflows of zip header fields in minizip +- Fix bug in inflateSync() for data held in bit buffer +- Add LIT_MEM define to use more memory for a small deflate speedup +- Fix decision on the emission of Zip64 end records in minizip +- Add bounds checking to ERR_MSG() macro, used by zError() +- Neutralize zip file traversal attacks in miniunz +- Fix a bug in ZLIB_DEBUG compiles in check_match() +- Various portability and appearance improvements + Changes in 1.3 (18 Aug 2023) - Remove K&R function definitions and zlib2ansi - Fix bug in deflateBound() for level 0 and memLevel 9 diff --git a/src/3rdparty/zlib/src/README b/src/3rdparty/zlib/src/README index f9c16220b20..af6b4f32bf5 100644 --- a/src/3rdparty/zlib/src/README +++ b/src/3rdparty/zlib/src/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.3 is a general purpose data compression library. All the code is +zlib 1.3.1 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and @@ -34,7 +34,7 @@ Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at https://marknelson.us/posts/1997/01/01/zlib-engine.html . -The changes made in version 1.3 are documented in the file ChangeLog. +The changes made in version 1.3.1 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . @@ -86,7 +86,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2023 Jean-loup Gailly and Mark Adler + (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/3rdparty/zlib/src/deflate.c b/src/3rdparty/zlib/src/deflate.c index bd011751920..012ea8148e8 100644 --- a/src/3rdparty/zlib/src/deflate.c +++ b/src/3rdparty/zlib/src/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.3 Copyright 1995-2023 Jean-loup Gailly and Mark Adler "; + " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -493,7 +493,7 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, * symbols from which it is being constructed. */ - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); s->pending_buf_size = (ulg)s->lit_bufsize * 4; if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || @@ -503,8 +503,14 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, deflateEnd (strm); return Z_MEM_ERROR; } +#ifdef LIT_MEM + s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); + s->l_buf = s->pending_buf + (s->lit_bufsize << 2); + s->sym_end = s->lit_bufsize - 1; +#else s->sym_buf = s->pending_buf + s->lit_bufsize; s->sym_end = (s->lit_bufsize - 1) * 3; +#endif /* We avoid equality with lit_bufsize*3 because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. @@ -720,9 +726,15 @@ int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; +#ifdef LIT_MEM + if (bits < 0 || bits > 16 || + (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#else if (bits < 0 || bits > 16 || s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; +#endif do { put = Buf_size - s->bi_valid; if (put > bits) @@ -1294,7 +1306,7 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { @@ -1305,10 +1317,15 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +#ifdef LIT_MEM + ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); + ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); +#else ds->sym_buf = ds->pending_buf + ds->lit_bufsize; +#endif ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; @@ -1539,13 +1556,21 @@ local uInt longest_match(deflate_state *s, IPos cur_match) { */ local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); + Bytef *back = s->window + (int)match, *here = s->window + start; + IPos len = length; + if (match == (IPos)-1) { + /* match starts one byte before the current window -- just compare the + subsequent length-1 bytes */ + back++; + here++; + len--; + } + if (zmemcmp(back, here, len) != EQUAL) { + fprintf(stderr, " start %u, match %d, length %d\n", + start, (int)match, length); do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); + fprintf(stderr, "(%02x %02x)", *back++, *here++); + } while (--len != 0); z_error("invalid match"); } if (z_verbose > 1) { diff --git a/src/3rdparty/zlib/src/deflate.h b/src/3rdparty/zlib/src/deflate.h index 8696791429f..300c6ada62b 100644 --- a/src/3rdparty/zlib/src/deflate.h +++ b/src/3rdparty/zlib/src/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2018 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -23,6 +23,10 @@ # define GZIP #endif +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at + the cost of a larger memory footprint */ +/* #define LIT_MEM */ + /* =========================================================================== * Internal compression state. */ @@ -217,7 +221,14 @@ typedef struct internal_state { /* Depth of each subtree used as tie breaker for trees of equal frequency */ +#ifdef LIT_MEM +# define LIT_BUFS 5 + ushf *d_buf; /* buffer for distances */ + uchf *l_buf; /* buffer for literals/lengths */ +#else +# define LIT_BUFS 4 uchf *sym_buf; /* buffer for distances and literals/lengths */ +#endif uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for @@ -239,7 +250,7 @@ typedef struct internal_state { * - I can't count above 4 */ - uInt sym_next; /* running index in sym_buf */ + uInt sym_next; /* running index in symbol buffer */ uInt sym_end; /* symbol table full when sym_next reaches this */ ulg opt_len; /* bit length of current block with optimal trees */ @@ -318,6 +329,25 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, extern const uch ZLIB_INTERNAL _dist_code[]; #endif +#ifdef LIT_MEM +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->sym_next] = 0; \ + s->l_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->sym_next] = dist; \ + s->l_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->sym_buf[s->sym_next++] = 0; \ @@ -337,6 +367,7 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->sym_next == s->sym_end); \ } +#endif #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ diff --git a/src/3rdparty/zlib/src/gzguts.h b/src/3rdparty/zlib/src/gzguts.h index cadba0b24e4..d5512b5406a 100644 --- a/src/3rdparty/zlib/src/gzguts.h +++ b/src/3rdparty/zlib/src/gzguts.h @@ -1,5 +1,5 @@ /* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -229,9 +229,5 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error); /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t value -- needed when comparing unsigned to z_off64_t, which is signed (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else unsigned ZLIB_INTERNAL gz_intmax(void); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/src/3rdparty/zlib/src/gzlib.c b/src/3rdparty/zlib/src/gzlib.c index 29fc4486fba..983153cc8e4 100644 --- a/src/3rdparty/zlib/src/gzlib.c +++ b/src/3rdparty/zlib/src/gzlib.c @@ -1,5 +1,5 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -563,20 +563,20 @@ void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { #endif } -#ifndef INT_MAX /* portably return maximum value for an int (when limits.h presumed not available) -- we need to do this to cover cases where 2's complement not used, since C standard permits 1's complement and sign-bit representations, otherwise we could just use ((unsigned)-1) >> 1 */ unsigned ZLIB_INTERNAL gz_intmax(void) { - unsigned p, q; - - p = 1; +#ifdef INT_MAX + return INT_MAX; +#else + unsigned p = 1, q; do { q = p; p <<= 1; p++; } while (p > q); return q >> 1; -} #endif +} diff --git a/src/3rdparty/zlib/src/inflate.c b/src/3rdparty/zlib/src/inflate.c index b0757a9b249..94ecff015a9 100644 --- a/src/3rdparty/zlib/src/inflate.c +++ b/src/3rdparty/zlib/src/inflate.c @@ -1387,7 +1387,7 @@ int ZEXPORT inflateSync(z_streamp strm) { /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; - state->hold <<= state->bits & 7; + state->hold >>= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { diff --git a/src/3rdparty/zlib/src/inftrees.c b/src/3rdparty/zlib/src/inftrees.c index 8a208c2daa8..98cfe164458 100644 --- a/src/3rdparty/zlib/src/inftrees.c +++ b/src/3rdparty/zlib/src/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2023 Mark Adler + * Copyright (C) 1995-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.3 Copyright 1995-2023 Mark Adler "; + " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -57,7 +57,7 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 203}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/src/3rdparty/zlib/src/inftrees.h b/src/3rdparty/zlib/src/inftrees.h index a10712d8cb5..396f74b5da7 100644 --- a/src/3rdparty/zlib/src/inftrees.h +++ b/src/3rdparty/zlib/src/inftrees.h @@ -41,8 +41,8 @@ typedef struct { examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ diff --git a/src/3rdparty/zlib/src/trees.c b/src/3rdparty/zlib/src/trees.c index 8dbdc40bacc..6a523ef34e3 100644 --- a/src/3rdparty/zlib/src/trees.c +++ b/src/3rdparty/zlib/src/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2021 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -899,14 +899,19 @@ local void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ + unsigned sx = 0; /* running index in symbol buffers */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->sym_next != 0) do { +#ifdef LIT_MEM + dist = s->d_buf[sx]; + lc = s->l_buf[sx++]; +#else dist = s->sym_buf[sx++] & 0xff; dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; lc = s->sym_buf[sx++]; +#endif if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); @@ -931,8 +936,12 @@ local void compress_block(deflate_state *s, const ct_data *ltree, } } /* literal or match pair ? */ - /* Check that the overlay between pending_buf and sym_buf is ok: */ + /* Check for no overlay of pending_buf on needed symbols */ +#ifdef LIT_MEM + Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); +#else Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); +#endif } while (sx < s->sym_next); @@ -1082,9 +1091,14 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, * the current block must be flushed. */ int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { +#ifdef LIT_MEM + s->d_buf[s->sym_next] = (ush)dist; + s->l_buf[s->sym_next++] = (uch)lc; +#else s->sym_buf[s->sym_next++] = (uch)dist; s->sym_buf[s->sym_next++] = (uch)(dist >> 8); s->sym_buf[s->sym_next++] = (uch)lc; +#endif if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; diff --git a/src/3rdparty/zlib/src/zconf.h b/src/3rdparty/zlib/src/zconf.h index 18be576f50d..4e14507a22d 100644 --- a/src/3rdparty/zlib/src/zconf.h +++ b/src/3rdparty/zlib/src/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -304,14 +304,6 @@ # endif #endif -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have diff --git a/src/3rdparty/zlib/src/zlib.h b/src/3rdparty/zlib/src/zlib.h index ffe3b177e29..2cff72ee865 100644 --- a/src/3rdparty/zlib/src/zlib.h +++ b/src/3rdparty/zlib/src/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.3, August 18th, 2023 + version 1.3.1, January 22nd, 2024 - Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -41,11 +41,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.3 (Qt)" -#define ZLIB_VERNUM 0x1300 +#define ZLIB_VERSION "1.3.1 (Qt)" +#define ZLIB_VERNUM 0x1310 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 3 -#define ZLIB_VER_REVISION 0 +#define ZLIB_VER_REVISION 1 #define ZLIB_VER_SUBREVISION 0 /* @@ -940,10 +940,10 @@ ZEXTERN int ZEXPORT inflateSync(z_streamp strm); inflateSync returns Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, @@ -1762,14 +1762,14 @@ ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. + len2. len2 must be non-negative. */ /* ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); Return the operator corresponding to length len2, to be used with - crc32_combine_op(). + crc32_combine_op(). len2 must be non-negative. */ ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); diff --git a/src/3rdparty/zlib/src/zutil.h b/src/3rdparty/zlib/src/zutil.h index 9253060f74d..8608a05a107 100644 --- a/src/3rdparty/zlib/src/zutil.h +++ b/src/3rdparty/zlib/src/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -64,7 +64,7 @@ typedef unsigned long ulg; extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] #define ERR_RETURN(strm,err) \ return (strm->msg = ERR_MSG(err), (err)) @@ -145,22 +145,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif -#if defined(MACOS) || defined(TARGET_OS_MAC) +#if defined(MACOS) # define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -// We need to include stdio.h here because zlib.h will include TargetConditionals.h -// This will define TARGET_OS_MAC that leads to this check. -// Since zutil.h will include gzguts.h and gzguts.h includes stdio.h -// AFTER check for fdopen we need to include stdio.h directly -# include -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif #endif #ifdef __acorn @@ -183,18 +169,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 19 #endif -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - #if defined(__BORLANDC__) && !defined(MSDOS) #pragma warn -8004 #pragma warn -8008 From 96a21d719689e044be67213ee8e328e9989accba Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Tue, 16 Jan 2024 21:14:21 +0100 Subject: [PATCH 28/58] SQLite: Update SQLite to v3.45.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ChangeLog][Third-Party Code] Updated SQLite to v3.45.0 Change-Id: Ibf37acf5bcee4639766d445991f5265dc78593c4 Reviewed-by: Kai Köhne (cherry picked from commit 24a95c22fc9f09ca4415946e965615d022704ca3) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 6224c3b0dc1bd08e1c5fc0a184b2d22627c480dd) (cherry picked from commit 57e98a41364dd9433bc8b18f7b8d1d21606c4cf0) (cherry picked from commit 8e6d961a3242758948042c3b0a3e0707995dfb7e) (cherry picked from commit 6406d7ace379b4a41b3b2474c601ad74b5b1efa3) --- src/3rdparty/sqlite/qt_attribution.json | 4 +- src/3rdparty/sqlite/sqlite3.c | 8025 ++++++++++++++++------- src/3rdparty/sqlite/sqlite3.h | 91 +- 3 files changed, 5547 insertions(+), 2573 deletions(-) diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json index 8b8622548f3..036aa756bb5 100644 --- a/src/3rdparty/sqlite/qt_attribution.json +++ b/src/3rdparty/sqlite/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Homepage": "https://www.sqlite.org/", - "Version": "3.44.2", - "DownloadLocation": "https://www.sqlite.org/2023/sqlite-amalgamation-3440200.zip", + "Version": "3.45.0", + "DownloadLocation": "https://www.sqlite.org/2023/sqlite-amalgamation-3450000.zip", "License": "Public Domain", "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." } diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 9443127f46e..6e6dc8a6c8c 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.44.2. By combining all the individual C code files into this +** version 3.45.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** ebead0e7230cd33bcec9f95d2183069565b9. +** 1066602b2b1976fe58b5150777cced894af1. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -459,9 +459,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.2" -#define SQLITE_VERSION_NUMBER 3044002 -#define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f" +#define SQLITE_VERSION "3.45.0" +#define SQLITE_VERSION_NUMBER 3045000 +#define SQLITE_SOURCE_ID "2024-01-15 17:01:13 1066602b2b1976fe58b5150777cced894af17c803e068f5918390d6915b46e1d" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -4267,15 +4267,17 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); ** ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language -** text that describes the error, as either UTF-8 or UTF-16 respectively. +** text that describes the error, as either UTF-8 or UTF-16 respectively, +** or NULL if no error message is available. ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** -** ^The sqlite3_errstr() interface returns the English-language text -** that describes the [result code], as UTF-8. +** ^The sqlite3_errstr(E) interface returns the English-language text +** that describes the [result code] E, as UTF-8, or NULL if E is not an +** result code for which a text error message is available. ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** @@ -8350,9 +8352,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** ^(Some systems (for example, Windows 95) do not support the operation ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() -** will always return SQLITE_BUSY. The SQLite core only ever uses -** sqlite3_mutex_try() as an optimization so this is acceptable -** behavior.)^ +** will always return SQLITE_BUSY. In most cases the SQLite core only uses +** sqlite3_mutex_try() as an optimization, so this is acceptable +** behavior. The exceptions are unix builds that set the +** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working +** sqlite3_mutex_try() is required.)^ ** ** ^The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior @@ -8611,6 +8615,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ +#define SQLITE_TESTCTRL_JSON_SELFCHECK 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ @@ -13124,8 +13129,11 @@ struct Fts5PhraseIter { ** created with the "columnsize=0" option. ** ** xColumnText: -** This function attempts to retrieve the text of column iCol of the -** current document. If successful, (*pz) is set to point to a buffer +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the text of column iCol of +** the current document. If successful, (*pz) is set to point to a buffer ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, ** if an error occurs, an SQLite error code is returned and the final values @@ -13135,8 +13143,10 @@ struct Fts5PhraseIter { ** Returns the number of phrases in the current query expression. ** ** xPhraseSize: -** Returns the number of tokens in phrase iPhrase of the query. Phrases -** are numbered starting from zero. +** If parameter iCol is less than zero, or greater than or equal to the +** number of phrases in the current query, as returned by xPhraseCount, +** 0 is returned. Otherwise, this function returns the number of tokens in +** phrase iPhrase of the query. Phrases are numbered starting from zero. ** ** xInstCount: ** Set *pnInst to the total number of occurrences of all phrases within @@ -13152,12 +13162,13 @@ struct Fts5PhraseIter { ** Query for the details of phrase match iIdx within the current row. ** Phrase matches are numbered starting from zero, so the iIdx argument ** should be greater than or equal to zero and smaller than the value -** output by xInstCount(). +** output by xInstCount(). If iIdx is less than zero or greater than +** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. ** -** Usually, output parameter *piPhrase is set to the phrase number, *piCol +** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. Returns SQLITE_OK if successful, or an error -** code (i.e. SQLITE_NOMEM) if an error occurs. +** first token of the phrase. SQLITE_OK is returned if successful, or an +** error code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -13183,6 +13194,10 @@ struct Fts5PhraseIter { ** Invoking Api.xUserData() returns a copy of the pointer passed as ** the third argument to pUserData. ** +** If parameter iPhrase is less than zero, or greater than or equal to +** the number of phrases in the query, as returned by xPhraseCount(), +** this function returns SQLITE_RANGE. +** ** If the callback function returns any value other than SQLITE_OK, the ** query is abandoned and the xQueryPhrase function returns immediately. ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. @@ -13297,9 +13312,42 @@ struct Fts5PhraseIter { ** ** xPhraseNextColumn() ** See xPhraseFirstColumn above. +** +** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase iPhrase of the current +** query. Before returning, output parameter *ppToken is set to point +** to a buffer containing the requested token, and *pnToken to the +** size of this buffer in bytes. +** +** If iPhrase or iToken are less than zero, or if iPhrase is greater than +** or equal to the number of phrases in the query as reported by +** xPhraseCount(), or if iToken is equal to or greater than the number of +** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken + are both zeroed. +** +** The output text is not a copy of the query text that specified the +** token. It is the output of the tokenizer module. For tokendata=1 +** tables, this includes any embedded 0x00 and trailing data. +** +** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase hit iIdx within the +** current row. If iIdx is less than zero or greater than or equal to the +** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, +** output variable (*ppToken) is set to point to a buffer containing the +** matching document token, and (*pnToken) to the size of that buffer in +** bytes. This API is not available if the specified token matches a +** prefix query term. In that case both output variables are always set +** to 0. +** +** The output text is not a copy of the document text that was tokenized. +** It is the output of the tokenizer module. For tokendata=1 tables, this +** includes any embedded 0x00 and trailing data. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ void *(*xUserData)(Fts5Context*); @@ -13334,6 +13382,13 @@ struct Fts5ExtensionApi { int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); + + /* Below this point are iVersion>=3 only */ + int (*xQueryToken)(Fts5Context*, + int iPhrase, int iToken, + const char **ppToken, int *pnToken + ); + int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); }; /* @@ -13820,7 +13875,7 @@ struct fts5_api { ** max_page_count macro. */ #ifndef SQLITE_MAX_PAGE_COUNT -# define SQLITE_MAX_PAGE_COUNT 1073741823 +# define SQLITE_MAX_PAGE_COUNT 0xfffffffe /* 4294967294 */ #endif /* @@ -13959,6 +14014,19 @@ struct fts5_api { # undef SQLITE_USE_SEH #endif +/* +** Enable SQLITE_DIRECT_OVERFLOW_READ, unless the build explicitly +** disables it using -DSQLITE_DIRECT_OVERFLOW_READ=0 +*/ +#if defined(SQLITE_DIRECT_OVERFLOW_READ) && SQLITE_DIRECT_OVERFLOW_READ+1==1 + /* Disable if -DSQLITE_DIRECT_OVERFLOW_READ=0 */ +# undef SQLITE_DIRECT_OVERFLOW_READ +#else + /* In all other cases, enable */ +# define SQLITE_DIRECT_OVERFLOW_READ 1 +#endif + + /* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never @@ -15841,7 +15909,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*); SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); -SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, u64*); SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*); SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); @@ -16428,6 +16496,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ +#define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 @@ -16650,13 +16719,15 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Pagecount 178 #define OP_MaxPgcnt 179 #define OP_ClrSubtype 180 /* synopsis: r[P1].subtype = 0 */ -#define OP_FilterAdd 181 /* synopsis: filter(P1) += key(P3@P4) */ -#define OP_Trace 182 -#define OP_CursorHint 183 -#define OP_ReleaseReg 184 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 185 -#define OP_Explain 186 -#define OP_Abortable 187 +#define OP_GetSubtype 181 /* synopsis: r[P2] = r[P1].subtype */ +#define OP_SetSubtype 182 /* synopsis: r[P2].subtype = r[P1] */ +#define OP_FilterAdd 183 /* synopsis: filter(P1) += key(P3@P4) */ +#define OP_Trace 184 +#define OP_CursorHint 185 +#define OP_ReleaseReg 186 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 187 +#define OP_Explain 188 +#define OP_Abortable 189 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -16692,8 +16763,8 @@ typedef struct VdbeOpList VdbeOpList; /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ -/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00,\ -/* 184 */ 0x00, 0x00, 0x00, 0x00,} +/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\ +/* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} /* The resolve3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -17954,11 +18025,11 @@ struct FuncDestructor { #define MFUNCTION(zName, nArg, xPtr, xFunc) \ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } -#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, iArg, xFunc) \ +#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, bJsonB, iArg, xFunc) \ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\ SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\ ((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } + SQLITE_INT_TO_PTR(iArg|((bJsonB)*JSON_BLOB)),0,xFunc,0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_FUNC_BUILTIN|\ SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ @@ -18593,6 +18664,7 @@ struct Index { unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ + unsigned bLowQual:1; /* sqlite_stat1 says this is a low-quality index */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ @@ -18706,6 +18778,7 @@ struct AggInfo { int iOBTab; /* Ephemeral table to implement ORDER BY */ u8 bOBPayload; /* iOBTab has payload columns separate from key */ u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */ + u8 bUseSubtype; /* Transfer subtype info through sorter */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ @@ -19239,6 +19312,7 @@ struct NameContext { int nRef; /* Number of names resolved by this context */ int nNcErr; /* Number of errors encountered while resolving names */ int ncFlags; /* Zero or more NC_* flags defined below */ + u32 nNestedSelect; /* Number of nested selects using this NC */ Select *pWinSelect; /* SELECT statement for any window functions */ }; @@ -19955,6 +20029,9 @@ struct sqlite3_str { ** ** 3. Make a (read-only) copy of a read-only RCStr string using ** sqlite3RCStrRef(). +** +** "String" is in the name, but an RCStr object can also be used to hold +** binary data. */ struct RCStr { u64 nRCRef; /* Number of references */ @@ -20013,6 +20090,9 @@ struct Sqlite3Config { u8 bSmallMalloc; /* Avoid large memory allocations if true */ u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ u8 bUseLongDouble; /* Make use of long double */ +#ifdef SQLITE_DEBUG + u8 bJsonSelfcheck; /* Double-check JSON parsing */ +#endif int mxStrlen; /* Maximum string length */ int neverCorrupt; /* Database is always well-formed */ int szLookaside; /* Default lookaside buffer size */ @@ -20639,6 +20719,7 @@ SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse*,Expr*); SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); +SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3*,void*); SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*); SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*); SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); @@ -20648,6 +20729,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int); SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int); SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); +SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3*,void*); SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*); SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); @@ -20738,6 +20820,7 @@ SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); +SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3*, void*); SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*); #ifndef SQLITE_OMIT_AUTOINCREMENT SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); @@ -20774,6 +20857,7 @@ SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,u32,Expr*); SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); +SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3*,void*); SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*); SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); @@ -21000,6 +21084,7 @@ SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); #endif SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); +SQLITE_PRIVATE int sqlite3Utf8ReadLimited(const u8*, int, u32*); SQLITE_PRIVATE LogEst sqlite3LogEst(u64); SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); @@ -21346,6 +21431,7 @@ SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8); SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*); SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*); SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); +SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3*,void*); SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); #else # define sqlite3CteNew(P,T,E,S) ((void*)0) @@ -22723,6 +22809,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* bSmallMalloc */ 1, /* bExtraSchemaChecks */ sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */ +#ifdef SQLITE_DEBUG + 0, /* bJsonSelfcheck */ +#endif 0x7ffffffe, /* mxStrlen */ 0, /* neverCorrupt */ SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ @@ -23975,7 +24064,7 @@ SQLITE_API int sqlite3_db_status( case SQLITE_DBSTATUS_CACHE_MISS: case SQLITE_DBSTATUS_CACHE_WRITE:{ int i; - int nRet = 0; + u64 nRet = 0; assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 ); assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 ); @@ -23988,7 +24077,7 @@ SQLITE_API int sqlite3_db_status( *pHighwater = 0; /* IMP: R-42420-56072 */ /* IMP: R-54100-20147 */ /* IMP: R-29431-39229 */ - *pCurrent = nRet; + *pCurrent = (int)nRet & 0x7fffffff; break; } @@ -25057,6 +25146,12 @@ static int isDate( } computeJD(p); if( p->isError || !validJulianDay(p->iJD) ) return 1; + if( argc==1 && p->validYMD && p->D>28 ){ + /* Make sure a YYYY-MM-DD is normalized. + ** Example: 2023-02-31 -> 2023-03-03 */ + assert( p->validJD ); + p->validYMD = 0; + } return 0; } @@ -32085,7 +32180,7 @@ SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ /***************************************************************************** -** Reference counted string storage +** Reference counted string/blob storage *****************************************************************************/ /* @@ -32937,7 +33032,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m assert( pExpr->x.pList->nExpr==2 ); pY = pExpr->x.pList->a[0].pExpr; pZ = pExpr->x.pList->a[1].pExpr; - sqlite3TreeViewLine(pView, "BETWEEN"); + sqlite3TreeViewLine(pView, "BETWEEN%s", zFlgs); sqlite3TreeViewExpr(pView, pX, 1); sqlite3TreeViewExpr(pView, pY, 1); sqlite3TreeViewExpr(pView, pZ, 0); @@ -34072,7 +34167,38 @@ SQLITE_PRIVATE u32 sqlite3Utf8Read( return c; } - +/* +** Read a single UTF8 character out of buffer z[], but reading no +** more than n characters from the buffer. z[] is not zero-terminated. +** +** Return the number of bytes used to construct the character. +** +** Invalid UTF8 might generate a strange result. No effort is made +** to detect invalid UTF8. +** +** At most 4 bytes will be read out of z[]. The return value will always +** be between 1 and 4. +*/ +SQLITE_PRIVATE int sqlite3Utf8ReadLimited( + const u8 *z, + int n, + u32 *piOut +){ + u32 c; + int i = 1; + assert( n>0 ); + c = z[0]; + if( c>=0xc0 ){ + c = sqlite3Utf8Trans1[c-0xc0]; + if( n>4 ) n = 4; + while( iiBusyTimeout; +#if SQLITE_ENABLE_SETLK_TIMEOUT==1 pFile->iBusyTimeout = *(int*)pArg; +#elif SQLITE_ENABLE_SETLK_TIMEOUT==2 + pFile->iBusyTimeout = !!(*(int*)pArg); +#else +# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2" +#endif *(int*)pArg = iOld; return SQLITE_OK; } @@ -42146,6 +42280,25 @@ static int unixGetpagesize(void){ ** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and ** unixMutexHeld() is true when reading or writing any other field ** in this structure. +** +** aLock[SQLITE_SHM_NLOCK]: +** This array records the various locks held by clients on each of the +** SQLITE_SHM_NLOCK slots. If the aLock[] entry is set to 0, then no +** locks are held by the process on this slot. If it is set to -1, then +** some client holds an EXCLUSIVE lock on the locking slot. If the aLock[] +** value is set to a positive value, then it is the number of shared +** locks currently held on the slot. +** +** aMutex[SQLITE_SHM_NLOCK]: +** Normally, when SQLITE_ENABLE_SETLK_TIMEOUT is not defined, mutex +** pShmMutex is used to protect the aLock[] array and the right to +** call fcntl() on unixShmNode.hShm to obtain or release locks. +** +** If SQLITE_ENABLE_SETLK_TIMEOUT is defined though, we use an array +** of mutexes - one for each locking slot. To read or write locking +** slot aLock[iSlot], the caller must hold the corresponding mutex +** aMutex[iSlot]. Similarly, to call fcntl() to obtain or release a +** lock corresponding to slot iSlot, mutex aMutex[iSlot] must be held. */ struct unixShmNode { unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ @@ -42159,10 +42312,11 @@ struct unixShmNode { char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + sqlite3_mutex *aMutex[SQLITE_SHM_NLOCK]; +#endif int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */ #ifdef SQLITE_DEBUG - u8 exclMask; /* Mask of exclusive locks held */ - u8 sharedMask; /* Mask of shared locks held */ u8 nextShmId; /* Next available unixShm.id value */ #endif }; @@ -42245,16 +42399,35 @@ static int unixShmSystemLock( struct flock f; /* The posix advisory locking structure */ int rc = SQLITE_OK; /* Result code form fcntl() */ - /* Access to the unixShmNode object is serialized by the caller */ pShmNode = pFile->pInode->pShmNode; - assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); - assert( pShmNode->nRef>0 || unixMutexHeld() ); + + /* Assert that the parameters are within expected range and that the + ** correct mutex or mutexes are held. */ + assert( pShmNode->nRef>=0 ); + assert( (ofst==UNIX_SHM_DMS && n==1) + || (ofst>=UNIX_SHM_BASE && ofst+n<=(UNIX_SHM_BASE+SQLITE_SHM_NLOCK)) + ); + if( ofst==UNIX_SHM_DMS ){ + assert( pShmNode->nRef>0 || unixMutexHeld() ); + assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); + }else{ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int ii; + for(ii=ofst-UNIX_SHM_BASE; iiaMutex[ii]) ); + } +#else + assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); + assert( pShmNode->nRef>0 ); +#endif + } /* Shared locks never span more than one byte */ assert( n==1 || lockType!=F_RDLCK ); /* Locks are within range */ assert( n>=1 && n<=SQLITE_SHM_NLOCK ); + assert( ofst>=UNIX_SHM_BASE && ofst<=(UNIX_SHM_DMS+SQLITE_SHM_NLOCK) ); if( pShmNode->hShm>=0 ){ int res; @@ -42265,7 +42438,7 @@ static int unixShmSystemLock( f.l_len = n; res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile); if( res==-1 ){ -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && SQLITE_ENABLE_SETLK_TIMEOUT==1 rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY); #else rc = SQLITE_BUSY; @@ -42273,39 +42446,28 @@ static int unixShmSystemLock( } } - /* Update the global lock state and do debug tracing */ + /* Do debug tracing */ #ifdef SQLITE_DEBUG - { u16 mask; OSTRACE(("SHM-LOCK ")); - mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<exclMask &= ~mask; - pShmNode->sharedMask &= ~mask; + OSTRACE(("unlock %d..%d ok\n", ofst, ofst+n-1)); }else if( lockType==F_RDLCK ){ - OSTRACE(("read-lock %d ok", ofst)); - pShmNode->exclMask &= ~mask; - pShmNode->sharedMask |= mask; + OSTRACE(("read-lock %d..%d ok\n", ofst, ofst+n-1)); }else{ assert( lockType==F_WRLCK ); - OSTRACE(("write-lock %d ok", ofst)); - pShmNode->exclMask |= mask; - pShmNode->sharedMask &= ~mask; + OSTRACE(("write-lock %d..%d ok\n", ofst, ofst+n-1)); } }else{ if( lockType==F_UNLCK ){ - OSTRACE(("unlock %d failed", ofst)); + OSTRACE(("unlock %d..%d failed\n", ofst, ofst+n-1)); }else if( lockType==F_RDLCK ){ - OSTRACE(("read-lock failed")); + OSTRACE(("read-lock %d..%d failed\n", ofst, ofst+n-1)); }else{ assert( lockType==F_WRLCK ); - OSTRACE(("write-lock %d failed", ofst)); + OSTRACE(("write-lock %d..%d failed\n", ofst, ofst+n-1)); } } - OSTRACE((" - afterwards %03x,%03x\n", - pShmNode->sharedMask, pShmNode->exclMask)); - } #endif return rc; @@ -42342,6 +42504,11 @@ static void unixShmPurge(unixFile *pFd){ int i; assert( p->pInode==pFd->pInode ); sqlite3_mutex_free(p->pShmMutex); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + for(i=0; iaMutex[i]); + } +#endif for(i=0; inRegion; i+=nShmPerMap){ if( p->hShm>=0 ){ osMunmap(p->apRegion[i], p->szRegion); @@ -42401,7 +42568,20 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){ pShmNode->isUnlocked = 1; rc = SQLITE_READONLY_CANTINIT; }else{ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* Do not use a blocking lock here. If the lock cannot be obtained + ** immediately, it means some other connection is truncating the + ** *-shm file. And after it has done so, it will not release its + ** lock, but only downgrade it to a shared lock. So no point in + ** blocking here. The call below to obtain the shared DMS lock may + ** use a blocking lock. */ + int iSaveTimeout = pDbFd->iBusyTimeout; + pDbFd->iBusyTimeout = 0; +#endif rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + pDbFd->iBusyTimeout = iSaveTimeout; +#endif /* The first connection to attach must truncate the -shm file. We ** truncate to 3 bytes (an arbitrary small number, less than the ** -shm header size) rather than 0 as a system debugging aid, to @@ -42522,6 +42702,18 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ rc = SQLITE_NOMEM_BKPT; goto shm_open_err; } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + { + int ii; + for(ii=0; iiaMutex[ii] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->aMutex[ii]==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shm_open_err; + } + } + } +#endif } if( pInode->bProcessLock==0 ){ @@ -42743,9 +42935,11 @@ shmpage_out: */ #ifdef SQLITE_DEBUG static int assertLockingArrayOk(unixShmNode *pShmNode){ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + return 1; +#else unixShm *pX; int aLock[SQLITE_SHM_NLOCK]; - assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); memset(aLock, 0, sizeof(aLock)); for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ @@ -42763,13 +42957,14 @@ static int assertLockingArrayOk(unixShmNode *pShmNode){ assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) ); return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0); +#endif } #endif /* ** Change the lock state for a shared-memory segment. ** -** Note that the relationship between SHAREd and EXCLUSIVE locks is a little +** Note that the relationship between SHARED and EXCLUSIVE locks is a little ** different here than in posix. In xShmLock(), one can go from unlocked ** to shared and back or from unlocked to exclusive and back. But one may ** not go from shared to exclusive or from exclusive to shared. @@ -42784,7 +42979,7 @@ static int unixShmLock( unixShm *p; /* The shared memory being locked */ unixShmNode *pShmNode; /* The underlying file iNode */ int rc = SQLITE_OK; /* Result code */ - u16 mask; /* Mask of locks to take or release */ + u16 mask = (1<<(ofst+n)) - (1<pShm; @@ -42819,88 +43014,151 @@ static int unixShmLock( ** It is not permitted to block on the RECOVER lock. */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT - assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( - (ofst!=2) /* not RECOVER */ - && (ofst!=1 || (p->exclMask|p->sharedMask)==0) - && (ofst!=0 || (p->exclMask|p->sharedMask)<3) - && (ofst<3 || (p->exclMask|p->sharedMask)<(1<exclMask|p->sharedMask); + assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( + (ofst!=2) /* not RECOVER */ + && (ofst!=1 || lockMask==0 || lockMask==2) + && (ofst!=0 || lockMask<3) + && (ofst<3 || lockMask<(1<1 || mask==(1<pShmMutex); - assert( assertLockingArrayOk(pShmNode) ); - if( flags & SQLITE_SHM_UNLOCK ){ - if( (p->exclMask|p->sharedMask) & mask ){ - int ii; - int bUnlock = 1; + /* Check if there is any work to do. There are three cases: + ** + ** a) An unlock operation where there are locks to unlock, + ** b) An shared lock where the requested lock is not already held + ** c) An exclusive lock where the requested lock is not already held + ** + ** The SQLite core never requests an exclusive lock that it already holds. + ** This is assert()ed below. + */ + assert( flags!=(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK) + || 0==(p->exclMask & mask) + ); + if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask)) + || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask)) + || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)) + ){ - for(ii=ofst; ii((p->sharedMask & (1<aMutex[iMutex]); + if( rc!=SQLITE_OK ) goto leave_shmnode_mutexes; + }else{ + sqlite3_mutex_enter(pShmNode->aMutex[iMutex]); } + } +#else + sqlite3_mutex_enter(pShmNode->pShmMutex); +#endif - if( bUnlock ){ - rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); + if( ALWAYS(rc==SQLITE_OK) ){ + if( flags & SQLITE_SHM_UNLOCK ){ + /* Case (a) - unlock. */ + int bUnlock = 1; + assert( (p->exclMask & p->sharedMask)==0 ); + assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask ); + assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask ); + + /* If this is a SHARED lock being unlocked, it is possible that other + ** clients within this process are holding the same SHARED lock. In + ** this case, set bUnlock to 0 so that the posix lock is not removed + ** from the file-descriptor below. */ + if( flags & SQLITE_SHM_SHARED ){ + assert( n==1 ); + assert( aLock[ofst]>=1 ); + if( aLock[ofst]>1 ){ + bUnlock = 0; + aLock[ofst]--; + p->sharedMask &= ~mask; + } + } + + if( bUnlock ){ + rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); + if( rc==SQLITE_OK ){ + memset(&aLock[ofst], 0, sizeof(int)*n); + p->sharedMask &= ~mask; + p->exclMask &= ~mask; + } + } + }else if( flags & SQLITE_SHM_SHARED ){ + /* Case (b) - a shared lock. */ + + if( aLock[ofst]<0 ){ + /* An exclusive lock is held by some other connection. BUSY. */ + rc = SQLITE_BUSY; + }else if( aLock[ofst]==0 ){ + rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); + } + + /* Get the local shared locks */ if( rc==SQLITE_OK ){ - memset(&aLock[ofst], 0, sizeof(int)*n); + p->sharedMask |= mask; + aLock[ofst]++; } - }else if( ALWAYS(p->sharedMask & (1<1 ); - aLock[ofst]--; - } + }else{ + /* Case (c) - an exclusive lock. */ + int ii; - /* Undo the local locks */ - if( rc==SQLITE_OK ){ - p->exclMask &= ~mask; - p->sharedMask &= ~mask; - } - } - }else if( flags & SQLITE_SHM_SHARED ){ - assert( n==1 ); - assert( (p->exclMask & (1<sharedMask & mask)==0 ){ - if( aLock[ofst]<0 ){ - rc = SQLITE_BUSY; - }else if( aLock[ofst]==0 ){ - rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); - } - - /* Get the local shared locks */ - if( rc==SQLITE_OK ){ - p->sharedMask |= mask; - aLock[ofst]++; - } - } - }else{ - /* Make sure no sibling connections hold locks that will block this - ** lock. If any do, return SQLITE_BUSY right away. */ - int ii; - for(ii=ofst; iisharedMask & mask)==0 ); - if( ALWAYS((p->exclMask & (1<sharedMask & mask)==0 ); - p->exclMask |= mask; + assert( (p->exclMask & mask)==0 ); + + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. */ for(ii=ofst; iiexclMask |= mask; + for(ii=ofst; ii=ofst; iMutex--){ + sqlite3_mutex_leave(pShmNode->aMutex[iMutex]); + } +#else + sqlite3_mutex_leave(pShmNode->pShmMutex); +#endif } - assert( assertLockingArrayOk(pShmNode) ); - sqlite3_mutex_leave(pShmNode->pShmMutex); + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", p->id, osGetpid(0), p->sharedMask, p->exclMask)); return rc; @@ -57118,7 +57376,7 @@ struct Pager { char *zJournal; /* Name of the journal file */ int (*xBusyHandler)(void*); /* Function to call when busy */ void *pBusyHandlerArg; /* Context argument for xBusyHandler */ - int aStat[4]; /* Total cache hits, misses, writes, spills */ + u32 aStat[4]; /* Total cache hits, misses, writes, spills */ #ifdef SQLITE_TEST int nRead; /* Database pages read */ #endif @@ -57248,9 +57506,8 @@ SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ #ifndef SQLITE_OMIT_WAL if( pPager->pWal ){ u32 iRead = 0; - int rc; - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); - return (rc==SQLITE_OK && iRead==0); + (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); + return iRead==0; } #endif return 1; @@ -63262,11 +63519,11 @@ SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; a[4] = pPager->eState; a[5] = pPager->errCode; - a[6] = pPager->aStat[PAGER_STAT_HIT]; - a[7] = pPager->aStat[PAGER_STAT_MISS]; + a[6] = (int)pPager->aStat[PAGER_STAT_HIT] & 0x7fffffff; + a[7] = (int)pPager->aStat[PAGER_STAT_MISS] & 0x7fffffff; a[8] = 0; /* Used to be pPager->nOvfl */ a[9] = pPager->nRead; - a[10] = pPager->aStat[PAGER_STAT_WRITE]; + a[10] = (int)pPager->aStat[PAGER_STAT_WRITE] & 0x7fffffff; return a; } #endif @@ -63282,7 +63539,7 @@ SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ ** reset parameter is non-zero, the cache hit or miss count is zeroed before ** returning. */ -SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, u64 *pnVal){ assert( eStat==SQLITE_DBSTATUS_CACHE_HIT || eStat==SQLITE_DBSTATUS_CACHE_MISS @@ -64222,7 +64479,7 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ } #endif -#ifdef SQLITE_USE_SEH +#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ return sqlite3WalSystemErrno(pPager->pWal); } @@ -66238,6 +66495,19 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ } #ifdef SQLITE_ENABLE_SETLK_TIMEOUT + + +/* +** Attempt to enable blocking locks that block for nMs ms. Return 1 if +** blocking locks are successfully enabled, or 0 otherwise. +*/ +static int walEnableBlockingMs(Wal *pWal, int nMs){ + int rc = sqlite3OsFileControl( + pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&nMs + ); + return (rc==SQLITE_OK); +} + /* ** Attempt to enable blocking locks. Blocking locks are enabled only if (a) ** they are supported by the VFS, and (b) the database handle is configured @@ -66249,11 +66519,7 @@ static int walEnableBlocking(Wal *pWal){ if( pWal->db ){ int tmout = pWal->db->busyTimeout; if( tmout ){ - int rc; - rc = sqlite3OsFileControl( - pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout - ); - res = (rc==SQLITE_OK); + res = walEnableBlockingMs(pWal, tmout); } } return res; @@ -66302,20 +66568,10 @@ SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){ pWal->db = db; } -/* -** Take an exclusive WRITE lock. Blocking if so configured. -*/ -static int walLockWriter(Wal *pWal){ - int rc; - walEnableBlocking(pWal); - rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); - walDisableBlocking(pWal); - return rc; -} #else # define walEnableBlocking(x) 0 # define walDisableBlocking(x) -# define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1) +# define walEnableBlockingMs(pWal, ms) 0 # define sqlite3WalDb(pWal, db) #endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */ @@ -66916,7 +67172,9 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ } }else{ int bWriteLock = pWal->writeLock; - if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){ + if( bWriteLock + || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) + ){ pWal->writeLock = 1; if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ badHdr = walIndexTryHdr(pWal, pChanged); @@ -66924,7 +67182,8 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ /* If the wal-index header is still malformed even while holding ** a WRITE lock, it can only mean that the header is corrupted and ** needs to be reconstructed. So run recovery to do exactly that. - */ + ** Disable blocking locks first. */ + walDisableBlocking(pWal); rc = walIndexRecover(pWal); *pChanged = 1; } @@ -67134,6 +67393,37 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ return rc; } +/* +** The final argument passed to walTryBeginRead() is of type (int*). The +** caller should invoke walTryBeginRead as follows: +** +** int cnt = 0; +** do { +** rc = walTryBeginRead(..., &cnt); +** }while( rc==WAL_RETRY ); +** +** The final value of "cnt" is of no use to the caller. It is used by +** the implementation of walTryBeginRead() as follows: +** +** + Each time walTryBeginRead() is called, it is incremented. Once +** it reaches WAL_RETRY_PROTOCOL_LIMIT - indicating that walTryBeginRead() +** has many times been invoked and failed with WAL_RETRY - walTryBeginRead() +** returns SQLITE_PROTOCOL. +** +** + If SQLITE_ENABLE_SETLK_TIMEOUT is defined and walTryBeginRead() failed +** because a blocking lock timed out (SQLITE_BUSY_TIMEOUT from the OS +** layer), the WAL_RETRY_BLOCKED_MASK bit is set in "cnt". In this case +** the next invocation of walTryBeginRead() may omit an expected call to +** sqlite3OsSleep(). There has already been a delay when the previous call +** waited on a lock. +*/ +#define WAL_RETRY_PROTOCOL_LIMIT 100 +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +# define WAL_RETRY_BLOCKED_MASK 0x10000000 +#else +# define WAL_RETRY_BLOCKED_MASK 0 +#endif + /* ** Attempt to start a read transaction. This might fail due to a race or ** other transient condition. When that happens, it returns WAL_RETRY to @@ -67184,13 +67474,16 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ ** so it takes care to hold an exclusive lock on the corresponding ** WAL_READ_LOCK() while changing values. */ -static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ +static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ u32 mxReadMark; /* Largest aReadMark[] value */ int mxI; /* Index of largest aReadMark[] value */ int i; /* Loop counter */ int rc = SQLITE_OK; /* Return code */ u32 mxFrame; /* Wal frame to lock to */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int nBlockTmout = 0; +#endif assert( pWal->readLock<0 ); /* Not currently locked */ @@ -67214,14 +67507,34 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ ** so that on the 100th (and last) RETRY we delay for 323 milliseconds. ** The total delay time before giving up is less than 10 seconds. */ - if( cnt>5 ){ + (*pCnt)++; + if( *pCnt>5 ){ int nDelay = 1; /* Pause time in microseconds */ - if( cnt>100 ){ + int cnt = (*pCnt & ~WAL_RETRY_BLOCKED_MASK); + if( cnt>WAL_RETRY_PROTOCOL_LIMIT ){ VVA_ONLY( pWal->lockError = 1; ) return SQLITE_PROTOCOL; } - if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; + if( *pCnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* In SQLITE_ENABLE_SETLK_TIMEOUT builds, configure the file-descriptor + ** to block for locks for approximately nDelay us. This affects three + ** locks: (a) the shared lock taken on the DMS slot in os_unix.c (if + ** using os_unix.c), (b) the WRITER lock taken in walIndexReadHdr() if the + ** first attempted read fails, and (c) the shared lock taken on the + ** read-mark. + ** + ** If the previous call failed due to an SQLITE_BUSY_TIMEOUT error, + ** then sleep for the minimum of 1us. The previous call already provided + ** an extra delay while it was blocking on the lock. + */ + nBlockTmout = (nDelay+998) / 1000; + if( !useWal && walEnableBlockingMs(pWal, nBlockTmout) ){ + if( *pCnt & WAL_RETRY_BLOCKED_MASK ) nDelay = 1; + } +#endif sqlite3OsSleep(pWal->pVfs, nDelay); + *pCnt &= ~WAL_RETRY_BLOCKED_MASK; } if( !useWal ){ @@ -67229,6 +67542,13 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ if( pWal->bShmUnreliable==0 ){ rc = walIndexReadHdr(pWal, pChanged); } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + walDisableBlocking(pWal); + if( rc==SQLITE_BUSY_TIMEOUT ){ + rc = SQLITE_BUSY; + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } +#endif if( rc==SQLITE_BUSY ){ /* If there is not a recovery running in another thread or process ** then convert BUSY errors to WAL_RETRY. If recovery is known to @@ -67343,9 +67663,19 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; } + (void)walEnableBlockingMs(pWal, nBlockTmout); rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); + walDisableBlocking(pWal); if( rc ){ - return rc==SQLITE_BUSY ? WAL_RETRY : rc; +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ){ + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } +#else + assert( rc!=SQLITE_BUSY_TIMEOUT ); +#endif + assert( (rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT ); + return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; } /* Now that the read-lock has been obtained, check that neither the ** value in the aReadMark[] array or the contents of the wal-index @@ -67533,7 +67863,7 @@ static int walBeginReadTransaction(Wal *pWal, int *pChanged){ #endif do{ - rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); + rc = walTryBeginRead(pWal, pChanged, 0, &cnt); }while( rc==WAL_RETRY ); testcase( (rc&0xff)==SQLITE_BUSY ); testcase( (rc&0xff)==SQLITE_IOERR ); @@ -67714,6 +68044,7 @@ static int walFindFrame( iRead = iFrame; } if( (nCollide--)==0 ){ + *piRead = 0; return SQLITE_CORRUPT_BKPT; } iKey = walNextHash(iKey); @@ -68017,7 +68348,7 @@ static int walRestartLog(Wal *pWal){ cnt = 0; do{ int notUsed; - rc = walTryBeginRead(pWal, ¬Used, 1, ++cnt); + rc = walTryBeginRead(pWal, ¬Used, 1, &cnt); }while( rc==WAL_RETRY ); assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */ testcase( (rc&0xff)==SQLITE_IOERR ); @@ -68438,10 +68769,9 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( if( pWal->readOnly ) return SQLITE_READONLY; WALTRACE(("WAL%p: checkpoint begins\n", pWal)); - /* Enable blocking locks, if possible. If blocking locks are successfully - ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */ + /* Enable blocking locks, if possible. */ sqlite3WalDb(pWal, db); - (void)walEnableBlocking(pWal); + if( xBusy2 ) (void)walEnableBlocking(pWal); /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive ** "checkpoint" lock on the database file. @@ -68482,9 +68812,14 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( /* Read the wal-index header. */ SEH_TRY { if( rc==SQLITE_OK ){ + /* For a passive checkpoint, do not re-enable blocking locks after + ** reading the wal-index header. A passive checkpoint should not block + ** or invoke the busy handler. The only lock such a checkpoint may + ** attempt to obtain is a lock on a read-slot, and it should give up + ** immediately and do a partial checkpoint if it cannot obtain it. */ walDisableBlocking(pWal); rc = walIndexReadHdr(pWal, &isChanged); - (void)walEnableBlocking(pWal); + if( eMode2!=SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal); if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ sqlite3OsUnfetch(pWal->pDbFd, 0, 0); } @@ -68821,7 +69156,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ ** 22 1 Min embedded payload fraction (must be 32) ** 23 1 Min leaf payload fraction (must be 32) ** 24 4 File change counter -** 28 4 Reserved for future use +** 28 4 The size of the database in pages ** 32 4 First freelist page ** 36 4 Number of freelist pages in the file ** 40 60 15 4-byte meta values passed to higher layers @@ -74948,7 +75283,6 @@ static int accessPayload( assert( aWrite>=pBufStart ); /* due to (6) */ memcpy(aSave, aWrite, 4); rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); - if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT; nextPage = get4byte(aWrite); memcpy(aWrite, aSave, 4); }else @@ -85372,6 +85706,10 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); break; } + case P4_TABLEREF: { + if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); + break; + } } } @@ -85499,7 +85837,7 @@ static void SQLITE_NOINLINE vdbeChangeP4Full( int n ){ if( pOp->p4type ){ - freeP4(p->db, pOp->p4type, pOp->p4.p); + assert( pOp->p4type > P4_FREE_IF_LE ); pOp->p4type = 0; pOp->p4.p = 0; } @@ -89622,7 +89960,15 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ int rc = SQLITE_OK; Vdbe *p = (Vdbe*)pStmt; #if SQLITE_THREADSAFE - sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex; + sqlite3_mutex *mutex; +#endif +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif +#if SQLITE_THREADSAFE + mutex = p->db->mutex; #endif sqlite3_mutex_enter(mutex); for(i=0; inVar; i++){ @@ -90412,9 +90758,8 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ #ifdef SQLITE_ENABLE_API_ARMOR if( p==0 ) return 0; -#else - assert( p && p->pFunc ); #endif + assert( p && p->pFunc ); return p->pFunc->pUserData; } @@ -94233,7 +94578,7 @@ case OP_AddImm: { /* in1 */ pIn1 = &aMem[pOp->p1]; memAboutToChange(p, pIn1); sqlite3VdbeMemIntegerify(pIn1); - pIn1->u.i += pOp->p2; + *(u64*)&pIn1->u.i += (u64)pOp->p2; break; } @@ -100379,9 +100724,10 @@ case OP_VCheck: { /* out2 */ pOut = &aMem[pOp->p2]; sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ - assert( pOp->p4type==P4_TABLE ); + assert( pOp->p4type==P4_TABLEREF ); pTab = pOp->p4.pTab; assert( pTab!=0 ); + assert( pTab->nTabRef>0 ); assert( IsVirtual(pTab) ); if( pTab->u.vtab.p==0 ) break; pVtab = pTab->u.vtab.p->pVtab; @@ -100390,13 +100736,11 @@ case OP_VCheck: { /* out2 */ assert( pModule!=0 ); assert( pModule->iVersion>=4 ); assert( pModule->xIntegrity!=0 ); - pTab->nTabRef++; sqlite3VtabLock(pTab->u.vtab.p); assert( pOp->p1>=0 && pOp->p1nDb ); rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName, pOp->p3, &zErr); sqlite3VtabUnlock(pTab->u.vtab.p); - sqlite3DeleteTable(db, pTab); if( rc ){ sqlite3_free(zErr); goto abort_due_to_error; @@ -100521,6 +100865,7 @@ case OP_VColumn: { /* ncycle */ const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; + FuncDef nullFunc; VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur!=0 ); @@ -100538,6 +100883,9 @@ case OP_VColumn: { /* ncycle */ memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; sContext.enc = encoding; + nullFunc.pUserData = 0; + nullFunc.funcFlags = SQLITE_RESULT_SUBTYPE; + sContext.pFunc = &nullFunc; assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 ); if( pOp->p5 & OPFLAG_NOCHNG ){ sqlite3VdbeMemSetNull(pDest); @@ -100870,6 +101218,42 @@ case OP_ClrSubtype: { /* in1 */ break; } +/* Opcode: GetSubtype P1 P2 * * * +** Synopsis: r[P2] = r[P1].subtype +** +** Extract the subtype value from register P1 and write that subtype +** into register P2. If P1 has no subtype, then P1 gets a NULL. +*/ +case OP_GetSubtype: { /* in1 out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( pIn1->flags & MEM_Subtype ){ + sqlite3VdbeMemSetInt64(pOut, pIn1->eSubtype); + }else{ + sqlite3VdbeMemSetNull(pOut); + } + break; +} + +/* Opcode: SetSubtype P1 P2 * * * +** Synopsis: r[P2].subtype = r[P1] +** +** Set the subtype value of register P2 to the integer from register P1. +** If P1 is NULL, clear the subtype from p2. +*/ +case OP_SetSubtype: { /* in1 out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( pIn1->flags & MEM_Null ){ + pOut->flags &= ~MEM_Subtype; + }else{ + assert( pIn1->flags & MEM_Int ); + pOut->flags |= MEM_Subtype; + pOut->eSubtype = (u8)(pIn1->u.i & 0xff); + } + break; +} + /* Opcode: FilterAdd P1 * P3 P4 * ** Synopsis: filter(P1) += key(P3@P4) ** @@ -105918,6 +106302,7 @@ SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){ assert( ExprUseYTab(pExpr) ); pExTab = pExpr->y.pTab; assert( pExTab!=0 ); + assert( n < pExTab->nCol ); if( (pExTab->tabFlags & TF_HasGenerated)!=0 && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 ){ @@ -106494,6 +106879,7 @@ static int lookupName( sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); pParse->checkSchema = 1; pTopNC->nNcErr++; + eNewExprOp = TK_NULL; } assert( pFJMatch==0 ); @@ -106520,7 +106906,7 @@ static int lookupName( ** If a generated column is referenced, set bits for every column ** of the table. */ - if( pExpr->iColumn>=0 && pMatch!=0 ){ + if( pExpr->iColumn>=0 && cnt==1 && pMatch!=0 ){ pMatch->colUsed |= sqlite3ExprColUsed(pExpr); } @@ -106985,11 +107371,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ while( pNC2 && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0 ){ - pExpr->op2++; + pExpr->op2 += (1 + pNC2->nNestedSelect); pNC2 = pNC2->pNext; } assert( pDef!=0 || IN_RENAME_OBJECT ); if( pNC2 && pDef ){ + pExpr->op2 += pNC2->nNestedSelect; assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg ); testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); @@ -107548,6 +107935,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Recursively resolve names in all subqueries in the FROM clause */ + if( pOuterNC ) pOuterNC->nNestedSelect++; for(i=0; ipSrc->nSrc; i++){ SrcItem *pItem = &p->pSrc->a[i]; if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ @@ -107572,6 +107960,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } } } + if( pOuterNC && ALWAYS(pOuterNC->nNestedSelect>0) ){ + pOuterNC->nNestedSelect--; + } /* Set up the local name-context to pass to sqlite3ResolveExprNames() to ** resolve the result-set expression list. @@ -109159,9 +109550,7 @@ SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy( assert( ExprUseXList(pExpr) ); if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){ /* Ignore ORDER BY on zero-argument aggregates */ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - pOrderBy); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pOrderBy); return; } if( IsWindowFunc(pExpr) ){ @@ -109342,6 +109731,9 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ if( p ) sqlite3ExprDeleteNN(db, p); } +SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3 *db, void *p){ + if( ALWAYS(p) ) sqlite3ExprDeleteNN(db, (Expr*)p); +} /* ** Clear both elements of an OnOrUsing object @@ -109367,9 +109759,7 @@ SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ ** pExpr to the pParse->pConstExpr list with a register number of 0. */ SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprDelete, - pExpr); + sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr); } /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the @@ -110175,6 +110565,9 @@ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ if( pList ) exprListDeleteNN(db, pList); } +SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3 *db, void *pList){ + if( ALWAYS(pList) ) exprListDeleteNN(db, (ExprList*)pList); +} /* ** Return the bitwise-OR of all Expr.flags fields in the given @@ -110674,9 +111067,10 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ case TK_COLUMN: assert( ExprUseYTab(p) ); return ExprHasProperty(p, EP_CanBeNull) || - p->y.pTab==0 || /* Reference to column of index on expression */ + NEVER(p->y.pTab==0) || /* Reference to column of index on expr */ (p->iColumn>=0 && p->y.pTab->aCol!=0 /* Possible due to prior error */ + && ALWAYS(p->iColumny.pTab->nCol) && p->y.pTab->aCol[p->iColumn].notNull==0); default: return 1; @@ -113258,8 +113652,10 @@ SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); if( inReg!=target ){ u8 op; - if( ALWAYS(pExpr) - && (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER) + Expr *pX = sqlite3ExprSkipCollateAndLikely(pExpr); + testcase( pX!=pExpr ); + if( ALWAYS(pX) + && (ExprHasProperty(pX,EP_Subquery) || pX->op==TK_REGISTER) ){ op = OP_Copy; }else{ @@ -114705,13 +115101,14 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ case TK_AGG_FUNCTION: { if( (pNC->ncFlags & NC_InAggFunc)==0 && pWalker->walkerDepth==pExpr->op2 + && pExpr->pAggInfo==0 ){ /* Check to see if pExpr is a duplicate of another aggregate ** function that is already in the pAggInfo structure */ struct AggInfo_func *pItem = pAggInfo->aFunc; for(i=0; inFunc; i++, pItem++){ - if( pItem->pFExpr==pExpr ) break; + if( NEVER(pItem->pFExpr==pExpr) ) break; if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ break; } @@ -114754,6 +115151,8 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ }else{ pItem->bOBPayload = 1; } + pItem->bUseSubtype = + (pItem->pFunc->funcFlags & SQLITE_SUBTYPE)!=0; }else{ pItem->iOBTab = -1; } @@ -117520,9 +117919,9 @@ static void openStatTable( typedef struct StatAccum StatAccum; typedef struct StatSample StatSample; struct StatSample { - tRowcnt *anEq; /* sqlite_stat4.nEq */ tRowcnt *anDLt; /* sqlite_stat4.nDLt */ #ifdef SQLITE_ENABLE_STAT4 + tRowcnt *anEq; /* sqlite_stat4.nEq */ tRowcnt *anLt; /* sqlite_stat4.nLt */ union { i64 iRowid; /* Rowid in main table of the key */ @@ -117680,9 +118079,9 @@ static void statInit( /* Allocate the space required for the StatAccum object */ n = sizeof(*p) - + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */ - + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ + + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ #ifdef SQLITE_ENABLE_STAT4 + n += sizeof(tRowcnt)*nColUp; /* StatAccum.anEq */ if( mxSample ){ n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */ + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */ @@ -117703,9 +118102,9 @@ static void statInit( p->nKeyCol = nKeyCol; p->nSkipAhead = 0; p->current.anDLt = (tRowcnt*)&p[1]; - p->current.anEq = &p->current.anDLt[nColUp]; #ifdef SQLITE_ENABLE_STAT4 + p->current.anEq = &p->current.anDLt[nColUp]; p->mxSample = p->nLimit==0 ? mxSample : 0; if( mxSample ){ u8 *pSpace; /* Allocated space not yet assigned */ @@ -117972,7 +118371,9 @@ static void statPush( if( p->nRow==0 ){ /* This is the first call to this function. Do initialization. */ +#ifdef SQLITE_ENABLE_STAT4 for(i=0; inCol; i++) p->current.anEq[i] = 1; +#endif }else{ /* Second and subsequent calls get processed here */ #ifdef SQLITE_ENABLE_STAT4 @@ -117981,15 +118382,17 @@ static void statPush( /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply ** to the current row of the index. */ +#ifdef SQLITE_ENABLE_STAT4 for(i=0; icurrent.anEq[i]++; } +#endif for(i=iChng; inCol; i++){ p->current.anDLt[i]++; #ifdef SQLITE_ENABLE_STAT4 if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i]; -#endif p->current.anEq[i] = 1; +#endif } } @@ -118123,7 +118526,9 @@ static void statGet( u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; sqlite3_str_appendf(&sStat, " %llu", iVal); +#ifdef SQLITE_ENABLE_STAT4 assert( p->current.anEq[i] ); +#endif } sqlite3ResultStrAccum(context, &sStat); } @@ -118812,6 +119217,16 @@ static void decodeIntArray( while( z[0]!=0 && z[0]!=' ' ) z++; while( z[0]==' ' ) z++; } + + /* Set the bLowQual flag if the peak number of rows obtained + ** from a full equality match is so large that a full table scan + ** seems likely to be faster than using the index. + */ + if( aLog[0] > 66 /* Index has more than 100 rows */ + && aLog[0] <= aLog[nOut-1] /* And only a single value seen */ + ){ + pIndex->bLowQual = 1; + } } } @@ -120858,7 +121273,7 @@ SQLITE_PRIVATE void sqlite3ColumnSetExpr( */ SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ if( pCol->iDflt==0 ) return 0; - if( NEVER(!IsOrdinaryTable(pTab)) ) return 0; + if( !IsOrdinaryTable(pTab) ) return 0; if( NEVER(pTab->u.tab.pDfltList==0) ) return 0; if( NEVER(pTab->u.tab.pDfltList->nExpriDflt) ) return 0; return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; @@ -121011,6 +121426,9 @@ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return; deleteTable(db, pTable); } +SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3 *db, void *pTable){ + sqlite3DeleteTable(db, (Table*)pTable); +} /* @@ -121548,7 +121966,8 @@ SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ /* ** Clean up the data structures associated with the RETURNING clause. */ -static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ +static void sqlite3DeleteReturning(sqlite3 *db, void *pArg){ + Returning *pRet = (Returning*)pArg; Hash *pHash; pHash = &(db->aDb[1].pSchema->trigHash); sqlite3HashInsert(pHash, pRet->zName, 0); @@ -121590,8 +122009,7 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ pParse->u1.pReturning = pRet; pRet->pParse = pParse; pRet->pReturnEL = pList; - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); + sqlite3ParserAddCleanup(pParse, sqlite3DeleteReturning, pRet); testcase( pParse->earlyCleanup ); if( db->mallocFailed ) return; sqlite3_snprintf(sizeof(pRet->zName), pRet->zName, @@ -121790,7 +122208,8 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){ assert( zIn!=0 ); while( zIn[0] ){ - h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff]; + u8 x = *(u8*)zIn; + h = (h<<8) + sqlite3UpperToLower[x]; zIn++; if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ aff = SQLITE_AFF_TEXT; @@ -125655,7 +126074,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ if( iDb<0 ) return; z = sqlite3NameFromToken(db, pObjName); if( z==0 ) return; - zDb = db->aDb[iDb].zDbSName; + zDb = pName2->n ? db->aDb[iDb].zDbSName : 0; pTab = sqlite3FindTable(db, z, zDb); if( pTab ){ reindexTable(pParse, pTab, 0); @@ -125665,6 +126084,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ pIndex = sqlite3FindIndex(db, z, zDb); sqlite3DbFree(db, z); if( pIndex ){ + iDb = sqlite3SchemaToIndex(db, pIndex->pTable->pSchema); sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3RefillIndex(pParse, pIndex, -1); return; @@ -125830,6 +126250,9 @@ SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ sqlite3DbFree(db, pWith); } } +SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3 *db, void *pWith){ + sqlite3WithDelete(db, (With*)pWith); +} #endif /* !defined(SQLITE_OMIT_CTE) */ /************** End of build.c ***********************************************/ @@ -139055,7 +139478,8 @@ SQLITE_PRIVATE void sqlite3Pragma( if( pVTab->pModule->iVersion<4 ) continue; if( pVTab->pModule->xIntegrity==0 ) continue; sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); - sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + pTab->nTabRef++; + sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF); a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, a1); @@ -141082,6 +141506,7 @@ static int sqlite3LockAndPrepare( assert( (rc&db->errMask)==rc ); db->busyHandler.nBusy = 0; sqlite3_mutex_leave(db->mutex); + assert( rc==SQLITE_OK || (*ppStmt)==0 ); return rc; } @@ -141479,6 +141904,9 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); } +SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3 *db, void *p){ + if( ALWAYS(p) ) clearSelect(db, (Select*)p, 1); +} /* ** Return a pointer to the right-most SELECT statement in a compound. @@ -144499,9 +144927,7 @@ multi_select_end: pDest->iSdst = dest.iSdst; pDest->nSdst = dest.nSdst; if( pDelete ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3SelectDelete, - pDelete); + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete); } return rc; } @@ -145052,8 +145478,7 @@ static int multiSelectOrderBy( /* Make arrangements to free the 2nd and subsequent arms of the compound ** after the parse has finished */ if( pSplit->pPrior ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior); + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSplit->pPrior); } pSplit->pPrior = pPrior; pPrior->pNext = pSplit; @@ -145874,9 +146299,7 @@ static int flattenSubquery( Table *pTabToDel = pSubitem->pTab; if( pTabToDel->nTabRef==1 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); - sqlite3ParserAddCleanup(pToplevel, - (void(*)(sqlite3*,void*))sqlite3DeleteTable, - pTabToDel); + sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel); testcase( pToplevel->earlyCleanup ); }else{ pTabToDel->nTabRef--; @@ -146923,8 +147346,7 @@ static struct Cte *searchWith( SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ if( pWith ){ if( bFree ){ - pWith = (With*)sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3WithDelete, + pWith = (With*)sqlite3ParserAddCleanup(pParse, sqlite3WithDeleteGeneric, pWith); if( pWith==0 ) return 0; } @@ -147957,6 +148379,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ assert( pFunc->pFExpr->pLeft!=0 ); assert( pFunc->pFExpr->pLeft->op==TK_ORDER ); assert( ExprUseXList(pFunc->pFExpr->pLeft) ); + assert( pFunc->pFunc!=0 ); pOBList = pFunc->pFExpr->pLeft->x.pList; if( !pFunc->bOBUnique ){ nExtra++; /* One extra column for the OP_Sequence */ @@ -147966,6 +148389,9 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ assert( ExprUseXList(pFunc->pFExpr) ); nExtra += pFunc->pFExpr->x.pList->nExpr; } + if( pFunc->bUseSubtype ){ + nExtra += pFunc->pFExpr->x.pList->nExpr; + } pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra); if( !pFunc->bOBUnique && pParse->nErr==0 ){ pKeyInfo->nKeyField++; @@ -147992,9 +148418,9 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ assert( ExprUseXList(pF->pFExpr) ); pList = pF->pFExpr->x.pList; if( pF->iOBTab>=0 ){ - /* For an ORDER BY aggregate, calls to OP_AggStep where deferred and - ** all content was stored in emphermal table pF->iOBTab. Extract that - ** content now (in ORDER BY order) and make all calls to OP_AggStep + /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs + ** were stored in emphermal table pF->iOBTab. Here, we extract those + ** inputs (in ORDER BY order) and make all calls to OP_AggStep ** before doing the OP_AggFinal call. */ int iTop; /* Start of loop for extracting columns */ int nArg; /* Number of columns to extract */ @@ -148002,6 +148428,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ int regAgg; /* Extract into this array */ int j; /* Loop counter */ + assert( pF->pFunc!=0 ); nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); @@ -148018,6 +148445,15 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ for(j=nArg-1; j>=0; j--){ sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j); } + if( pF->bUseSubtype ){ + int regSubtype = sqlite3GetTempReg(pParse); + int iBaseCol = nKey + nArg + (pF->bOBPayload==0 && pF->bOBUnique==0); + for(j=nArg-1; j>=0; j--){ + sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype); + sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j); + } + sqlite3ReleaseTempReg(pParse, regSubtype); + } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); @@ -148072,6 +148508,7 @@ static void updateAccumulator( ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); assert( !IsWindowFunc(pF->pFExpr) ); + assert( pF->pFunc!=0 ); pList = pF->pFExpr->x.pList; if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){ Expr *pFilter = pF->pFExpr->y.pWin->pFilter; @@ -148116,6 +148553,9 @@ static void updateAccumulator( if( pF->bOBPayload ){ regAggSz += nArg; } + if( pF->bUseSubtype ){ + regAggSz += nArg; + } regAggSz++; /* One extra register to hold result of MakeRecord */ regAgg = sqlite3GetTempRange(pParse, regAggSz); regDistinct = regAgg; @@ -148128,6 +148568,14 @@ static void updateAccumulator( if( pF->bOBPayload ){ regDistinct = regAgg+jj; sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP); + jj += nArg; + } + if( pF->bUseSubtype ){ + int kk; + int regBase = pF->bOBPayload ? regDistinct : regAgg; + for(kk=0; kknExpr; @@ -148332,7 +148780,8 @@ static SrcItem *isSelfJoinView( /* ** Deallocate a single AggInfo object */ -static void agginfoFree(sqlite3 *db, AggInfo *p){ +static void agginfoFree(sqlite3 *db, void *pArg){ + AggInfo *p = (AggInfo*)pArg; sqlite3DbFree(db, p->aCol); sqlite3DbFree(db, p->aFunc); sqlite3DbFreeNN(db, p); @@ -148406,7 +148855,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ pSub->selFlags |= SF_Aggregate; pSub->selFlags &= ~SF_Compound; pSub->nSelectRow = 0; - sqlite3ExprListDelete(db, pSub->pEList); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList); pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm); pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0); @@ -148586,9 +149035,8 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); } #endif - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - p->pOrderBy); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, + p->pOrderBy); testcase( pParse->earlyCleanup ); p->pOrderBy = 0; } @@ -148780,9 +149228,8 @@ SQLITE_PRIVATE int sqlite3Select( ){ TREETRACE(0x800,pParse,p, ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - pSub->pOrderBy); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, + pSub->pOrderBy); pSub->pOrderBy = 0; } @@ -149311,8 +149758,7 @@ SQLITE_PRIVATE int sqlite3Select( */ pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) ); if( pAggInfo ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))agginfoFree, pAggInfo); + sqlite3ParserAddCleanup(pParse, agginfoFree, pAggInfo); testcase( pParse->earlyCleanup ); } if( db->mallocFailed ){ @@ -153961,7 +154407,6 @@ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ if( p ){ db->pDisconnect = 0; - sqlite3ExpirePreparedStatements(db, 0); do { VTable *pNext = p->pNext; sqlite3VtabUnlock(p); @@ -155527,7 +155972,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int); #ifdef WHERETRACE_ENABLED SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC); SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm); -SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC); +SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC); #endif SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( WhereClause *pWC, /* The WHERE clause to be searched */ @@ -160989,12 +161434,22 @@ static void translateColumnToCopy( for(; iStartp1!=iTabCur ) continue; if( pOp->opcode==OP_Column ){ +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE OP_Column to OP_Copy at %d\n", iStart); + } +#endif pOp->opcode = OP_Copy; pOp->p1 = pOp->p2 + iRegister; pOp->p2 = pOp->p3; pOp->p3 = 0; pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */ }else if( pOp->opcode==OP_Rowid ){ +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE OP_Rowid to OP_Sequence at %d\n", iStart); + } +#endif pOp->opcode = OP_Sequence; pOp->p1 = iAutoidxCur; #ifdef SQLITE_ALLOW_ROWID_IN_VIEW @@ -162321,7 +162776,8 @@ static int whereRangeScanEst( ** sample, then assume they are 4x more selective. This brings ** the estimated selectivity more in line with what it would be ** if estimated without the use of STAT4 tables. */ - if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) ); + if( iLwrIdx==iUprIdx ){ nNew -= 20; } + assert( 20==sqlite3LogEst(4) ); }else{ nNew = 10; assert( 10==sqlite3LogEst(2) ); } @@ -162545,17 +163001,34 @@ SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ #ifdef WHERETRACE_ENABLED /* ** Print a WhereLoop object for debugging purposes +** +** Format example: +** +** .--- Position in WHERE clause rSetup, rRun, nOut ---. +** | | +** | .--- selfMask nTerm ------. | +** | | | | +** | | .-- prereq Idx wsFlags----. | | +** | | | Name | | | +** | | | __|__ nEq ---. ___|__ | __|__ +** | / \ / \ / \ | / \ / \ / \ +** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31 */ -SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ - WhereInfo *pWInfo = pWC->pWInfo; - int nb = 1+(pWInfo->pTabList->nSrc+3)/4; - SrcItem *pItem = pWInfo->pTabList->a + p->iTab; - Table *pTab = pItem->pTab; - Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; - sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, - p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); - sqlite3DebugPrintf(" %12s", - pItem->zAlias ? pItem->zAlias : pTab->zName); +SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){ + if( pWC ){ + WhereInfo *pWInfo = pWC->pWInfo; + int nb = 1+(pWInfo->pTabList->nSrc+3)/4; + SrcItem *pItem = pWInfo->pTabList->a + p->iTab; + Table *pTab = pItem->pTab; + Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; + sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, + p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); + sqlite3DebugPrintf(" %12s", + pItem->zAlias ? pItem->zAlias : pTab->zName); + }else{ + sqlite3DebugPrintf("%c%2d.%03llx.%03llx %c%d", + p->cId, p->iTab, p->maskSelf, p->prereq & 0xfff, p->cId, p->iTab); + } if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ const char *zName; if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ @@ -162592,6 +163065,15 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ } } } +SQLITE_PRIVATE void sqlite3ShowWhereLoop(const WhereLoop *p){ + if( p ) sqlite3WhereLoopPrint(p, 0); +} +SQLITE_PRIVATE void sqlite3ShowWhereLoopList(const WhereLoop *p){ + while( p ){ + sqlite3ShowWhereLoop(p); + p = p->pNextLoop; + } +} #endif /* @@ -162704,46 +163186,60 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ } /* -** Return TRUE if all of the following are true: +** Return TRUE if X is a proper subset of Y but is of equal or less cost. +** In other words, return true if all constraints of X are also part of Y +** and Y has additional constraints that might speed the search that X lacks +** but the cost of running X is not more than the cost of running Y. ** -** (1) X has the same or lower cost, or returns the same or fewer rows, -** than Y. -** (2) X uses fewer WHERE clause terms than Y -** (3) Every WHERE clause term used by X is also used by Y -** (4) X skips at least as many columns as Y -** (5) If X is a covering index, than Y is too +** In other words, return true if the cost relationwship between X and Y +** is inverted and needs to be adjusted. ** -** Conditions (2) and (3) mean that X is a "proper subset" of Y. -** If X is a proper subset of Y then Y is a better choice and ought -** to have a lower cost. This routine returns TRUE when that cost -** relationship is inverted and needs to be adjusted. Constraint (4) -** was added because if X uses skip-scan less than Y it still might -** deserve a lower cost even if it is a proper subset of Y. Constraint (5) -** was added because a covering index probably deserves to have a lower cost -** than a non-covering index even if it is a proper subset. +** Case 1: +** +** (1a) X and Y use the same index. +** (1b) X has fewer == terms than Y +** (1c) Neither X nor Y use skip-scan +** (1d) X does not have a a greater cost than Y +** +** Case 2: +** +** (2a) X has the same or lower cost, or returns the same or fewer rows, +** than Y. +** (2b) X uses fewer WHERE clause terms than Y +** (2c) Every WHERE clause term used by X is also used by Y +** (2d) X skips at least as many columns as Y +** (2e) If X is a covering index, than Y is too */ static int whereLoopCheaperProperSubset( const WhereLoop *pX, /* First WhereLoop to compare */ const WhereLoop *pY /* Compare against this WhereLoop */ ){ int i, j; - if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ - return 0; /* X is not a subset of Y */ + if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; /* (1d) and (2a) */ + assert( (pX->wsFlags & WHERE_VIRTUALTABLE)==0 ); + assert( (pY->wsFlags & WHERE_VIRTUALTABLE)==0 ); + if( pX->u.btree.nEq < pY->u.btree.nEq /* (1b) */ + && pX->u.btree.pIndex==pY->u.btree.pIndex /* (1a) */ + && pX->nSkip==0 && pY->nSkip==0 /* (1c) */ + ){ + return 1; /* Case 1 is true */ } - if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; - if( pY->nSkip > pX->nSkip ) return 0; + if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ + return 0; /* (2b) */ + } + if( pY->nSkip > pX->nSkip ) return 0; /* (2d) */ for(i=pX->nLTerm-1; i>=0; i--){ if( pX->aLTerm[i]==0 ) continue; for(j=pY->nLTerm-1; j>=0; j--){ if( pY->aLTerm[j]==pX->aLTerm[i] ) break; } - if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ + if( j<0 ) return 0; /* (2c) */ } if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){ - return 0; /* Constraint (5) */ + return 0; /* (2e) */ } - return 1; /* All conditions meet */ + return 1; /* Case 2 is true */ } /* @@ -163233,7 +163729,10 @@ static int whereLoopAddBtreeIndex( assert( pNew->u.btree.nBtm==0 ); opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; } - if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); + if( pProbe->bUnordered || pProbe->bLowQual ){ + if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); + if( pProbe->bLowQual ) opMask &= ~(WO_EQ|WO_IN|WO_IS); + } assert( pNew->u.btree.nEqnColumn ); assert( pNew->u.btree.nEqnKeyCol @@ -166338,7 +166837,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** field (type Bitmask) it must be aligned on an 8-byte boundary on ** some architectures. Hence the ROUND8() below. */ - nByteWInfo = ROUND8P(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); + nByteWInfo = ROUND8P(sizeof(WhereInfo)); + if( nTabList>1 ){ + nByteWInfo = ROUND8P(nByteWInfo + (nTabList-1)*sizeof(WhereLevel)); + } pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); if( db->mallocFailed ){ sqlite3DbFree(db, pWInfo); @@ -166900,6 +167402,11 @@ whereBeginError: pParse->nQueryLoop = pWInfo->savedNQueryLoop; whereInfoFree(db, pWInfo); } +#ifdef WHERETRACE_ENABLED + /* Prevent harmless compiler warnings about debugging routines + ** being declared but never used */ + sqlite3ShowWhereLoopList(0); +#endif /* WHERETRACE_ENABLED */ return 0; } @@ -182236,6 +182743,28 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } #endif + + /* sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &onOff); + ** + ** Activate or deactivate validation of JSONB that is generated from + ** text. Off by default, as the validation is slow. Validation is + ** only available if compiled using SQLITE_DEBUG. + ** + ** If onOff is initially 1, then turn it on. If onOff is initially + ** off, turn it off. If onOff is initially -1, then change onOff + ** to be the current setting. + */ + case SQLITE_TESTCTRL_JSON_SELFCHECK: { +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) + int *pOnOff = va_arg(ap, int*); + if( *pOnOff<0 ){ + *pOnOff = sqlite3Config.bJsonSelfcheck; + }else{ + sqlite3Config.bJsonSelfcheck = (u8)((*pOnOff)&0xff); + } +#endif + break; + } } va_end(ap); #endif /* SQLITE_UNTESTABLE */ @@ -202650,24 +203179,145 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ ** ****************************************************************************** ** -** This SQLite JSON functions. +** SQLite JSON functions. ** ** This file began as an extension in ext/misc/json1.c in 2015. That ** extension proved so useful that it has now been moved into the core. ** -** For the time being, all JSON is stored as pure text. (We might add -** a JSONB type in the future which stores a binary encoding of JSON in -** a BLOB, but there is no support for JSONB in the current implementation. -** This implementation parses JSON text at 250 MB/s, so it is hard to see -** how JSONB might improve on that.) +** The original design stored all JSON as pure text, canonical RFC-8259. +** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16). +** All generated JSON text still conforms strictly to RFC-8259, but text +** with JSON-5 extensions is accepted as input. +** +** Beginning with version 3.45.0 (circa 2024-01-01), these routines also +** accept BLOB values that have JSON encoded using a binary representation +** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk +** format SQLite JSONB is completely different and incompatible with +** PostgreSQL JSONB. +** +** Decoding and interpreting JSONB is still O(N) where N is the size of +** the input, the same as text JSON. However, the constant of proportionality +** for JSONB is much smaller due to faster parsing. The size of each +** element in JSONB is encoded in its header, so there is no need to search +** for delimiters using persnickety syntax rules. JSONB seems to be about +** 3x faster than text JSON as a result. JSONB is also tends to be slightly +** smaller than text JSON, by 5% or 10%, but there are corner cases where +** JSONB can be slightly larger. So you are not far mistaken to say that +** a JSONB blob is the same size as the equivalent RFC-8259 text. +** +** +** THE JSONB ENCODING: +** +** Every JSON element is encoded in JSONB as a header and a payload. +** The header is between 1 and 9 bytes in size. The payload is zero +** or more bytes. +** +** The lower 4 bits of the first byte of the header determines the +** element type: +** +** 0: NULL +** 1: TRUE +** 2: FALSE +** 3: INT -- RFC-8259 integer literal +** 4: INT5 -- JSON5 integer literal +** 5: FLOAT -- RFC-8259 floating point literal +** 6: FLOAT5 -- JSON5 floating point literal +** 7: TEXT -- Text literal acceptable to both SQL and JSON +** 8: TEXTJ -- Text containing RFC-8259 escapes +** 9: TEXT5 -- Text containing JSON5 and/or RFC-8259 escapes +** 10: TEXTRAW -- Text containing unescaped syntax characters +** 11: ARRAY +** 12: OBJECT +** +** The other three possible values (13-15) are reserved for future +** enhancements. +** +** The upper 4 bits of the first byte determine the size of the header +** and sometimes also the size of the payload. If X is the first byte +** of the element and if X>>4 is between 0 and 11, then the payload +** will be that many bytes in size and the header is exactly one byte +** in size. Other four values for X>>4 (12-15) indicate that the header +** is more than one byte in size and that the payload size is determined +** by the remainder of the header, interpreted as a unsigned big-endian +** integer. +** +** Value of X>>4 Size integer Total header size +** ------------- -------------------- ----------------- +** 12 1 byte (0-255) 2 +** 13 2 byte (0-65535) 3 +** 14 4 byte (0-4294967295) 5 +** 15 8 byte (0-1.8e19) 9 +** +** The payload size need not be expressed in its minimal form. For example, +** if the payload size is 10, the size can be expressed in any of 5 different +** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by on 0x0a byte, +** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by +** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and +** a single byte of 0x0a. The shorter forms are preferred, of course, but +** sometimes when generating JSONB, the payload size is not known in advance +** and it is convenient to reserve sufficient header space to cover the +** largest possible payload size and then come back later and patch up +** the size when it becomes known, resulting in a non-minimal encoding. +** +** The value (X>>4)==15 is not actually used in the current implementation +** (as SQLite is currently unable handle BLOBs larger than about 2GB) +** but is included in the design to allow for future enhancements. +** +** The payload follows the header. NULL, TRUE, and FALSE have no payload and +** their payload size must always be zero. The payload for INT, INT5, +** FLOAT, FLOAT5, TEXT, TEXTJ, TEXT5, and TEXTROW is text. Note that the +** "..." or '...' delimiters are omitted from the various text encodings. +** The payload for ARRAY and OBJECT is a list of additional elements that +** are the content for the array or object. The payload for an OBJECT +** must be an even number of elements. The first element of each pair is +** the label and must be of type TEXT, TEXTJ, TEXT5, or TEXTRAW. +** +** A valid JSONB blob consists of a single element, as described above. +** Usually this will be an ARRAY or OBJECT element which has many more +** elements as its content. But the overall blob is just a single element. +** +** Input validation for JSONB blobs simply checks that the element type +** code is between 0 and 12 and that the total size of the element +** (header plus payload) is the same as the size of the BLOB. If those +** checks are true, the BLOB is assumed to be JSONB and processing continues. +** Errors are only raised if some other miscoding is discovered during +** processing. +** +** Additional information can be found in the doc/jsonb.md file of the +** canonical SQLite source tree. */ #ifndef SQLITE_OMIT_JSON /* #include "sqliteInt.h" */ +/* JSONB element types +*/ +#define JSONB_NULL 0 /* "null" */ +#define JSONB_TRUE 1 /* "true" */ +#define JSONB_FALSE 2 /* "false" */ +#define JSONB_INT 3 /* integer acceptable to JSON and SQL */ +#define JSONB_INT5 4 /* integer in 0x000 notation */ +#define JSONB_FLOAT 5 /* float acceptable to JSON and SQL */ +#define JSONB_FLOAT5 6 /* float with JSON5 extensions */ +#define JSONB_TEXT 7 /* Text compatible with both JSON and SQL */ +#define JSONB_TEXTJ 8 /* Text with JSON escapes */ +#define JSONB_TEXT5 9 /* Text with JSON-5 escape */ +#define JSONB_TEXTRAW 10 /* SQL text that needs escaping for JSON */ +#define JSONB_ARRAY 11 /* An array */ +#define JSONB_OBJECT 12 /* An object */ + +/* Human-readable names for the JSONB values. The index for each +** string must correspond to the JSONB_* integer above. +*/ +static const char * const jsonbType[] = { + "null", "true", "false", "integer", "integer", + "real", "real", "text", "text", "text", + "text", "array", "object", "", "", "", "" +}; + /* ** Growing our own isspace() routine this way is twice as fast as ** the library isspace() function, resulting in a 7% overall performance -** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). +** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). */ static const char jsonIsSpace[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, @@ -202688,11 +203338,19 @@ static const char jsonIsSpace[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -#define fast_isspace(x) (jsonIsSpace[(unsigned char)x]) +#define jsonIsspace(x) (jsonIsSpace[(unsigned char)x]) /* -** Characters that are special to JSON. Control charaters, -** '"' and '\\'. +** The set of all space characters recognized by jsonIsspace(). +** Useful as the second argument to strspn(). +*/ +static const char jsonSpaces[] = "\011\012\015\040"; + +/* +** Characters that are special to JSON. Control characters, +** '"' and '\\' and '\''. Actually, '\'' is not special to +** canonical JSON, but it is special in JSON-5, so we include +** it in the set of special characters. */ static const char jsonIsOk[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -202714,22 +203372,49 @@ static const char jsonIsOk[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - -#if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) -# define VVA(X) -#else -# define VVA(X) X -#endif - /* Objects */ +typedef struct JsonCache JsonCache; typedef struct JsonString JsonString; -typedef struct JsonNode JsonNode; typedef struct JsonParse JsonParse; -typedef struct JsonCleanup JsonCleanup; + +/* +** Magic number used for the JSON parse cache in sqlite3_get_auxdata() +*/ +#define JSON_CACHE_ID (-429938) /* Cache entry */ +#define JSON_CACHE_SIZE 4 /* Max number of cache entries */ + +/* +** jsonUnescapeOneChar() returns this invalid code point if it encounters +** a syntax error. +*/ +#define JSON_INVALID_CHAR 0x99999 + +/* A cache mapping JSON text into JSONB blobs. +** +** Each cache entry is a JsonParse object with the following restrictions: +** +** * The bReadOnly flag must be set +** +** * The aBlob[] array must be owned by the JsonParse object. In other +** words, nBlobAlloc must be non-zero. +** +** * eEdit and delta must be zero. +** +** * zJson must be an RCStr. In other words bJsonIsRCStr must be true. +*/ +struct JsonCache { + sqlite3 *db; /* Database connection */ + int nUsed; /* Number of active entries in the cache */ + JsonParse *a[JSON_CACHE_SIZE]; /* One line for each cache entry */ +}; /* An instance of this object represents a JSON string ** under construction. Really, this is a generic string accumulator ** that can be and is used to create strings other than JSON. +** +** If the generated string is longer than will fit into the zSpace[] buffer, +** then it will be an RCStr string. This aids with caching of large +** JSON strings. */ struct JsonString { sqlite3_context *pCtx; /* Function context - put error messages here */ @@ -202737,121 +203422,75 @@ struct JsonString { u64 nAlloc; /* Bytes of storage available in zBuf[] */ u64 nUsed; /* Bytes of zBuf[] currently used */ u8 bStatic; /* True if zBuf is static space */ - u8 bErr; /* True if an error has been encountered */ + u8 eErr; /* True if an error has been encountered */ char zSpace[100]; /* Initial static space */ }; -/* A deferred cleanup task. A list of JsonCleanup objects might be -** run when the JsonParse object is destroyed. -*/ -struct JsonCleanup { - JsonCleanup *pJCNext; /* Next in a list */ - void (*xOp)(void*); /* Routine to run */ - void *pArg; /* Argument to xOp() */ -}; +/* Allowed values for JsonString.eErr */ +#define JSTRING_OOM 0x01 /* Out of memory */ +#define JSTRING_MALFORMED 0x02 /* Malformed JSONB */ +#define JSTRING_ERR 0x04 /* Error already sent to sqlite3_result */ -/* JSON type values +/* The "subtype" set for text JSON values passed through using +** sqlite3_result_subtype() and sqlite3_value_subtype(). */ -#define JSON_SUBST 0 /* Special edit node. Uses u.iPrev */ -#define JSON_NULL 1 -#define JSON_TRUE 2 -#define JSON_FALSE 3 -#define JSON_INT 4 -#define JSON_REAL 5 -#define JSON_STRING 6 -#define JSON_ARRAY 7 -#define JSON_OBJECT 8 - -/* The "subtype" set for JSON values */ #define JSON_SUBTYPE 74 /* Ascii for "J" */ /* -** Names of the various JSON types: +** Bit values for the flags passed into various SQL function implementations +** via the sqlite3_user_data() value. */ -static const char * const jsonType[] = { - "subst", - "null", "true", "false", "integer", "real", "text", "array", "object" -}; - -/* Bit values for the JsonNode.jnFlag field -*/ -#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ -#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ -#define JNODE_REMOVE 0x04 /* Do not output */ -#define JNODE_REPLACE 0x08 /* Target of a JSON_SUBST node */ -#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */ -#define JNODE_LABEL 0x20 /* Is a label of an object */ -#define JNODE_JSON5 0x40 /* Node contains JSON5 enhancements */ +#define JSON_JSON 0x01 /* Result is always JSON */ +#define JSON_SQL 0x02 /* Result is always SQL */ +#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ +#define JSON_ISSET 0x04 /* json_set(), not json_insert() */ +#define JSON_BLOB 0x08 /* Use the BLOB output format */ -/* A single node of parsed JSON. An array of these nodes describes -** a parse of JSON + edits. +/* A parsed JSON value. Lifecycle: ** -** Use the json_parse() SQL function (available when compiled with -** -DSQLITE_DEBUG) to see a dump of complete JsonParse objects, including -** a complete listing and decoding of the array of JsonNodes. -*/ -struct JsonNode { - u8 eType; /* One of the JSON_ type values */ - u8 jnFlags; /* JNODE flags */ - u8 eU; /* Which union element to use */ - u32 n; /* Bytes of content for INT, REAL or STRING - ** Number of sub-nodes for ARRAY and OBJECT - ** Node that SUBST applies to */ - union { - const char *zJContent; /* 1: Content for INT, REAL, and STRING */ - u32 iAppend; /* 2: More terms for ARRAY and OBJECT */ - u32 iKey; /* 3: Key for ARRAY objects in json_tree() */ - u32 iPrev; /* 4: Previous SUBST node, or 0 */ - } u; -}; - - -/* A parsed and possibly edited JSON string. Lifecycle: +** 1. JSON comes in and is parsed into a JSONB value in aBlob. The +** original text is stored in zJson. This step is skipped if the +** input is JSONB instead of text JSON. ** -** 1. JSON comes in and is parsed into an array aNode[]. The original -** JSON text is stored in zJson. +** 2. The aBlob[] array is searched using the JSON path notation, if needed. ** -** 2. Zero or more changes are made (via json_remove() or json_replace() -** or similar) to the aNode[] array. +** 3. Zero or more changes are made to aBlob[] (via json_remove() or +** json_replace() or json_patch() or similar). ** -** 3. A new, edited and mimified JSON string is generated from aNode -** and stored in zAlt. The JsonParse object always owns zAlt. -** -** Step 1 always happens. Step 2 and 3 may or may not happen, depending -** on the operation. -** -** aNode[].u.zJContent entries typically point into zJson. Hence zJson -** must remain valid for the lifespan of the parse. For edits, -** aNode[].u.zJContent might point to malloced space other than zJson. -** Entries in pClup are responsible for freeing that extra malloced space. -** -** When walking the parse tree in aNode[], edits are ignored if useMod is -** false. +** 4. New JSON text is generated from the aBlob[] for output. This step +** is skipped if the function is one of the jsonb_* functions that +** returns JSONB instead of text JSON. */ struct JsonParse { - u32 nNode; /* Number of slots of aNode[] used */ - u32 nAlloc; /* Number of slots of aNode[] allocated */ - JsonNode *aNode; /* Array of nodes containing the parse */ - char *zJson; /* Original JSON string (before edits) */ - char *zAlt; /* Revised and/or mimified JSON */ - u32 *aUp; /* Index of parent of each node */ - JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */ + u8 *aBlob; /* JSONB representation of JSON value */ + u32 nBlob; /* Bytes of aBlob[] actually used */ + u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */ + char *zJson; /* Json text used for parsing */ + sqlite3 *db; /* The database connection to which this object belongs */ + int nJson; /* Length of the zJson string in bytes */ + u32 nJPRef; /* Number of references to this object */ + u32 iErr; /* Error location in zJson[] */ u16 iDepth; /* Nesting depth */ u8 nErr; /* Number of errors seen */ u8 oom; /* Set to true if out of memory */ u8 bJsonIsRCStr; /* True if zJson is an RCStr */ u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ - u8 useMod; /* Actually use the edits contain inside aNode */ - u8 hasMod; /* aNode contains edits from the original zJson */ - u32 nJPRef; /* Number of references to this object */ - int nJson; /* Length of the zJson string in bytes */ - int nAlt; /* Length of alternative JSON string zAlt, in bytes */ - u32 iErr; /* Error location in zJson[] */ - u32 iSubst; /* Last JSON_SUBST entry in aNode[] */ - u32 iHold; /* Age of this entry in the cache for LRU replacement */ + u8 bReadOnly; /* Do not modify. */ + /* Search and edit information. See jsonLookupStep() */ + u8 eEdit; /* Edit operation to apply */ + int delta; /* Size change due to the edit */ + u32 nIns; /* Number of bytes to insert */ + u32 iLabel; /* Location of label if search landed on an object value */ + u8 *aIns; /* Content to be inserted */ }; +/* Allowed values for JsonParse.eEdit */ +#define JEDIT_DEL 1 /* Delete if exists */ +#define JEDIT_REPL 2 /* Overwrite if exists */ +#define JEDIT_INS 3 /* Insert if not exists */ +#define JEDIT_SET 4 /* Insert or overwrite */ + /* ** Maximum nesting depth of JSON for this implementation. ** @@ -202859,15 +203498,151 @@ struct JsonParse { ** descent parser. A depth of 1000 is far deeper than any sane JSON ** should go. Historical note: This limit was 2000 prior to version 3.42.0 */ -#define JSON_MAX_DEPTH 1000 +#ifndef SQLITE_JSON_MAX_DEPTH +# define JSON_MAX_DEPTH 1000 +#else +# define JSON_MAX_DEPTH SQLITE_JSON_MAX_DEPTH +#endif + +/* +** Allowed values for the flgs argument to jsonParseFuncArg(); +*/ +#define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */ +#define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */ + +/************************************************************************** +** Forward references +**************************************************************************/ +static void jsonReturnStringAsBlob(JsonString*); +static int jsonFuncArgMightBeBinary(sqlite3_value *pJson); +static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*); +static void jsonReturnParse(sqlite3_context*,JsonParse*); +static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); +static void jsonParseFree(JsonParse*); +static u32 jsonbPayloadSize(const JsonParse*, u32, u32*); +static u32 jsonUnescapeOneChar(const char*, u32, u32*); + +/************************************************************************** +** Utility routines for dealing with JsonCache objects +**************************************************************************/ + +/* +** Free a JsonCache object. +*/ +static void jsonCacheDelete(JsonCache *p){ + int i; + for(i=0; inUsed; i++){ + jsonParseFree(p->a[i]); + } + sqlite3DbFree(p->db, p); +} +static void jsonCacheDeleteGeneric(void *p){ + jsonCacheDelete((JsonCache*)p); +} + +/* +** Insert a new entry into the cache. If the cache is full, expel +** the least recently used entry. Return SQLITE_OK on success or a +** result code otherwise. +** +** Cache entries are stored in age order, oldest first. +*/ +static int jsonCacheInsert( + sqlite3_context *ctx, /* The SQL statement context holding the cache */ + JsonParse *pParse /* The parse object to be added to the cache */ +){ + JsonCache *p; + + assert( pParse->zJson!=0 ); + assert( pParse->bJsonIsRCStr ); + assert( pParse->delta==0 ); + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ){ + sqlite3 *db = sqlite3_context_db_handle(ctx); + p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM; + p->db = db; + sqlite3_set_auxdata(ctx, JSON_CACHE_ID, p, jsonCacheDeleteGeneric); + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ) return SQLITE_NOMEM; + } + if( p->nUsed >= JSON_CACHE_SIZE ){ + jsonParseFree(p->a[0]); + memmove(p->a, &p->a[1], (JSON_CACHE_SIZE-1)*sizeof(p->a[0])); + p->nUsed = JSON_CACHE_SIZE-1; + } + assert( pParse->nBlobAlloc>0 ); + pParse->eEdit = 0; + pParse->nJPRef++; + pParse->bReadOnly = 1; + p->a[p->nUsed] = pParse; + p->nUsed++; + return SQLITE_OK; +} + +/* +** Search for a cached translation the json text supplied by pArg. Return +** the JsonParse object if found. Return NULL if not found. +** +** When a match if found, the matching entry is moved to become the +** most-recently used entry if it isn't so already. +** +** The JsonParse object returned still belongs to the Cache and might +** be deleted at any moment. If the caller whants the JsonParse to +** linger, it needs to increment the nPJRef reference counter. +*/ +static JsonParse *jsonCacheSearch( + sqlite3_context *ctx, /* The SQL statement context holding the cache */ + sqlite3_value *pArg /* Function argument containing SQL text */ +){ + JsonCache *p; + int i; + const char *zJson; + int nJson; + + if( sqlite3_value_type(pArg)!=SQLITE_TEXT ){ + return 0; + } + zJson = (const char*)sqlite3_value_text(pArg); + if( zJson==0 ) return 0; + nJson = sqlite3_value_bytes(pArg); + + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ){ + return 0; + } + for(i=0; inUsed; i++){ + if( p->a[i]->zJson==zJson ) break; + } + if( i>=p->nUsed ){ + for(i=0; inUsed; i++){ + if( p->a[i]->nJson!=nJson ) continue; + if( memcmp(p->a[i]->zJson, zJson, nJson)==0 ) break; + } + } + if( inUsed ){ + if( inUsed-1 ){ + /* Make the matching entry the most recently used entry */ + JsonParse *tmp = p->a[i]; + memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp)); + p->a[p->nUsed-1] = tmp; + i = p->nUsed - 1; + } + assert( p->a[i]->delta==0 ); + return p->a[i]; + }else{ + return 0; + } +} /************************************************************************** ** Utility routines for dealing with JsonString objects **************************************************************************/ -/* Set the JsonString object to an empty string +/* Turn uninitialized bulk memory into a valid JsonString object +** holding a zero-length string. */ -static void jsonZero(JsonString *p){ +static void jsonStringZero(JsonString *p){ p->zBuf = p->zSpace; p->nAlloc = sizeof(p->zSpace); p->nUsed = 0; @@ -202876,39 +203651,39 @@ static void jsonZero(JsonString *p){ /* Initialize the JsonString object */ -static void jsonInit(JsonString *p, sqlite3_context *pCtx){ +static void jsonStringInit(JsonString *p, sqlite3_context *pCtx){ p->pCtx = pCtx; - p->bErr = 0; - jsonZero(p); + p->eErr = 0; + jsonStringZero(p); } /* Free all allocated memory and reset the JsonString object back to its ** initial state. */ -static void jsonReset(JsonString *p){ +static void jsonStringReset(JsonString *p){ if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf); - jsonZero(p); + jsonStringZero(p); } /* Report an out-of-memory (OOM) condition */ -static void jsonOom(JsonString *p){ - p->bErr = 1; - sqlite3_result_error_nomem(p->pCtx); - jsonReset(p); +static void jsonStringOom(JsonString *p){ + p->eErr |= JSTRING_OOM; + if( p->pCtx ) sqlite3_result_error_nomem(p->pCtx); + jsonStringReset(p); } /* Enlarge pJson->zBuf so that it can hold at least N more bytes. ** Return zero on success. Return non-zero on an OOM error */ -static int jsonGrow(JsonString *p, u32 N){ +static int jsonStringGrow(JsonString *p, u32 N){ u64 nTotal = NnAlloc ? p->nAlloc*2 : p->nAlloc+N+10; char *zNew; if( p->bStatic ){ - if( p->bErr ) return 1; + if( p->eErr ) return 1; zNew = sqlite3RCStrNew(nTotal); if( zNew==0 ){ - jsonOom(p); + jsonStringOom(p); return SQLITE_NOMEM; } memcpy(zNew, p->zBuf, (size_t)p->nUsed); @@ -202917,8 +203692,8 @@ static int jsonGrow(JsonString *p, u32 N){ }else{ p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal); if( p->zBuf==0 ){ - p->bErr = 1; - jsonZero(p); + p->eErr |= JSTRING_OOM; + jsonStringZero(p); return SQLITE_NOMEM; } } @@ -202928,20 +203703,20 @@ static int jsonGrow(JsonString *p, u32 N){ /* Append N bytes from zIn onto the end of the JsonString string. */ -static SQLITE_NOINLINE void jsonAppendExpand( +static SQLITE_NOINLINE void jsonStringExpandAndAppend( JsonString *p, const char *zIn, u32 N ){ assert( N>0 ); - if( jsonGrow(p,N) ) return; + if( jsonStringGrow(p,N) ) return; memcpy(p->zBuf+p->nUsed, zIn, N); p->nUsed += N; } static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ if( N==0 ) return; if( N+p->nUsed >= p->nAlloc ){ - jsonAppendExpand(p,zIn,N); + jsonStringExpandAndAppend(p,zIn,N); }else{ memcpy(p->zBuf+p->nUsed, zIn, N); p->nUsed += N; @@ -202950,7 +203725,7 @@ static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ assert( N>0 ); if( N+p->nUsed >= p->nAlloc ){ - jsonAppendExpand(p,zIn,N); + jsonStringExpandAndAppend(p,zIn,N); }else{ memcpy(p->zBuf+p->nUsed, zIn, N); p->nUsed += N; @@ -202962,7 +203737,7 @@ static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ */ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ va_list ap; - if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return; + if( (p->nUsed + N >= p->nAlloc) && jsonStringGrow(p, N) ) return; va_start(ap, zFormat); sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); va_end(ap); @@ -202972,7 +203747,7 @@ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ /* Append a single character */ static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){ - if( jsonGrow(p,1) ) return; + if( jsonStringGrow(p,1) ) return; p->zBuf[p->nUsed++] = c; } static void jsonAppendChar(JsonString *p, char c){ @@ -202983,24 +203758,17 @@ static void jsonAppendChar(JsonString *p, char c){ } } -/* Try to force the string to be a zero-terminated RCStr string. +/* Make sure there is a zero terminator on p->zBuf[] ** ** Return true on success. Return false if an OOM prevents this ** from happening. */ -static int jsonForceRCStr(JsonString *p){ +static int jsonStringTerminate(JsonString *p){ jsonAppendChar(p, 0); - if( p->bErr ) return 0; p->nUsed--; - if( p->bStatic==0 ) return 1; - p->nAlloc = 0; - p->nUsed++; - jsonGrow(p, p->nUsed); - p->nUsed--; - return p->bStatic==0; + return p->eErr==0; } - /* Append a comma separator to the output buffer, if the previous ** character is not '[' or '{'. */ @@ -203013,21 +203781,66 @@ static void jsonAppendSeparator(JsonString *p){ } /* Append the N-byte string in zIn to the end of the JsonString string -** under construction. Enclose the string in "..." and escape -** any double-quotes or backslash characters contained within the +** under construction. Enclose the string in double-quotes ("...") and +** escape any double-quotes or backslash characters contained within the ** string. +** +** This routine is a high-runner. There is a measurable performance +** increase associated with unwinding the jsonIsOk[] loop. */ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ - u32 i; - if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return; + u32 k; + u8 c; + const u8 *z = (const u8*)zIn; + if( z==0 ) return; + if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return; p->zBuf[p->nUsed++] = '"'; - for(i=0; izBuf[p->nUsed++] = c; - }else if( c=='"' || c=='\\' ){ + while( 1 /*exit-by-break*/ ){ + k = 0; + /* The following while() is the 4-way unwound equivalent of + ** + ** while( k=N ){ + while( k=N ){ + if( k>0 ){ + memcpy(&p->zBuf[p->nUsed], z, k); + p->nUsed += k; + } + break; + } + if( k>0 ){ + memcpy(&p->zBuf[p->nUsed], z, k); + p->nUsed += k; + z += k; + N -= k; + } + c = z[0]; + if( c=='"' || c=='\\' ){ json_simple_escape: - if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; + if( (p->nUsed+N+3 > p->nAlloc) && jsonStringGrow(p,N+3)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; p->zBuf[p->nUsed++] = c; }else if( c=='\'' ){ @@ -203048,7 +203861,7 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ c = aSpecial[c]; goto json_simple_escape; } - if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; + if( (p->nUsed+N+7 > p->nAlloc) && jsonStringGrow(p,N+7)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; p->zBuf[p->nUsed++] = 'u'; p->zBuf[p->nUsed++] = '0'; @@ -203056,146 +203869,18 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4]; p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf]; } + z++; + N--; } p->zBuf[p->nUsed++] = '"'; assert( p->nUsednAlloc ); } /* -** The zIn[0..N] string is a JSON5 string literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. +** Append an sqlite3_value (such as a function parameter) to the JSON +** string under construction in p. */ -static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){ - u32 i; - jsonAppendChar(p, '"'); - zIn++; - N -= 2; - while( N>0 ){ - for(i=0; i0 ){ - jsonAppendRawNZ(p, zIn, i); - zIn += i; - N -= i; - if( N==0 ) break; - } - if( zIn[0]=='"' ){ - jsonAppendRawNZ(p, "\\\"", 2); - zIn++; - N--; - continue; - } - assert( zIn[0]=='\\' ); - switch( (u8)zIn[1] ){ - case '\'': - jsonAppendChar(p, '\''); - break; - case 'v': - jsonAppendRawNZ(p, "\\u0009", 6); - break; - case 'x': - jsonAppendRawNZ(p, "\\u00", 4); - jsonAppendRawNZ(p, &zIn[2], 2); - zIn += 2; - N -= 2; - break; - case '0': - jsonAppendRawNZ(p, "\\u0000", 6); - break; - case '\r': - if( zIn[2]=='\n' ){ - zIn++; - N--; - } - break; - case '\n': - break; - case 0xe2: - assert( N>=4 ); - assert( 0x80==(u8)zIn[2] ); - assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] ); - zIn += 2; - N -= 2; - break; - default: - jsonAppendRawNZ(p, zIn, 2); - break; - } - zIn += 2; - N -= 2; - } - jsonAppendChar(p, '"'); -} - -/* -** The zIn[0..N] string is a JSON5 integer literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. -*/ -static void jsonAppendNormalizedInt(JsonString *p, const char *zIn, u32 N){ - if( zIn[0]=='+' ){ - zIn++; - N--; - }else if( zIn[0]=='-' ){ - jsonAppendChar(p, '-'); - zIn++; - N--; - } - if( zIn[0]=='0' && (zIn[1]=='x' || zIn[1]=='X') ){ - sqlite3_int64 i = 0; - int rc = sqlite3DecOrHexToI64(zIn, &i); - if( rc<=1 ){ - jsonPrintf(100,p,"%lld",i); - }else{ - assert( rc==2 ); - jsonAppendRawNZ(p, "9.0e999", 7); - } - return; - } - assert( N>0 ); - jsonAppendRawNZ(p, zIn, N); -} - -/* -** The zIn[0..N] string is a JSON5 real literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. -*/ -static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){ - u32 i; - if( zIn[0]=='+' ){ - zIn++; - N--; - }else if( zIn[0]=='-' ){ - jsonAppendChar(p, '-'); - zIn++; - N--; - } - if( zIn[0]=='.' ){ - jsonAppendChar(p, '0'); - } - for(i=0; i0 ){ - jsonAppendRawNZ(p, zIn, N); - } -} - - - -/* -** Append a function parameter value to the JSON string under -** construction. -*/ -static void jsonAppendValue( +static void jsonAppendSqlValue( JsonString *p, /* Append to this JSON string */ sqlite3_value *pValue /* Value to append */ ){ @@ -203225,291 +203910,127 @@ static void jsonAppendValue( break; } default: { - if( p->bErr==0 ){ + if( jsonFuncArgMightBeBinary(pValue) ){ + JsonParse px; + memset(&px, 0, sizeof(px)); + px.aBlob = (u8*)sqlite3_value_blob(pValue); + px.nBlob = sqlite3_value_bytes(pValue); + jsonTranslateBlobToText(&px, 0, p); + }else if( p->eErr==0 ){ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); - p->bErr = 2; - jsonReset(p); + p->eErr = JSTRING_ERR; + jsonStringReset(p); } break; } } } - -/* Make the JSON in p the result of the SQL function. +/* Make the text in p (which is probably a generated JSON text string) +** the result of the SQL function. ** -** The JSON string is reset. +** The JsonString is reset. +** +** If pParse and ctx are both non-NULL, then the SQL string in p is +** loaded into the zJson field of the pParse object as a RCStr and the +** pParse is added to the cache. */ -static void jsonResult(JsonString *p){ - if( p->bErr==0 ){ - if( p->bStatic ){ +static void jsonReturnString( + JsonString *p, /* String to return */ + JsonParse *pParse, /* JSONB source or NULL */ + sqlite3_context *ctx /* Where to cache */ +){ + assert( (pParse!=0)==(ctx!=0) ); + assert( ctx==0 || ctx==p->pCtx ); + if( p->eErr==0 ){ + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx)); + if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(p); + }else if( p->bStatic ){ sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, SQLITE_TRANSIENT, SQLITE_UTF8); - }else if( jsonForceRCStr(p) ){ - sqlite3RCStrRef(p->zBuf); - sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + }else if( jsonStringTerminate(p) ){ + if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){ + int rc; + pParse->zJson = sqlite3RCStrRef(p->zBuf); + pParse->nJson = p->nUsed; + pParse->bJsonIsRCStr = 1; + rc = jsonCacheInsert(ctx, pParse); + if( rc==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(ctx); + jsonStringReset(p); + return; + } + } + sqlite3_result_text64(p->pCtx, sqlite3RCStrRef(p->zBuf), p->nUsed, sqlite3RCStrUnref, SQLITE_UTF8); + }else{ + sqlite3_result_error_nomem(p->pCtx); } - } - if( p->bErr==1 ){ + }else if( p->eErr & JSTRING_OOM ){ sqlite3_result_error_nomem(p->pCtx); + }else if( p->eErr & JSTRING_MALFORMED ){ + sqlite3_result_error(p->pCtx, "malformed JSON", -1); } - jsonReset(p); + jsonStringReset(p); } /************************************************************************** -** Utility routines for dealing with JsonNode and JsonParse objects +** Utility routines for dealing with JsonParse objects **************************************************************************/ -/* -** Return the number of consecutive JsonNode slots need to represent -** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and -** OBJECT types, the number might be larger. -** -** Appended elements are not counted. The value returned is the number -** by which the JsonNode counter should increment in order to go to the -** next peer value. -*/ -static u32 jsonNodeSize(JsonNode *pNode){ - return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1; -} - /* ** Reclaim all memory allocated by a JsonParse object. But do not ** delete the JsonParse object itself. */ static void jsonParseReset(JsonParse *pParse){ - while( pParse->pClup ){ - JsonCleanup *pTask = pParse->pClup; - pParse->pClup = pTask->pJCNext; - pTask->xOp(pTask->pArg); - sqlite3_free(pTask); - } assert( pParse->nJPRef<=1 ); - if( pParse->aNode ){ - sqlite3_free(pParse->aNode); - pParse->aNode = 0; - } - pParse->nNode = 0; - pParse->nAlloc = 0; - if( pParse->aUp ){ - sqlite3_free(pParse->aUp); - pParse->aUp = 0; - } if( pParse->bJsonIsRCStr ){ sqlite3RCStrUnref(pParse->zJson); pParse->zJson = 0; + pParse->nJson = 0; pParse->bJsonIsRCStr = 0; } - if( pParse->zAlt ){ - sqlite3RCStrUnref(pParse->zAlt); - pParse->zAlt = 0; + if( pParse->nBlobAlloc ){ + sqlite3DbFree(pParse->db, pParse->aBlob); + pParse->aBlob = 0; + pParse->nBlob = 0; + pParse->nBlobAlloc = 0; } } /* -** Free a JsonParse object that was obtained from sqlite3_malloc(). -** -** Note that destroying JsonParse might call sqlite3RCStrUnref() to -** destroy the zJson value. The RCStr object might recursively invoke -** JsonParse to destroy this pParse object again. Take care to ensure -** that this recursive destructor sequence terminates harmlessly. +** Decrement the reference count on the JsonParse object. When the +** count reaches zero, free the object. */ static void jsonParseFree(JsonParse *pParse){ - if( pParse->nJPRef>1 ){ - pParse->nJPRef--; - }else{ - jsonParseReset(pParse); - sqlite3_free(pParse); - } -} - -/* -** Add a cleanup task to the JsonParse object. -** -** If an OOM occurs, the cleanup operation happens immediately -** and this function returns SQLITE_NOMEM. -*/ -static int jsonParseAddCleanup( - JsonParse *pParse, /* Add the cleanup task to this parser */ - void(*xOp)(void*), /* The cleanup task */ - void *pArg /* Argument to the cleanup */ -){ - JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) ); - if( pTask==0 ){ - pParse->oom = 1; - xOp(pArg); - return SQLITE_ERROR; - } - pTask->pJCNext = pParse->pClup; - pParse->pClup = pTask; - pTask->xOp = xOp; - pTask->pArg = pArg; - return SQLITE_OK; -} - -/* -** Convert the JsonNode pNode into a pure JSON string and -** append to pOut. Subsubstructure is also included. Return -** the number of JsonNode objects that are encoded. -*/ -static void jsonRenderNode( - JsonParse *pParse, /* the complete parse of the JSON */ - JsonNode *pNode, /* The node to render */ - JsonString *pOut /* Write JSON here */ -){ - assert( pNode!=0 ); - while( (pNode->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){ - u32 idx = (u32)(pNode - pParse->aNode); - u32 i = pParse->iSubst; - while( 1 /*exit-by-break*/ ){ - assert( inNode ); - assert( pParse->aNode[i].eType==JSON_SUBST ); - assert( pParse->aNode[i].eU==4 ); - assert( pParse->aNode[i].u.iPrevaNode[i].n==idx ){ - pNode = &pParse->aNode[i+1]; - break; - } - i = pParse->aNode[i].u.iPrev; - } - } - switch( pNode->eType ){ - default: { - assert( pNode->eType==JSON_NULL ); - jsonAppendRawNZ(pOut, "null", 4); - break; - } - case JSON_TRUE: { - jsonAppendRawNZ(pOut, "true", 4); - break; - } - case JSON_FALSE: { - jsonAppendRawNZ(pOut, "false", 5); - break; - } - case JSON_STRING: { - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_RAW ){ - if( pNode->jnFlags & JNODE_LABEL ){ - jsonAppendChar(pOut, '"'); - jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); - jsonAppendChar(pOut, '"'); - }else{ - jsonAppendString(pOut, pNode->u.zJContent, pNode->n); - } - }else if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); - } - break; - } - case JSON_REAL: { - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); - } - break; - } - case JSON_INT: { - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); - } - break; - } - case JSON_ARRAY: { - u32 j = 1; - jsonAppendChar(pOut, '['); - for(;;){ - while( j<=pNode->n ){ - if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ - jsonAppendSeparator(pOut); - jsonRenderNode(pParse, &pNode[j], pOut); - } - j += jsonNodeSize(&pNode[j]); - } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pNode->eU==2 ); - pNode = &pParse->aNode[pNode->u.iAppend]; - j = 1; - } - jsonAppendChar(pOut, ']'); - break; - } - case JSON_OBJECT: { - u32 j = 1; - jsonAppendChar(pOut, '{'); - for(;;){ - while( j<=pNode->n ){ - if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ - jsonAppendSeparator(pOut); - jsonRenderNode(pParse, &pNode[j], pOut); - jsonAppendChar(pOut, ':'); - jsonRenderNode(pParse, &pNode[j+1], pOut); - } - j += 1 + jsonNodeSize(&pNode[j+1]); - } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pNode->eU==2 ); - pNode = &pParse->aNode[pNode->u.iAppend]; - j = 1; - } - jsonAppendChar(pOut, '}'); - break; + if( pParse ){ + if( pParse->nJPRef>1 ){ + pParse->nJPRef--; + }else{ + jsonParseReset(pParse); + sqlite3DbFree(pParse->db, pParse); } } } -/* -** Return a JsonNode and all its descendants as a JSON string. -*/ -static void jsonReturnJson( - JsonParse *pParse, /* The complete JSON */ - JsonNode *pNode, /* Node to return */ - sqlite3_context *pCtx, /* Return value for this function */ - int bGenerateAlt, /* Also store the rendered text in zAlt */ - int omitSubtype /* Do not call sqlite3_result_subtype() */ -){ - JsonString s; - if( pParse->oom ){ - sqlite3_result_error_nomem(pCtx); - return; - } - if( pParse->nErr==0 ){ - jsonInit(&s, pCtx); - jsonRenderNode(pParse, pNode, &s); - if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){ - pParse->zAlt = sqlite3RCStrRef(s.zBuf); - pParse->nAlt = s.nUsed; - } - jsonResult(&s); - if( !omitSubtype ) sqlite3_result_subtype(pCtx, JSON_SUBTYPE); - } -} +/************************************************************************** +** Utility routines for the JSON text parser +**************************************************************************/ /* ** Translate a single byte of Hex into an integer. -** This routine only works if h really is a valid hexadecimal -** character: 0..9a..fA..F +** This routine only gives a correct answer if h really is a valid hexadecimal +** character: 0..9a..fA..F. But unlike sqlite3HexToInt(), it does not +** assert() if the digit is not hex. */ static u8 jsonHexToInt(int h){ - assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif #ifdef SQLITE_EBCDIC h += 9*(1&~(h>>4)); -#else - h += 9*(1&(h>>6)); #endif return (u8)(h & 0xf); } @@ -203519,10 +204040,6 @@ static u8 jsonHexToInt(int h){ */ static u32 jsonHexToInt4(const char *z){ u32 v; - assert( sqlite3Isxdigit(z[0]) ); - assert( sqlite3Isxdigit(z[1]) ); - assert( sqlite3Isxdigit(z[2]) ); - assert( sqlite3Isxdigit(z[3]) ); v = (jsonHexToInt(z[0])<<12) + (jsonHexToInt(z[1])<<8) + (jsonHexToInt(z[2])<<4) @@ -203530,282 +204047,6 @@ static u32 jsonHexToInt4(const char *z){ return v; } -/* -** Make the JsonNode the return value of the function. -*/ -static void jsonReturn( - JsonParse *pParse, /* Complete JSON parse tree */ - JsonNode *pNode, /* Node to return */ - sqlite3_context *pCtx, /* Return value for this function */ - int omitSubtype /* Do not call sqlite3_result_subtype() */ -){ - switch( pNode->eType ){ - default: { - assert( pNode->eType==JSON_NULL ); - sqlite3_result_null(pCtx); - break; - } - case JSON_TRUE: { - sqlite3_result_int(pCtx, 1); - break; - } - case JSON_FALSE: { - sqlite3_result_int(pCtx, 0); - break; - } - case JSON_INT: { - sqlite3_int64 i = 0; - int rc; - int bNeg = 0; - const char *z; - - assert( pNode->eU==1 ); - z = pNode->u.zJContent; - if( z[0]=='-' ){ z++; bNeg = 1; } - else if( z[0]=='+' ){ z++; } - rc = sqlite3DecOrHexToI64(z, &i); - if( rc<=1 ){ - sqlite3_result_int64(pCtx, bNeg ? -i : i); - }else if( rc==3 && bNeg ){ - sqlite3_result_int64(pCtx, SMALLEST_INT64); - }else{ - goto to_double; - } - break; - } - case JSON_REAL: { - double r; - const char *z; - assert( pNode->eU==1 ); - to_double: - z = pNode->u.zJContent; - sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); - sqlite3_result_double(pCtx, r); - break; - } - case JSON_STRING: { - if( pNode->jnFlags & JNODE_RAW ){ - assert( pNode->eU==1 ); - sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, - SQLITE_TRANSIENT); - }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ - /* JSON formatted without any backslash-escapes */ - assert( pNode->eU==1 ); - sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, - SQLITE_TRANSIENT); - }else{ - /* Translate JSON formatted string into raw text */ - u32 i; - u32 n = pNode->n; - const char *z; - char *zOut; - u32 j; - u32 nOut = n; - assert( pNode->eU==1 ); - z = pNode->u.zJContent; - zOut = sqlite3_malloc( nOut+1 ); - if( zOut==0 ){ - sqlite3_result_error_nomem(pCtx); - break; - } - for(i=1, j=0; i>6)); - zOut[j++] = 0x80 | (v&0x3f); - }else{ - u32 vlo; - if( (v&0xfc00)==0xd800 - && i>18); - zOut[j++] = 0x80 | ((v>>12)&0x3f); - zOut[j++] = 0x80 | ((v>>6)&0x3f); - zOut[j++] = 0x80 | (v&0x3f); - }else{ - zOut[j++] = 0xe0 | (v>>12); - zOut[j++] = 0x80 | ((v>>6)&0x3f); - zOut[j++] = 0x80 | (v&0x3f); - } - } - continue; - }else if( c=='b' ){ - c = '\b'; - }else if( c=='f' ){ - c = '\f'; - }else if( c=='n' ){ - c = '\n'; - }else if( c=='r' ){ - c = '\r'; - }else if( c=='t' ){ - c = '\t'; - }else if( c=='v' ){ - c = '\v'; - }else if( c=='\'' || c=='"' || c=='/' || c=='\\' ){ - /* pass through unchanged */ - }else if( c=='0' ){ - c = 0; - }else if( c=='x' ){ - c = (jsonHexToInt(z[i+1])<<4) | jsonHexToInt(z[i+2]); - i += 2; - }else if( c=='\r' && z[i+1]=='\n' ){ - i++; - continue; - }else if( 0xe2==(u8)c ){ - assert( 0x80==(u8)z[i+1] ); - assert( 0xa8==(u8)z[i+2] || 0xa9==(u8)z[i+2] ); - i += 2; - continue; - }else{ - continue; - } - } /* end if( c=='\\' ) */ - zOut[j++] = c; - } /* end for() */ - zOut[j] = 0; - sqlite3_result_text(pCtx, zOut, j, sqlite3_free); - } - break; - } - case JSON_ARRAY: - case JSON_OBJECT: { - jsonReturnJson(pParse, pNode, pCtx, 0, omitSubtype); - break; - } - } -} - -/* Forward reference */ -static int jsonParseAddNode(JsonParse*,u32,u32,const char*); - -/* -** A macro to hint to the compiler that a function should not be -** inlined. -*/ -#if defined(__GNUC__) -# define JSON_NOINLINE __attribute__((noinline)) -#elif defined(_MSC_VER) && _MSC_VER>=1310 -# define JSON_NOINLINE __declspec(noinline) -#else -# define JSON_NOINLINE -#endif - - -/* -** Add a single node to pParse->aNode after first expanding the -** size of the aNode array. Return the index of the new node. -** -** If an OOM error occurs, set pParse->oom and return -1. -*/ -static JSON_NOINLINE int jsonParseAddNodeExpand( - JsonParse *pParse, /* Append the node to this object */ - u32 eType, /* Node type */ - u32 n, /* Content size or sub-node count */ - const char *zContent /* Content */ -){ - u32 nNew; - JsonNode *pNew; - assert( pParse->nNode>=pParse->nAlloc ); - if( pParse->oom ) return -1; - nNew = pParse->nAlloc*2 + 10; - pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew); - if( pNew==0 ){ - pParse->oom = 1; - return -1; - } - pParse->nAlloc = sqlite3_msize(pNew)/sizeof(JsonNode); - pParse->aNode = pNew; - assert( pParse->nNodenAlloc ); - return jsonParseAddNode(pParse, eType, n, zContent); -} - -/* -** Create a new JsonNode instance based on the arguments and append that -** instance to the JsonParse. Return the index in pParse->aNode[] of the -** new node, or -1 if a memory allocation fails. -*/ -static int jsonParseAddNode( - JsonParse *pParse, /* Append the node to this object */ - u32 eType, /* Node type */ - u32 n, /* Content size or sub-node count */ - const char *zContent /* Content */ -){ - JsonNode *p; - assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc ); - if( pParse->nNode>=pParse->nAlloc ){ - return jsonParseAddNodeExpand(pParse, eType, n, zContent); - } - assert( pParse->aNode!=0 ); - p = &pParse->aNode[pParse->nNode]; - assert( p!=0 ); - p->eType = (u8)(eType & 0xff); - p->jnFlags = (u8)(eType >> 8); - VVA( p->eU = zContent ? 1 : 0 ); - p->n = n; - p->u.zJContent = zContent; - return pParse->nNode++; -} - -/* -** Add an array of new nodes to the current pParse->aNode array. -** Return the index of the first node added. -** -** If an OOM error occurs, set pParse->oom. -*/ -static void jsonParseAddNodeArray( - JsonParse *pParse, /* Append the node to this object */ - JsonNode *aNode, /* Array of nodes to add */ - u32 nNode /* Number of elements in aNew */ -){ - assert( aNode!=0 ); - assert( nNode>=1 ); - if( pParse->nNode + nNode > pParse->nAlloc ){ - u32 nNew = pParse->nNode + nNode; - JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode)); - if( aNew==0 ){ - pParse->oom = 1; - return; - } - pParse->nAlloc = sqlite3_msize(aNew)/sizeof(JsonNode); - pParse->aNode = aNew; - } - memcpy(&pParse->aNode[pParse->nNode], aNode, nNode*sizeof(JsonNode)); - pParse->nNode += nNode; -} - -/* -** Add a new JSON_SUBST node. The node immediately following -** this new node will be the substitute content for iNode. -*/ -static int jsonParseAddSubstNode( - JsonParse *pParse, /* Add the JSON_SUBST here */ - u32 iNode /* References this node */ -){ - int idx = jsonParseAddNode(pParse, JSON_SUBST, iNode, 0); - if( pParse->oom ) return -1; - pParse->aNode[iNode].jnFlags |= JNODE_REPLACE; - pParse->aNode[idx].eU = 4; - pParse->aNode[idx].u.iPrev = pParse->iSubst; - pParse->iSubst = idx; - pParse->hasMod = 1; - pParse->useMod = 1; - return idx; -} - /* ** Return true if z[] begins with 2 (or more) hexadecimal digits */ @@ -203959,63 +204200,500 @@ static const struct NanInfName { char *zMatch; char *zRepl; } aNanInfName[] = { - { 'i', 'I', 3, JSON_REAL, 7, "inf", "9.0e999" }, - { 'i', 'I', 8, JSON_REAL, 7, "infinity", "9.0e999" }, - { 'n', 'N', 3, JSON_NULL, 4, "NaN", "null" }, - { 'q', 'Q', 4, JSON_NULL, 4, "QNaN", "null" }, - { 's', 'S', 4, JSON_NULL, 4, "SNaN", "null" }, + { 'i', 'I', 3, JSONB_FLOAT, 7, "inf", "9.0e999" }, + { 'i', 'I', 8, JSONB_FLOAT, 7, "infinity", "9.0e999" }, + { 'n', 'N', 3, JSONB_NULL, 4, "NaN", "null" }, + { 'q', 'Q', 4, JSONB_NULL, 4, "QNaN", "null" }, + { 's', 'S', 4, JSONB_NULL, 4, "SNaN", "null" }, }; + /* -** Parse a single JSON value which begins at pParse->zJson[i]. Return the -** index of the first character past the end of the value parsed. +** Report the wrong number of arguments for json_insert(), json_replace() +** or json_set(). +*/ +static void jsonWrongNumArgs( + sqlite3_context *pCtx, + const char *zFuncName +){ + char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", + zFuncName); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); +} + +/**************************************************************************** +** Utility routines for dealing with the binary BLOB representation of JSON +****************************************************************************/ + +/* +** Expand pParse->aBlob so that it holds at least N bytes. ** -** Special return values: +** Return the number of errors. +*/ +static int jsonBlobExpand(JsonParse *pParse, u32 N){ + u8 *aNew; + u32 t; + assert( N>pParse->nBlobAlloc ); + if( pParse->nBlobAlloc==0 ){ + t = 100; + }else{ + t = pParse->nBlobAlloc*2; + } + if( tdb, pParse->aBlob, t); + if( aNew==0 ){ pParse->oom = 1; return 1; } + pParse->aBlob = aNew; + pParse->nBlobAlloc = t; + return 0; +} + +/* +** If pParse->aBlob is not previously editable (because it is taken +** from sqlite3_value_blob(), as indicated by the fact that +** pParse->nBlobAlloc==0 and pParse->nBlob>0) then make it editable +** by making a copy into space obtained from malloc. +** +** Return true on success. Return false on OOM. +*/ +static int jsonBlobMakeEditable(JsonParse *pParse, u32 nExtra){ + u8 *aOld; + u32 nSize; + assert( !pParse->bReadOnly ); + if( pParse->oom ) return 0; + if( pParse->nBlobAlloc>0 ) return 1; + aOld = pParse->aBlob; + nSize = pParse->nBlob + nExtra; + pParse->aBlob = 0; + if( jsonBlobExpand(pParse, nSize) ){ + return 0; + } + assert( pParse->nBlobAlloc >= pParse->nBlob + nExtra ); + memcpy(pParse->aBlob, aOld, pParse->nBlob); + return 1; +} + +/* Expand pParse->aBlob and append one bytes. +*/ +static SQLITE_NOINLINE void jsonBlobExpandAndAppendOneByte( + JsonParse *pParse, + u8 c +){ + jsonBlobExpand(pParse, pParse->nBlob+1); + if( pParse->oom==0 ){ + assert( pParse->nBlob+1<=pParse->nBlobAlloc ); + pParse->aBlob[pParse->nBlob++] = c; + } +} + +/* Append a single character. +*/ +static void jsonBlobAppendOneByte(JsonParse *pParse, u8 c){ + if( pParse->nBlob >= pParse->nBlobAlloc ){ + jsonBlobExpandAndAppendOneByte(pParse, c); + }else{ + pParse->aBlob[pParse->nBlob++] = c; + } +} + +/* Slow version of jsonBlobAppendNode() that first resizes the +** pParse->aBlob structure. +*/ +static void jsonBlobAppendNode(JsonParse*,u8,u32,const void*); +static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( + JsonParse *pParse, + u8 eType, + u32 szPayload, + const void *aPayload +){ + if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return; + jsonBlobAppendNode(pParse, eType, szPayload, aPayload); +} + + +/* Append an node type byte together with the payload size and +** possibly also the payload. +** +** If aPayload is not NULL, then it is a pointer to the payload which +** is also appended. If aPayload is NULL, the pParse->aBlob[] array +** is resized (if necessary) so that it is big enough to hold the +** payload, but the payload is not appended and pParse->nBlob is left +** pointing to where the first byte of payload will eventually be. +*/ +static void jsonBlobAppendNode( + JsonParse *pParse, /* The JsonParse object under construction */ + u8 eType, /* Node type. One of JSONB_* */ + u32 szPayload, /* Number of bytes of payload */ + const void *aPayload /* The payload. Might be NULL */ +){ + u8 *a; + if( pParse->nBlob+szPayload+9 > pParse->nBlobAlloc ){ + jsonBlobExpandAndAppendNode(pParse,eType,szPayload,aPayload); + return; + } + assert( pParse->aBlob!=0 ); + a = &pParse->aBlob[pParse->nBlob]; + if( szPayload<=11 ){ + a[0] = eType | (szPayload<<4); + pParse->nBlob += 1; + }else if( szPayload<=0xff ){ + a[0] = eType | 0xc0; + a[1] = szPayload & 0xff; + pParse->nBlob += 2; + }else if( szPayload<=0xffff ){ + a[0] = eType | 0xd0; + a[1] = (szPayload >> 8) & 0xff; + a[2] = szPayload & 0xff; + pParse->nBlob += 3; + }else{ + a[0] = eType | 0xe0; + a[1] = (szPayload >> 24) & 0xff; + a[2] = (szPayload >> 16) & 0xff; + a[3] = (szPayload >> 8) & 0xff; + a[4] = szPayload & 0xff; + pParse->nBlob += 5; + } + if( aPayload ){ + pParse->nBlob += szPayload; + memcpy(&pParse->aBlob[pParse->nBlob-szPayload], aPayload, szPayload); + } +} + +/* Change the payload size for the node at index i to be szPayload. +*/ +static int jsonBlobChangePayloadSize( + JsonParse *pParse, + u32 i, + u32 szPayload +){ + u8 *a; + u8 szType; + u8 nExtra; + u8 nNeeded; + int delta; + if( pParse->oom ) return 0; + a = &pParse->aBlob[i]; + szType = a[0]>>4; + if( szType<=11 ){ + nExtra = 0; + }else if( szType==12 ){ + nExtra = 1; + }else if( szType==13 ){ + nExtra = 2; + }else{ + nExtra = 4; + } + if( szPayload<=11 ){ + nNeeded = 0; + }else if( szPayload<=0xff ){ + nNeeded = 1; + }else if( szPayload<=0xffff ){ + nNeeded = 2; + }else{ + nNeeded = 4; + } + delta = nNeeded - nExtra; + if( delta ){ + u32 newSize = pParse->nBlob + delta; + if( delta>0 ){ + if( newSize>pParse->nBlobAlloc && jsonBlobExpand(pParse, newSize) ){ + return 0; /* OOM error. Error state recorded in pParse->oom. */ + } + a = &pParse->aBlob[i]; + memmove(&a[1+delta], &a[1], pParse->nBlob - (i+1)); + }else{ + memmove(&a[1], &a[1-delta], pParse->nBlob - (i+1-delta)); + } + pParse->nBlob = newSize; + } + if( nNeeded==0 ){ + a[0] = (a[0] & 0x0f) | (szPayload<<4); + }else if( nNeeded==1 ){ + a[0] = (a[0] & 0x0f) | 0xc0; + a[1] = szPayload & 0xff; + }else if( nNeeded==2 ){ + a[0] = (a[0] & 0x0f) | 0xd0; + a[1] = (szPayload >> 8) & 0xff; + a[2] = szPayload & 0xff; + }else{ + a[0] = (a[0] & 0x0f) | 0xe0; + a[1] = (szPayload >> 24) & 0xff; + a[2] = (szPayload >> 16) & 0xff; + a[3] = (szPayload >> 8) & 0xff; + a[4] = szPayload & 0xff; + } + return delta; +} + +/* +** If z[0] is 'u' and is followed by exactly 4 hexadecimal character, +** then set *pOp to JSONB_TEXTJ and return true. If not, do not make +** any changes to *pOp and return false. +*/ +static int jsonIs4HexB(const char *z, int *pOp){ + if( z[0]!='u' ) return 0; + if( !jsonIs4Hex(&z[1]) ) return 0; + *pOp = JSONB_TEXTJ; + return 1; +} + +/* +** Check a single element of the JSONB in pParse for validity. +** +** The element to be checked starts at offset i and must end at on the +** last byte before iEnd. +** +** Return 0 if everything is correct. Return the 1-based byte offset of the +** error if a problem is detected. (In other words, if the error is at offset +** 0, return 1). +*/ +static u32 jsonbValidityCheck( + const JsonParse *pParse, /* Input JSONB. Only aBlob and nBlob are used */ + u32 i, /* Start of element as pParse->aBlob[i] */ + u32 iEnd, /* One more than the last byte of the element */ + u32 iDepth /* Current nesting depth */ +){ + u32 n, sz, j, k; + const u8 *z; + u8 x; + if( iDepth>JSON_MAX_DEPTH ) return i+1; + sz = 0; + n = jsonbPayloadSize(pParse, i, &sz); + if( NEVER(n==0) ) return i+1; /* Checked by caller */ + if( NEVER(i+n+sz!=iEnd) ) return i+1; /* Checked by caller */ + z = pParse->aBlob; + x = z[i] & 0x0f; + switch( x ){ + case JSONB_NULL: + case JSONB_TRUE: + case JSONB_FALSE: { + return n+sz==1 ? 0 : i+1; + } + case JSONB_INT: { + if( sz<1 ) return i+1; + j = i+n; + if( z[j]=='-' ){ + j++; + if( sz<2 ) return i+1; + } + k = i+n+sz; + while( jk ) return j+1; + if( z[j+1]!='.' && z[j+1]!='e' && z[j+1]!='E' ) return j+1; + j++; + } + for(; j0 ) return j+1; + if( x==JSONB_FLOAT && (j==k-1 || !sqlite3Isdigit(z[j+1])) ){ + return j+1; + } + seen = 1; + continue; + } + if( z[j]=='e' || z[j]=='E' ){ + if( seen==2 ) return j+1; + if( j==k-1 ) return j+1; + if( z[j+1]=='+' || z[j+1]=='-' ){ + j++; + if( j==k-1 ) return j+1; + } + seen = 2; + continue; + } + return j+1; + } + if( seen==0 ) return i+1; + return 0; + } + case JSONB_TEXT: { + j = i+n; + k = j+sz; + while( j=k ){ + return j+1; + }else if( strchr("\"\\/bfnrt",z[j+1])!=0 ){ + j++; + }else if( z[j+1]=='u' ){ + if( j+5>=k ) return j+1; + if( !jsonIs4Hex((const char*)&z[j+2]) ) return j+1; + j++; + }else if( x!=JSONB_TEXT5 ){ + return j+1; + }else{ + u32 c = 0; + u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c); + if( c==JSON_INVALID_CHAR ) return j+1; + j += szC - 1; + } + } + j++; + } + return 0; + } + case JSONB_TEXTRAW: { + return 0; + } + case JSONB_ARRAY: { + u32 sub; + j = i+n; + k = j+sz; + while( jk ) return j+1; + sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); + if( sub ) return sub; + j += n + sz; + } + assert( j==k ); + return 0; + } + case JSONB_OBJECT: { + u32 cnt = 0; + u32 sub; + j = i+n; + k = j+sz; + while( jk ) return j+1; + if( (cnt & 1)==0 ){ + x = z[j] & 0x0f; + if( xJSONB_TEXTRAW ) return j+1; + } + sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); + if( sub ) return sub; + cnt++; + j += n + sz; + } + assert( j==k ); + if( (cnt & 1)!=0 ) return j+1; + return 0; + } + default: { + return i+1; + } + } +} + +/* +** Translate a single element of JSON text at pParse->zJson[i] into +** its equivalent binary JSONB representation. Append the translation into +** pParse->aBlob[] beginning at pParse->nBlob. The size of +** pParse->aBlob[] is increased as necessary. +** +** Return the index of the first character past the end of the element parsed, +** or one of the following special result codes: ** ** 0 End of input -** -1 Syntax error -** -2 '}' seen -** -3 ']' seen -** -4 ',' seen -** -5 ':' seen +** -1 Syntax error or OOM +** -2 '}' seen \ +** -3 ']' seen \___ For these returns, pParse->iErr is set to +** -4 ',' seen / the index in zJson[] of the seen character +** -5 ':' seen / */ -static int jsonParseValue(JsonParse *pParse, u32 i){ +static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){ char c; u32 j; - int iThis; + u32 iThis, iStart; int x; - JsonNode *pNode; + u8 t; const char *z = pParse->zJson; json_parse_restart: switch( (u8)z[i] ){ case '{': { /* Parse object */ - iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); - if( iThis<0 ) return -1; + iThis = pParse->nBlob; + jsonBlobAppendNode(pParse, JSONB_OBJECT, pParse->nJson-i, 0); if( ++pParse->iDepth > JSON_MAX_DEPTH ){ pParse->iErr = i; return -1; } + iStart = pParse->nBlob; for(j=i+1;;j++){ - u32 nNode = pParse->nNode; - x = jsonParseValue(pParse, j); + u32 iBlob = pParse->nBlob; + x = jsonTranslateTextToBlob(pParse, j); if( x<=0 ){ + int op; if( x==(-2) ){ j = pParse->iErr; - if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; + if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1; break; } j += json5Whitespace(&z[j]); + op = JSONB_TEXT; if( sqlite3JsonId1(z[j]) - || (z[j]=='\\' && z[j+1]=='u' && jsonIs4Hex(&z[j+2])) + || (z[j]=='\\' && jsonIs4HexB(&z[j+1], &op)) ){ int k = j+1; while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0) - || (z[k]=='\\' && z[k+1]=='u' && jsonIs4Hex(&z[k+2])) + || (z[k]=='\\' && jsonIs4HexB(&z[k+1], &op)) ){ k++; } - jsonParseAddNode(pParse, JSON_STRING | (JNODE_RAW<<8), k-j, &z[j]); + assert( iBlob==pParse->nBlob ); + jsonBlobAppendNode(pParse, op, k-j, &z[j]); pParse->hasNonstd = 1; x = k; }else{ @@ -204024,24 +204702,24 @@ json_parse_restart: } } if( pParse->oom ) return -1; - pNode = &pParse->aNode[nNode]; - if( pNode->eType!=JSON_STRING ){ + t = pParse->aBlob[iBlob] & 0x0f; + if( tJSONB_TEXTRAW ){ pParse->iErr = j; return -1; } - pNode->jnFlags |= JNODE_LABEL; j = x; if( z[j]==':' ){ j++; }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); + if( jsonIsspace(z[j]) ){ + /* strspn() is not helpful here */ + do{ j++; }while( jsonIsspace(z[j]) ); if( z[j]==':' ){ j++; goto parse_object_value; } } - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x!=(-5) ){ if( x!=(-1) ) pParse->iErr = j; return -1; @@ -204049,7 +204727,7 @@ json_parse_restart: j = pParse->iErr+1; } parse_object_value: - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x<=0 ){ if( x!=(-1) ) pParse->iErr = j; return -1; @@ -204060,15 +204738,15 @@ json_parse_restart: }else if( z[j]=='}' ){ break; }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); + if( jsonIsspace(z[j]) ){ + j += 1 + (u32)strspn(&z[j+1], jsonSpaces); if( z[j]==',' ){ continue; }else if( z[j]=='}' ){ break; } } - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x==(-4) ){ j = pParse->iErr; continue; @@ -204081,25 +204759,26 @@ json_parse_restart: pParse->iErr = j; return -1; } - pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; + jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); pParse->iDepth--; return j+1; } case '[': { /* Parse array */ - iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); - if( iThis<0 ) return -1; + iThis = pParse->nBlob; + jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0); + iStart = pParse->nBlob; + if( pParse->oom ) return -1; if( ++pParse->iDepth > JSON_MAX_DEPTH ){ pParse->iErr = i; return -1; } - memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u)); for(j=i+1;;j++){ - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x<=0 ){ if( x==(-3) ){ j = pParse->iErr; - if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; + if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1; break; } if( x!=(-1) ) pParse->iErr = j; @@ -204111,15 +204790,15 @@ json_parse_restart: }else if( z[j]==']' ){ break; }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); + if( jsonIsspace(z[j]) ){ + j += 1 + (u32)strspn(&z[j+1], jsonSpaces); if( z[j]==',' ){ continue; }else if( z[j]==']' ){ break; } } - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x==(-4) ){ j = pParse->iErr; continue; @@ -204132,23 +204811,33 @@ json_parse_restart: pParse->iErr = j; return -1; } - pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; + jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); pParse->iDepth--; return j+1; } case '\'': { - u8 jnFlags; + u8 opcode; char cDelim; pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; + opcode = JSONB_TEXT; goto parse_string; case '"': /* Parse string */ - jnFlags = 0; + opcode = JSONB_TEXT; parse_string: cDelim = z[i]; - for(j=i+1; 1; j++){ - if( jsonIsOk[(unsigned char)z[j]] ) continue; + j = i+1; + while( 1 /*exit-by-break*/ ){ + if( jsonIsOk[(u8)z[j]] ){ + if( !jsonIsOk[(u8)z[j+1]] ){ + j += 1; + }else if( !jsonIsOk[(u8)z[j+2]] ){ + j += 2; + }else{ + j += 3; + continue; + } + } c = z[j]; if( c==cDelim ){ break; @@ -204157,16 +204846,16 @@ json_parse_restart: if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' || c=='n' || c=='r' || c=='t' || (c=='u' && jsonIs4Hex(&z[j+1])) ){ - jnFlags |= JNODE_ESCAPE; + if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ; }else if( c=='\'' || c=='0' || c=='v' || c=='\n' || (0xe2==(u8)c && 0x80==(u8)z[j+1] && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])) || (c=='x' && jsonIs2Hex(&z[j+1])) ){ - jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); + opcode = JSONB_TEXT5; pParse->hasNonstd = 1; }else if( c=='\r' ){ if( z[j+1]=='\n' ) j++; - jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); + opcode = JSONB_TEXT5; pParse->hasNonstd = 1; }else{ pParse->iErr = j; @@ -204176,14 +204865,17 @@ json_parse_restart: /* Control characters are not allowed in strings */ pParse->iErr = j; return -1; + }else if( c=='"' ){ + opcode = JSONB_TEXT5; } + j++; } - jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]); + jsonBlobAppendNode(pParse, opcode, j-1-i, &z[i+1]); return j+1; } case 't': { if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){ - jsonParseAddNode(pParse, JSON_TRUE, 0, 0); + jsonBlobAppendOneByte(pParse, JSONB_TRUE); return i+4; } pParse->iErr = i; @@ -204191,23 +204883,22 @@ json_parse_restart: } case 'f': { if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){ - jsonParseAddNode(pParse, JSON_FALSE, 0, 0); + jsonBlobAppendOneByte(pParse, JSONB_FALSE); return i+5; } pParse->iErr = i; return -1; } case '+': { - u8 seenDP, seenE, jnFlags; + u8 seenE; pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; + t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ goto parse_number; case '.': if( sqlite3Isdigit(z[i+1]) ){ pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; + t = 0x03; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ seenE = 0; - seenDP = JSON_REAL; goto parse_number_2; } pParse->iErr = i; @@ -204224,9 +204915,8 @@ json_parse_restart: case '8': case '9': /* Parse number */ - jnFlags = 0; + t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ parse_number: - seenDP = JSON_INT; seenE = 0; assert( '-' < '0' ); assert( '+' < '0' ); @@ -204236,9 +204926,9 @@ json_parse_restart: if( c<='0' ){ if( c=='0' ){ if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){ - assert( seenDP==JSON_INT ); + assert( t==0x00 ); pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t = 0x01; for(j=i+3; sqlite3Isxdigit(z[j]); j++){} goto parse_number_finish; }else if( sqlite3Isdigit(z[i+1]) ){ @@ -204255,15 +204945,15 @@ json_parse_restart: ){ pParse->hasNonstd = 1; if( z[i]=='-' ){ - jsonParseAddNode(pParse, JSON_REAL, 8, "-9.0e999"); + jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); }else{ - jsonParseAddNode(pParse, JSON_REAL, 7, "9.0e999"); + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); } return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4); } if( z[i+1]=='.' ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; goto parse_number_2; } pParse->iErr = i; @@ -204275,30 +204965,31 @@ json_parse_restart: return -1; }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; for(j=i+4; sqlite3Isxdigit(z[j]); j++){} goto parse_number_finish; } } } } + parse_number_2: for(j=i+1;; j++){ c = z[j]; if( sqlite3Isdigit(c) ) continue; if( c=='.' ){ - if( seenDP==JSON_REAL ){ + if( (t & 0x02)!=0 ){ pParse->iErr = j; return -1; } - seenDP = JSON_REAL; + t |= 0x02; continue; } if( c=='e' || c=='E' ){ if( z[j-1]<'0' ){ if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; }else{ pParse->iErr = j; return -1; @@ -204308,7 +204999,7 @@ json_parse_restart: pParse->iErr = j; return -1; } - seenDP = JSON_REAL; + t |= 0x02; seenE = 1; c = z[j+1]; if( c=='+' || c=='-' ){ @@ -204326,14 +205017,18 @@ json_parse_restart: if( z[j-1]<'0' ){ if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; }else{ pParse->iErr = j; return -1; } } parse_number_finish: - jsonParseAddNode(pParse, seenDP | (jnFlags<<8), j - i, &z[i]); + assert( JSONB_INT+0x01==JSONB_INT5 ); + assert( JSONB_FLOAT+0x01==JSONB_FLOAT5 ); + assert( JSONB_INT+0x02==JSONB_FLOAT ); + if( z[i]=='+' ) i++; + jsonBlobAppendNode(pParse, JSONB_INT+t, j-i, &z[i]); return j; } case '}': { @@ -204359,9 +205054,7 @@ json_parse_restart: case 0x0a: case 0x0d: case 0x20: { - do{ - i++; - }while( fast_isspace(z[i]) ); + i += 1 + (u32)strspn(&z[i+1], jsonSpaces); goto json_parse_restart; } case 0x0b: @@ -204383,7 +205076,7 @@ json_parse_restart: } case 'n': { if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){ - jsonParseAddNode(pParse, JSON_NULL, 0, 0); + jsonBlobAppendOneByte(pParse, JSONB_NULL); return i+4; } /* fall-through into the default case that checks for NaN */ @@ -204399,8 +205092,11 @@ json_parse_restart: continue; } if( sqlite3Isalnum(z[i+nn]) ) continue; - jsonParseAddNode(pParse, aNanInfName[k].eType, - aNanInfName[k].nRepl, aNanInfName[k].zRepl); + if( aNanInfName[k].eType==JSONB_FLOAT ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); + }else{ + jsonBlobAppendOneByte(pParse, JSONB_NULL); + } pParse->hasNonstd = 1; return i + nn; } @@ -204410,6 +205106,7 @@ json_parse_restart: } /* End switch(z[i]) */ } + /* ** Parse a complete JSON string. Return 0 on success or non-zero if there ** are any errors. If an error occurs, free all memory held by pParse, @@ -204418,20 +205115,26 @@ json_parse_restart: ** pParse must be initialized to an empty parse object prior to calling ** this routine. */ -static int jsonParse( +static int jsonConvertTextToBlob( JsonParse *pParse, /* Initialize and fill this JsonParse object */ sqlite3_context *pCtx /* Report errors here */ ){ int i; const char *zJson = pParse->zJson; - i = jsonParseValue(pParse, 0); + i = jsonTranslateTextToBlob(pParse, 0); if( pParse->oom ) i = -1; if( i>0 ){ +#ifdef SQLITE_DEBUG assert( pParse->iDepth==0 ); - while( fast_isspace(zJson[i]) ) i++; + if( sqlite3Config.bJsonSelfcheck ){ + assert( jsonbValidityCheck(pParse, 0, pParse->nBlob, 0)==0 ); + } +#endif + while( jsonIsspace(zJson[i]) ) i++; if( zJson[i] ){ i += json5Whitespace(&zJson[i]); if( zJson[i] ){ + if( pCtx ) sqlite3_result_error(pCtx, "malformed JSON", -1); jsonParseReset(pParse); return 1; } @@ -204452,248 +205155,710 @@ static int jsonParse( return 0; } - -/* Mark node i of pParse as being a child of iParent. Call recursively -** to fill in all the descendants of node i. +/* +** The input string pStr is a well-formed JSON text string. Convert +** this into the JSONB format and make it the return value of the +** SQL function. */ -static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ - JsonNode *pNode = &pParse->aNode[i]; - u32 j; - pParse->aUp[i] = iParent; - switch( pNode->eType ){ - case JSON_ARRAY: { - for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){ - jsonParseFillInParentage(pParse, i+j, i); - } - break; - } - case JSON_OBJECT: { - for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){ - pParse->aUp[i+j] = i; - jsonParseFillInParentage(pParse, i+j+1, i); - } - break; - } - default: { - break; - } +static void jsonReturnStringAsBlob(JsonString *pStr){ + JsonParse px; + memset(&px, 0, sizeof(px)); + jsonStringTerminate(pStr); + px.zJson = pStr->zBuf; + px.nJson = pStr->nUsed; + px.db = sqlite3_context_db_handle(pStr->pCtx); + (void)jsonTranslateTextToBlob(&px, 0); + if( px.oom ){ + sqlite3DbFree(px.db, px.aBlob); + sqlite3_result_error_nomem(pStr->pCtx); + }else{ + assert( px.nBlobAlloc>0 ); + assert( !px.bReadOnly ); + sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, SQLITE_DYNAMIC); } } -/* -** Compute the parentage of all nodes in a completed parse. +/* The byte at index i is a node type-code. This routine +** determines the payload size for that node and writes that +** payload size in to *pSz. It returns the offset from i to the +** beginning of the payload. Return 0 on error. */ -static int jsonParseFindParents(JsonParse *pParse){ - u32 *aUp; - assert( pParse->aUp==0 ); - aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode ); - if( aUp==0 ){ - pParse->oom = 1; - return SQLITE_NOMEM; - } - jsonParseFillInParentage(pParse, 0, 0); - return SQLITE_OK; -} - -/* -** Magic number used for the JSON parse cache in sqlite3_get_auxdata() -*/ -#define JSON_CACHE_ID (-429938) /* First cache entry */ -#define JSON_CACHE_SZ 4 /* Max number of cache entries */ - -/* -** Obtain a complete parse of the JSON found in the pJson argument -** -** Use the sqlite3_get_auxdata() cache to find a preexisting parse -** if it is available. If the cache is not available or if it -** is no longer valid, parse the JSON again and return the new parse. -** Also register the new parse so that it will be available for -** future sqlite3_get_auxdata() calls. -** -** If an error occurs and pErrCtx!=0 then report the error on pErrCtx -** and return NULL. -** -** The returned pointer (if it is not NULL) is owned by the cache in -** most cases, not the caller. The caller does NOT need to invoke -** jsonParseFree(), in most cases. -** -** Except, if an error occurs and pErrCtx==0 then return the JsonParse -** object with JsonParse.nErr non-zero and the caller will own the JsonParse -** object. In that case, it will be the responsibility of the caller to -** invoke jsonParseFree(). To summarize: -** -** pErrCtx!=0 || p->nErr==0 ==> Return value p is owned by the -** cache. Call does not need to -** free it. -** -** pErrCtx==0 && p->nErr!=0 ==> Return value is owned by the caller -** and so the caller must free it. -*/ -static JsonParse *jsonParseCached( - sqlite3_context *pCtx, /* Context to use for cache search */ - sqlite3_value *pJson, /* Function param containing JSON text */ - sqlite3_context *pErrCtx, /* Write parse errors here if not NULL */ - int bUnedited /* No prior edits allowed */ -){ - char *zJson = (char*)sqlite3_value_text(pJson); - int nJson = sqlite3_value_bytes(pJson); - JsonParse *p; - JsonParse *pMatch = 0; - int iKey; - int iMinKey = 0; - u32 iMinHold = 0xffffffff; - u32 iMaxHold = 0; - int bJsonRCStr; - - if( zJson==0 ) return 0; - for(iKey=0; iKeynJson==nJson - && (p->hasMod==0 || bUnedited==0) - && (p->zJson==zJson || memcmp(p->zJson,zJson,nJson)==0) - ){ - p->nErr = 0; - p->useMod = 0; - pMatch = p; - }else - if( pMatch==0 - && p->zAlt!=0 - && bUnedited==0 - && p->nAlt==nJson - && memcmp(p->zAlt, zJson, nJson)==0 - ){ - p->nErr = 0; - p->useMod = 1; - pMatch = p; - }else if( p->iHoldiHold; - iMinKey = iKey; - } - if( p->iHold>iMaxHold ){ - iMaxHold = p->iHold; - } - } - if( pMatch ){ - /* The input JSON text was found in the cache. Use the preexisting - ** parse of this JSON */ - pMatch->nErr = 0; - pMatch->iHold = iMaxHold+1; - assert( pMatch->nJPRef>0 ); /* pMatch is owned by the cache */ - return pMatch; - } - - /* The input JSON was not found anywhere in the cache. We will need - ** to parse it ourselves and generate a new JsonParse object. - */ - bJsonRCStr = sqlite3ValueIsOfClass(pJson,sqlite3RCStrUnref); - p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) ); - if( p==0 ){ - sqlite3_result_error_nomem(pCtx); +static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ + u8 x; + u32 sz; + u32 n; + if( NEVER(i>pParse->nBlob) ){ + *pSz = 0; return 0; } - memset(p, 0, sizeof(*p)); - if( bJsonRCStr ){ - p->zJson = sqlite3RCStrRef(zJson); - p->bJsonIsRCStr = 1; - }else{ - p->zJson = (char*)&p[1]; - memcpy(p->zJson, zJson, nJson+1); - } - p->nJPRef = 1; - if( jsonParse(p, pErrCtx) ){ - if( pErrCtx==0 ){ - p->nErr = 1; - assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */ - return p; - } - jsonParseFree(p); - return 0; - } - p->nJson = nJson; - p->iHold = iMaxHold+1; - /* Transfer ownership of the new JsonParse to the cache */ - sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, - (void(*)(void*))jsonParseFree); - return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); -} - -/* -** Compare the OBJECT label at pNode against zKey,nKey. Return true on -** a match. -*/ -static int jsonLabelCompare(const JsonNode *pNode, const char *zKey, u32 nKey){ - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_RAW ){ - if( pNode->n!=nKey ) return 0; - return strncmp(pNode->u.zJContent, zKey, nKey)==0; - }else{ - if( pNode->n!=nKey+2 ) return 0; - return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; - } -} -static int jsonSameLabel(const JsonNode *p1, const JsonNode *p2){ - if( p1->jnFlags & JNODE_RAW ){ - return jsonLabelCompare(p2, p1->u.zJContent, p1->n); - }else if( p2->jnFlags & JNODE_RAW ){ - return jsonLabelCompare(p1, p2->u.zJContent, p2->n); - }else{ - return p1->n==p2->n && strncmp(p1->u.zJContent,p2->u.zJContent,p1->n)==0; - } -} - -/* forward declaration */ -static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); - -/* -** Search along zPath to find the node specified. Return a pointer -** to that node, or NULL if zPath is malformed or if there is no such -** node. -** -** If pApnd!=0, then try to append new nodes to complete zPath if it is -** possible to do so and if no existing node corresponds to zPath. If -** new nodes are appended *pApnd is set to 1. -*/ -static JsonNode *jsonLookupStep( - JsonParse *pParse, /* The JSON to search */ - u32 iRoot, /* Begin the search at this node */ - const char *zPath, /* The path to search */ - int *pApnd, /* Append nodes to complete path if not NULL */ - const char **pzErr /* Make *pzErr point to any syntax error in zPath */ -){ - u32 i, j, nKey; - const char *zKey; - JsonNode *pRoot; - if( pParse->oom ) return 0; - pRoot = &pParse->aNode[iRoot]; - if( pRoot->jnFlags & (JNODE_REPLACE|JNODE_REMOVE) && pParse->useMod ){ - while( (pRoot->jnFlags & JNODE_REPLACE)!=0 ){ - u32 idx = (u32)(pRoot - pParse->aNode); - i = pParse->iSubst; - while( 1 /*exit-by-break*/ ){ - assert( inNode ); - assert( pParse->aNode[i].eType==JSON_SUBST ); - assert( pParse->aNode[i].eU==4 ); - assert( pParse->aNode[i].u.iPrevaNode[i].n==idx ){ - pRoot = &pParse->aNode[i+1]; - iRoot = i+1; - break; - } - i = pParse->aNode[i].u.iPrev; - } - } - if( pRoot->jnFlags & JNODE_REMOVE ){ + x = pParse->aBlob[i]>>4; + if( x<=11 ){ + sz = x; + n = 1; + }else if( x==12 ){ + if( i+1>=pParse->nBlob ){ + *pSz = 0; return 0; } + sz = pParse->aBlob[i+1]; + n = 2; + }else if( x==13 ){ + if( i+2>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = (pParse->aBlob[i+1]<<8) + pParse->aBlob[i+2]; + n = 3; + }else if( x==14 ){ + if( i+4>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = ((u32)pParse->aBlob[i+1]<<24) + (pParse->aBlob[i+2]<<16) + + (pParse->aBlob[i+3]<<8) + pParse->aBlob[i+4]; + n = 5; + }else{ + if( i+8>=pParse->nBlob + || pParse->aBlob[i+1]!=0 + || pParse->aBlob[i+2]!=0 + || pParse->aBlob[i+3]!=0 + || pParse->aBlob[i+4]!=0 + ){ + *pSz = 0; + return 0; + } + sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + + (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8]; + n = 9; + } + if( i+sz+n > pParse->nBlob + && i+sz+n > pParse->nBlob-pParse->delta + ){ + sz = 0; + n = 0; + } + *pSz = sz; + return n; +} + + +/* +** Translate the binary JSONB representation of JSON beginning at +** pParse->aBlob[i] into a JSON text string. Append the JSON +** text onto the end of pOut. Return the index in pParse->aBlob[] +** of the first byte past the end of the element that is translated. +** +** If an error is detected in the BLOB input, the pOut->eErr flag +** might get set to JSTRING_MALFORMED. But not all BLOB input errors +** are detected. So a malformed JSONB input might either result +** in an error, or in incorrect JSON. +** +** The pOut->eErr JSTRING_OOM flag is set on a OOM. +*/ +static u32 jsonTranslateBlobToText( + const JsonParse *pParse, /* the complete parse of the JSON */ + u32 i, /* Start rendering at this index */ + JsonString *pOut /* Write JSON here */ +){ + u32 sz, n, j, iEnd; + + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + pOut->eErr |= JSTRING_MALFORMED; + return pParse->nBlob+1; + } + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_NULL: { + jsonAppendRawNZ(pOut, "null", 4); + return i+1; + } + case JSONB_TRUE: { + jsonAppendRawNZ(pOut, "true", 4); + return i+1; + } + case JSONB_FALSE: { + jsonAppendRawNZ(pOut, "false", 5); + return i+1; + } + case JSONB_INT: + case JSONB_FLOAT: { + jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz); + break; + } + case JSONB_INT5: { /* Integer literal in hexadecimal notation */ + u32 k = 2; + sqlite3_uint64 u = 0; + const char *zIn = (const char*)&pParse->aBlob[i+n]; + int bOverflow = 0; + if( zIn[0]=='-' ){ + jsonAppendChar(pOut, '-'); + k++; + }else if( zIn[0]=='+' ){ + k++; + } + for(; keErr |= JSTRING_MALFORMED; + break; + }else if( (u>>60)!=0 ){ + bOverflow = 1; + }else{ + u = u*16 + sqlite3HexToInt(zIn[k]); + } + } + jsonPrintf(100,pOut,bOverflow?"9.0e999":"%llu", u); + break; + } + case JSONB_FLOAT5: { /* Float literal missing digits beside "." */ + u32 k = 0; + const char *zIn = (const char*)&pParse->aBlob[i+n]; + if( zIn[0]=='-' ){ + jsonAppendChar(pOut, '-'); + k++; + } + if( zIn[k]=='.' ){ + jsonAppendChar(pOut, '0'); + } + for(; kaBlob[i+n], sz); + jsonAppendChar(pOut, '"'); + break; + } + case JSONB_TEXT5: { + const char *zIn; + u32 k; + u32 sz2 = sz; + zIn = (const char*)&pParse->aBlob[i+n]; + jsonAppendChar(pOut, '"'); + while( sz2>0 ){ + for(k=0; k0 ){ + jsonAppendRawNZ(pOut, zIn, k); + if( k>=sz2 ){ + break; + } + zIn += k; + sz2 -= k; + } + if( zIn[0]=='"' ){ + jsonAppendRawNZ(pOut, "\\\"", 2); + zIn++; + sz2--; + continue; + } + assert( zIn[0]=='\\' ); + assert( sz2>=1 ); + if( sz2<2 ){ + pOut->eErr |= JSTRING_MALFORMED; + break; + } + switch( (u8)zIn[1] ){ + case '\'': + jsonAppendChar(pOut, '\''); + break; + case 'v': + jsonAppendRawNZ(pOut, "\\u0009", 6); + break; + case 'x': + if( sz2<4 ){ + pOut->eErr |= JSTRING_MALFORMED; + sz2 = 2; + break; + } + jsonAppendRawNZ(pOut, "\\u00", 4); + jsonAppendRawNZ(pOut, &zIn[2], 2); + zIn += 2; + sz2 -= 2; + break; + case '0': + jsonAppendRawNZ(pOut, "\\u0000", 6); + break; + case '\r': + if( sz2>2 && zIn[2]=='\n' ){ + zIn++; + sz2--; + } + break; + case '\n': + break; + case 0xe2: + /* '\' followed by either U+2028 or U+2029 is ignored as + ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29. + ** U+2029 is the same except for the last byte */ + if( sz2<4 + || 0x80!=(u8)zIn[2] + || (0xa8!=(u8)zIn[3] && 0xa9!=(u8)zIn[3]) + ){ + pOut->eErr |= JSTRING_MALFORMED; + sz2 = 2; + break; + } + zIn += 2; + sz2 -= 2; + break; + default: + jsonAppendRawNZ(pOut, zIn, 2); + break; + } + assert( sz2>=2 ); + zIn += 2; + sz2 -= 2; + } + jsonAppendChar(pOut, '"'); + break; + } + case JSONB_TEXTRAW: { + jsonAppendString(pOut, (const char*)&pParse->aBlob[i+n], sz); + break; + } + case JSONB_ARRAY: { + jsonAppendChar(pOut, '['); + j = i+n; + iEnd = j+sz; + while( j0 ) pOut->nUsed--; + jsonAppendChar(pOut, ']'); + break; + } + case JSONB_OBJECT: { + int x = 0; + jsonAppendChar(pOut, '{'); + j = i+n; + iEnd = j+sz; + while( jeErr |= JSTRING_MALFORMED; + if( sz>0 ) pOut->nUsed--; + jsonAppendChar(pOut, '}'); + break; + } + + default: { + pOut->eErr |= JSTRING_MALFORMED; + break; + } + } + return i+n+sz; +} + +/* Return true if the input pJson +** +** For performance reasons, this routine does not do a detailed check of the +** input BLOB to ensure that it is well-formed. Hence, false positives are +** possible. False negatives should never occur, however. +*/ +static int jsonFuncArgMightBeBinary(sqlite3_value *pJson){ + u32 sz, n; + const u8 *aBlob; + int nBlob; + JsonParse s; + if( sqlite3_value_type(pJson)!=SQLITE_BLOB ) return 0; + aBlob = sqlite3_value_blob(pJson); + nBlob = sqlite3_value_bytes(pJson); + if( nBlob<1 ) return 0; + if( NEVER(aBlob==0) || (aBlob[0] & 0x0f)>JSONB_OBJECT ) return 0; + memset(&s, 0, sizeof(s)); + s.aBlob = (u8*)aBlob; + s.nBlob = nBlob; + n = jsonbPayloadSize(&s, 0, &sz); + if( n==0 ) return 0; + if( sz+n!=(u32)nBlob ) return 0; + if( (aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0 ) return 0; + return sz+n==(u32)nBlob; +} + +/* +** Given that a JSONB_ARRAY object starts at offset i, return +** the number of entries in that array. +*/ +static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){ + u32 n, sz, i, iEnd; + u32 k = 0; + n = jsonbPayloadSize(pParse, iRoot, &sz); + iEnd = iRoot+n+sz; + for(i=iRoot+n; n>0 && idelta. +*/ +static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){ + u32 sz = 0; + u32 nBlob; + assert( pParse->delta!=0 ); + assert( pParse->nBlobAlloc >= pParse->nBlob ); + nBlob = pParse->nBlob; + pParse->nBlob = pParse->nBlobAlloc; + (void)jsonbPayloadSize(pParse, iRoot, &sz); + pParse->nBlob = nBlob; + sz += pParse->delta; + pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz); +} + +/* +** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of +** content beginning at iDel, and replacing them with nIns bytes of +** content given by aIns. +** +** nDel may be zero, in which case no bytes are removed. But iDel is +** still important as new bytes will be insert beginning at iDel. +** +** aIns may be zero, in which case space is created to hold nIns bytes +** beginning at iDel, but that space is uninitialized. +** +** Set pParse->oom if an OOM occurs. +*/ +static void jsonBlobEdit( + JsonParse *pParse, /* The JSONB to be modified is in pParse->aBlob */ + u32 iDel, /* First byte to be removed */ + u32 nDel, /* Number of bytes to remove */ + const u8 *aIns, /* Content to insert */ + u32 nIns /* Bytes of content to insert */ +){ + i64 d = (i64)nIns - (i64)nDel; + if( d!=0 ){ + if( pParse->nBlob + d > pParse->nBlobAlloc ){ + jsonBlobExpand(pParse, pParse->nBlob+d); + if( pParse->oom ) return; + } + memmove(&pParse->aBlob[iDel+nIns], + &pParse->aBlob[iDel+nDel], + pParse->nBlob - (iDel+nDel)); + pParse->nBlob += d; + pParse->delta += d; + } + if( nIns && aIns ) memcpy(&pParse->aBlob[iDel], aIns, nIns); +} + +/* +** Return the number of escaped newlines to be ignored. +** An escaped newline is a one of the following byte sequences: +** +** 0x5c 0x0a +** 0x5c 0x0d +** 0x5c 0x0d 0x0a +** 0x5c 0xe2 0x80 0xa8 +** 0x5c 0xe2 0x80 0xa9 +*/ +static u32 jsonBytesToBypass(const char *z, u32 n){ + u32 i = 0; + while( i+10 ); + assert( z[0]=='\\' ); + if( n<2 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + switch( (u8)z[1] ){ + case 'u': { + u32 v, vlo; + if( n<6 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + v = jsonHexToInt4(&z[2]); + if( (v & 0xfc00)==0xd800 + && n>=12 + && z[6]=='\\' + && z[7]=='u' + && ((vlo = jsonHexToInt4(&z[8]))&0xfc00)==0xdc00 + ){ + *piOut = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000; + return 12; + }else{ + *piOut = v; + return 6; + } + } + case 'b': { *piOut = '\b'; return 2; } + case 'f': { *piOut = '\f'; return 2; } + case 'n': { *piOut = '\n'; return 2; } + case 'r': { *piOut = '\r'; return 2; } + case 't': { *piOut = '\t'; return 2; } + case 'v': { *piOut = '\v'; return 2; } + case '0': { *piOut = 0; return 2; } + case '\'': + case '"': + case '/': + case '\\':{ *piOut = z[1]; return 2; } + case 'x': { + if( n<4 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + *piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]); + return 4; + } + case 0xe2: + case '\r': + case '\n': { + u32 nSkip = jsonBytesToBypass(z, n); + if( nSkip==0 ){ + *piOut = JSON_INVALID_CHAR; + return n; + }else if( nSkip==n ){ + *piOut = 0; + return n; + }else if( z[nSkip]=='\\' ){ + return nSkip + jsonUnescapeOneChar(&z[nSkip], n-nSkip, piOut); + }else{ + int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut); + return nSkip + sz; + } + } + default: { + *piOut = JSON_INVALID_CHAR; + return 2; + } + } +} + + +/* +** Compare two object labels. Return 1 if they are equal and +** 0 if they differ. +** +** In this version, we know that one or the other or both of the +** two comparands contains an escape sequence. +*/ +static SQLITE_NOINLINE int jsonLabelCompareEscaped( + const char *zLeft, /* The left label */ + u32 nLeft, /* Size of the left label in bytes */ + int rawLeft, /* True if zLeft contains no escapes */ + const char *zRight, /* The right label */ + u32 nRight, /* Size of the right label in bytes */ + int rawRight /* True if zRight is escape-free */ +){ + u32 cLeft, cRight; + assert( rawLeft==0 || rawRight==0 ); + while( 1 /*exit-by-return*/ ){ + if( nLeft==0 ){ + cLeft = 0; + }else if( rawLeft || zLeft[0]!='\\' ){ + cLeft = ((u8*)zLeft)[0]; + if( cLeft>=0xc0 ){ + int sz = sqlite3Utf8ReadLimited((u8*)zLeft, nLeft, &cLeft); + zLeft += sz; + nLeft -= sz; + }else{ + zLeft++; + nLeft--; + } + }else{ + u32 n = jsonUnescapeOneChar(zLeft, nLeft, &cLeft); + zLeft += n; + assert( n<=nLeft ); + nLeft -= n; + } + if( nRight==0 ){ + cRight = 0; + }else if( rawRight || zRight[0]!='\\' ){ + cRight = ((u8*)zRight)[0]; + if( cRight>=0xc0 ){ + int sz = sqlite3Utf8ReadLimited((u8*)zRight, nRight, &cRight); + zRight += sz; + nRight -= sz; + }else{ + zRight++; + nRight--; + } + }else{ + u32 n = jsonUnescapeOneChar(zRight, nRight, &cRight); + zRight += n; + assert( n<=nRight ); + nRight -= n; + } + if( cLeft!=cRight ) return 0; + if( cLeft==0 ) return 1; + } +} + +/* +** Compare two object labels. Return 1 if they are equal and +** 0 if they differ. Return -1 if an OOM occurs. +*/ +static int jsonLabelCompare( + const char *zLeft, /* The left label */ + u32 nLeft, /* Size of the left label in bytes */ + int rawLeft, /* True if zLeft contains no escapes */ + const char *zRight, /* The right label */ + u32 nRight, /* Size of the right label in bytes */ + int rawRight /* True if zRight is escape-free */ +){ + if( rawLeft && rawRight ){ + /* Simpliest case: Neither label contains escapes. A simple + ** memcmp() is sufficient. */ + if( nLeft!=nRight ) return 0; + return memcmp(zLeft, zRight, nLeft)==0; + }else{ + return jsonLabelCompareEscaped(zLeft, nLeft, rawLeft, + zRight, nRight, rawRight); + } +} + +/* +** Error returns from jsonLookupStep() +*/ +#define JSON_LOOKUP_ERROR 0xffffffff +#define JSON_LOOKUP_NOTFOUND 0xfffffffe +#define JSON_LOOKUP_PATHERROR 0xfffffffd +#define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR) + +/* Forward declaration */ +static u32 jsonLookupStep(JsonParse*,u32,const char*,u32); + + +/* This helper routine for jsonLookupStep() populates pIns with +** binary data that is to be inserted into pParse. +** +** In the common case, pIns just points to pParse->aIns and pParse->nIns. +** But if the zPath of the original edit operation includes path elements +** that go deeper, additional substructure must be created. +** +** For example: +** +** json_insert('{}', '$.a.b.c', 123); +** +** The search stops at '$.a' But additional substructure must be +** created for the ".b.c" part of the patch so that the final result +** is: {"a":{"b":{"c"::123}}}. This routine populates pIns with +** the binary equivalent of {"b":{"c":123}} so that it can be inserted. +** +** The caller is responsible for resetting pIns when it has finished +** using the substructure. +*/ +static u32 jsonCreateEditSubstructure( + JsonParse *pParse, /* The original JSONB that is being edited */ + JsonParse *pIns, /* Populate this with the blob data to insert */ + const char *zTail /* Tail of the path that determins substructure */ +){ + static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT }; + int rc; + memset(pIns, 0, sizeof(*pIns)); + pIns->db = pParse->db; + if( zTail[0]==0 ){ + /* No substructure. Just insert what is given in pParse. */ + pIns->aBlob = pParse->aIns; + pIns->nBlob = pParse->nIns; + rc = 0; + }else{ + /* Construct the binary substructure */ + pIns->nBlob = 1; + pIns->aBlob = (u8*)&emptyObject[zTail[0]=='.']; + pIns->eEdit = pParse->eEdit; + pIns->nIns = pParse->nIns; + pIns->aIns = pParse->aIns; + rc = jsonLookupStep(pIns, 0, zTail, 0); + pParse->oom |= pIns->oom; + } + return rc; /* Error code only */ +} + +/* +** Search along zPath to find the Json element specified. Return an +** index into pParse->aBlob[] for the start of that element's value. +** +** If the value found by this routine is the value half of label/value pair +** within an object, then set pPath->iLabel to the start of the corresponding +** label, before returning. +** +** Return one of the JSON_LOOKUP error codes if problems are seen. +** +** This routine will also modify the blob. If pParse->eEdit is one of +** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, or JEDIT_SET, then changes might be +** made to the selected value. If an edit is performed, then the return +** value does not necessarily point to the select element. If an edit +** is performed, the return value is only useful for detecting error +** conditions. +*/ +static u32 jsonLookupStep( + JsonParse *pParse, /* The JSON to search */ + u32 iRoot, /* Begin the search at this element of aBlob[] */ + const char *zPath, /* The path to search */ + u32 iLabel /* Label if iRoot is a value of in an object */ +){ + u32 i, j, k, nKey, sz, n, iEnd, rc; + const char *zKey; + u8 x; + + if( zPath[0]==0 ){ + if( pParse->eEdit && jsonBlobMakeEditable(pParse, pParse->nIns) ){ + n = jsonbPayloadSize(pParse, iRoot, &sz); + sz += n; + if( pParse->eEdit==JEDIT_DEL ){ + if( iLabel>0 ){ + sz += iRoot - iLabel; + iRoot = iLabel; + } + jsonBlobEdit(pParse, iRoot, sz, 0, 0); + }else if( pParse->eEdit==JEDIT_INS ){ + /* Already exists, so json_insert() is a no-op */ + }else{ + /* json_set() or json_replace() */ + jsonBlobEdit(pParse, iRoot, sz, pParse->aIns, pParse->nIns); + } + } + pParse->iLabel = iLabel; + return iRoot; } - if( zPath[0]==0 ) return pRoot; if( zPath[0]=='.' ){ - if( pRoot->eType!=JSON_OBJECT ) return 0; + int rawKey = 1; + x = pParse->aBlob[iRoot]; zPath++; if( zPath[0]=='"' ){ zKey = zPath + 1; @@ -204702,251 +205867,677 @@ static JsonNode *jsonLookupStep( if( zPath[i] ){ i++; }else{ - *pzErr = zPath; - return 0; + return JSON_LOOKUP_PATHERROR; } testcase( nKey==0 ); + rawKey = memchr(zKey, '\\', nKey)==0; }else{ zKey = zPath; for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} nKey = i; if( nKey==0 ){ - *pzErr = zPath; - return 0; + return JSON_LOOKUP_PATHERROR; } } - j = 1; - for(;;){ - while( j<=pRoot->n ){ - if( jsonLabelCompare(pRoot+j, zKey, nKey) ){ - return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); + if( (x & 0x0f)!=JSONB_OBJECT ) return JSON_LOOKUP_NOTFOUND; + n = jsonbPayloadSize(pParse, iRoot, &sz); + j = iRoot + n; /* j is the index of a label */ + iEnd = j+sz; + while( jaBlob[j] & 0x0f; + if( xJSONB_TEXTRAW ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + k = j+n; /* k is the index of the label text */ + if( k+sz>=iEnd ) return JSON_LOOKUP_ERROR; + zLabel = (const char*)&pParse->aBlob[k]; + rawLabel = x==JSONB_TEXT || x==JSONB_TEXTRAW; + if( jsonLabelCompare(zKey, nKey, rawKey, zLabel, sz, rawLabel) ){ + u32 v = k+sz; /* v is the index of the value */ + if( ((pParse->aBlob[v])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, v, &sz); + if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR; + assert( j>0 ); + rc = jsonLookupStep(pParse, v, &zPath[i], j); + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } + j = k+sz; + if( ((pParse->aBlob[j])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + j += n+sz; + } + if( j>iEnd ) return JSON_LOOKUP_ERROR; + if( pParse->eEdit>=JEDIT_INS ){ + u32 nIns; /* Total bytes to insert (label+value) */ + JsonParse v; /* BLOB encoding of the value to be inserted */ + JsonParse ix; /* Header of the label to be inserted */ + testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_SET ); + memset(&ix, 0, sizeof(ix)); + ix.db = pParse->db; + jsonBlobAppendNode(&ix, rawKey?JSONB_TEXTRAW:JSONB_TEXT5, nKey, 0); + pParse->oom |= ix.oom; + rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i]); + if( !JSON_LOOKUP_ISERROR(rc) + && jsonBlobMakeEditable(pParse, ix.nBlob+nKey+v.nBlob) + ){ + assert( !pParse->oom ); + nIns = ix.nBlob + nKey + v.nBlob; + jsonBlobEdit(pParse, j, 0, 0, nIns); + if( !pParse->oom ){ + assert( pParse->aBlob!=0 ); /* Because pParse->oom!=0 */ + assert( ix.aBlob!=0 ); /* Because pPasre->oom!=0 */ + memcpy(&pParse->aBlob[j], ix.aBlob, ix.nBlob); + k = j + ix.nBlob; + memcpy(&pParse->aBlob[k], zKey, nKey); + k += nKey; + memcpy(&pParse->aBlob[k], v.aBlob, v.nBlob); + if( ALWAYS(pParse->delta) ) jsonAfterEditSizeAdjust(pParse, iRoot); } - j++; - j += jsonNodeSize(&pRoot[j]); } - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pRoot->eU==2 ); - iRoot = pRoot->u.iAppend; - pRoot = &pParse->aNode[iRoot]; - j = 1; - } - if( pApnd ){ - u32 iStart, iLabel; - JsonNode *pNode; - assert( pParse->useMod ); - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); - iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); - zPath += i; - pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); - if( pParse->oom ) return 0; - if( pNode ){ - pRoot = &pParse->aNode[iRoot]; - assert( pRoot->eU==0 ); - pRoot->u.iAppend = iStart; - pRoot->jnFlags |= JNODE_APPEND; - VVA( pRoot->eU = 2 ); - pParse->aNode[iLabel].jnFlags |= JNODE_RAW; - } - return pNode; + jsonParseReset(&v); + jsonParseReset(&ix); + return rc; } }else if( zPath[0]=='[' ){ - i = 0; - j = 1; - while( sqlite3Isdigit(zPath[j]) ){ - i = i*10 + zPath[j] - '0'; - j++; + x = pParse->aBlob[iRoot] & 0x0f; + if( x!=JSONB_ARRAY ) return JSON_LOOKUP_NOTFOUND; + n = jsonbPayloadSize(pParse, iRoot, &sz); + k = 0; + i = 1; + while( sqlite3Isdigit(zPath[i]) ){ + k = k*10 + zPath[i] - '0'; + i++; } - if( j<2 || zPath[j]!=']' ){ + if( i<2 || zPath[i]!=']' ){ if( zPath[1]=='#' ){ - JsonNode *pBase = pRoot; - int iBase = iRoot; - if( pRoot->eType!=JSON_ARRAY ) return 0; - for(;;){ - while( j<=pBase->n ){ - if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i++; - j += jsonNodeSize(&pBase[j]); - } - if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pBase->eU==2 ); - iBase = pBase->u.iAppend; - pBase = &pParse->aNode[iBase]; - j = 1; - } - j = 2; + k = jsonbArrayCount(pParse, iRoot); + i = 2; if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ - unsigned int x = 0; - j = 3; + unsigned int nn = 0; + i = 3; do{ - x = x*10 + zPath[j] - '0'; - j++; - }while( sqlite3Isdigit(zPath[j]) ); - if( x>i ) return 0; - i -= x; + nn = nn*10 + zPath[i] - '0'; + i++; + }while( sqlite3Isdigit(zPath[i]) ); + if( nn>k ) return JSON_LOOKUP_NOTFOUND; + k -= nn; } - if( zPath[j]!=']' ){ - *pzErr = zPath; - return 0; + if( zPath[i]!=']' ){ + return JSON_LOOKUP_PATHERROR; } }else{ - *pzErr = zPath; - return 0; + return JSON_LOOKUP_PATHERROR; } } - if( pRoot->eType!=JSON_ARRAY ) return 0; - zPath += j + 1; - j = 1; - for(;;){ - while( j<=pRoot->n - && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod)) + j = iRoot+n; + iEnd = j+sz; + while( jdelta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } + k--; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + j += n+sz; + } + if( j>iEnd ) return JSON_LOOKUP_ERROR; + if( k>0 ) return JSON_LOOKUP_NOTFOUND; + if( pParse->eEdit>=JEDIT_INS ){ + JsonParse v; + testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_SET ); + rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]); + if( !JSON_LOOKUP_ISERROR(rc) + && jsonBlobMakeEditable(pParse, v.nBlob) ){ - if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--; - j += jsonNodeSize(&pRoot[j]); + assert( !pParse->oom ); + jsonBlobEdit(pParse, j, 0, v.aBlob, v.nBlob); } - if( i==0 && j<=pRoot->n ) break; - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pRoot->eU==2 ); - iRoot = pRoot->u.iAppend; - pRoot = &pParse->aNode[iRoot]; - j = 1; - } - if( j<=pRoot->n ){ - return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); - } - if( i==0 && pApnd ){ - u32 iStart; - JsonNode *pNode; - assert( pParse->useMod ); - iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); - pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); - if( pParse->oom ) return 0; - if( pNode ){ - pRoot = &pParse->aNode[iRoot]; - assert( pRoot->eU==0 ); - pRoot->u.iAppend = iStart; - pRoot->jnFlags |= JNODE_APPEND; - VVA( pRoot->eU = 2 ); - } - return pNode; + jsonParseReset(&v); + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; } }else{ - *pzErr = zPath; + return JSON_LOOKUP_PATHERROR; } - return 0; + return JSON_LOOKUP_NOTFOUND; } /* -** Append content to pParse that will complete zPath. Return a pointer -** to the inserted node, or return NULL if the append fails. +** Convert a JSON BLOB into text and make that text the return value +** of an SQL function. */ -static JsonNode *jsonLookupAppend( - JsonParse *pParse, /* Append content to the JSON parse */ - const char *zPath, /* Description of content to append */ - int *pApnd, /* Set this flag to 1 */ - const char **pzErr /* Make this point to any syntax error */ +static void jsonReturnTextJsonFromBlob( + sqlite3_context *ctx, + const u8 *aBlob, + u32 nBlob ){ - *pApnd = 1; - if( zPath[0]==0 ){ - jsonParseAddNode(pParse, JSON_NULL, 0, 0); - return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; + JsonParse x; + JsonString s; + + if( NEVER(aBlob==0) ) return; + memset(&x, 0, sizeof(x)); + x.aBlob = (u8*)aBlob; + x.nBlob = nBlob; + jsonStringInit(&s, ctx); + jsonTranslateBlobToText(&x, 0, &s); + jsonReturnString(&s, 0, 0); +} + + +/* +** Return the value of the BLOB node at index i. +** +** If the value is a primitive, return it as an SQL value. +** If the value is an array or object, return it as either +** JSON text or the BLOB encoding, depending on the JSON_B flag +** on the userdata. +*/ +static void jsonReturnFromBlob( + JsonParse *pParse, /* Complete JSON parse tree */ + u32 i, /* Index of the node */ + sqlite3_context *pCtx, /* Return value for this function */ + int textOnly /* return text JSON. Disregard user-data */ +){ + u32 n, sz; + int rc; + sqlite3 *db = sqlite3_context_db_handle(pCtx); + + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + sqlite3_result_error(pCtx, "malformed JSON", -1); + return; } - if( zPath[0]=='.' ){ - jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); - }else if( strncmp(zPath,"[0]",3)==0 ){ - jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_NULL: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_null(pCtx); + break; + } + case JSONB_TRUE: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_int(pCtx, 1); + break; + } + case JSONB_FALSE: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_int(pCtx, 0); + break; + } + case JSONB_INT5: + case JSONB_INT: { + sqlite3_int64 iRes = 0; + char *z; + int bNeg = 0; + char x; + if( sz==0 ) goto returnfromblob_malformed; + x = (char)pParse->aBlob[i+n]; + if( x=='-' ){ + if( sz<2 ) goto returnfromblob_malformed; + n++; + sz--; + bNeg = 1; + } + z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); + if( z==0 ) goto returnfromblob_oom; + rc = sqlite3DecOrHexToI64(z, &iRes); + sqlite3DbFree(db, z); + if( rc==0 ){ + sqlite3_result_int64(pCtx, bNeg ? -iRes : iRes); + }else if( rc==3 && bNeg ){ + sqlite3_result_int64(pCtx, SMALLEST_INT64); + }else if( rc==1 ){ + goto returnfromblob_malformed; + }else{ + if( bNeg ){ n--; sz++; } + goto to_double; + } + break; + } + case JSONB_FLOAT5: + case JSONB_FLOAT: { + double r; + char *z; + if( sz==0 ) goto returnfromblob_malformed; + to_double: + z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); + if( z==0 ) goto returnfromblob_oom; + rc = sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); + sqlite3DbFree(db, z); + if( rc<=0 ) goto returnfromblob_malformed; + sqlite3_result_double(pCtx, r); + break; + } + case JSONB_TEXTRAW: + case JSONB_TEXT: { + sqlite3_result_text(pCtx, (char*)&pParse->aBlob[i+n], sz, + SQLITE_TRANSIENT); + break; + } + case JSONB_TEXT5: + case JSONB_TEXTJ: { + /* Translate JSON formatted string into raw text */ + u32 iIn, iOut; + const char *z; + char *zOut; + u32 nOut = sz; + z = (const char*)&pParse->aBlob[i+n]; + zOut = sqlite3DbMallocRaw(db, nOut+1); + if( zOut==0 ) goto returnfromblob_oom; + for(iIn=iOut=0; iIn=2 ); + zOut[iOut++] = (char)(0xc0 | (v>>6)); + zOut[iOut++] = 0x80 | (v&0x3f); + }else if( v<0x10000 ){ + assert( szEscape>=3 ); + zOut[iOut++] = 0xe0 | (v>>12); + zOut[iOut++] = 0x80 | ((v>>6)&0x3f); + zOut[iOut++] = 0x80 | (v&0x3f); + }else if( v==JSON_INVALID_CHAR ){ + /* Silently ignore illegal unicode */ + }else{ + assert( szEscape>=4 ); + zOut[iOut++] = 0xf0 | (v>>18); + zOut[iOut++] = 0x80 | ((v>>12)&0x3f); + zOut[iOut++] = 0x80 | ((v>>6)&0x3f); + zOut[iOut++] = 0x80 | (v&0x3f); + } + iIn += szEscape - 1; + }else{ + zOut[iOut++] = c; + } + } /* end for() */ + assert( iOut<=nOut ); + zOut[iOut] = 0; + sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC); + break; + } + case JSONB_ARRAY: + case JSONB_OBJECT: { + int flags = textOnly ? 0 : SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx)); + if( flags & JSON_BLOB ){ + sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT); + }else{ + jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n); + } + break; + } + default: { + goto returnfromblob_malformed; + } + } + return; + +returnfromblob_oom: + sqlite3_result_error_nomem(pCtx); + return; + +returnfromblob_malformed: + sqlite3_result_error(pCtx, "malformed JSON", -1); + return; +} + +/* +** pArg is a function argument that might be an SQL value or a JSON +** value. Figure out what it is and encode it as a JSONB blob. +** Return the results in pParse. +** +** pParse is uninitialized upon entry. This routine will handle the +** initialization of pParse. The result will be contained in +** pParse->aBlob and pParse->nBlob. pParse->aBlob might be dynamically +** allocated (if pParse->nBlobAlloc is greater than zero) in which case +** the caller is responsible for freeing the space allocated to pParse->aBlob +** when it has finished with it. Or pParse->aBlob might be a static string +** or a value obtained from sqlite3_value_blob(pArg). +** +** If the argument is a BLOB that is clearly not a JSONB, then this +** function might set an error message in ctx and return non-zero. +** It might also set an error message and return non-zero on an OOM error. +*/ +static int jsonFunctionArgToBlob( + sqlite3_context *ctx, + sqlite3_value *pArg, + JsonParse *pParse +){ + int eType = sqlite3_value_type(pArg); + static u8 aNull[] = { 0x00 }; + memset(pParse, 0, sizeof(pParse[0])); + pParse->db = sqlite3_context_db_handle(ctx); + switch( eType ){ + default: { + pParse->aBlob = aNull; + pParse->nBlob = 1; + return 0; + } + case SQLITE_BLOB: { + if( jsonFuncArgMightBeBinary(pArg) ){ + pParse->aBlob = (u8*)sqlite3_value_blob(pArg); + pParse->nBlob = sqlite3_value_bytes(pArg); + }else{ + sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1); + return 1; + } + break; + } + case SQLITE_TEXT: { + const char *zJson = (const char*)sqlite3_value_text(pArg); + int nJson = sqlite3_value_bytes(pArg); + if( zJson==0 ) return 1; + if( sqlite3_value_subtype(pArg)==JSON_SUBTYPE ){ + pParse->zJson = (char*)zJson; + pParse->nJson = nJson; + if( jsonConvertTextToBlob(pParse, ctx) ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + sqlite3DbFree(pParse->db, pParse->aBlob); + memset(pParse, 0, sizeof(pParse[0])); + return 1; + } + }else{ + jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson); + } + break; + } + case SQLITE_FLOAT: { + double r = sqlite3_value_double(pArg); + if( NEVER(sqlite3IsNaN(r)) ){ + jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0); + }else{ + int n = sqlite3_value_bytes(pArg); + const char *z = (const char*)sqlite3_value_text(pArg); + if( z==0 ) return 1; + if( z[0]=='I' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); + }else if( z[0]=='-' && z[1]=='I' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); + }else{ + jsonBlobAppendNode(pParse, JSONB_FLOAT, n, z); + } + } + break; + } + case SQLITE_INTEGER: { + int n = sqlite3_value_bytes(pArg); + const char *z = (const char*)sqlite3_value_text(pArg); + if( z==0 ) return 1; + jsonBlobAppendNode(pParse, JSONB_INT, n, z); + break; + } + } + if( pParse->oom ){ + sqlite3_result_error_nomem(ctx); + return 1; }else{ return 0; } - if( pParse->oom ) return 0; - return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); } /* -** Return the text of a syntax error message on a JSON path. Space is -** obtained from sqlite3_malloc(). -*/ -static char *jsonPathSyntaxError(const char *zErr){ - return sqlite3_mprintf("JSON path error near '%q'", zErr); -} - -/* -** Do a node lookup using zPath. Return a pointer to the node on success. -** Return NULL if not found or if there is an error. +** Generate a bad path error. ** -** On an error, write an error message into pCtx and increment the -** pParse->nErr counter. -** -** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if -** nodes are appended. +** If ctx is not NULL then push the error message into ctx and return NULL. +** If ctx is NULL, then return the text of the error message. */ -static JsonNode *jsonLookup( - JsonParse *pParse, /* The JSON to search */ - const char *zPath, /* The path to search */ - int *pApnd, /* Append nodes to complete path if not NULL */ - sqlite3_context *pCtx /* Report errors here, if not NULL */ +static char *jsonBadPathError( + sqlite3_context *ctx, /* The function call containing the error */ + const char *zPath /* The path with the problem */ ){ - const char *zErr = 0; - JsonNode *pNode = 0; - char *zMsg; - - if( zPath==0 ) return 0; - if( zPath[0]!='$' ){ - zErr = zPath; - goto lookup_err; - } - zPath++; - pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr); - if( zErr==0 ) return pNode; - -lookup_err: - pParse->nErr++; - assert( zErr!=0 && pCtx!=0 ); - zMsg = jsonPathSyntaxError(zErr); + char *zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath); + if( ctx==0 ) return zMsg; if( zMsg ){ - sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_result_error(ctx, zMsg, -1); sqlite3_free(zMsg); }else{ - sqlite3_result_error_nomem(pCtx); + sqlite3_result_error_nomem(ctx); } return 0; } - -/* -** Report the wrong number of arguments for json_insert(), json_replace() -** or json_set(). +/* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent +** arguments come in parse where each pair contains a JSON path and +** content to insert or set at that patch. Do the updates +** and return the result. +** +** The specific operation is determined by eEdit, which can be one +** of JEDIT_INS, JEDIT_REPL, or JEDIT_SET. */ -static void jsonWrongNumArgs( - sqlite3_context *pCtx, - const char *zFuncName +static void jsonInsertIntoBlob( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv, + int eEdit /* JEDIT_INS, JEDIT_REPL, or JEDIT_SET */ ){ - char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", - zFuncName); - sqlite3_result_error(pCtx, zMsg, -1); - sqlite3_free(zMsg); + int i; + u32 rc = 0; + const char *zPath = 0; + int flgs; + JsonParse *p; + JsonParse ax; + + assert( (argc&1)==1 ); + flgs = argc==1 ? 0 : JSON_EDITABLE; + p = jsonParseFuncArg(ctx, argv[0], flgs); + if( p==0 ) return; + for(i=1; inBlob, ax.aBlob, ax.nBlob); + } + rc = 0; + }else{ + p->eEdit = eEdit; + p->nIns = ax.nBlob; + p->aIns = ax.aBlob; + p->delta = 0; + rc = jsonLookupStep(p, 0, zPath+1, 0); + } + jsonParseReset(&ax); + if( rc==JSON_LOOKUP_NOTFOUND ) continue; + if( JSON_LOOKUP_ISERROR(rc) ) goto jsonInsertIntoBlob_patherror; + } + jsonReturnParse(ctx, p); + jsonParseFree(p); + return; + +jsonInsertIntoBlob_patherror: + jsonParseFree(p); + if( rc==JSON_LOOKUP_ERROR ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + }else{ + jsonBadPathError(ctx, zPath); + } + return; } /* -** Mark all NULL entries in the Object passed in as JNODE_REMOVE. +** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob, +** from the SQL function argument pArg. Return a pointer to the new +** JsonParse object. +** +** Ownership of the new JsonParse object is passed to the caller. The +** caller should invoke jsonParseFree() on the return value when it +** has finished using it. +** +** If any errors are detected, an appropriate error messages is set +** using sqlite3_result_error() or the equivalent and this routine +** returns NULL. This routine also returns NULL if the pArg argument +** is an SQL NULL value, but no error message is set in that case. This +** is so that SQL functions that are given NULL arguments will return +** a NULL value. */ -static void jsonRemoveAllNulls(JsonNode *pNode){ - int i, n; - assert( pNode->eType==JSON_OBJECT ); - n = pNode->n; - for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){ - switch( pNode[i].eType ){ - case JSON_NULL: - pNode[i].jnFlags |= JNODE_REMOVE; - break; - case JSON_OBJECT: - jsonRemoveAllNulls(&pNode[i]); - break; +static JsonParse *jsonParseFuncArg( + sqlite3_context *ctx, + sqlite3_value *pArg, + u32 flgs +){ + int eType; /* Datatype of pArg */ + JsonParse *p = 0; /* Value to be returned */ + JsonParse *pFromCache = 0; /* Value taken from cache */ + sqlite3 *db; /* The database connection */ + + assert( ctx!=0 ); + eType = sqlite3_value_type(pArg); + if( eType==SQLITE_NULL ){ + return 0; + } + pFromCache = jsonCacheSearch(ctx, pArg); + if( pFromCache ){ + pFromCache->nJPRef++; + if( (flgs & JSON_EDITABLE)==0 ){ + return pFromCache; } } + db = sqlite3_context_db_handle(ctx); +rebuild_from_cache: + p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p==0 ) goto json_pfa_oom; + memset(p, 0, sizeof(*p)); + p->db = db; + p->nJPRef = 1; + if( pFromCache!=0 ){ + u32 nBlob = pFromCache->nBlob; + p->aBlob = sqlite3DbMallocRaw(db, nBlob); + if( p->aBlob==0 ) goto json_pfa_oom; + memcpy(p->aBlob, pFromCache->aBlob, nBlob); + p->nBlobAlloc = p->nBlob = nBlob; + p->hasNonstd = pFromCache->hasNonstd; + jsonParseFree(pFromCache); + return p; + } + if( eType==SQLITE_BLOB ){ + u32 n, sz = 0; + p->aBlob = (u8*)sqlite3_value_blob(pArg); + p->nBlob = (u32)sqlite3_value_bytes(pArg); + if( p->nBlob==0 ){ + goto json_pfa_malformed; + } + if( NEVER(p->aBlob==0) ){ + goto json_pfa_oom; + } + if( (p->aBlob[0] & 0x0f)>JSONB_OBJECT ){ + goto json_pfa_malformed; + } + n = jsonbPayloadSize(p, 0, &sz); + if( n==0 + || sz+n!=p->nBlob + || ((p->aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0) + ){ + goto json_pfa_malformed; + } + if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){ + goto json_pfa_oom; + } + return p; + } + p->zJson = (char*)sqlite3_value_text(pArg); + p->nJson = sqlite3_value_bytes(pArg); + if( p->nJson==0 ) goto json_pfa_malformed; + if( NEVER(p->zJson==0) ) goto json_pfa_oom; + if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){ + if( flgs & JSON_KEEPERROR ){ + p->nErr = 1; + return p; + }else{ + jsonParseFree(p); + return 0; + } + }else{ + int isRCStr = sqlite3ValueIsOfClass(pArg, sqlite3RCStrUnref); + int rc; + if( !isRCStr ){ + char *zNew = sqlite3RCStrNew( p->nJson ); + if( zNew==0 ) goto json_pfa_oom; + memcpy(zNew, p->zJson, p->nJson); + p->zJson = zNew; + p->zJson[p->nJson] = 0; + }else{ + sqlite3RCStrRef(p->zJson); + } + p->bJsonIsRCStr = 1; + rc = jsonCacheInsert(ctx, p); + if( rc==SQLITE_NOMEM ) goto json_pfa_oom; + if( flgs & JSON_EDITABLE ){ + pFromCache = p; + p = 0; + goto rebuild_from_cache; + } + } + return p; + +json_pfa_malformed: + if( flgs & JSON_KEEPERROR ){ + p->nErr = 1; + return p; + }else{ + jsonParseFree(p); + sqlite3_result_error(ctx, "malformed JSON", -1); + return 0; + } + +json_pfa_oom: + jsonParseFree(pFromCache); + jsonParseFree(p); + sqlite3_result_error_nomem(ctx); + return 0; } +/* +** Make the return value of a JSON function either the raw JSONB blob +** or make it JSON text, depending on whether the JSON_BLOB flag is +** set on the function. +*/ +static void jsonReturnParse( + sqlite3_context *ctx, + JsonParse *p +){ + int flgs; + if( p->oom ){ + sqlite3_result_error_nomem(ctx); + return; + } + flgs = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( flgs & JSON_BLOB ){ + if( p->nBlobAlloc>0 && !p->bReadOnly ){ + sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_DYNAMIC); + p->nBlobAlloc = 0; + }else{ + sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT); + } + }else{ + JsonString s; + jsonStringInit(&s, ctx); + p->delta = 0; + jsonTranslateBlobToText(p, 0, &s); + jsonReturnString(&s, p, ctx); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } +} /**************************************************************************** ** SQL functions used for testing and debugging @@ -204954,63 +206545,124 @@ static void jsonRemoveAllNulls(JsonNode *pNode){ #if SQLITE_DEBUG /* -** Print N node entries. +** Decode JSONB bytes in aBlob[] starting at iStart through but not +** including iEnd. Indent the +** content by nIndent spaces. */ -static void jsonDebugPrintNodeEntries( - JsonNode *aNode, /* First node entry to print */ - int N /* Number of node entries to print */ +static void jsonDebugPrintBlob( + JsonParse *pParse, /* JSON content */ + u32 iStart, /* Start rendering here */ + u32 iEnd, /* Do not render this byte or any byte after this one */ + int nIndent, /* Indent by this many spaces */ + sqlite3_str *pOut /* Generate output into this sqlite3_str object */ ){ - int i; - for(i=0; iaBlob[iStart] & 0x0f; + u32 savedNBlob = pParse->nBlob; + sqlite3_str_appendf(pOut, "%5d:%*s", iStart, nIndent, ""); + if( pParse->nBlobAlloc>pParse->nBlob ){ + pParse->nBlob = pParse->nBlobAlloc; } - printf("node %4u: %-7s n=%-5d", i, zType, aNode[i].n); - if( (aNode[i].jnFlags & ~JNODE_LABEL)!=0 ){ - u8 f = aNode[i].jnFlags; - if( f & JNODE_RAW ) printf(" RAW"); - if( f & JNODE_ESCAPE ) printf(" ESCAPE"); - if( f & JNODE_REMOVE ) printf(" REMOVE"); - if( f & JNODE_REPLACE ) printf(" REPLACE"); - if( f & JNODE_APPEND ) printf(" APPEND"); - if( f & JNODE_JSON5 ) printf(" JSON5"); + nn = n = jsonbPayloadSize(pParse, iStart, &sz); + if( nn==0 ) nn = 1; + if( sz>0 && xaBlob[iStart+i]); } + if( n==0 ){ + sqlite3_str_appendf(pOut, " ERROR invalid node size\n"); + iStart = n==0 ? iStart+1 : iEnd; + continue; + } + pParse->nBlob = savedNBlob; + if( iStart+n+sz>iEnd ){ + iEnd = iStart+n+sz; + if( iEnd>pParse->nBlob ){ + if( pParse->nBlobAlloc>0 && iEnd>pParse->nBlobAlloc ){ + iEnd = pParse->nBlobAlloc; + }else{ + iEnd = pParse->nBlob; + } + } + } + sqlite3_str_appendall(pOut," <-- "); + switch( x ){ + case JSONB_NULL: sqlite3_str_appendall(pOut,"null"); break; + case JSONB_TRUE: sqlite3_str_appendall(pOut,"true"); break; + case JSONB_FALSE: sqlite3_str_appendall(pOut,"false"); break; + case JSONB_INT: sqlite3_str_appendall(pOut,"int"); break; + case JSONB_INT5: sqlite3_str_appendall(pOut,"int5"); break; + case JSONB_FLOAT: sqlite3_str_appendall(pOut,"float"); break; + case JSONB_FLOAT5: sqlite3_str_appendall(pOut,"float5"); break; + case JSONB_TEXT: sqlite3_str_appendall(pOut,"text"); break; + case JSONB_TEXTJ: sqlite3_str_appendall(pOut,"textj"); break; + case JSONB_TEXT5: sqlite3_str_appendall(pOut,"text5"); break; + case JSONB_TEXTRAW: sqlite3_str_appendall(pOut,"textraw"); break; + case JSONB_ARRAY: { + sqlite3_str_appendf(pOut,"array, %u bytes\n", sz); + jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); + showContent = 0; + break; + } + case JSONB_OBJECT: { + sqlite3_str_appendf(pOut, "object, %u bytes\n", sz); + jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); + showContent = 0; + break; + } + default: { + sqlite3_str_appendall(pOut, "ERROR: unknown node type\n"); + showContent = 0; + break; + } + } + if( showContent ){ + if( sz==0 && x<=JSONB_FALSE ){ + sqlite3_str_append(pOut, "\n", 1); + }else{ + u32 i; + sqlite3_str_appendall(pOut, ": \""); + for(i=iStart+n; iaBlob[i]; + if( c<0x20 || c>=0x7f ) c = '.'; + sqlite3_str_append(pOut, (char*)&c, 1); + } + sqlite3_str_append(pOut, "\"\n", 2); + } + } + iStart += n + sz; } } +static void jsonShowParse(JsonParse *pParse){ + sqlite3_str out; + char zBuf[1000]; + if( pParse==0 ){ + printf("NULL pointer\n"); + return; + }else{ + printf("nBlobAlloc = %u\n", pParse->nBlobAlloc); + printf("nBlob = %u\n", pParse->nBlob); + printf("delta = %d\n", pParse->delta); + if( pParse->nBlob==0 ) return; + printf("content (bytes 0..%u):\n", pParse->nBlob-1); + } + sqlite3StrAccumInit(&out, 0, zBuf, sizeof(zBuf), 1000000); + jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0, &out); + printf("%s", sqlite3_str_value(&out)); + sqlite3_str_reset(&out); +} #endif /* SQLITE_DEBUG */ - -#if 0 /* 1 for debugging. 0 normally. Requires -DSQLITE_DEBUG too */ -static void jsonDebugPrintParse(JsonParse *p){ - jsonDebugPrintNodeEntries(p->aNode, p->nNode); -} -static void jsonDebugPrintNode(JsonNode *pNode){ - jsonDebugPrintNodeEntries(pNode, jsonNodeSize(pNode)); -} -#else - /* The usual case */ -# define jsonDebugPrintNode(X) -# define jsonDebugPrintParse(X) -#endif - #ifdef SQLITE_DEBUG /* ** SQL function: json_parse(JSON) ** -** Parse JSON using jsonParseCached(). Then print a dump of that -** parse on standard output. Return the mimified JSON result, just -** like the json() function. +** Parse JSON using jsonParseFuncArg(). Return text that is a +** human-readable dump of the binary JSONB for the input parameter. */ static void jsonParseFunc( sqlite3_context *ctx, @@ -205018,38 +206670,19 @@ static void jsonParseFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ + sqlite3_str out; - assert( argc==1 ); - p = jsonParseCached(ctx, argv[0], ctx, 0); + assert( argc>=1 ); + sqlite3StrAccumInit(&out, 0, 0, 0, 1000000); + p = jsonParseFuncArg(ctx, argv[0], 0); if( p==0 ) return; - printf("nNode = %u\n", p->nNode); - printf("nAlloc = %u\n", p->nAlloc); - printf("nJson = %d\n", p->nJson); - printf("nAlt = %d\n", p->nAlt); - printf("nErr = %u\n", p->nErr); - printf("oom = %u\n", p->oom); - printf("hasNonstd = %u\n", p->hasNonstd); - printf("useMod = %u\n", p->useMod); - printf("hasMod = %u\n", p->hasMod); - printf("nJPRef = %u\n", p->nJPRef); - printf("iSubst = %u\n", p->iSubst); - printf("iHold = %u\n", p->iHold); - jsonDebugPrintNodeEntries(p->aNode, p->nNode); - jsonReturnJson(p, p->aNode, ctx, 1, 0); -} - -/* -** The json_test1(JSON) function return true (1) if the input is JSON -** text generated by another json function. It returns (0) if the input -** is not known to be JSON. -*/ -static void jsonTest1Func( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - UNUSED_PARAMETER(argc); - sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); + if( argc==1 ){ + jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out); + sqlite3_result_text64(ctx, out.zText, out.nChar, SQLITE_DYNAMIC, SQLITE_UTF8); + }else{ + jsonShowParse(p); + } + jsonParseFree(p); } #endif /* SQLITE_DEBUG */ @@ -205058,7 +206691,7 @@ static void jsonTest1Func( ****************************************************************************/ /* -** Implementation of the json_QUOTE(VALUE) function. Return a JSON value +** Implementation of the json_quote(VALUE) function. Return a JSON value ** corresponding to the SQL value input. Mostly this means putting ** double-quotes around strings and returning the unquoted string "null" ** when given a NULL input. @@ -205071,9 +206704,9 @@ static void jsonQuoteFunc( JsonString jx; UNUSED_PARAMETER(argc); - jsonInit(&jx, ctx); - jsonAppendValue(&jx, argv[0]); - jsonResult(&jx); + jsonStringInit(&jx, ctx); + jsonAppendSqlValue(&jx, argv[0]); + jsonReturnString(&jx, 0, 0); sqlite3_result_subtype(ctx, JSON_SUBTYPE); } @@ -205090,18 +206723,17 @@ static void jsonArrayFunc( int i; JsonString jx; - jsonInit(&jx, ctx); + jsonStringInit(&jx, ctx); jsonAppendChar(&jx, '['); for(i=0; inNode ); if( argc==2 ){ const char *zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(p, zPath, 0, ctx); - }else{ - pNode = p->aNode; - } - if( pNode==0 ){ - return; - } - if( pNode->eType==JSON_ARRAY ){ - while( 1 /*exit-by-break*/ ){ - i = 1; - while( i<=pNode->n ){ - if( (pNode[i].jnFlags & JNODE_REMOVE)==0 ) n++; - i += jsonNodeSize(&pNode[i]); - } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( p->useMod==0 ) break; - assert( pNode->eU==2 ); - pNode = &p->aNode[pNode->u.iAppend]; + if( zPath==0 ){ + jsonParseFree(p); + return; } + i = jsonLookupStep(p, 0, zPath[0]=='$' ? zPath+1 : "@", 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + /* no-op */ + }else if( i==JSON_LOOKUP_PATHERROR ){ + jsonBadPathError(ctx, zPath); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + eErr = 1; + i = 0; + } + }else{ + i = 0; } - sqlite3_result_int64(ctx, n); + if( (p->aBlob[i] & 0x0f)==JSONB_ARRAY ){ + cnt = jsonbArrayCount(p, i); + } + if( !eErr ) sqlite3_result_int64(ctx, cnt); + jsonParseFree(p); } -/* -** Bit values for the flags passed into jsonExtractFunc() or -** jsonSetFunc() via the user-data value. -*/ -#define JSON_JSON 0x01 /* Result is always JSON */ -#define JSON_SQL 0x02 /* Result is always SQL */ -#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ -#define JSON_ISSET 0x04 /* json_set(), not json_insert() */ +/* True if the string is all digits */ +static int jsonAllDigits(const char *z, int n){ + int i; + for(i=0; i and ->> operators accept abbreviated PATH arguments. This - ** is mostly for compatibility with PostgreSQL, but also for - ** convenience. - ** - ** NUMBER ==> $[NUMBER] // PG compatible - ** LABEL ==> $.LABEL // PG compatible - ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience - */ - jsonInit(&jx, ctx); - if( sqlite3Isdigit(zPath[0]) ){ - jsonAppendRawNZ(&jx, "$[", 2); - jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); - jsonAppendRawNZ(&jx, "]", 2); - }else{ - jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='[')); - jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); - jsonAppendChar(&jx, 0); - } - pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx); - jsonReset(&jx); - }else{ - pNode = jsonLookup(p, zPath, 0, ctx); - } - if( pNode ){ - if( flags & JSON_JSON ){ - jsonReturnJson(p, pNode, ctx, 0, 0); - }else{ - jsonReturn(p, pNode, ctx, 1); - } - } - }else{ - pNode = jsonLookup(p, zPath, 0, ctx); - if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx, 0); - } - }else{ - /* Two or more PATH arguments results in a JSON array with each - ** element of the array being the value selected by one of the PATHs */ - int i; - jsonInit(&jx, ctx); + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + jsonStringInit(&jx, ctx); + if( argc>2 ){ jsonAppendChar(&jx, '['); - for(i=1; inErr ) break; - jsonAppendSeparator(&jx); - if( pNode ){ - jsonRenderNode(p, pNode, &jx); + } + for(i=1; i and ->> operators accept abbreviated PATH arguments. This + ** is mostly for compatibility with PostgreSQL, but also for + ** convenience. + ** + ** NUMBER ==> $[NUMBER] // PG compatible + ** LABEL ==> $.LABEL // PG compatible + ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience + */ + jsonStringInit(&jx, ctx); + if( jsonAllDigits(zPath, nPath) ){ + jsonAppendRawNZ(&jx, "[", 1); + jsonAppendRaw(&jx, zPath, nPath); + jsonAppendRawNZ(&jx, "]", 2); + }else if( jsonAllAlphanum(zPath, nPath) ){ + jsonAppendRawNZ(&jx, ".", 1); + jsonAppendRaw(&jx, zPath, nPath); + }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){ + jsonAppendRaw(&jx, zPath, nPath); }else{ + jsonAppendRawNZ(&jx, ".\"", 2); + jsonAppendRaw(&jx, zPath, nPath); + jsonAppendRawNZ(&jx, "\"", 1); + } + jsonStringTerminate(&jx); + j = jsonLookupStep(p, 0, jx.zBuf, 0); + jsonStringReset(&jx); + }else{ + jsonBadPathError(ctx, zPath); + goto json_extract_error; + } + if( jnBlob ){ + if( argc==2 ){ + if( flags & JSON_JSON ){ + jsonStringInit(&jx, ctx); + jsonTranslateBlobToText(p, j, &jx); + jsonReturnString(&jx, 0, 0); + jsonStringReset(&jx); + assert( (flags & JSON_BLOB)==0 ); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + }else{ + jsonReturnFromBlob(p, j, ctx, 0); + if( (flags & (JSON_SQL|JSON_BLOB))==0 + && (p->aBlob[j]&0x0f)>=JSONB_ARRAY + ){ + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } + } + }else{ + jsonAppendSeparator(&jx); + jsonTranslateBlobToText(p, j, &jx); + } + }else if( j==JSON_LOOKUP_NOTFOUND ){ + if( argc==2 ){ + goto json_extract_error; /* Return NULL if not found */ + }else{ + jsonAppendSeparator(&jx); jsonAppendRawNZ(&jx, "null", 4); } + }else if( j==JSON_LOOKUP_ERROR ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + goto json_extract_error; + }else{ + jsonBadPathError(ctx, zPath); + goto json_extract_error; } - if( i==argc ){ - jsonAppendChar(&jx, ']'); - jsonResult(&jx); + } + if( argc>2 ){ + jsonAppendChar(&jx, ']'); + jsonReturnString(&jx, 0, 0); + if( (flags & JSON_BLOB)==0 ){ sqlite3_result_subtype(ctx, JSON_SUBTYPE); } - jsonReset(&jx); } +json_extract_error: + jsonStringReset(&jx); + jsonParseFree(p); + return; } -/* This is the RFC 7396 MergePatch algorithm. +/* +** Return codes for jsonMergePatch() */ -static JsonNode *jsonMergePatch( - JsonParse *pParse, /* The JSON parser that contains the TARGET */ - u32 iTarget, /* Node of the TARGET in pParse */ - JsonNode *pPatch /* The PATCH */ +#define JSON_MERGE_OK 0 /* Success */ +#define JSON_MERGE_BADTARGET 1 /* Malformed TARGET blob */ +#define JSON_MERGE_BADPATCH 2 /* Malformed PATCH blob */ +#define JSON_MERGE_OOM 3 /* Out-of-memory condition */ + +/* +** RFC-7396 MergePatch for two JSONB blobs. +** +** pTarget is the target. pPatch is the patch. The target is updated +** in place. The patch is read-only. +** +** The original RFC-7396 algorithm is this: +** +** define MergePatch(Target, Patch): +** if Patch is an Object: +** if Target is not an Object: +** Target = {} # Ignore the contents and set it to an empty Object +** for each Name/Value pair in Patch: +** if Value is null: +** if Name exists in Target: +** remove the Name/Value pair from Target +** else: +** Target[Name] = MergePatch(Target[Name], Value) +** return Target +** else: +** return Patch +** +** Here is an equivalent algorithm restructured to show the actual +** implementation: +** +** 01 define MergePatch(Target, Patch): +** 02 if Patch is not an Object: +** 03 return Patch +** 04 else: // if Patch is an Object +** 05 if Target is not an Object: +** 06 Target = {} +** 07 for each Name/Value pair in Patch: +** 08 if Name exists in Target: +** 09 if Value is null: +** 10 remove the Name/Value pair from Target +** 11 else +** 12 Target[name] = MergePatch(Target[Name], Value) +** 13 else if Value is not NULL: +** 14 if Value is not an Object: +** 15 Target[name] = Value +** 16 else: +** 17 Target[name] = MergePatch('{}',value) +** 18 return Target +** | +** ^---- Line numbers referenced in comments in the implementation +*/ +static int jsonMergePatch( + JsonParse *pTarget, /* The JSON parser that contains the TARGET */ + u32 iTarget, /* Index of TARGET in pTarget->aBlob[] */ + const JsonParse *pPatch, /* The PATCH */ + u32 iPatch /* Index of PATCH in pPatch->aBlob[] */ ){ - u32 i, j; - u32 iRoot; - JsonNode *pTarget; - if( pPatch->eType!=JSON_OBJECT ){ - return pPatch; + u8 x; /* Type of a single node */ + u32 n, sz=0; /* Return values from jsonbPayloadSize() */ + u32 iTCursor; /* Cursor position while scanning the target object */ + u32 iTStart; /* First label in the target object */ + u32 iTEndBE; /* Original first byte past end of target, before edit */ + u32 iTEnd; /* Current first byte past end of target */ + u8 eTLabel; /* Node type of the target label */ + u32 iTLabel = 0; /* Index of the label */ + u32 nTLabel = 0; /* Header size in bytes for the target label */ + u32 szTLabel = 0; /* Size of the target label payload */ + u32 iTValue = 0; /* Index of the target value */ + u32 nTValue = 0; /* Header size of the target value */ + u32 szTValue = 0; /* Payload size for the target value */ + + u32 iPCursor; /* Cursor position while scanning the patch */ + u32 iPEnd; /* First byte past the end of the patch */ + u8 ePLabel; /* Node type of the patch label */ + u32 iPLabel; /* Start of patch label */ + u32 nPLabel; /* Size of header on the patch label */ + u32 szPLabel; /* Payload size of the patch label */ + u32 iPValue; /* Start of patch value */ + u32 nPValue; /* Header size for the patch value */ + u32 szPValue; /* Payload size of the patch value */ + + assert( iTarget>=0 && iTargetnBlob ); + assert( iPatch>=0 && iPatchnBlob ); + x = pPatch->aBlob[iPatch] & 0x0f; + if( x!=JSONB_OBJECT ){ /* Algorithm line 02 */ + u32 szPatch; /* Total size of the patch, header+payload */ + u32 szTarget; /* Total size of the target, header+payload */ + n = jsonbPayloadSize(pPatch, iPatch, &sz); + szPatch = n+sz; + sz = 0; + n = jsonbPayloadSize(pTarget, iTarget, &sz); + szTarget = n+sz; + jsonBlobEdit(pTarget, iTarget, szTarget, pPatch->aBlob+iPatch, szPatch); + return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; /* Line 03 */ } - assert( iTargetnNode ); - pTarget = &pParse->aNode[iTarget]; - assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); - if( pTarget->eType!=JSON_OBJECT ){ - jsonRemoveAllNulls(pPatch); - return pPatch; + x = pTarget->aBlob[iTarget] & 0x0f; + if( x!=JSONB_OBJECT ){ /* Algorithm line 05 */ + n = jsonbPayloadSize(pTarget, iTarget, &sz); + jsonBlobEdit(pTarget, iTarget+n, sz, 0, 0); + x = pTarget->aBlob[iTarget]; + pTarget->aBlob[iTarget] = (x & 0xf0) | JSONB_OBJECT; } - iRoot = iTarget; - for(i=1; in; i += jsonNodeSize(&pPatch[i+1])+1){ - u32 nKey; - const char *zKey; - assert( pPatch[i].eType==JSON_STRING ); - assert( pPatch[i].jnFlags & JNODE_LABEL ); - assert( pPatch[i].eU==1 ); - nKey = pPatch[i].n; - zKey = pPatch[i].u.zJContent; - for(j=1; jn; j += jsonNodeSize(&pTarget[j+1])+1 ){ - assert( pTarget[j].eType==JSON_STRING ); - assert( pTarget[j].jnFlags & JNODE_LABEL ); - if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){ - if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ) break; - if( pPatch[i+1].eType==JSON_NULL ){ - pTarget[j+1].jnFlags |= JNODE_REMOVE; - }else{ - JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); - if( pNew==0 ) return 0; - if( pNew!=&pParse->aNode[iTarget+j+1] ){ - jsonParseAddSubstNode(pParse, iTarget+j+1); - jsonParseAddNodeArray(pParse, pNew, jsonNodeSize(pNew)); - } - pTarget = &pParse->aNode[iTarget]; - } - break; + n = jsonbPayloadSize(pPatch, iPatch, &sz); + if( NEVER(n==0) ) return JSON_MERGE_BADPATCH; + iPCursor = iPatch+n; + iPEnd = iPCursor+sz; + n = jsonbPayloadSize(pTarget, iTarget, &sz); + if( NEVER(n==0) ) return JSON_MERGE_BADTARGET; + iTStart = iTarget+n; + iTEndBE = iTStart+sz; + + while( iPCursoraBlob[iPCursor] & 0x0f; + if( ePLabelJSONB_TEXTRAW ){ + return JSON_MERGE_BADPATCH; + } + nPLabel = jsonbPayloadSize(pPatch, iPCursor, &szPLabel); + if( nPLabel==0 ) return JSON_MERGE_BADPATCH; + iPValue = iPCursor + nPLabel + szPLabel; + if( iPValue>=iPEnd ) return JSON_MERGE_BADPATCH; + nPValue = jsonbPayloadSize(pPatch, iPValue, &szPValue); + if( nPValue==0 ) return JSON_MERGE_BADPATCH; + iPCursor = iPValue + nPValue + szPValue; + if( iPCursor>iPEnd ) return JSON_MERGE_BADPATCH; + + iTCursor = iTStart; + iTEnd = iTEndBE + pTarget->delta; + while( iTCursoraBlob[iTCursor] & 0x0f; + if( eTLabelJSONB_TEXTRAW ){ + return JSON_MERGE_BADTARGET; + } + nTLabel = jsonbPayloadSize(pTarget, iTCursor, &szTLabel); + if( nTLabel==0 ) return JSON_MERGE_BADTARGET; + iTValue = iTLabel + nTLabel + szTLabel; + if( iTValue>=iTEnd ) return JSON_MERGE_BADTARGET; + nTValue = jsonbPayloadSize(pTarget, iTValue, &szTValue); + if( nTValue==0 ) return JSON_MERGE_BADTARGET; + if( iTValue + nTValue + szTValue > iTEnd ) return JSON_MERGE_BADTARGET; + isEqual = jsonLabelCompare( + (const char*)&pPatch->aBlob[iPLabel+nPLabel], + szPLabel, + (ePLabel==JSONB_TEXT || ePLabel==JSONB_TEXTRAW), + (const char*)&pTarget->aBlob[iTLabel+nTLabel], + szTLabel, + (eTLabel==JSONB_TEXT || eTLabel==JSONB_TEXTRAW)); + if( isEqual ) break; + iTCursor = iTValue + nTValue + szTValue; + } + x = pPatch->aBlob[iPValue] & 0x0f; + if( iTCursoroom) ) return JSON_MERGE_OOM; + }else{ + /* Algorithm line 12 */ + int rc, savedDelta = pTarget->delta; + pTarget->delta = 0; + rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue); + if( rc ) return rc; + pTarget->delta += savedDelta; + } + }else if( x>0 ){ /* Algorithm line 13 */ + /* No match and patch value is not NULL */ + u32 szNew = szPLabel+nPLabel; + if( (pPatch->aBlob[iPValue] & 0x0f)!=JSONB_OBJECT ){ /* Line 14 */ + jsonBlobEdit(pTarget, iTEnd, 0, 0, szPValue+nPValue+szNew); + if( pTarget->oom ) return JSON_MERGE_OOM; + memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); + memcpy(&pTarget->aBlob[iTEnd+szNew], + &pPatch->aBlob[iPValue], szPValue+nPValue); + }else{ + int rc, savedDelta; + jsonBlobEdit(pTarget, iTEnd, 0, 0, szNew+1); + if( pTarget->oom ) return JSON_MERGE_OOM; + memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); + pTarget->aBlob[iTEnd+szNew] = 0x00; + savedDelta = pTarget->delta; + pTarget->delta = 0; + rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue); + if( rc ) return rc; + pTarget->delta += savedDelta; } } - if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ - int iStart; - JsonNode *pApnd; - u32 nApnd; - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); - jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); - pApnd = &pPatch[i+1]; - if( pApnd->eType==JSON_OBJECT ) jsonRemoveAllNulls(pApnd); - nApnd = jsonNodeSize(pApnd); - jsonParseAddNodeArray(pParse, pApnd, jsonNodeSize(pApnd)); - if( pParse->oom ) return 0; - pParse->aNode[iStart].n = 1+nApnd; - pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; - pParse->aNode[iRoot].u.iAppend = iStart; - VVA( pParse->aNode[iRoot].eU = 2 ); - iRoot = iStart; - pTarget = &pParse->aNode[iTarget]; - } } - return pTarget; + if( pTarget->delta ) jsonAfterEditSizeAdjust(pTarget, iTarget); + return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; } + /* ** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON ** object that is the result of running the RFC 7396 MergePatch() algorithm @@ -205336,28 +207131,27 @@ static void jsonPatchFunc( int argc, sqlite3_value **argv ){ - JsonParse *pX; /* The JSON that is being patched */ - JsonParse *pY; /* The patch */ - JsonNode *pResult; /* The result of the merge */ + JsonParse *pTarget; /* The TARGET */ + JsonParse *pPatch; /* The PATCH */ + int rc; /* Result code */ UNUSED_PARAMETER(argc); - pX = jsonParseCached(ctx, argv[0], ctx, 1); - if( pX==0 ) return; - assert( pX->hasMod==0 ); - pX->hasMod = 1; - pY = jsonParseCached(ctx, argv[1], ctx, 1); - if( pY==0 ) return; - pX->useMod = 1; - pY->useMod = 1; - pResult = jsonMergePatch(pX, 0, pY->aNode); - assert( pResult!=0 || pX->oom ); - if( pResult && pX->oom==0 ){ - jsonDebugPrintParse(pX); - jsonDebugPrintNode(pResult); - jsonReturnJson(pX, pResult, ctx, 0, 0); - }else{ - sqlite3_result_error_nomem(ctx); + assert( argc==2 ); + pTarget = jsonParseFuncArg(ctx, argv[0], JSON_EDITABLE); + if( pTarget==0 ) return; + pPatch = jsonParseFuncArg(ctx, argv[1], 0); + if( pPatch ){ + rc = jsonMergePatch(pTarget, 0, pPatch, 0); + if( rc==JSON_MERGE_OK ){ + jsonReturnParse(ctx, pTarget); + }else if( rc==JSON_MERGE_OOM ){ + sqlite3_result_error_nomem(ctx); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + jsonParseFree(pPatch); } + jsonParseFree(pTarget); } @@ -205381,23 +207175,23 @@ static void jsonObjectFunc( "of arguments", -1); return; } - jsonInit(&jx, ctx); + jsonStringInit(&jx, ctx); jsonAppendChar(&jx, '{'); for(i=0; i1); - if( pParse==0 ) return; - for(i=1; i<(u32)argc; i++){ + p = jsonParseFuncArg(ctx, argv[0], argc>1 ? JSON_EDITABLE : 0); + if( p==0 ) return; + for(i=1; inErr ) goto remove_done; - if( pNode ){ - pNode->jnFlags |= JNODE_REMOVE; - pParse->hasMod = 1; - pParse->useMod = 1; + if( zPath==0 ){ + goto json_remove_done; } - } - if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){ - jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); - } -remove_done: - jsonDebugPrintParse(p); -} - -/* -** Substitute the value at iNode with the pValue parameter. -*/ -static void jsonReplaceNode( - sqlite3_context *pCtx, - JsonParse *p, - int iNode, - sqlite3_value *pValue -){ - int idx = jsonParseAddSubstNode(p, iNode); - if( idx<=0 ){ - assert( p->oom ); - return; - } - switch( sqlite3_value_type(pValue) ){ - case SQLITE_NULL: { - jsonParseAddNode(p, JSON_NULL, 0, 0); - break; + if( zPath[0]!='$' ){ + goto json_remove_patherror; } - case SQLITE_FLOAT: { - char *z = sqlite3_mprintf("%!0.15g", sqlite3_value_double(pValue)); - int n; - if( z==0 ){ - p->oom = 1; - break; - } - n = sqlite3Strlen30(z); - jsonParseAddNode(p, JSON_REAL, n, z); - jsonParseAddCleanup(p, sqlite3_free, z); - break; + if( zPath[1]==0 ){ + /* json_remove(j,'$') returns NULL */ + goto json_remove_done; } - case SQLITE_INTEGER: { - char *z = sqlite3_mprintf("%lld", sqlite3_value_int64(pValue)); - int n; - if( z==0 ){ - p->oom = 1; - break; - } - n = sqlite3Strlen30(z); - jsonParseAddNode(p, JSON_INT, n, z); - jsonParseAddCleanup(p, sqlite3_free, z); - - break; - } - case SQLITE_TEXT: { - const char *z = (const char*)sqlite3_value_text(pValue); - u32 n = (u32)sqlite3_value_bytes(pValue); - if( z==0 ){ - p->oom = 1; - break; - } - if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){ - char *zCopy = sqlite3_malloc64( n+1 ); - int k; - if( zCopy ){ - memcpy(zCopy, z, n); - zCopy[n] = 0; - jsonParseAddCleanup(p, sqlite3_free, zCopy); - }else{ - p->oom = 1; - sqlite3_result_error_nomem(pCtx); - } - k = jsonParseAddNode(p, JSON_STRING, n, zCopy); - assert( k>0 || p->oom ); - if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW; + p->eEdit = JEDIT_DEL; + p->delta = 0; + rc = jsonLookupStep(p, 0, zPath+1, 0); + if( JSON_LOOKUP_ISERROR(rc) ){ + if( rc==JSON_LOOKUP_NOTFOUND ){ + continue; /* No-op */ + }else if( rc==JSON_LOOKUP_PATHERROR ){ + jsonBadPathError(ctx, zPath); }else{ - JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1); - if( pPatch==0 ){ - p->oom = 1; - break; - } - jsonParseAddNodeArray(p, pPatch->aNode, pPatch->nNode); - /* The nodes copied out of pPatch and into p likely contain - ** u.zJContent pointers into pPatch->zJson. So preserve the - ** content of pPatch until p is destroyed. */ - assert( pPatch->nJPRef>=1 ); - pPatch->nJPRef++; - jsonParseAddCleanup(p, (void(*)(void*))jsonParseFree, pPatch); + sqlite3_result_error(ctx, "malformed JSON", -1); } - break; - } - default: { - jsonParseAddNode(p, JSON_NULL, 0, 0); - sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1); - p->nErr++; - break; + goto json_remove_done; } } + jsonReturnParse(ctx, p); + jsonParseFree(p); + return; + +json_remove_patherror: + jsonBadPathError(ctx, zPath); + +json_remove_done: + jsonParseFree(p); + return; } /* @@ -205540,32 +207264,12 @@ static void jsonReplaceFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ - JsonNode *pNode; - const char *zPath; - u32 i; - if( argc<1 ) return; if( (argc&1)==0 ) { jsonWrongNumArgs(ctx, "replace"); return; } - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; - pParse->nJPRef++; - for(i=1; i<(u32)argc; i+=2){ - zPath = (const char*)sqlite3_value_text(argv[i]); - pParse->useMod = 1; - pNode = jsonLookup(pParse, zPath, 0, ctx); - if( pParse->nErr ) goto replace_err; - if( pNode ){ - jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); - } - } - jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); -replace_err: - jsonDebugPrintParse(pParse); - jsonParseFree(pParse); + jsonInsertIntoBlob(ctx, argc, argv, JEDIT_REPL); } @@ -205586,39 +207290,16 @@ static void jsonSetFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ - JsonNode *pNode; - const char *zPath; - u32 i; - int bApnd; - int bIsSet = sqlite3_user_data(ctx)!=0; + + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + int bIsSet = (flags&JSON_ISSET)!=0; if( argc<1 ) return; if( (argc&1)==0 ) { jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); return; } - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; - pParse->nJPRef++; - for(i=1; i<(u32)argc; i+=2){ - zPath = (const char*)sqlite3_value_text(argv[i]); - bApnd = 0; - pParse->useMod = 1; - pNode = jsonLookup(pParse, zPath, &bApnd, ctx); - if( pParse->oom ){ - sqlite3_result_error_nomem(ctx); - goto jsonSetDone; - }else if( pParse->nErr ){ - goto jsonSetDone; - }else if( pNode && (bApnd || bIsSet) ){ - jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); - } - } - jsonDebugPrintParse(pParse); - jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); -jsonSetDone: - jsonParseFree(pParse); + jsonInsertIntoBlob(ctx, argc, argv, bIsSet ? JEDIT_SET : JEDIT_INS); } /* @@ -205634,27 +207315,93 @@ static void jsonTypeFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ - const char *zPath; - JsonNode *pNode; + const char *zPath = 0; + u32 i; - p = jsonParseCached(ctx, argv[0], ctx, 0); + p = jsonParseFuncArg(ctx, argv[0], 0); if( p==0 ) return; if( argc==2 ){ zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(p, zPath, 0, ctx); + if( zPath==0 ) goto json_type_done; + if( zPath[0]!='$' ){ + jsonBadPathError(ctx, zPath); + goto json_type_done; + } + i = jsonLookupStep(p, 0, zPath+1, 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + /* no-op */ + }else if( i==JSON_LOOKUP_PATHERROR ){ + jsonBadPathError(ctx, zPath); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + goto json_type_done; + } }else{ - pNode = p->aNode; - } - if( pNode ){ - sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); + i = 0; } + sqlite3_result_text(ctx, jsonbType[p->aBlob[i]&0x0f], -1, SQLITE_STATIC); +json_type_done: + jsonParseFree(p); } /* ** json_valid(JSON) +** json_valid(JSON, FLAGS) ** -** Return 1 if JSON is a well-formed canonical JSON string according -** to RFC-7159. Return 0 otherwise. +** Check the JSON argument to see if it is well-formed. The FLAGS argument +** encodes the various constraints on what is meant by "well-formed": +** +** 0x01 Canonical RFC-8259 JSON text +** 0x02 JSON text with optional JSON-5 extensions +** 0x04 Superficially appears to be JSONB +** 0x08 Strictly well-formed JSONB +** +** If the FLAGS argument is omitted, it defaults to 1. Useful values for +** FLAGS include: +** +** 1 Strict canonical JSON text +** 2 JSON text perhaps with JSON-5 extensions +** 4 Superficially appears to be JSONB +** 5 Canonical JSON text or superficial JSONB +** 6 JSON-5 text or superficial JSONB +** 8 Strict JSONB +** 9 Canonical JSON text or strict JSONB +** 10 JSON-5 text or strict JSONB +** +** Other flag combinations are redundant. For example, every canonical +** JSON text is also well-formed JSON-5 text, so FLAG values 2 and 3 +** are the same. Similarly, any input that passes a strict JSONB validation +** will also pass the superficial validation so 12 through 15 are the same +** as 8 through 11 respectively. +** +** This routine runs in linear time to validate text and when doing strict +** JSONB validation. Superficial JSONB validation is constant time, +** assuming the BLOB is already in memory. The performance advantage +** of superficial JSONB validation is why that option is provided. +** Application developers can choose to do fast superficial validation or +** slower strict validation, according to their specific needs. +** +** Only the lower four bits of the FLAGS argument are currently used. +** Higher bits are reserved for future expansion. To facilitate +** compatibility, the current implementation raises an error if any bit +** in FLAGS is set other than the lower four bits. +** +** The original circa 2015 implementation of the JSON routines in +** SQLite only supported canonical RFC-8259 JSON text and the json_valid() +** function only accepted one argument. That is why the default value +** for the FLAGS argument is 1, since FLAGS=1 causes this routine to only +** recognize canonical RFC-8259 JSON text as valid. The extra FLAGS +** argument was added when the JSON routines were extended to support +** JSON5-like extensions and binary JSONB stored in BLOBs. +** +** Return Values: +** +** * Raise an error if FLAGS is outside the range of 1 to 15. +** * Return NULL if the input is NULL +** * Return 1 if the input is well-formed. +** * Return 0 if the input is not well-formed. */ static void jsonValidFunc( sqlite3_context *ctx, @@ -205662,79 +207409,125 @@ static void jsonValidFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ - UNUSED_PARAMETER(argc); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + u8 flags = 1; + u8 res = 0; + if( argc==2 ){ + i64 f = sqlite3_value_int64(argv[1]); + if( f<1 || f>15 ){ + sqlite3_result_error(ctx, "FLAGS parameter to json_valid() must be" + " between 1 and 15", -1); + return; + } + flags = f & 0x0f; + } + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_NULL: { #ifdef SQLITE_LEGACY_JSON_VALID - /* Incorrect legacy behavior was to return FALSE for a NULL input */ - sqlite3_result_int(ctx, 0); + /* Incorrect legacy behavior was to return FALSE for a NULL input */ + sqlite3_result_int(ctx, 0); #endif - return; - } - p = jsonParseCached(ctx, argv[0], 0, 0); - if( p==0 || p->oom ){ - sqlite3_result_error_nomem(ctx); - sqlite3_free(p); - }else{ - sqlite3_result_int(ctx, p->nErr==0 && (p->hasNonstd==0 || p->useMod)); - if( p->nErr ) jsonParseFree(p); + return; + } + case SQLITE_BLOB: { + if( (flags & 0x0c)!=0 && jsonFuncArgMightBeBinary(argv[0]) ){ + if( flags & 0x04 ){ + /* Superficial checking only - accomplished by the + ** jsonFuncArgMightBeBinary() call above. */ + res = 1; + }else{ + /* Strict checking. Check by translating BLOB->TEXT->BLOB. If + ** no errors occur, call that a "strict check". */ + JsonParse px; + u32 iErr; + memset(&px, 0, sizeof(px)); + px.aBlob = (u8*)sqlite3_value_blob(argv[0]); + px.nBlob = sqlite3_value_bytes(argv[0]); + iErr = jsonbValidityCheck(&px, 0, px.nBlob, 1); + res = iErr==0; + } + } + break; + } + default: { + JsonParse px; + if( (flags & 0x3)==0 ) break; + memset(&px, 0, sizeof(px)); + + p = jsonParseFuncArg(ctx, argv[0], JSON_KEEPERROR); + if( p ){ + if( p->oom ){ + sqlite3_result_error_nomem(ctx); + }else if( p->nErr ){ + /* no-op */ + }else if( (flags & 0x02)!=0 || p->hasNonstd==0 ){ + res = 1; + } + jsonParseFree(p); + }else{ + sqlite3_result_error_nomem(ctx); + } + break; + } } + sqlite3_result_int(ctx, res); } /* ** json_error_position(JSON) ** -** If the argument is not an interpretable JSON string, then return the 1-based -** character position at which the parser first recognized that the input -** was in error. The left-most character is 1. If the string is valid -** JSON, then return 0. +** If the argument is NULL, return NULL ** -** Note that json_valid() is only true for strictly conforming canonical JSON. -** But this routine returns zero if the input contains extension. Thus: +** If the argument is BLOB, do a full validity check and return non-zero +** if the check fails. The return value is the approximate 1-based offset +** to the byte of the element that contains the first error. ** -** (1) If the input X is strictly conforming canonical JSON: -** -** json_valid(X) returns true -** json_error_position(X) returns 0 -** -** (2) If the input X is JSON but it includes extension (such as JSON5) that -** are not part of RFC-8259: -** -** json_valid(X) returns false -** json_error_position(X) return 0 -** -** (3) If the input X cannot be interpreted as JSON even taking extensions -** into account: -** -** json_valid(X) return false -** json_error_position(X) returns 1 or more +** Otherwise interpret the argument is TEXT (even if it is numeric) and +** return the 1-based character position for where the parser first recognized +** that the input was not valid JSON, or return 0 if the input text looks +** ok. JSON-5 extensions are accepted. */ static void jsonErrorFunc( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ - JsonParse *p; /* The parse */ + i64 iErrPos = 0; /* Error position to be returned */ + JsonParse s; + + assert( argc==1 ); UNUSED_PARAMETER(argc); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - p = jsonParseCached(ctx, argv[0], 0, 0); - if( p==0 || p->oom ){ - sqlite3_result_error_nomem(ctx); - sqlite3_free(p); - }else if( p->nErr==0 ){ - sqlite3_result_int(ctx, 0); + memset(&s, 0, sizeof(s)); + s.db = sqlite3_context_db_handle(ctx); + if( jsonFuncArgMightBeBinary(argv[0]) ){ + s.aBlob = (u8*)sqlite3_value_blob(argv[0]); + s.nBlob = sqlite3_value_bytes(argv[0]); + iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1); }else{ - int n = 1; - u32 i; - const char *z = (const char*)sqlite3_value_text(argv[0]); - for(i=0; iiErr && ALWAYS(z[i]); i++){ - if( (z[i]&0xc0)!=0x80 ) n++; + s.zJson = (char*)sqlite3_value_text(argv[0]); + if( s.zJson==0 ) return; /* NULL input or OOM */ + s.nJson = sqlite3_value_bytes(argv[0]); + if( jsonConvertTextToBlob(&s,0) ){ + if( s.oom ){ + iErrPos = -1; + }else{ + /* Convert byte-offset s.iErr into a character offset */ + u32 k; + assert( s.zJson!=0 ); /* Because s.oom is false */ + for(k=0; kzBuf==0 ){ - jsonInit(pStr, ctx); + jsonStringInit(pStr, ctx); jsonAppendChar(pStr, '['); }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); } pStr->pCtx = ctx; - jsonAppendValue(pStr, argv[0]); + jsonAppendSqlValue(pStr, argv[0]); } } static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ + int flags; pStr->pCtx = ctx; jsonAppendChar(pStr, ']'); - if( pStr->bErr ){ - if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); - assert( pStr->bStatic ); + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + }else if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(pStr); + if( isFinal ){ + if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); + }else{ + pStr->nUsed--; + } + return; }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : @@ -205859,27 +207662,38 @@ static void jsonObjectStep( pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ - jsonInit(pStr, ctx); + jsonStringInit(pStr, ctx); jsonAppendChar(pStr, '{'); }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); } pStr->pCtx = ctx; z = (const char*)sqlite3_value_text(argv[0]); - n = (u32)sqlite3_value_bytes(argv[0]); + n = sqlite3Strlen30(z); jsonAppendString(pStr, z, n); jsonAppendChar(pStr, ':'); - jsonAppendValue(pStr, argv[1]); + jsonAppendSqlValue(pStr, argv[1]); } } static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ + int flags; jsonAppendChar(pStr, '}'); - if( pStr->bErr ){ - if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); - assert( pStr->bStatic ); + pStr->pCtx = ctx; + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + }else if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(pStr); + if( isFinal ){ + if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); + }else{ + pStr->nUsed--; + } + return; }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : @@ -205907,19 +207721,37 @@ static void jsonObjectFinal(sqlite3_context *ctx){ /**************************************************************************** ** The json_each virtual table ****************************************************************************/ +typedef struct JsonParent JsonParent; +struct JsonParent { + u32 iHead; /* Start of object or array */ + u32 iValue; /* Start of the value */ + u32 iEnd; /* First byte past the end */ + u32 nPath; /* Length of path */ + i64 iKey; /* Key for JSONB_ARRAY */ +}; + typedef struct JsonEachCursor JsonEachCursor; struct JsonEachCursor { sqlite3_vtab_cursor base; /* Base class - must be first */ u32 iRowid; /* The rowid */ - u32 iBegin; /* The first node of the scan */ - u32 i; /* Index in sParse.aNode[] of current row */ + u32 i; /* Index in sParse.aBlob[] of current row */ u32 iEnd; /* EOF when i equals or exceeds this value */ - u8 eType; /* Type of top-level element */ + u32 nRoot; /* Size of the root path in bytes */ + u8 eType; /* Type of the container for element i */ u8 bRecursive; /* True for json_tree(). False for json_each() */ - char *zJson; /* Input JSON */ - char *zRoot; /* Path by which to filter zJson */ + u32 nParent; /* Current nesting depth */ + u32 nParentAlloc; /* Space allocated for aParent[] */ + JsonParent *aParent; /* Parent elements of i */ + sqlite3 *db; /* Database connection */ + JsonString path; /* Current path */ JsonParse sParse; /* Parse of the input JSON */ }; +typedef struct JsonEachConnection JsonEachConnection; +struct JsonEachConnection { + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection */ +}; + /* Constructor for the json_each virtual table */ static int jsonEachConnect( @@ -205929,7 +207761,7 @@ static int jsonEachConnect( sqlite3_vtab **ppVtab, char **pzErr ){ - sqlite3_vtab *pNew; + JsonEachConnection *pNew; int rc; /* Column numbers */ @@ -205955,28 +207787,32 @@ static int jsonEachConnect( "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," "json HIDDEN,root HIDDEN)"); if( rc==SQLITE_OK ){ - pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew)); + *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) return SQLITE_NOMEM; - memset(pNew, 0, sizeof(*pNew)); sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + pNew->db = db; } return rc; } /* destructor for json_each virtual table */ static int jsonEachDisconnect(sqlite3_vtab *pVtab){ - sqlite3_free(pVtab); + JsonEachConnection *p = (JsonEachConnection*)pVtab; + sqlite3DbFree(p->db, pVtab); return SQLITE_OK; } /* constructor for a JsonEachCursor object for json_each(). */ static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + JsonEachConnection *pVtab = (JsonEachConnection*)p; JsonEachCursor *pCur; UNUSED_PARAMETER(p); - pCur = sqlite3_malloc( sizeof(*pCur) ); + pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur)); if( pCur==0 ) return SQLITE_NOMEM; - memset(pCur, 0, sizeof(*pCur)); + pCur->db = pVtab->db; + jsonStringZero(&pCur->path); *ppCursor = &pCur->base; return SQLITE_OK; } @@ -205994,21 +207830,24 @@ static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ /* Reset a JsonEachCursor back to its original state. Free any memory ** held. */ static void jsonEachCursorReset(JsonEachCursor *p){ - sqlite3_free(p->zRoot); jsonParseReset(&p->sParse); + jsonStringReset(&p->path); + sqlite3DbFree(p->db, p->aParent); p->iRowid = 0; p->i = 0; + p->aParent = 0; + p->nParent = 0; + p->nParentAlloc = 0; p->iEnd = 0; p->eType = 0; - p->zJson = 0; - p->zRoot = 0; } /* Destructor for a jsonEachCursor object */ static int jsonEachClose(sqlite3_vtab_cursor *cur){ JsonEachCursor *p = (JsonEachCursor*)cur; jsonEachCursorReset(p); - sqlite3_free(cur); + + sqlite3DbFree(p->db, cur); return SQLITE_OK; } @@ -206019,200 +207858,230 @@ static int jsonEachEof(sqlite3_vtab_cursor *cur){ return p->i >= p->iEnd; } -/* Advance the cursor to the next element for json_tree() */ -static int jsonEachNext(sqlite3_vtab_cursor *cur){ - JsonEachCursor *p = (JsonEachCursor*)cur; - if( p->bRecursive ){ - if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++; - p->i++; - p->iRowid++; - if( p->iiEnd ){ - u32 iUp = p->sParse.aUp[p->i]; - JsonNode *pUp = &p->sParse.aNode[iUp]; - p->eType = pUp->eType; - if( pUp->eType==JSON_ARRAY ){ - assert( pUp->eU==0 || pUp->eU==3 ); - testcase( pUp->eU==3 ); - VVA( pUp->eU = 3 ); - if( iUp==p->i-1 ){ - pUp->u.iKey = 0; - }else{ - pUp->u.iKey++; +/* +** If the cursor is currently pointing at the label of a object entry, +** then return the index of the value. For all other cases, return the +** current pointer position, which is the value. +*/ +static int jsonSkipLabel(JsonEachCursor *p){ + if( p->eType==JSONB_OBJECT ){ + u32 sz = 0; + u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz); + return p->i + n + sz; + }else{ + return p->i; + } +} + +/* +** Append the path name for the current element. +*/ +static void jsonAppendPathName(JsonEachCursor *p){ + assert( p->nParent>0 ); + assert( p->eType==JSONB_ARRAY || p->eType==JSONB_OBJECT ); + if( p->eType==JSONB_ARRAY ){ + jsonPrintf(30, &p->path, "[%lld]", p->aParent[p->nParent-1].iKey); + }else{ + u32 n, sz = 0, k, i; + const char *z; + int needQuote = 0; + n = jsonbPayloadSize(&p->sParse, p->i, &sz); + k = p->i + n; + z = (const char*)&p->sParse.aBlob[k]; + if( sz==0 || !sqlite3Isalpha(z[0]) ){ + needQuote = 1; + }else{ + for(i=0; ipath,".\"%.*s\"", sz, z); + }else{ + jsonPrintf(sz+2,&p->path,".%.*s", sz, z); + } + } +} + +/* Advance the cursor to the next element for json_tree() */ +static int jsonEachNext(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + int rc = SQLITE_OK; + if( p->bRecursive ){ + u8 x; + u8 levelChange = 0; + u32 n, sz = 0; + u32 i = jsonSkipLabel(p); + x = p->sParse.aBlob[i] & 0x0f; + n = jsonbPayloadSize(&p->sParse, i, &sz); + if( x==JSONB_OBJECT || x==JSONB_ARRAY ){ + JsonParent *pParent; + if( p->nParent>=p->nParentAlloc ){ + JsonParent *pNew; + u64 nNew; + nNew = p->nParentAlloc*2 + 3; + pNew = sqlite3DbRealloc(p->db, p->aParent, sizeof(JsonParent)*nNew); + if( pNew==0 ) return SQLITE_NOMEM; + p->nParentAlloc = (u32)nNew; + p->aParent = pNew; + } + levelChange = 1; + pParent = &p->aParent[p->nParent]; + pParent->iHead = p->i; + pParent->iValue = i; + pParent->iEnd = i + n + sz; + pParent->iKey = -1; + pParent->nPath = (u32)p->path.nUsed; + if( p->eType && p->nParent ){ + jsonAppendPathName(p); + if( p->path.eErr ) rc = SQLITE_NOMEM; + } + p->nParent++; + p->i = i + n; + }else{ + p->i = i + n + sz; + } + while( p->nParent>0 && p->i >= p->aParent[p->nParent-1].iEnd ){ + p->nParent--; + p->path.nUsed = p->aParent[p->nParent].nPath; + levelChange = 1; + } + if( levelChange ){ + if( p->nParent>0 ){ + JsonParent *pParent = &p->aParent[p->nParent-1]; + u32 iVal = pParent->iValue; + p->eType = p->sParse.aBlob[iVal] & 0x0f; + }else{ + p->eType = 0; + } + } }else{ - switch( p->eType ){ - case JSON_ARRAY: { - p->i += jsonNodeSize(&p->sParse.aNode[p->i]); - p->iRowid++; - break; - } - case JSON_OBJECT: { - p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]); - p->iRowid++; - break; - } - default: { - p->i = p->iEnd; - break; + u32 n, sz = 0; + u32 i = jsonSkipLabel(p); + n = jsonbPayloadSize(&p->sParse, i, &sz); + p->i = i + n + sz; + } + if( p->eType==JSONB_ARRAY && p->nParent ){ + p->aParent[p->nParent-1].iKey++; + } + p->iRowid++; + return rc; +} + +/* Length of the path for rowid==0 in bRecursive mode. +*/ +static int jsonEachPathLength(JsonEachCursor *p){ + u32 n = p->path.nUsed; + char *z = p->path.zBuf; + if( p->iRowid==0 && p->bRecursive && n>=2 ){ + while( n>1 ){ + n--; + if( z[n]=='[' || z[n]=='.' ){ + u32 x, sz = 0; + char cSaved = z[n]; + z[n] = 0; + assert( p->sParse.eEdit==0 ); + x = jsonLookupStep(&p->sParse, 0, z+1, 0); + z[n] = cSaved; + if( JSON_LOOKUP_ISERROR(x) ) continue; + if( x + jsonbPayloadSize(&p->sParse, x, &sz) == p->i ) break; } } } - return SQLITE_OK; -} - -/* Append an object label to the JSON Path being constructed -** in pStr. -*/ -static void jsonAppendObjectPathElement( - JsonString *pStr, - JsonNode *pNode -){ - int jj, nn; - const char *z; - assert( pNode->eType==JSON_STRING ); - assert( pNode->jnFlags & JNODE_LABEL ); - assert( pNode->eU==1 ); - z = pNode->u.zJContent; - nn = pNode->n; - if( (pNode->jnFlags & JNODE_RAW)==0 ){ - assert( nn>=2 ); - assert( z[0]=='"' || z[0]=='\'' ); - assert( z[nn-1]=='"' || z[0]=='\'' ); - if( nn>2 && sqlite3Isalpha(z[1]) ){ - for(jj=2; jjsParse.aUp[i]; - jsonEachComputePath(p, pStr, iUp); - pNode = &p->sParse.aNode[i]; - pUp = &p->sParse.aNode[iUp]; - if( pUp->eType==JSON_ARRAY ){ - assert( pUp->eU==3 || (pUp->eU==0 && pUp->u.iKey==0) ); - testcase( pUp->eU==0 ); - jsonPrintf(30, pStr, "[%d]", pUp->u.iKey); - }else{ - assert( pUp->eType==JSON_OBJECT ); - if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; - jsonAppendObjectPathElement(pStr, pNode); - } + return n; } /* Return the value of a column */ static int jsonEachColumn( sqlite3_vtab_cursor *cur, /* The cursor */ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ - int i /* Which column to return */ + int iColumn /* Which column to return */ ){ JsonEachCursor *p = (JsonEachCursor*)cur; - JsonNode *pThis = &p->sParse.aNode[p->i]; - switch( i ){ + switch( iColumn ){ case JEACH_KEY: { - if( p->i==0 ) break; - if( p->eType==JSON_OBJECT ){ - jsonReturn(&p->sParse, pThis, ctx, 0); - }else if( p->eType==JSON_ARRAY ){ - u32 iKey; - if( p->bRecursive ){ - if( p->iRowid==0 ) break; - assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 ); - iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey; + if( p->nParent==0 ){ + u32 n, j; + if( p->nRoot==1 ) break; + j = jsonEachPathLength(p); + n = p->nRoot - j; + if( n==0 ){ + break; + }else if( p->path.zBuf[j]=='[' ){ + i64 x; + sqlite3Atoi64(&p->path.zBuf[j+1], &x, n-1, SQLITE_UTF8); + sqlite3_result_int64(ctx, x); + }else if( p->path.zBuf[j+1]=='"' ){ + sqlite3_result_text(ctx, &p->path.zBuf[j+2], n-3, SQLITE_TRANSIENT); }else{ - iKey = p->iRowid; + sqlite3_result_text(ctx, &p->path.zBuf[j+1], n-1, SQLITE_TRANSIENT); } - sqlite3_result_int64(ctx, (sqlite3_int64)iKey); + break; + } + if( p->eType==JSONB_OBJECT ){ + jsonReturnFromBlob(&p->sParse, p->i, ctx, 1); + }else{ + assert( p->eType==JSONB_ARRAY ); + sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey); } break; } case JEACH_VALUE: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - jsonReturn(&p->sParse, pThis, ctx, 0); + u32 i = jsonSkipLabel(p); + jsonReturnFromBlob(&p->sParse, i, ctx, 1); break; } case JEACH_TYPE: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); + u32 i = jsonSkipLabel(p); + u8 eType = p->sParse.aBlob[i] & 0x0f; + sqlite3_result_text(ctx, jsonbType[eType], -1, SQLITE_STATIC); break; } case JEACH_ATOM: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - if( pThis->eType>=JSON_ARRAY ) break; - jsonReturn(&p->sParse, pThis, ctx, 0); + u32 i = jsonSkipLabel(p); + if( (p->sParse.aBlob[i] & 0x0f)sParse, i, ctx, 1); + } break; } case JEACH_ID: { - sqlite3_result_int64(ctx, - (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); + sqlite3_result_int64(ctx, (sqlite3_int64)p->i); break; } case JEACH_PARENT: { - if( p->i>p->iBegin && p->bRecursive ){ - sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]); + if( p->nParent>0 && p->bRecursive ){ + sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iHead); } break; } case JEACH_FULLKEY: { - JsonString x; - jsonInit(&x, ctx); - if( p->bRecursive ){ - jsonEachComputePath(p, &x, p->i); - }else{ - if( p->zRoot ){ - jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); - }else{ - jsonAppendChar(&x, '$'); - } - if( p->eType==JSON_ARRAY ){ - jsonPrintf(30, &x, "[%d]", p->iRowid); - }else if( p->eType==JSON_OBJECT ){ - jsonAppendObjectPathElement(&x, pThis); - } - } - jsonResult(&x); + u64 nBase = p->path.nUsed; + if( p->nParent ) jsonAppendPathName(p); + sqlite3_result_text64(ctx, p->path.zBuf, p->path.nUsed, + SQLITE_TRANSIENT, SQLITE_UTF8); + p->path.nUsed = nBase; break; } case JEACH_PATH: { - if( p->bRecursive ){ - JsonString x; - jsonInit(&x, ctx); - jsonEachComputePath(p, &x, p->sParse.aUp[p->i]); - jsonResult(&x); - break; - } - /* For json_each() path and root are the same so fall through - ** into the root case */ - /* no break */ deliberate_fall_through + u32 n = jsonEachPathLength(p); + sqlite3_result_text64(ctx, p->path.zBuf, n, + SQLITE_TRANSIENT, SQLITE_UTF8); + break; } default: { - const char *zRoot = p->zRoot; - if( zRoot==0 ) zRoot = "$"; - sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); + sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_STATIC); break; } case JEACH_JSON: { - assert( i==JEACH_JSON ); - sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); + if( p->sParse.zJson==0 ){ + sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob, + SQLITE_STATIC); + }else{ + sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); + } break; } } @@ -206303,86 +208172,101 @@ static int jsonEachFilter( int argc, sqlite3_value **argv ){ JsonEachCursor *p = (JsonEachCursor*)cur; - const char *z; const char *zRoot = 0; - sqlite3_int64 n; + u32 i, n, sz; UNUSED_PARAMETER(idxStr); UNUSED_PARAMETER(argc); jsonEachCursorReset(p); if( idxNum==0 ) return SQLITE_OK; - z = (const char*)sqlite3_value_text(argv[0]); - if( z==0 ) return SQLITE_OK; memset(&p->sParse, 0, sizeof(p->sParse)); p->sParse.nJPRef = 1; - if( sqlite3ValueIsOfClass(argv[0], sqlite3RCStrUnref) ){ - p->sParse.zJson = sqlite3RCStrRef((char*)z); - }else{ - n = sqlite3_value_bytes(argv[0]); - p->sParse.zJson = sqlite3RCStrNew( n+1 ); - if( p->sParse.zJson==0 ) return SQLITE_NOMEM; - memcpy(p->sParse.zJson, z, (size_t)n+1); - } - p->sParse.bJsonIsRCStr = 1; - p->zJson = p->sParse.zJson; - if( jsonParse(&p->sParse, 0) ){ - int rc = SQLITE_NOMEM; - if( p->sParse.oom==0 ){ - sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); - if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; + p->sParse.db = p->db; + if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ + if( jsonFuncArgMightBeBinary(argv[0]) ){ + p->sParse.nBlob = sqlite3_value_bytes(argv[0]); + p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]); + }else{ + goto json_each_malformed_input; } - jsonEachCursorReset(p); - return rc; - }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){ - jsonEachCursorReset(p); - return SQLITE_NOMEM; }else{ - JsonNode *pNode = 0; - if( idxNum==3 ){ - const char *zErr = 0; - zRoot = (const char*)sqlite3_value_text(argv[1]); - if( zRoot==0 ) return SQLITE_OK; - n = sqlite3_value_bytes(argv[1]); - p->zRoot = sqlite3_malloc64( n+1 ); - if( p->zRoot==0 ) return SQLITE_NOMEM; - memcpy(p->zRoot, zRoot, (size_t)n+1); - if( zRoot[0]!='$' ){ - zErr = zRoot; - }else{ - pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); + p->sParse.zJson = (char*)sqlite3_value_text(argv[0]); + p->sParse.nJson = sqlite3_value_bytes(argv[0]); + if( p->sParse.zJson==0 ){ + p->i = p->iEnd = 0; + return SQLITE_OK; + } + if( jsonConvertTextToBlob(&p->sParse, 0) ){ + if( p->sParse.oom ){ + return SQLITE_NOMEM; } - if( zErr ){ + goto json_each_malformed_input; + } + } + if( idxNum==3 ){ + zRoot = (const char*)sqlite3_value_text(argv[1]); + if( zRoot==0 ) return SQLITE_OK; + if( zRoot[0]!='$' ){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + } + p->nRoot = sqlite3Strlen30(zRoot); + if( zRoot[1]==0 ){ + i = p->i = 0; + p->eType = 0; + }else{ + i = jsonLookupStep(&p->sParse, 0, zRoot+1, 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + p->i = 0; + p->eType = 0; + p->iEnd = 0; + return SQLITE_OK; + } sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); jsonEachCursorReset(p); return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; - }else if( pNode==0 ){ - return SQLITE_OK; } - }else{ - pNode = p->sParse.aNode; - } - p->iBegin = p->i = (int)(pNode - p->sParse.aNode); - p->eType = pNode->eType; - if( p->eType>=JSON_ARRAY ){ - assert( pNode->eU==0 ); - VVA( pNode->eU = 3 ); - pNode->u.iKey = 0; - p->iEnd = p->i + pNode->n + 1; - if( p->bRecursive ){ - p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType; - if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){ - p->i--; - } + if( p->sParse.iLabel ){ + p->i = p->sParse.iLabel; + p->eType = JSONB_OBJECT; }else{ - p->i++; + p->i = i; + p->eType = JSONB_ARRAY; } - }else{ - p->iEnd = p->i+1; } + jsonAppendRaw(&p->path, zRoot, p->nRoot); + }else{ + i = p->i = 0; + p->eType = 0; + p->nRoot = 1; + jsonAppendRaw(&p->path, "$", 1); + } + p->nParent = 0; + n = jsonbPayloadSize(&p->sParse, i, &sz); + p->iEnd = i+n+sz; + if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY && !p->bRecursive ){ + p->i = i + n; + p->eType = p->sParse.aBlob[i] & 0x0f; + p->aParent = sqlite3DbMallocZero(p->db, sizeof(JsonParent)); + if( p->aParent==0 ) return SQLITE_NOMEM; + p->nParent = 1; + p->nParentAlloc = 1; + p->aParent[0].iKey = 0; + p->aParent[0].iEnd = p->iEnd; + p->aParent[0].iHead = p->i; + p->aParent[0].iValue = i; } return SQLITE_OK; + +json_each_malformed_input: + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; } /* The methods of the json_each virtual table */ @@ -206451,40 +208335,54 @@ static sqlite3_module jsonTreeModule = { SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ #ifndef SQLITE_OMIT_JSON static FuncDef aJsonFunc[] = { - /* calls sqlite3_result_subtype() */ - /* | */ - /* Uses cache ______ | __ calls sqlite3_value_subtype() */ - /* | | | */ - /* Num args _________ | | | ___ Flags */ - /* | | | | | */ - /* | | | | | */ - JFUNCTION(json, 1, 1, 1, 0, 0, jsonRemoveFunc), - JFUNCTION(json_array, -1, 0, 1, 1, 0, jsonArrayFunc), - JFUNCTION(json_array_length, 1, 1, 0, 0, 0, jsonArrayLengthFunc), - JFUNCTION(json_array_length, 2, 1, 0, 0, 0, jsonArrayLengthFunc), - JFUNCTION(json_error_position,1, 1, 0, 0, 0, jsonErrorFunc), - JFUNCTION(json_extract, -1, 1, 1, 0, 0, jsonExtractFunc), - JFUNCTION(->, 2, 1, 1, 0, JSON_JSON, jsonExtractFunc), - JFUNCTION(->>, 2, 1, 0, 0, JSON_SQL, jsonExtractFunc), - JFUNCTION(json_insert, -1, 1, 1, 1, 0, jsonSetFunc), - JFUNCTION(json_object, -1, 0, 1, 1, 0, jsonObjectFunc), - JFUNCTION(json_patch, 2, 1, 1, 0, 0, jsonPatchFunc), - JFUNCTION(json_quote, 1, 0, 1, 1, 0, jsonQuoteFunc), - JFUNCTION(json_remove, -1, 1, 1, 0, 0, jsonRemoveFunc), - JFUNCTION(json_replace, -1, 1, 1, 1, 0, jsonReplaceFunc), - JFUNCTION(json_set, -1, 1, 1, 1, JSON_ISSET, jsonSetFunc), - JFUNCTION(json_type, 1, 1, 0, 0, 0, jsonTypeFunc), - JFUNCTION(json_type, 2, 1, 0, 0, 0, jsonTypeFunc), - JFUNCTION(json_valid, 1, 1, 0, 0, 0, jsonValidFunc), -#ifdef SQLITE_DEBUG - JFUNCTION(json_parse, 1, 1, 1, 0, 0, jsonParseFunc), - JFUNCTION(json_test1, 1, 1, 0, 1, 0, jsonTest1Func), + /* sqlite3_result_subtype() ----, ,--- sqlite3_value_subtype() */ + /* | | */ + /* Uses cache ------, | | ,---- Returns JSONB */ + /* | | | | */ + /* Number of arguments ---, | | | | ,--- Flags */ + /* | | | | | | */ + JFUNCTION(json, 1,1,1, 0,0,0, jsonRemoveFunc), + JFUNCTION(jsonb, 1,1,0, 0,1,0, jsonRemoveFunc), + JFUNCTION(json_array, -1,0,1, 1,0,0, jsonArrayFunc), + JFUNCTION(jsonb_array, -1,0,1, 1,1,0, jsonArrayFunc), + JFUNCTION(json_array_length, 1,1,0, 0,0,0, jsonArrayLengthFunc), + JFUNCTION(json_array_length, 2,1,0, 0,0,0, jsonArrayLengthFunc), + JFUNCTION(json_error_position,1,1,0, 0,0,0, jsonErrorFunc), + JFUNCTION(json_extract, -1,1,1, 0,0,0, jsonExtractFunc), + JFUNCTION(jsonb_extract, -1,1,0, 0,1,0, jsonExtractFunc), + JFUNCTION(->, 2,1,1, 0,0,JSON_JSON, jsonExtractFunc), + JFUNCTION(->>, 2,1,0, 0,0,JSON_SQL, jsonExtractFunc), + JFUNCTION(json_insert, -1,1,1, 1,0,0, jsonSetFunc), + JFUNCTION(jsonb_insert, -1,1,0, 1,1,0, jsonSetFunc), + JFUNCTION(json_object, -1,0,1, 1,0,0, jsonObjectFunc), + JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc), + JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc), + JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc), + JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc), + JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc), + JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc), + JFUNCTION(json_replace, -1,1,1, 1,0,0, jsonReplaceFunc), + JFUNCTION(jsonb_replace, -1,1,0, 1,1,0, jsonReplaceFunc), + JFUNCTION(json_set, -1,1,1, 1,0,JSON_ISSET, jsonSetFunc), + JFUNCTION(jsonb_set, -1,1,0, 1,1,JSON_ISSET, jsonSetFunc), + JFUNCTION(json_type, 1,1,0, 0,0,0, jsonTypeFunc), + JFUNCTION(json_type, 2,1,0, 0,0,0, jsonTypeFunc), + JFUNCTION(json_valid, 1,1,0, 0,0,0, jsonValidFunc), + JFUNCTION(json_valid, 2,1,0, 0,0,0, jsonValidFunc), +#if SQLITE_DEBUG + JFUNCTION(json_parse, 1,1,0, 0,0,0, jsonParseFunc), #endif WAGGREGATE(json_group_array, 1, 0, 0, jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| SQLITE_DETERMINISTIC), + WAGGREGATE(jsonb_group_array, 1, JSON_BLOB, 0, + jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), WAGGREGATE(json_group_object, 2, 0, 0, + jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), + WAGGREGATE(jsonb_group_object,2, JSON_BLOB, 0, jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| SQLITE_DETERMINISTIC) @@ -207235,7 +209133,7 @@ static int nodeAcquire( ** increase its reference count and return it. */ if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ - if( pParent && pParent!=pNode->pParent ){ + if( pParent && ALWAYS(pParent!=pNode->pParent) ){ RTREE_IS_CORRUPT(pRtree); return SQLITE_CORRUPT_VTAB; } @@ -209970,7 +211868,7 @@ static int rtreeSqlInit( } sqlite3_free(zSql); } - if( pRtree->nAux ){ + if( pRtree->nAux && rc!=SQLITE_NOMEM ){ pRtree->zReadAuxSql = sqlite3_mprintf( "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1", zDb, zPrefix); @@ -210659,15 +212557,13 @@ static int rtreeCheckTable( check.zTab = zTab; /* Find the number of auxiliary columns */ - if( check.rc==SQLITE_OK ){ - pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); - if( pStmt ){ - nAux = sqlite3_column_count(pStmt) - 2; - sqlite3_finalize(pStmt); - }else - if( check.rc!=SQLITE_NOMEM ){ - check.rc = SQLITE_OK; - } + pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); + if( pStmt ){ + nAux = sqlite3_column_count(pStmt) - 2; + sqlite3_finalize(pStmt); + }else + if( check.rc!=SQLITE_NOMEM ){ + check.rc = SQLITE_OK; } /* Find number of dimensions in the rtree table. */ @@ -210722,6 +212618,7 @@ static int rtreeIntegrity( if( rc==SQLITE_OK && *pzErr ){ *pzErr = sqlite3_mprintf("In RTree %s.%s:\n%z", pRtree->zDb, pRtree->zName, *pzErr); + if( (*pzErr)==0 ) rc = SQLITE_NOMEM; } return rc; } @@ -223392,9 +225289,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){ ** associated hash-tables. */ sessionDeleteTable(pSession, pSession->pTable); - /* Assert that all allocations have been freed and then free the - ** session object itself. */ - // assert( pSession->nMalloc==0 ); + /* Free the session object. */ sqlite3_free(pSession); } @@ -227607,8 +229502,11 @@ struct Fts5PhraseIter { ** created with the "columnsize=0" option. ** ** xColumnText: -** This function attempts to retrieve the text of column iCol of the -** current document. If successful, (*pz) is set to point to a buffer +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the text of column iCol of +** the current document. If successful, (*pz) is set to point to a buffer ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, ** if an error occurs, an SQLite error code is returned and the final values @@ -227618,8 +229516,10 @@ struct Fts5PhraseIter { ** Returns the number of phrases in the current query expression. ** ** xPhraseSize: -** Returns the number of tokens in phrase iPhrase of the query. Phrases -** are numbered starting from zero. +** If parameter iCol is less than zero, or greater than or equal to the +** number of phrases in the current query, as returned by xPhraseCount, +** 0 is returned. Otherwise, this function returns the number of tokens in +** phrase iPhrase of the query. Phrases are numbered starting from zero. ** ** xInstCount: ** Set *pnInst to the total number of occurrences of all phrases within @@ -227635,12 +229535,13 @@ struct Fts5PhraseIter { ** Query for the details of phrase match iIdx within the current row. ** Phrase matches are numbered starting from zero, so the iIdx argument ** should be greater than or equal to zero and smaller than the value -** output by xInstCount(). +** output by xInstCount(). If iIdx is less than zero or greater than +** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. ** -** Usually, output parameter *piPhrase is set to the phrase number, *piCol +** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. Returns SQLITE_OK if successful, or an error -** code (i.e. SQLITE_NOMEM) if an error occurs. +** first token of the phrase. SQLITE_OK is returned if successful, or an +** error code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -227666,6 +229567,10 @@ struct Fts5PhraseIter { ** Invoking Api.xUserData() returns a copy of the pointer passed as ** the third argument to pUserData. ** +** If parameter iPhrase is less than zero, or greater than or equal to +** the number of phrases in the query, as returned by xPhraseCount(), +** this function returns SQLITE_RANGE. +** ** If the callback function returns any value other than SQLITE_OK, the ** query is abandoned and the xQueryPhrase function returns immediately. ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. @@ -227780,9 +229685,42 @@ struct Fts5PhraseIter { ** ** xPhraseNextColumn() ** See xPhraseFirstColumn above. +** +** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase iPhrase of the current +** query. Before returning, output parameter *ppToken is set to point +** to a buffer containing the requested token, and *pnToken to the +** size of this buffer in bytes. +** +** If iPhrase or iToken are less than zero, or if iPhrase is greater than +** or equal to the number of phrases in the query as reported by +** xPhraseCount(), or if iToken is equal to or greater than the number of +** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken + are both zeroed. +** +** The output text is not a copy of the query text that specified the +** token. It is the output of the tokenizer module. For tokendata=1 +** tables, this includes any embedded 0x00 and trailing data. +** +** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase hit iIdx within the +** current row. If iIdx is less than zero or greater than or equal to the +** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, +** output variable (*ppToken) is set to point to a buffer containing the +** matching document token, and (*pnToken) to the size of that buffer in +** bytes. This API is not available if the specified token matches a +** prefix query term. In that case both output variables are always set +** to 0. +** +** The output text is not a copy of the document text that was tokenized. +** It is the output of the tokenizer module. For tokendata=1 tables, this +** includes any embedded 0x00 and trailing data. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ void *(*xUserData)(Fts5Context*); @@ -227817,6 +229755,13 @@ struct Fts5ExtensionApi { int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); + + /* Below this point are iVersion>=3 only */ + int (*xQueryToken)(Fts5Context*, + int iPhrase, int iToken, + const char **ppToken, int *pnToken + ); + int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); }; /* @@ -228291,6 +230236,7 @@ struct Fts5Config { char *zContent; /* content table */ char *zContentRowid; /* "content_rowid=" option value */ int bColumnsize; /* "columnsize=" option value (dflt==1) */ + int bTokendata; /* "tokendata=" option value (dflt==0) */ int eDetail; /* FTS5_DETAIL_XXX value */ char *zContentExprlist; Fts5Tokenizer *pTok; @@ -228479,17 +230425,19 @@ struct Fts5IndexIter { /* ** Values used as part of the flags argument passed to IndexQuery(). */ -#define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */ -#define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */ -#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */ -#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */ +#define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */ +#define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */ +#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */ +#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */ /* The following are used internally by the fts5_index.c module. They are ** defined here only to make it easier to avoid clashes with the flags ** above. */ -#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 -#define FTS5INDEX_QUERY_NOOUTPUT 0x0020 -#define FTS5INDEX_QUERY_SKIPHASH 0x0040 +#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 +#define FTS5INDEX_QUERY_NOOUTPUT 0x0020 +#define FTS5INDEX_QUERY_SKIPHASH 0x0040 +#define FTS5INDEX_QUERY_NOTOKENDATA 0x0080 +#define FTS5INDEX_QUERY_SCANONETERM 0x0100 /* ** Create/destroy an Fts5Index object. @@ -228558,6 +230506,10 @@ static void *sqlite3Fts5StructureRef(Fts5Index*); static void sqlite3Fts5StructureRelease(void*); static int sqlite3Fts5StructureTest(Fts5Index*, void*); +/* +** Used by xInstToken(): +*/ +static int sqlite3Fts5IterToken(Fts5IndexIter*, i64, int, int, const char**, int*); /* ** Insert or remove data to or from the index. Each time a document is @@ -228635,6 +230587,13 @@ static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin); static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid); +static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter*); + +/* Used to populate hash tables for xInstToken in detail=none/column mode. */ +static int sqlite3Fts5IndexIterWriteTokendata( + Fts5IndexIter*, const char*, int, i64 iRowid, int iCol, int iOff +); + /* ** End of interface to code in fts5_index.c. **************************************************************************/ @@ -228740,6 +230699,7 @@ static void sqlite3Fts5HashScanNext(Fts5Hash*); static int sqlite3Fts5HashScanEof(Fts5Hash*); static void sqlite3Fts5HashScanEntry(Fts5Hash *, const char **pzTerm, /* OUT: term (nul-terminated) */ + int *pnTerm, /* OUT: Size of term in bytes */ const u8 **ppDoclist, /* OUT: pointer to doclist */ int *pnDoclist /* OUT: size of doclist in bytes */ ); @@ -228866,6 +230826,10 @@ static int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**); static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *); +static int sqlite3Fts5ExprQueryToken(Fts5Expr*, int, int, const char**, int*); +static int sqlite3Fts5ExprInstToken(Fts5Expr*, i64, int, int, int, int, const char**, int*); +static void sqlite3Fts5ExprClearTokens(Fts5Expr*); + /******************************************* ** The fts5_expr.c API above this point is used by the other hand-written ** C code in this module. The interfaces below this point are called by @@ -230681,6 +232645,14 @@ static int fts5HighlightCb( } if( iPos==p->iRangeEnd ){ + if( p->bOpen ){ + if( p->iter.iStart>=0 && iPos>=p->iter.iStart ){ + fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); + p->iOff = iEndOff; + } + fts5HighlightAppend(&rc, p, p->zClose, -1); + p->bOpen = 0; + } fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); p->iOff = iEndOff; } @@ -230714,8 +232686,10 @@ static void fts5HighlightFunction( ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); ctx.iRangeEnd = -1; rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); - - if( ctx.zIn ){ + if( rc==SQLITE_RANGE ){ + sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); + rc = SQLITE_OK; + }else if( ctx.zIn ){ if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); } @@ -231282,6 +233256,7 @@ static void sqlite3Fts5BufferAppendBlob( ){ if( nData ){ if( fts5BufferGrow(pRc, pBuf, nData) ) return; + assert( pBuf->p!=0 ); memcpy(&pBuf->p[pBuf->n], pData, nData); pBuf->n += nData; } @@ -231383,6 +233358,7 @@ static int sqlite3Fts5PoslistNext64( i64 *piOff /* IN/OUT: Current offset */ ){ int i = *pi; + assert( a!=0 || i==0 ); if( i>=n ){ /* EOF */ *piOff = -1; @@ -231390,6 +233366,7 @@ static int sqlite3Fts5PoslistNext64( }else{ i64 iOff = *piOff; u32 iVal; + assert( a!=0 ); fts5FastGetVarint32(a, i, iVal); if( iVal<=1 ){ if( iVal==0 ){ @@ -232021,6 +233998,16 @@ static int fts5ConfigParseSpecial( return rc; } + if( sqlite3_strnicmp("tokendata", zCmd, nCmd)==0 ){ + if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ + *pzErr = sqlite3_mprintf("malformed tokendata=... directive"); + rc = SQLITE_ERROR; + }else{ + pConfig->bTokendata = (zArg[0]=='1'); + } + return rc; + } + *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd); return SQLITE_ERROR; } @@ -232754,7 +234741,9 @@ struct Fts5ExprNode { struct Fts5ExprTerm { u8 bPrefix; /* True for a prefix term */ u8 bFirst; /* True if token must be first in column */ - char *zTerm; /* nul-terminated term */ + char *pTerm; /* Term data */ + int nQueryTerm; /* Effective size of term in bytes */ + int nFullTerm; /* Size of term in bytes incl. tokendata */ Fts5IndexIter *pIter; /* Iterator for this term */ Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */ }; @@ -233621,7 +235610,7 @@ static int fts5ExprNearInitAll( p->pIter = 0; } rc = sqlite3Fts5IndexQuery( - pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm), + pExpr->pIndex, p->pTerm, p->nQueryTerm, (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) | (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0), pNear->pColset, @@ -234258,7 +236247,7 @@ static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){ Fts5ExprTerm *pSyn; Fts5ExprTerm *pNext; Fts5ExprTerm *pTerm = &pPhrase->aTerm[i]; - sqlite3_free(pTerm->zTerm); + sqlite3_free(pTerm->pTerm); sqlite3Fts5IterClose(pTerm->pIter); for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){ pNext = pSyn->pSynonym; @@ -234356,6 +236345,7 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( typedef struct TokenCtx TokenCtx; struct TokenCtx { Fts5ExprPhrase *pPhrase; + Fts5Config *pConfig; int rc; }; @@ -234389,8 +236379,12 @@ static int fts5ParseTokenize( rc = SQLITE_NOMEM; }else{ memset(pSyn, 0, (size_t)nByte); - pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); - memcpy(pSyn->zTerm, pToken, nToken); + pSyn->pTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); + pSyn->nFullTerm = pSyn->nQueryTerm = nToken; + if( pCtx->pConfig->bTokendata ){ + pSyn->nQueryTerm = (int)strlen(pSyn->pTerm); + } + memcpy(pSyn->pTerm, pToken, nToken); pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym; pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn; } @@ -234415,7 +236409,11 @@ static int fts5ParseTokenize( if( rc==SQLITE_OK ){ pTerm = &pPhrase->aTerm[pPhrase->nTerm++]; memset(pTerm, 0, sizeof(Fts5ExprTerm)); - pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken); + pTerm->pTerm = sqlite3Fts5Strndup(&rc, pToken, nToken); + pTerm->nFullTerm = pTerm->nQueryTerm = nToken; + if( pCtx->pConfig->bTokendata && rc==SQLITE_OK ){ + pTerm->nQueryTerm = (int)strlen(pTerm->pTerm); + } } } @@ -234482,6 +236480,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( memset(&sCtx, 0, sizeof(TokenCtx)); sCtx.pPhrase = pAppend; + sCtx.pConfig = pConfig; rc = fts5ParseStringFromToken(pToken, &z); if( rc==SQLITE_OK ){ @@ -234529,12 +236528,15 @@ static int sqlite3Fts5ExprClonePhrase( Fts5Expr **ppNew ){ int rc = SQLITE_OK; /* Return code */ - Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */ + Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */ Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ - TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */ - - pOrig = pExpr->apExprPhrase[iPhrase]; - pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); + TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */ + if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ + rc = SQLITE_RANGE; + }else{ + pOrig = pExpr->apExprPhrase[iPhrase]; + pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); + } if( rc==SQLITE_OK ){ pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase*)); @@ -234547,7 +236549,7 @@ static int sqlite3Fts5ExprClonePhrase( pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*)); } - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){ Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; if( pColsetOrig ){ sqlite3_int64 nByte; @@ -234561,26 +236563,27 @@ static int sqlite3Fts5ExprClonePhrase( } } - if( pOrig->nTerm ){ - int i; /* Used to iterate through phrase terms */ - for(i=0; rc==SQLITE_OK && inTerm; i++){ - int tflags = 0; - Fts5ExprTerm *p; - for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ - const char *zTerm = p->zTerm; - rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm), - 0, 0); - tflags = FTS5_TOKEN_COLOCATED; - } - if( rc==SQLITE_OK ){ - sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; - sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; + if( rc==SQLITE_OK ){ + if( pOrig->nTerm ){ + int i; /* Used to iterate through phrase terms */ + sCtx.pConfig = pExpr->pConfig; + for(i=0; rc==SQLITE_OK && inTerm; i++){ + int tflags = 0; + Fts5ExprTerm *p; + for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ + rc = fts5ParseTokenize((void*)&sCtx,tflags,p->pTerm,p->nFullTerm,0,0); + tflags = FTS5_TOKEN_COLOCATED; + } + if( rc==SQLITE_OK ){ + sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; + sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; + } } + }else{ + /* This happens when parsing a token or quoted phrase that contains + ** no token characters at all. (e.g ... MATCH '""'). */ + sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); } - }else{ - /* This happens when parsing a token or quoted phrase that contains - ** no token characters at all. (e.g ... MATCH '""'). */ - sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); } if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){ @@ -234950,11 +236953,13 @@ static Fts5ExprNode *fts5ParsePhraseToAnd( if( parseGrowPhraseArray(pParse) ){ fts5ExprPhraseFree(pPhrase); }else{ + Fts5ExprTerm *p = &pNear->apPhrase[0]->aTerm[ii]; + Fts5ExprTerm *pTo = &pPhrase->aTerm[0]; pParse->apPhrase[pParse->nPhrase++] = pPhrase; pPhrase->nTerm = 1; - pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup( - &pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1 - ); + pTo->pTerm = sqlite3Fts5Strndup(&pParse->rc, p->pTerm, p->nFullTerm); + pTo->nQueryTerm = p->nQueryTerm; + pTo->nFullTerm = p->nFullTerm; pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase) ); @@ -235139,16 +237144,17 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ /* Determine the maximum amount of space required. */ for(p=pTerm; p; p=p->pSynonym){ - nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2; + nByte += pTerm->nQueryTerm * 2 + 3 + 2; } zQuoted = sqlite3_malloc64(nByte); if( zQuoted ){ int i = 0; for(p=pTerm; p; p=p->pSynonym){ - char *zIn = p->zTerm; + char *zIn = p->pTerm; + char *zEnd = &zIn[p->nQueryTerm]; zQuoted[i++] = '"'; - while( *zIn ){ + while( zInnTerm; iTerm++){ - char *zTerm = pPhrase->aTerm[iTerm].zTerm; - zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" ", zTerm); + Fts5ExprTerm *p = &pPhrase->aTerm[iTerm]; + zRet = fts5PrintfAppend(zRet, "%s%.*s", iTerm==0?"":" ", + p->nQueryTerm, p->pTerm + ); if( pPhrase->aTerm[iTerm].bPrefix ){ zRet = fts5PrintfAppend(zRet, "*"); } @@ -235628,6 +237636,17 @@ static int fts5ExprColsetTest(Fts5Colset *pColset, int iCol){ return 0; } +/* +** pToken is a buffer nToken bytes in size that may or may not contain +** an embedded 0x00 byte. If it does, return the number of bytes in +** the buffer before the 0x00. If it does not, return nToken. +*/ +static int fts5QueryTerm(const char *pToken, int nToken){ + int ii; + for(ii=0; iipExpr; int i; + int nQuery = nToken; + i64 iRowid = pExpr->pRoot->iRowid; UNUSED_PARAM2(iUnused1, iUnused2); - if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; + if( nQuery>FTS5_MAX_TOKEN_SIZE ) nQuery = FTS5_MAX_TOKEN_SIZE; + if( pExpr->pConfig->bTokendata ){ + nQuery = fts5QueryTerm(pToken, nQuery); + } if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++; for(i=0; inPhrase; i++){ - Fts5ExprTerm *pTerm; + Fts5ExprTerm *pT; if( p->aPopulator[i].bOk==0 ) continue; - for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ - int nTerm = (int)strlen(pTerm->zTerm); - if( (nTerm==nToken || (nTermbPrefix)) - && memcmp(pTerm->zTerm, pToken, nTerm)==0 + for(pT=&pExpr->apExprPhrase[i]->aTerm[0]; pT; pT=pT->pSynonym){ + if( (pT->nQueryTerm==nQuery || (pT->nQueryTermbPrefix)) + && memcmp(pT->pTerm, pToken, pT->nQueryTerm)==0 ){ int rc = sqlite3Fts5PoslistWriterAppend( &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff ); + if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){ + int iCol = p->iOff>>32; + int iTokOff = p->iOff & 0x7FFFFFFF; + rc = sqlite3Fts5IndexIterWriteTokendata( + pT->pIter, pToken, nToken, iRowid, iCol, iTokOff + ); + } if( rc ) return rc; break; } @@ -235790,6 +237820,83 @@ static int sqlite3Fts5ExprPhraseCollist( return rc; } +/* +** Does the work of the fts5_api.xQueryToken() API method. +*/ +static int sqlite3Fts5ExprQueryToken( + Fts5Expr *pExpr, + int iPhrase, + int iToken, + const char **ppOut, + int *pnOut +){ + Fts5ExprPhrase *pPhrase = 0; + + if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ + return SQLITE_RANGE; + } + pPhrase = pExpr->apExprPhrase[iPhrase]; + if( iToken<0 || iToken>=pPhrase->nTerm ){ + return SQLITE_RANGE; + } + + *ppOut = pPhrase->aTerm[iToken].pTerm; + *pnOut = pPhrase->aTerm[iToken].nFullTerm; + return SQLITE_OK; +} + +/* +** Does the work of the fts5_api.xInstToken() API method. +*/ +static int sqlite3Fts5ExprInstToken( + Fts5Expr *pExpr, + i64 iRowid, + int iPhrase, + int iCol, + int iOff, + int iToken, + const char **ppOut, + int *pnOut +){ + Fts5ExprPhrase *pPhrase = 0; + Fts5ExprTerm *pTerm = 0; + int rc = SQLITE_OK; + + if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ + return SQLITE_RANGE; + } + pPhrase = pExpr->apExprPhrase[iPhrase]; + if( iToken<0 || iToken>=pPhrase->nTerm ){ + return SQLITE_RANGE; + } + pTerm = &pPhrase->aTerm[iToken]; + if( pTerm->bPrefix==0 ){ + if( pExpr->pConfig->bTokendata ){ + rc = sqlite3Fts5IterToken( + pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut + ); + }else{ + *ppOut = pTerm->pTerm; + *pnOut = pTerm->nFullTerm; + } + } + return rc; +} + +/* +** Clear the token mappings for all Fts5IndexIter objects mannaged by +** the expression passed as the only argument. +*/ +static void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){ + int ii; + for(ii=0; iinPhrase; ii++){ + Fts5ExprTerm *pT; + for(pT=&pExpr->apExprPhrase[ii]->aTerm[0]; pT; pT=pT->pSynonym){ + sqlite3Fts5IndexIterClearTokendata(pT->pIter); + } + } +} + /* ** 2014 August 11 ** @@ -235828,10 +237935,15 @@ struct Fts5Hash { /* ** Each entry in the hash table is represented by an object of the -** following type. Each object, its key (a nul-terminated string) and -** its current data are stored in a single memory allocation. The -** key immediately follows the object in memory. The position list -** data immediately follows the key data in memory. +** following type. Each object, its key, and its current data are stored +** in a single memory allocation. The key immediately follows the object +** in memory. The position list data immediately follows the key data +** in memory. +** +** The key is Fts5HashEntry.nKey bytes in size. It consists of a single +** byte identifying the index (either the main term index or a prefix-index), +** followed by the term data. For example: "0token". There is no +** nul-terminator - in this case nKey=6. ** ** The data that follows the key is in a similar, but not identical format ** to the doclist data stored in the database. It is: @@ -235966,8 +238078,7 @@ static int fts5HashResize(Fts5Hash *pHash){ unsigned int iHash; Fts5HashEntry *p = apOld[i]; apOld[i] = p->pHashNext; - iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), - (int)strlen(fts5EntryKey(p))); + iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), p->nKey); p->pHashNext = apNew[iHash]; apNew[iHash] = p; } @@ -236051,7 +238162,7 @@ static int sqlite3Fts5HashWrite( for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ char *zKey = fts5EntryKey(p); if( zKey[0]==bByte - && p->nKey==nToken + && p->nKey==nToken+1 && memcmp(&zKey[1], pToken, nToken)==0 ){ break; @@ -236081,9 +238192,9 @@ static int sqlite3Fts5HashWrite( zKey[0] = bByte; memcpy(&zKey[1], pToken, nToken); assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) ); - p->nKey = nToken; + p->nKey = nToken+1; zKey[nToken+1] = '\0'; - p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry); + p->nData = nToken+1 + sizeof(Fts5HashEntry); p->pHashNext = pHash->aSlot[iHash]; pHash->aSlot[iHash] = p; pHash->nEntry++; @@ -236200,12 +238311,17 @@ static Fts5HashEntry *fts5HashEntryMerge( *ppOut = p1; p1 = 0; }else{ - int i = 0; char *zKey1 = fts5EntryKey(p1); char *zKey2 = fts5EntryKey(p2); - while( zKey1[i]==zKey2[i] ) i++; + int nMin = MIN(p1->nKey, p2->nKey); - if( ((u8)zKey1[i])>((u8)zKey2[i]) ){ + int cmp = memcmp(zKey1, zKey2, nMin); + if( cmp==0 ){ + cmp = p1->nKey - p2->nKey; + } + assert( cmp!=0 ); + + if( cmp>0 ){ /* p2 is smaller */ *ppOut = p2; ppOut = &p2->pScanNext; @@ -236247,7 +238363,7 @@ static int fts5HashEntrySort( Fts5HashEntry *pIter; for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){ if( pTerm==0 - || (pIter->nKey+1>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm)) + || (pIter->nKey>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm)) ){ Fts5HashEntry *pEntry = pIter; pEntry->pScanNext = 0; @@ -236286,12 +238402,11 @@ static int sqlite3Fts5HashQuery( for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ zKey = fts5EntryKey(p); - assert( p->nKey+1==(int)strlen(zKey) ); - if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break; + if( nTerm==p->nKey && memcmp(zKey, pTerm, nTerm)==0 ) break; } if( p ){ - int nHashPre = sizeof(Fts5HashEntry) + nTerm + 1; + int nHashPre = sizeof(Fts5HashEntry) + nTerm; int nList = p->nData - nHashPre; u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10)); if( pRet ){ @@ -236352,19 +238467,22 @@ static int sqlite3Fts5HashScanEof(Fts5Hash *p){ static void sqlite3Fts5HashScanEntry( Fts5Hash *pHash, const char **pzTerm, /* OUT: term (nul-terminated) */ + int *pnTerm, /* OUT: Size of term in bytes */ const u8 **ppDoclist, /* OUT: pointer to doclist */ int *pnDoclist /* OUT: size of doclist in bytes */ ){ Fts5HashEntry *p; if( (p = pHash->pScan) ){ char *zKey = fts5EntryKey(p); - int nTerm = (int)strlen(zKey); + int nTerm = p->nKey; fts5HashAddPoslistSize(pHash, p, 0); *pzTerm = zKey; - *ppDoclist = (const u8*)&zKey[nTerm+1]; - *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1); + *pnTerm = nTerm; + *ppDoclist = (const u8*)&zKey[nTerm]; + *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm); }else{ *pzTerm = 0; + *pnTerm = 0; *ppDoclist = 0; *pnDoclist = 0; } @@ -236695,6 +238813,9 @@ typedef struct Fts5SegWriter Fts5SegWriter; typedef struct Fts5Structure Fts5Structure; typedef struct Fts5StructureLevel Fts5StructureLevel; typedef struct Fts5StructureSegment Fts5StructureSegment; +typedef struct Fts5TokenDataIter Fts5TokenDataIter; +typedef struct Fts5TokenDataMap Fts5TokenDataMap; +typedef struct Fts5TombstoneArray Fts5TombstoneArray; struct Fts5Data { u8 *p; /* Pointer to buffer containing record */ @@ -236729,6 +238850,7 @@ struct Fts5Index { /* Error state. */ int rc; /* Current error code */ + int flushRc; /* State used by the fts5DataXXX() functions. */ sqlite3_blob *pReader; /* RO incr-blob open on %_data table */ @@ -236737,6 +238859,7 @@ struct Fts5Index { sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */ sqlite3_stmt *pIdxSelect; + sqlite3_stmt *pIdxNextSelect; int nRead; /* Total number of blocks read */ sqlite3_stmt *pDeleteFromIdx; @@ -236890,8 +239013,7 @@ struct Fts5SegIter { Fts5Data *pLeaf; /* Current leaf data */ Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */ i64 iLeafOffset; /* Byte offset within current leaf */ - Fts5Data **apTombstone; /* Array of tombstone pages */ - int nTombstone; + Fts5TombstoneArray *pTombArray; /* Array of tombstone pages */ /* Next method */ void (*xNext)(Fts5Index*, Fts5SegIter*, int*); @@ -236918,6 +239040,15 @@ struct Fts5SegIter { u8 bDel; /* True if the delete flag is set */ }; +/* +** Array of tombstone pages. Reference counted. +*/ +struct Fts5TombstoneArray { + int nRef; /* Number of pointers to this object */ + int nTombstone; + Fts5Data *apTombstone[1]; /* Array of tombstone pages */ +}; + /* ** Argument is a pointer to an Fts5Data structure that contains a ** leaf page. @@ -236962,9 +239093,16 @@ struct Fts5SegIter { ** poslist: ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered. ** There is no way to tell if this is populated or not. +** +** pColset: +** If not NULL, points to an object containing a set of column indices. +** Only matches that occur in one of these columns will be returned. +** The Fts5Iter does not own the Fts5Colset object, and so it is not +** freed when the iterator is closed - it is owned by the upper layer. */ struct Fts5Iter { Fts5IndexIter base; /* Base class containing output vars */ + Fts5TokenDataIter *pTokenDataIter; Fts5Index *pIndex; /* Index that owns this iterator */ Fts5Buffer poslist; /* Buffer containing current poslist */ @@ -236982,7 +239120,6 @@ struct Fts5Iter { Fts5SegIter aSeg[1]; /* Array of segment iterators */ }; - /* ** An instance of the following type is used to iterate through the contents ** of a doclist-index record. @@ -237900,9 +240037,9 @@ static int fts5DlidxLvlNext(Fts5DlidxLvl *pLvl){ } if( iOffnn ){ - i64 iVal; + u64 iVal; pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1; - iOff += fts5GetVarint(&pData->p[iOff], (u64*)&iVal); + iOff += fts5GetVarint(&pData->p[iOff], &iVal); pLvl->iRowid += iVal; pLvl->iOff = iOff; }else{ @@ -238281,18 +240418,20 @@ static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){ } /* -** Allocate a tombstone hash page array (pIter->apTombstone) for the -** iterator passed as the second argument. If an OOM error occurs, leave -** an error in the Fts5Index object. +** Allocate a tombstone hash page array object (pIter->pTombArray) for +** the iterator passed as the second argument. If an OOM error occurs, +** leave an error in the Fts5Index object. */ static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ const int nTomb = pIter->pSeg->nPgTombstone; if( nTomb>0 ){ - Fts5Data **apTomb = 0; - apTomb = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data)*nTomb); - if( apTomb ){ - pIter->apTombstone = apTomb; - pIter->nTombstone = nTomb; + int nByte = nTomb * sizeof(Fts5Data*) + sizeof(Fts5TombstoneArray); + Fts5TombstoneArray *pNew; + pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte); + if( pNew ){ + pNew->nTombstone = nTomb; + pNew->nRef = 1; + pIter->pTombArray = pNew; } } } @@ -238549,15 +240688,16 @@ static void fts5SegIterNext_None( }else{ const u8 *pList = 0; const char *zTerm = 0; + int nTerm = 0; int nList; sqlite3Fts5HashScanNext(p->pHash); - sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); + sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList); if( pList==0 ) goto next_none_eof; pIter->pLeaf->p = (u8*)pList; pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList; - sqlite3Fts5BufferSet(&p->rc,&pIter->term, (int)strlen(zTerm), (u8*)zTerm); + sqlite3Fts5BufferSet(&p->rc,&pIter->term, nTerm, (u8*)zTerm); pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); } @@ -238623,11 +240763,12 @@ static void fts5SegIterNext( }else if( pIter->pSeg==0 ){ const u8 *pList = 0; const char *zTerm = 0; + int nTerm = 0; int nList = 0; assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm ); if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){ sqlite3Fts5HashScanNext(p->pHash); - sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); + sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList); } if( pList==0 ){ fts5DataRelease(pIter->pLeaf); @@ -238637,8 +240778,7 @@ static void fts5SegIterNext( pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList+1; - sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm), - (u8*)zTerm); + sqlite3Fts5BufferSet(&p->rc, &pIter->term, nTerm, (u8*)zTerm); pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); *pbNewTerm = 1; } @@ -239024,7 +241164,7 @@ static void fts5SegIterSeekInit( fts5LeafSeek(p, bGe, pIter, pTerm, nTerm); } - if( p->rc==SQLITE_OK && bGe==0 ){ + if( p->rc==SQLITE_OK && (bGe==0 || (flags & FTS5INDEX_QUERY_SCANONETERM)) ){ pIter->flags |= FTS5_SEGITER_ONETERM; if( pIter->pLeaf ){ if( flags & FTS5INDEX_QUERY_DESC ){ @@ -239040,7 +241180,9 @@ static void fts5SegIterSeekInit( } fts5SegIterSetNext(p, pIter); - fts5SegIterAllocTombstone(p, pIter); + if( 0==(flags & FTS5INDEX_QUERY_SCANONETERM) ){ + fts5SegIterAllocTombstone(p, pIter); + } /* Either: ** @@ -239057,6 +241199,79 @@ static void fts5SegIterSeekInit( ); } + +/* +** SQL used by fts5SegIterNextInit() to find the page to open. +*/ +static sqlite3_stmt *fts5IdxNextStmt(Fts5Index *p){ + if( p->pIdxNextSelect==0 ){ + Fts5Config *pConfig = p->pConfig; + fts5IndexPrepareStmt(p, &p->pIdxNextSelect, sqlite3_mprintf( + "SELECT pgno FROM '%q'.'%q_idx' WHERE " + "segid=? AND term>? ORDER BY term ASC LIMIT 1", + pConfig->zDb, pConfig->zName + )); + + } + return p->pIdxNextSelect; +} + +/* +** This is similar to fts5SegIterSeekInit(), except that it initializes +** the segment iterator to point to the first term following the page +** with pToken/nToken on it. +*/ +static void fts5SegIterNextInit( + Fts5Index *p, + const char *pTerm, int nTerm, + Fts5StructureSegment *pSeg, /* Description of segment */ + Fts5SegIter *pIter /* Object to populate */ +){ + int iPg = -1; /* Page of segment to open */ + int bDlidx = 0; + sqlite3_stmt *pSel = 0; /* SELECT to find iPg */ + + pSel = fts5IdxNextStmt(p); + if( pSel ){ + assert( p->rc==SQLITE_OK ); + sqlite3_bind_int(pSel, 1, pSeg->iSegid); + sqlite3_bind_blob(pSel, 2, pTerm, nTerm, SQLITE_STATIC); + + if( sqlite3_step(pSel)==SQLITE_ROW ){ + i64 val = sqlite3_column_int64(pSel, 0); + iPg = (int)(val>>1); + bDlidx = (val & 0x0001); + } + p->rc = sqlite3_reset(pSel); + sqlite3_bind_null(pSel, 2); + if( p->rc ) return; + } + + memset(pIter, 0, sizeof(*pIter)); + pIter->pSeg = pSeg; + pIter->flags |= FTS5_SEGITER_ONETERM; + if( iPg>=0 ){ + pIter->iLeafPgno = iPg - 1; + fts5SegIterNextPage(p, pIter); + fts5SegIterSetNext(p, pIter); + } + if( pIter->pLeaf ){ + const u8 *a = pIter->pLeaf->p; + int iTermOff = 0; + + pIter->iPgidxOff = pIter->pLeaf->szLeaf; + pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], iTermOff); + pIter->iLeafOffset = iTermOff; + fts5SegIterLoadTerm(p, pIter, 0); + fts5SegIterLoadNPos(p, pIter); + if( bDlidx ) fts5SegIterLoadDlidx(p, pIter); + + assert( p->rc!=SQLITE_OK || + fts5BufferCompareBlob(&pIter->term, (const u8*)pTerm, nTerm)>0 + ); + } +} + /* ** Initialize the object pIter to point to term pTerm/nTerm within the ** in-memory hash table. If there is no such term in the hash-table, the @@ -239083,8 +241298,7 @@ static void fts5SegIterHashInit( const u8 *pList = 0; p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm); - sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList); - n = (z ? (int)strlen((const char*)z) : 0); + sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &n, &pList, &nList); if( pList ){ pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data)); if( pLeaf ){ @@ -239143,6 +241357,23 @@ static void fts5IndexFreeArray(Fts5Data **ap, int n){ } } +/* +** Decrement the ref-count of the object passed as the only argument. If it +** reaches 0, free it and its contents. +*/ +static void fts5TombstoneArrayDelete(Fts5TombstoneArray *p){ + if( p ){ + p->nRef--; + if( p->nRef<=0 ){ + int ii; + for(ii=0; iinTombstone; ii++){ + fts5DataRelease(p->apTombstone[ii]); + } + sqlite3_free(p); + } + } +} + /* ** Zero the iterator passed as the only argument. */ @@ -239150,7 +241381,7 @@ static void fts5SegIterClear(Fts5SegIter *pIter){ fts5BufferFree(&pIter->term); fts5DataRelease(pIter->pLeaf); fts5DataRelease(pIter->pNextLeaf); - fts5IndexFreeArray(pIter->apTombstone, pIter->nTombstone); + fts5TombstoneArrayDelete(pIter->pTombArray); fts5DlidxIterFree(pIter->pDlidx); sqlite3_free(pIter->aRowidOffset); memset(pIter, 0, sizeof(Fts5SegIter)); @@ -239395,7 +241626,6 @@ static void fts5SegIterNextFrom( }while( p->rc==SQLITE_OK ); } - /* ** Free the iterator object passed as the second argument. */ @@ -239540,24 +241770,25 @@ static int fts5IndexTombstoneQuery( static int fts5MultiIterIsDeleted(Fts5Iter *pIter){ int iFirst = pIter->aFirst[1].iFirst; Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; + Fts5TombstoneArray *pArray = pSeg->pTombArray; - if( pSeg->pLeaf && pSeg->nTombstone ){ + if( pSeg->pLeaf && pArray ){ /* Figure out which page the rowid might be present on. */ - int iPg = ((u64)pSeg->iRowid) % pSeg->nTombstone; + int iPg = ((u64)pSeg->iRowid) % pArray->nTombstone; assert( iPg>=0 ); /* If tombstone hash page iPg has not yet been loaded from the ** database, load it now. */ - if( pSeg->apTombstone[iPg]==0 ){ - pSeg->apTombstone[iPg] = fts5DataRead(pIter->pIndex, + if( pArray->apTombstone[iPg]==0 ){ + pArray->apTombstone[iPg] = fts5DataRead(pIter->pIndex, FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg) ); - if( pSeg->apTombstone[iPg]==0 ) return 0; + if( pArray->apTombstone[iPg]==0 ) return 0; } return fts5IndexTombstoneQuery( - pSeg->apTombstone[iPg], - pSeg->nTombstone, + pArray->apTombstone[iPg], + pArray->nTombstone, pSeg->iRowid ); } @@ -240096,6 +242327,32 @@ static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ } } +/* +** All the component segment-iterators of pIter have been set up. This +** functions finishes setup for iterator pIter itself. +*/ +static void fts5MultiIterFinishSetup(Fts5Index *p, Fts5Iter *pIter){ + int iIter; + for(iIter=pIter->nSeg-1; iIter>0; iIter--){ + int iEq; + if( (iEq = fts5MultiIterDoCompare(pIter, iIter)) ){ + Fts5SegIter *pSeg = &pIter->aSeg[iEq]; + if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0); + fts5MultiIterAdvanced(p, pIter, iEq, iIter); + } + } + fts5MultiIterSetEof(pIter); + fts5AssertMultiIterSetup(p, pIter); + + if( (pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter)) + || fts5MultiIterIsDeleted(pIter) + ){ + fts5MultiIterNext(p, pIter, 0, 0); + }else if( pIter->base.bEof==0 ){ + Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst]; + pIter->xSetOutputs(pIter, pSeg); + } +} /* ** Allocate a new Fts5Iter object. @@ -240177,31 +242434,12 @@ static void fts5MultiIterNew( assert( iIter==nSeg ); } - /* If the above was successful, each component iterators now points + /* If the above was successful, each component iterator now points ** to the first entry in its segment. In this case initialize the ** aFirst[] array. Or, if an error has occurred, free the iterator ** object and set the output variable to NULL. */ if( p->rc==SQLITE_OK ){ - for(iIter=pNew->nSeg-1; iIter>0; iIter--){ - int iEq; - if( (iEq = fts5MultiIterDoCompare(pNew, iIter)) ){ - Fts5SegIter *pSeg = &pNew->aSeg[iEq]; - if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0); - fts5MultiIterAdvanced(p, pNew, iEq, iIter); - } - } - fts5MultiIterSetEof(pNew); - fts5AssertMultiIterSetup(p, pNew); - - if( (pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew)) - || fts5MultiIterIsDeleted(pNew) - ){ - fts5MultiIterNext(p, pNew, 0, 0); - }else if( pNew->base.bEof==0 ){ - Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst]; - pNew->xSetOutputs(pNew, pSeg); - } - + fts5MultiIterFinishSetup(p, pNew); }else{ fts5MultiIterFree(pNew); *ppOut = 0; @@ -240226,7 +242464,6 @@ static void fts5MultiIterNew2( pNew = fts5MultiIterAlloc(p, 2); if( pNew ){ Fts5SegIter *pIter = &pNew->aSeg[1]; - pIter->flags = FTS5_SEGITER_ONETERM; if( pData->szLeaf>0 ){ pIter->pLeaf = pData; @@ -240374,6 +242611,7 @@ static void fts5IndexDiscardData(Fts5Index *p){ sqlite3Fts5HashClear(p->pHash); p->nPendingData = 0; p->nPendingRow = 0; + p->flushRc = SQLITE_OK; } p->nContentlessDelete = 0; } @@ -240589,7 +242827,7 @@ static void fts5WriteDlidxAppend( } if( pDlidx->bPrevValid ){ - iVal = iRowid - pDlidx->iPrev; + iVal = (u64)iRowid - (u64)pDlidx->iPrev; }else{ i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno); assert( pDlidx->buf.n==0 ); @@ -241712,10 +243950,10 @@ static void fts5FlushSecureDelete( Fts5Index *p, Fts5Structure *pStruct, const char *zTerm, + int nTerm, i64 iRowid ){ const int f = FTS5INDEX_QUERY_SKIPHASH; - int nTerm = (int)strlen(zTerm); Fts5Iter *pIter = 0; /* Used to find term instance */ fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter); @@ -241789,8 +244027,7 @@ static void fts5FlushOneHash(Fts5Index *p){ int nDoclist; /* Size of doclist in bytes */ /* Get the term and doclist for this entry. */ - sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); - nTerm = (int)strlen(zTerm); + sqlite3Fts5HashScanEntry(pHash, &zTerm, &nTerm, &pDoclist, &nDoclist); if( bSecureDelete==0 ){ fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); if( p->rc!=SQLITE_OK ) break; @@ -241820,7 +244057,7 @@ static void fts5FlushOneHash(Fts5Index *p){ if( bSecureDelete ){ if( eDetail==FTS5_DETAIL_NONE ){ if( iOffrc!=SQLITE_OK || pDoclist[iOff]==0x01 ){ iOff++; continue; @@ -241956,6 +244193,10 @@ static void fts5FlushOneHash(Fts5Index *p){ */ static void fts5IndexFlush(Fts5Index *p){ /* Unless it is empty, flush the hash table to disk */ + if( p->flushRc ){ + p->rc = p->flushRc; + return; + } if( p->nPendingData || p->nContentlessDelete ){ assert( p->pHash ); fts5FlushOneHash(p); @@ -241964,6 +244205,8 @@ static void fts5IndexFlush(Fts5Index *p){ p->nPendingData = 0; p->nPendingRow = 0; p->nContentlessDelete = 0; + }else if( p->nPendingData || p->nContentlessDelete ){ + p->flushRc = p->rc; } } } @@ -242450,7 +244693,7 @@ static void fts5SetupPrefixIter( u8 *pToken, /* Buffer containing prefix to match */ int nToken, /* Size of buffer pToken in bytes */ Fts5Colset *pColset, /* Restrict matches to these columns */ - Fts5Iter **ppIter /* OUT: New iterator */ + Fts5Iter **ppIter /* OUT: New iterator */ ){ Fts5Structure *pStruct; Fts5Buffer *aBuf; @@ -242471,8 +244714,9 @@ static void fts5SetupPrefixIter( aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf); pStruct = fts5StructureRead(p); + assert( p->rc!=SQLITE_OK || (aBuf && pStruct) ); - if( aBuf && pStruct ){ + if( p->rc==SQLITE_OK ){ const int flags = FTS5INDEX_QUERY_SCAN | FTS5INDEX_QUERY_SKIPEMPTY | FTS5INDEX_QUERY_NOOUTPUT; @@ -242484,6 +244728,12 @@ static void fts5SetupPrefixIter( int bNewTerm = 1; memset(&doclist, 0, sizeof(doclist)); + + /* If iIdx is non-zero, then it is the number of a prefix-index for + ** prefixes 1 character longer than the prefix being queried for. That + ** index contains all the doclists required, except for the one + ** corresponding to the prefix itself. That one is extracted from the + ** main term index here. */ if( iIdx!=0 ){ int dummy = 0; const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; @@ -242507,6 +244757,7 @@ static void fts5SetupPrefixIter( pToken[0] = FTS5_MAIN_PREFIX + iIdx; fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); fts5IterSetOutputCb(&p->rc, p1); + for( /* no-op */ ; fts5MultiIterEof(p, p1)==0; fts5MultiIterNext2(p, p1, &bNewTerm) @@ -242522,7 +244773,6 @@ static void fts5SetupPrefixIter( } if( p1->base.nData==0 ) continue; - if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ int i1 = i*nMerge; @@ -242561,7 +244811,7 @@ static void fts5SetupPrefixIter( } fts5MultiIterFree(p1); - pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING); + pData = fts5IdxMalloc(p, sizeof(*pData)+doclist.n+FTS5_DATA_ZERO_PADDING); if( pData ){ pData->p = (u8*)&pData[1]; pData->nn = pData->szLeaf = doclist.n; @@ -242704,6 +244954,7 @@ static int sqlite3Fts5IndexClose(Fts5Index *p){ sqlite3_finalize(p->pIdxWriter); sqlite3_finalize(p->pIdxDeleter); sqlite3_finalize(p->pIdxSelect); + sqlite3_finalize(p->pIdxNextSelect); sqlite3_finalize(p->pDataVersion); sqlite3_finalize(p->pDeleteFromIdx); sqlite3Fts5HashFree(p->pHash); @@ -242799,6 +245050,454 @@ static int sqlite3Fts5IndexWrite( return rc; } +/* +** pToken points to a buffer of size nToken bytes containing a search +** term, including the index number at the start, used on a tokendata=1 +** table. This function returns true if the term in buffer pBuf matches +** token pToken/nToken. +*/ +static int fts5IsTokendataPrefix( + Fts5Buffer *pBuf, + const u8 *pToken, + int nToken +){ + return ( + pBuf->n>=nToken + && 0==memcmp(pBuf->p, pToken, nToken) + && (pBuf->n==nToken || pBuf->p[nToken]==0x00) + ); +} + +/* +** Ensure the segment-iterator passed as the only argument points to EOF. +*/ +static void fts5SegIterSetEOF(Fts5SegIter *pSeg){ + fts5DataRelease(pSeg->pLeaf); + pSeg->pLeaf = 0; +} + +/* +** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an +** array of these for each row it visits. Or, for an iterator used by an +** "ORDER BY rank" query, it accumulates an array of these for the entire +** query. +** +** Each instance in the array indicates the iterator (and therefore term) +** associated with position iPos of rowid iRowid. This is used by the +** xInstToken() API. +*/ +struct Fts5TokenDataMap { + i64 iRowid; /* Row this token is located in */ + i64 iPos; /* Position of token */ + int iIter; /* Iterator token was read from */ +}; + +/* +** An object used to supplement Fts5Iter for tokendata=1 iterators. +*/ +struct Fts5TokenDataIter { + int nIter; + int nIterAlloc; + + int nMap; + int nMapAlloc; + Fts5TokenDataMap *aMap; + + Fts5PoslistReader *aPoslistReader; + int *aPoslistToIter; + Fts5Iter *apIter[1]; +}; + +/* +** This function appends iterator pAppend to Fts5TokenDataIter pIn and +** returns the result. +*/ +static Fts5TokenDataIter *fts5AppendTokendataIter( + Fts5Index *p, /* Index object (for error code) */ + Fts5TokenDataIter *pIn, /* Current Fts5TokenDataIter struct */ + Fts5Iter *pAppend /* Append this iterator */ +){ + Fts5TokenDataIter *pRet = pIn; + + if( p->rc==SQLITE_OK ){ + if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){ + int nAlloc = pIn ? pIn->nIterAlloc*2 : 16; + int nByte = nAlloc * sizeof(Fts5Iter*) + sizeof(Fts5TokenDataIter); + Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte); + + if( pNew==0 ){ + p->rc = SQLITE_NOMEM; + }else{ + if( pIn==0 ) memset(pNew, 0, nByte); + pRet = pNew; + pNew->nIterAlloc = nAlloc; + } + } + } + if( p->rc ){ + sqlite3Fts5IterClose((Fts5IndexIter*)pAppend); + }else{ + pRet->apIter[pRet->nIter++] = pAppend; + } + assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc ); + + return pRet; +} + +/* +** Delete an Fts5TokenDataIter structure and its contents. +*/ +static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){ + if( pSet ){ + int ii; + for(ii=0; iinIter; ii++){ + fts5MultiIterFree(pSet->apIter[ii]); + } + sqlite3_free(pSet->aPoslistReader); + sqlite3_free(pSet->aMap); + sqlite3_free(pSet); + } +} + +/* +** Append a mapping to the token-map belonging to object pT. +*/ +static void fts5TokendataIterAppendMap( + Fts5Index *p, + Fts5TokenDataIter *pT, + int iIter, + i64 iRowid, + i64 iPos +){ + if( p->rc==SQLITE_OK ){ + if( pT->nMap==pT->nMapAlloc ){ + int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; + int nByte = nNew * sizeof(Fts5TokenDataMap); + Fts5TokenDataMap *aNew; + + aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte); + if( aNew==0 ){ + p->rc = SQLITE_NOMEM; + return; + } + + pT->aMap = aNew; + pT->nMapAlloc = nNew; + } + + pT->aMap[pT->nMap].iRowid = iRowid; + pT->aMap[pT->nMap].iPos = iPos; + pT->aMap[pT->nMap].iIter = iIter; + pT->nMap++; + } +} + +/* +** The iterator passed as the only argument must be a tokendata=1 iterator +** (pIter->pTokenDataIter!=0). This function sets the iterator output +** variables (pIter->base.*) according to the contents of the current +** row. +*/ +static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){ + int ii; + int nHit = 0; + i64 iRowid = SMALLEST_INT64; + int iMin = 0; + + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + + pIter->base.nData = 0; + pIter->base.pData = 0; + + for(ii=0; iinIter; ii++){ + Fts5Iter *p = pT->apIter[ii]; + if( p->base.bEof==0 ){ + if( nHit==0 || p->base.iRowidbase.iRowid; + nHit = 1; + pIter->base.pData = p->base.pData; + pIter->base.nData = p->base.nData; + iMin = ii; + }else if( p->base.iRowid==iRowid ){ + nHit++; + } + } + } + + if( nHit==0 ){ + pIter->base.bEof = 1; + }else{ + int eDetail = pIter->pIndex->pConfig->eDetail; + pIter->base.bEof = 0; + pIter->base.iRowid = iRowid; + + if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){ + fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, iRowid, -1); + }else + if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){ + int nReader = 0; + int nByte = 0; + i64 iPrev = 0; + + /* Allocate array of iterators if they are not already allocated. */ + if( pT->aPoslistReader==0 ){ + pT->aPoslistReader = (Fts5PoslistReader*)sqlite3Fts5MallocZero( + &pIter->pIndex->rc, + pT->nIter * (sizeof(Fts5PoslistReader) + sizeof(int)) + ); + if( pT->aPoslistReader==0 ) return; + pT->aPoslistToIter = (int*)&pT->aPoslistReader[pT->nIter]; + } + + /* Populate an iterator for each poslist that will be merged */ + for(ii=0; iinIter; ii++){ + Fts5Iter *p = pT->apIter[ii]; + if( iRowid==p->base.iRowid ){ + pT->aPoslistToIter[nReader] = ii; + sqlite3Fts5PoslistReaderInit( + p->base.pData, p->base.nData, &pT->aPoslistReader[nReader++] + ); + nByte += p->base.nData; + } + } + + /* Ensure the output buffer is large enough */ + if( fts5BufferGrow(&pIter->pIndex->rc, &pIter->poslist, nByte+nHit*10) ){ + return; + } + + /* Ensure the token-mapping is large enough */ + if( eDetail==FTS5_DETAIL_FULL && pT->nMapAlloc<(pT->nMap + nByte) ){ + int nNew = (pT->nMapAlloc + nByte) * 2; + Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc( + pT->aMap, nNew*sizeof(Fts5TokenDataMap) + ); + if( aNew==0 ){ + pIter->pIndex->rc = SQLITE_NOMEM; + return; + } + pT->aMap = aNew; + pT->nMapAlloc = nNew; + } + + pIter->poslist.n = 0; + + while( 1 ){ + i64 iMinPos = LARGEST_INT64; + + /* Find smallest position */ + iMin = 0; + for(ii=0; iiaPoslistReader[ii]; + if( pReader->bEof==0 ){ + if( pReader->iPosiPos; + iMin = ii; + } + } + } + + /* If all readers were at EOF, break out of the loop. */ + if( iMinPos==LARGEST_INT64 ) break; + + sqlite3Fts5PoslistSafeAppend(&pIter->poslist, &iPrev, iMinPos); + sqlite3Fts5PoslistReaderNext(&pT->aPoslistReader[iMin]); + + if( eDetail==FTS5_DETAIL_FULL ){ + pT->aMap[pT->nMap].iPos = iMinPos; + pT->aMap[pT->nMap].iIter = pT->aPoslistToIter[iMin]; + pT->aMap[pT->nMap].iRowid = iRowid; + pT->nMap++; + } + } + + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + } + } +} + +/* +** The iterator passed as the only argument must be a tokendata=1 iterator +** (pIter->pTokenDataIter!=0). This function advances the iterator. If +** argument bFrom is false, then the iterator is advanced to the next +** entry. Or, if bFrom is true, it is advanced to the first entry with +** a rowid of iFrom or greater. +*/ +static void fts5TokendataIterNext(Fts5Iter *pIter, int bFrom, i64 iFrom){ + int ii; + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + + for(ii=0; iinIter; ii++){ + Fts5Iter *p = pT->apIter[ii]; + if( p->base.bEof==0 + && (p->base.iRowid==pIter->base.iRowid || (bFrom && p->base.iRowidpIndex, p, bFrom, iFrom); + while( bFrom && p->base.bEof==0 + && p->base.iRowidpIndex->rc==SQLITE_OK + ){ + fts5MultiIterNext(p->pIndex, p, 0, 0); + } + } + } + + fts5IterSetOutputsTokendata(pIter); +} + +/* +** If the segment-iterator passed as the first argument is at EOF, then +** set pIter->term to a copy of buffer pTerm. +*/ +static void fts5TokendataSetTermIfEof(Fts5Iter *pIter, Fts5Buffer *pTerm){ + if( pIter && pIter->aSeg[0].pLeaf==0 ){ + fts5BufferSet(&pIter->pIndex->rc, &pIter->aSeg[0].term, pTerm->n, pTerm->p); + } +} + +/* +** This function sets up an iterator to use for a non-prefix query on a +** tokendata=1 table. +*/ +static Fts5Iter *fts5SetupTokendataIter( + Fts5Index *p, /* FTS index to query */ + const u8 *pToken, /* Buffer containing query term */ + int nToken, /* Size of buffer pToken in bytes */ + Fts5Colset *pColset /* Colset to filter on */ +){ + Fts5Iter *pRet = 0; + Fts5TokenDataIter *pSet = 0; + Fts5Structure *pStruct = 0; + const int flags = FTS5INDEX_QUERY_SCANONETERM | FTS5INDEX_QUERY_SCAN; + + Fts5Buffer bSeek = {0, 0, 0}; + Fts5Buffer *pSmall = 0; + + fts5IndexFlush(p); + pStruct = fts5StructureRead(p); + + while( p->rc==SQLITE_OK ){ + Fts5Iter *pPrev = pSet ? pSet->apIter[pSet->nIter-1] : 0; + Fts5Iter *pNew = 0; + Fts5SegIter *pNewIter = 0; + Fts5SegIter *pPrevIter = 0; + + int iLvl, iSeg, ii; + + pNew = fts5MultiIterAlloc(p, pStruct->nSegment); + if( pSmall ){ + fts5BufferSet(&p->rc, &bSeek, pSmall->n, pSmall->p); + fts5BufferAppendBlob(&p->rc, &bSeek, 1, (const u8*)"\0"); + }else{ + fts5BufferSet(&p->rc, &bSeek, nToken, pToken); + } + if( p->rc ){ + sqlite3Fts5IterClose((Fts5IndexIter*)pNew); + break; + } + + pNewIter = &pNew->aSeg[0]; + pPrevIter = (pPrev ? &pPrev->aSeg[0] : 0); + for(iLvl=0; iLvlnLevel; iLvl++){ + for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){ + Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg]; + int bDone = 0; + + if( pPrevIter ){ + if( fts5BufferCompare(pSmall, &pPrevIter->term) ){ + memcpy(pNewIter, pPrevIter, sizeof(Fts5SegIter)); + memset(pPrevIter, 0, sizeof(Fts5SegIter)); + bDone = 1; + }else if( pPrevIter->iEndofDoclist>pPrevIter->pLeaf->szLeaf ){ + fts5SegIterNextInit(p,(const char*)bSeek.p,bSeek.n-1,pSeg,pNewIter); + bDone = 1; + } + } + + if( bDone==0 ){ + fts5SegIterSeekInit(p, bSeek.p, bSeek.n, flags, pSeg, pNewIter); + } + + if( pPrevIter ){ + if( pPrevIter->pTombArray ){ + pNewIter->pTombArray = pPrevIter->pTombArray; + pNewIter->pTombArray->nRef++; + } + }else{ + fts5SegIterAllocTombstone(p, pNewIter); + } + + pNewIter++; + if( pPrevIter ) pPrevIter++; + if( p->rc ) break; + } + } + fts5TokendataSetTermIfEof(pPrev, pSmall); + + pNew->bSkipEmpty = 1; + pNew->pColset = pColset; + fts5IterSetOutputCb(&p->rc, pNew); + + /* Loop through all segments in the new iterator. Find the smallest + ** term that any segment-iterator points to. Iterator pNew will be + ** used for this term. Also, set any iterator that points to a term that + ** does not match pToken/nToken to point to EOF */ + pSmall = 0; + for(ii=0; iinSeg; ii++){ + Fts5SegIter *pII = &pNew->aSeg[ii]; + if( 0==fts5IsTokendataPrefix(&pII->term, pToken, nToken) ){ + fts5SegIterSetEOF(pII); + } + if( pII->pLeaf && (!pSmall || fts5BufferCompare(pSmall, &pII->term)>0) ){ + pSmall = &pII->term; + } + } + + /* If pSmall is still NULL at this point, then the new iterator does + ** not point to any terms that match the query. So delete it and break + ** out of the loop - all required iterators have been collected. */ + if( pSmall==0 ){ + sqlite3Fts5IterClose((Fts5IndexIter*)pNew); + break; + } + + /* Append this iterator to the set and continue. */ + pSet = fts5AppendTokendataIter(p, pSet, pNew); + } + + if( p->rc==SQLITE_OK && pSet ){ + int ii; + for(ii=0; iinIter; ii++){ + Fts5Iter *pIter = pSet->apIter[ii]; + int iSeg; + for(iSeg=0; iSegnSeg; iSeg++){ + pIter->aSeg[iSeg].flags |= FTS5_SEGITER_ONETERM; + } + fts5MultiIterFinishSetup(p, pIter); + } + } + + if( p->rc==SQLITE_OK ){ + pRet = fts5MultiIterAlloc(p, 0); + } + if( pRet ){ + pRet->pTokenDataIter = pSet; + if( pSet ){ + fts5IterSetOutputsTokendata(pRet); + }else{ + pRet->base.bEof = 1; + } + }else{ + fts5TokendataIterDelete(pSet); + } + + fts5StructureRelease(pStruct); + fts5BufferFree(&bSeek); + return pRet; +} + + /* ** Open a new iterator to iterate though all rowid that match the ** specified token or token prefix. @@ -242820,8 +245519,13 @@ static int sqlite3Fts5IndexQuery( if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ int iPrefixIdx = 0; /* +1 prefix index */ + int bTokendata = pConfig->bTokendata; if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); + if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){ + bTokendata = 0; + } + /* Figure out which index to search and set iIdx accordingly. If this ** is a prefix query for which there is no prefix index, set iIdx to ** greater than pConfig->nPrefix to indicate that the query will be @@ -242847,7 +245551,10 @@ static int sqlite3Fts5IndexQuery( } } - if( iIdx<=pConfig->nPrefix ){ + if( bTokendata && iIdx==0 ){ + buf.p[0] = '0'; + pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset); + }else if( iIdx<=pConfig->nPrefix ){ /* Straight index lookup */ Fts5Structure *pStruct = fts5StructureRead(p); buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx); @@ -242894,7 +245601,11 @@ static int sqlite3Fts5IndexQuery( static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; assert( pIter->pIndex->rc==SQLITE_OK ); - fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); + if( pIter->pTokenDataIter ){ + fts5TokendataIterNext(pIter, 0, 0); + }else{ + fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); + } return fts5IndexReturn(pIter->pIndex); } @@ -242927,7 +245638,11 @@ static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ */ static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); + if( pIter->pTokenDataIter ){ + fts5TokendataIterNext(pIter, 1, iMatch); + }else{ + fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); + } return fts5IndexReturn(pIter->pIndex); } @@ -242942,6 +245657,99 @@ static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ return (z ? &z[1] : 0); } +/* +** This is used by xInstToken() to access the token at offset iOff, column +** iCol of row iRowid. The token is returned via output variables *ppOut +** and *pnOut. The iterator passed as the first argument must be a tokendata=1 +** iterator (pIter->pTokenDataIter!=0). +*/ +static int sqlite3Fts5IterToken( + Fts5IndexIter *pIndexIter, + i64 iRowid, + int iCol, + int iOff, + const char **ppOut, int *pnOut +){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + Fts5TokenDataMap *aMap = pT->aMap; + i64 iPos = (((i64)iCol)<<32) + iOff; + + int i1 = 0; + int i2 = pT->nMap; + int iTest = 0; + + while( i2>i1 ){ + iTest = (i1 + i2) / 2; + + if( aMap[iTest].iRowidiRowid ){ + i2 = iTest; + }else{ + if( aMap[iTest].iPosiPos ){ + i2 = iTest; + }else{ + break; + } + } + } + + if( i2>i1 ){ + Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter]; + *ppOut = (const char*)pMap->aSeg[0].term.p+1; + *pnOut = pMap->aSeg[0].term.n-1; + } + + return SQLITE_OK; +} + +/* +** Clear any existing entries from the token-map associated with the +** iterator passed as the only argument. +*/ +static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; + if( pIter && pIter->pTokenDataIter ){ + pIter->pTokenDataIter->nMap = 0; + } +} + +/* +** Set a token-mapping for the iterator passed as the first argument. This +** is used in detail=column or detail=none mode when a token is requested +** using the xInstToken() API. In this case the caller tokenizers the +** current row and configures the token-mapping via multiple calls to this +** function. +*/ +static int sqlite3Fts5IndexIterWriteTokendata( + Fts5IndexIter *pIndexIter, + const char *pToken, int nToken, + i64 iRowid, int iCol, int iOff +){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + Fts5Index *p = pIter->pIndex; + int ii; + + assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL ); + assert( pIter->pTokenDataIter ); + + for(ii=0; iinIter; ii++){ + Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term; + if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break; + } + if( iinIter ){ + fts5TokendataIterAppendMap(p, pT, ii, iRowid, (((i64)iCol)<<32) + iOff); + } + return fts5IndexReturn(p); +} + /* ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery(). */ @@ -242949,6 +245757,7 @@ static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ if( pIndexIter ){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *pIndex = pIter->pIndex; + fts5TokendataIterDelete(pIter->pTokenDataIter); fts5MultiIterFree(pIter); sqlite3Fts5IndexCloseReader(pIndex); } @@ -243456,7 +246265,9 @@ static int fts5QueryCksum( int eDetail = p->pConfig->eDetail; u64 cksum = *pCksum; Fts5IndexIter *pIter = 0; - int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter); + int rc = sqlite3Fts5IndexQuery( + p, z, n, (flags | FTS5INDEX_QUERY_NOTOKENDATA), 0, &pIter + ); while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){ i64 rowid = pIter->iRowid; @@ -243623,7 +246434,7 @@ static void fts5IndexIntegrityCheckEmpty( } static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){ - int iTermOff = 0; + i64 iTermOff = 0; int ii; Fts5Buffer buf1 = {0,0,0}; @@ -243632,7 +246443,7 @@ static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){ ii = pLeaf->szLeaf; while( iinn && p->rc==SQLITE_OK ){ int res; - int iOff; + i64 iOff; int nIncr; ii += fts5GetVarint32(&pLeaf->p[ii], nIncr); @@ -244154,6 +246965,24 @@ static void fts5DecodeRowidList( } #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +static void fts5BufferAppendTerm(int *pRc, Fts5Buffer *pBuf, Fts5Buffer *pTerm){ + int ii; + fts5BufferGrow(pRc, pBuf, pTerm->n*2 + 1); + if( *pRc==SQLITE_OK ){ + for(ii=0; iin; ii++){ + if( pTerm->p[ii]==0x00 ){ + pBuf->p[pBuf->n++] = '\\'; + pBuf->p[pBuf->n++] = '0'; + }else{ + pBuf->p[pBuf->n++] = pTerm->p[ii]; + } + } + pBuf->p[pBuf->n] = 0x00; + } +} +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ + #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) /* ** The implementation of user-defined scalar function fts5_decode(). @@ -244261,9 +247090,8 @@ static void fts5DecodeFunction( iOff += fts5GetVarint32(&a[iOff], nAppend); term.n = nKeep; fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]); - sqlite3Fts5BufferAppendPrintf( - &rc, &s, " term=%.*s", term.n, (const char*)term.p - ); + sqlite3Fts5BufferAppendPrintf(&rc, &s, " term="); + fts5BufferAppendTerm(&rc, &s, &term); iOff += nAppend; /* Figure out where the doclist for this term ends */ @@ -244371,9 +247199,8 @@ static void fts5DecodeFunction( fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]); iOff += nByte; - sqlite3Fts5BufferAppendPrintf( - &rc, &s, " term=%.*s", term.n, (const char*)term.p - ); + sqlite3Fts5BufferAppendPrintf(&rc, &s, " term="); + fts5BufferAppendTerm(&rc, &s, &term); iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff); } @@ -244848,7 +247675,7 @@ struct Fts5FullTable { Fts5Global *pGlobal; /* Global (connection wide) data */ Fts5Cursor *pSortCsr; /* Sort data from this cursor */ int iSavepoint; /* Successful xSavepoint()+1 */ - int bInSavepoint; + #ifdef SQLITE_DEBUG struct Fts5TransactionState ts; #endif @@ -245386,12 +248213,15 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ } idxStr[iIdxStr] = '\0'; - /* Set idxFlags flags for the ORDER BY clause */ + /* Set idxFlags flags for the ORDER BY clause + ** + ** Note that tokendata=1 tables cannot currently handle "ORDER BY rowid DESC". + */ if( pInfo->nOrderBy==1 ){ int iSort = pInfo->aOrderBy[0].iColumn; if( iSort==(pConfig->nCol+1) && bSeenMatch ){ idxFlags |= FTS5_BI_ORDER_RANK; - }else if( iSort==-1 ){ + }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){ idxFlags |= FTS5_BI_ORDER_ROWID; } if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){ @@ -245643,6 +248473,16 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ ); assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) ); + /* If this cursor uses FTS5_PLAN_MATCH and this is a tokendata=1 table, + ** clear any token mappings accumulated at the fts5_index.c level. In + ** other cases, specifically FTS5_PLAN_SOURCE and FTS5_PLAN_SORTED_MATCH, + ** we need to retain the mappings for the entire query. */ + if( pCsr->ePlan==FTS5_PLAN_MATCH + && ((Fts5Table*)pCursor->pVtab)->pConfig->bTokendata + ){ + sqlite3Fts5ExprClearTokens(pCsr->pExpr); + } + if( pCsr->ePlan<3 ){ int bSkip = 0; if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc; @@ -246303,7 +249143,10 @@ static int fts5SpecialInsert( }else if( 0==sqlite3_stricmp("flush", zCmd) ){ rc = sqlite3Fts5FlushToDisk(&pTab->p); }else{ - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + rc = sqlite3Fts5FlushToDisk(&pTab->p); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + } if( rc==SQLITE_OK ){ rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError); } @@ -246628,7 +249471,10 @@ static int fts5ApiColumnText( ){ int rc = SQLITE_OK; Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; - if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) + Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + if( iCol<0 || iCol>=pTab->pConfig->nCol ){ + rc = SQLITE_RANGE; + }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) || pCsr->ePlan==FTS5_PLAN_SPECIAL ){ *pz = 0; @@ -246653,8 +249499,9 @@ static int fts5CsrPoslist( int rc = SQLITE_OK; int bLive = (pCsr->pSorter==0); - if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ - + if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){ + rc = SQLITE_RANGE; + }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ Fts5PoslistPopulator *aPopulator; int i; @@ -246678,15 +249525,21 @@ static int fts5CsrPoslist( CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST); } - if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){ - Fts5Sorter *pSorter = pCsr->pSorter; - int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); - *pn = pSorter->aIdx[iPhrase] - i1; - *pa = &pSorter->aPoslist[i1]; + if( rc==SQLITE_OK ){ + if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){ + Fts5Sorter *pSorter = pCsr->pSorter; + int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); + *pn = pSorter->aIdx[iPhrase] - i1; + *pa = &pSorter->aPoslist[i1]; + }else{ + *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); + } }else{ - *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); + *pa = 0; + *pn = 0; } + return rc; } @@ -246793,12 +249646,6 @@ static int fts5ApiInst( ){ if( iIdx<0 || iIdx>=pCsr->nInstCount ){ rc = SQLITE_RANGE; -#if 0 - }else if( fts5IsOffsetless((Fts5Table*)pCsr->base.pVtab) ){ - *piPhrase = pCsr->aInst[iIdx*3]; - *piCol = pCsr->aInst[iIdx*3 + 2]; - *piOff = -1; -#endif }else{ *piPhrase = pCsr->aInst[iIdx*3]; *piCol = pCsr->aInst[iIdx*3 + 1]; @@ -247053,13 +249900,56 @@ static int fts5ApiPhraseFirstColumn( return rc; } +/* +** xQueryToken() API implemenetation. +*/ +static int fts5ApiQueryToken( + Fts5Context* pCtx, + int iPhrase, + int iToken, + const char **ppOut, + int *pnOut +){ + Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; + return sqlite3Fts5ExprQueryToken(pCsr->pExpr, iPhrase, iToken, ppOut, pnOut); +} + +/* +** xInstToken() API implemenetation. +*/ +static int fts5ApiInstToken( + Fts5Context *pCtx, + int iIdx, + int iToken, + const char **ppOut, int *pnOut +){ + Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; + int rc = SQLITE_OK; + if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0 + || SQLITE_OK==(rc = fts5CacheInstArray(pCsr)) + ){ + if( iIdx<0 || iIdx>=pCsr->nInstCount ){ + rc = SQLITE_RANGE; + }else{ + int iPhrase = pCsr->aInst[iIdx*3]; + int iCol = pCsr->aInst[iIdx*3 + 1]; + int iOff = pCsr->aInst[iIdx*3 + 2]; + i64 iRowid = fts5CursorRowid(pCsr); + rc = sqlite3Fts5ExprInstToken( + pCsr->pExpr, iRowid, iPhrase, iCol, iOff, iToken, ppOut, pnOut + ); + } + } + return rc; +} + static int fts5ApiQueryPhrase(Fts5Context*, int, void*, int(*)(const Fts5ExtensionApi*, Fts5Context*, void*) ); static const Fts5ExtensionApi sFts5Api = { - 2, /* iVersion */ + 3, /* iVersion */ fts5ApiUserData, fts5ApiColumnCount, fts5ApiRowCount, @@ -247079,6 +249969,8 @@ static const Fts5ExtensionApi sFts5Api = { fts5ApiPhraseNext, fts5ApiPhraseFirstColumn, fts5ApiPhraseNextColumn, + fts5ApiQueryToken, + fts5ApiInstToken }; /* @@ -247345,9 +250237,7 @@ static int fts5RenameMethod( ){ int rc; Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - pTab->bInSavepoint = 1; rc = sqlite3Fts5StorageRename(pTab->pStorage, zName); - pTab->bInSavepoint = 0; return rc; } @@ -247364,26 +250254,12 @@ static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; int rc = SQLITE_OK; - char *zSql = 0; + fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); - - if( pTab->bInSavepoint==0 ){ - zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", - pTab->p.pConfig->zDb, pTab->p.pConfig->zName, pTab->p.pConfig->zName - ); - if( zSql ){ - pTab->bInSavepoint = 1; - rc = sqlite3_exec(pTab->p.pConfig->db, zSql, 0, 0, 0); - pTab->bInSavepoint = 0; - sqlite3_free(zSql); - }else{ - rc = SQLITE_NOMEM; - } - if( rc==SQLITE_OK ){ - pTab->iSavepoint = iSavepoint+1; - } + rc = sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint+1; } - return rc; } @@ -247415,8 +250291,8 @@ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ int rc = SQLITE_OK; fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); fts5TripCursors(pTab); - pTab->p.pConfig->pgsz = 0; if( (iSavepoint+1)<=pTab->iSavepoint ){ + pTab->p.pConfig->pgsz = 0; rc = sqlite3Fts5StorageRollback(pTab->pStorage); } return rc; @@ -247621,7 +250497,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2024-01-15 17:01:13 1066602b2b1976fe58b5150777cced894af17c803e068f5918390d6915b46e1d", -1, SQLITE_TRANSIENT); } /* @@ -247644,7 +250520,7 @@ static int fts5ShadowName(const char *zName){ ** if anything is found amiss. Return a NULL pointer if everything is ** OK. */ -static int fts5Integrity( +static int fts5IntegrityMethod( sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */ const char *zSchema, /* Name of schema in which this table lives */ const char *zTabname, /* Name of the table itself */ @@ -247702,7 +250578,7 @@ static int fts5Init(sqlite3 *db){ /* xRelease */ fts5ReleaseMethod, /* xRollbackTo */ fts5RollbackToMethod, /* xShadowName */ fts5ShadowName, - /* xIntegrity */ fts5Integrity + /* xIntegrity */ fts5IntegrityMethod }; int rc; @@ -248468,7 +251344,7 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){ } if( rc==SQLITE_OK ){ - rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0); + rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, pConfig->pzErrmsg); } while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){ @@ -249255,6 +252131,12 @@ static const unsigned char sqlite3Utf8Trans1[] = { #endif /* ifndef SQLITE_AMALGAMATION */ +#define FTS5_SKIP_UTF8(zIn) { \ + if( ((unsigned char)(*(zIn++)))>=0xc0 ){ \ + while( (((unsigned char)*zIn) & 0xc0)==0x80 ){ zIn++; } \ + } \ +} + typedef struct Unicode61Tokenizer Unicode61Tokenizer; struct Unicode61Tokenizer { unsigned char aTokenChar[128]; /* ASCII range token characters */ @@ -250290,6 +253172,7 @@ static int fts5PorterTokenize( typedef struct TrigramTokenizer TrigramTokenizer; struct TrigramTokenizer { int bFold; /* True to fold to lower-case */ + int iFoldParam; /* Parameter to pass to Fts5UnicodeFold() */ }; /* @@ -250316,6 +253199,7 @@ static int fts5TriCreate( }else{ int i; pNew->bFold = 1; + pNew->iFoldParam = 0; for(i=0; rc==SQLITE_OK && ibFold = (zArg[0]=='0'); } + }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ + if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ + rc = SQLITE_ERROR; + }else{ + pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; + } }else{ rc = SQLITE_ERROR; } } + + if( pNew->iFoldParam!=0 && pNew->bFold==0 ){ + rc = SQLITE_ERROR; + } + if( rc!=SQLITE_OK ){ fts5TriDelete((Fts5Tokenizer*)pNew); pNew = 0; @@ -250350,40 +253245,62 @@ static int fts5TriTokenize( TrigramTokenizer *p = (TrigramTokenizer*)pTok; int rc = SQLITE_OK; char aBuf[32]; + char *zOut = aBuf; + int ii; const unsigned char *zIn = (const unsigned char*)pText; const unsigned char *zEof = &zIn[nText]; u32 iCode; + int aStart[3]; /* Input offset of each character in aBuf[] */ UNUSED_PARAM(unusedFlags); - while( 1 ){ - char *zOut = aBuf; - int iStart = zIn - (const unsigned char*)pText; - const unsigned char *zNext; - READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) break; - zNext = zIn; - if( zInbFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); - WRITE_UTF8(zOut, iCode); + /* Populate aBuf[] with the characters for the first trigram. */ + for(ii=0; ii<3; ii++){ + do { + aStart[ii] = zIn - (const unsigned char*)pText; + READ_UTF8(zIn, zEof, iCode); + if( iCode==0 ) return SQLITE_OK; + if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); + }while( iCode==0 ); + WRITE_UTF8(zOut, iCode); + } + + /* At the start of each iteration of this loop: + ** + ** aBuf: Contains 3 characters. The 3 characters of the next trigram. + ** zOut: Points to the byte following the last character in aBuf. + ** aStart[3]: Contains the byte offset in the input text corresponding + ** to the start of each of the three characters in the buffer. + */ + assert( zIn<=zEof ); + while( 1 ){ + int iNext; /* Start of character following current tri */ + const char *z1; + + /* Read characters from the input up until the first non-diacritic */ + do { + iNext = zIn - (const unsigned char*)pText; READ_UTF8(zIn, zEof, iCode); if( iCode==0 ) break; - }else{ - break; - } - if( zInbFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); - WRITE_UTF8(zOut, iCode); - READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) break; - if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); - WRITE_UTF8(zOut, iCode); - }else{ - break; - } - rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf); - if( rc!=SQLITE_OK ) break; - zIn = zNext; + if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); + }while( iCode==0 ); + + /* Pass the current trigram back to fts5 */ + rc = xToken(pCtx, 0, aBuf, zOut-aBuf, aStart[0], iNext); + if( iCode==0 || rc!=SQLITE_OK ) break; + + /* Remove the first character from buffer aBuf[]. Append the character + ** with codepoint iCode. */ + z1 = aBuf; + FTS5_SKIP_UTF8(z1); + memmove(aBuf, z1, zOut - z1); + zOut -= (z1 - aBuf); + WRITE_UTF8(zOut, iCode); + + /* Update the aStart[] array */ + aStart[0] = aStart[1]; + aStart[1] = aStart[2]; + aStart[2] = iNext; } return rc; @@ -250406,7 +253323,9 @@ static int sqlite3Fts5TokenizerPattern( ){ if( xCreate==fts5TriCreate ){ TrigramTokenizer *p = (TrigramTokenizer*)pTok; - return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; + if( p->iFoldParam==0 ){ + return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; + } } return FTS5_PATTERN_NONE; } @@ -252195,7 +255114,7 @@ static int fts5VocabFilterMethod( if( pEq ){ zTerm = (const char *)sqlite3_value_text(pEq); nTerm = sqlite3_value_bytes(pEq); - f = 0; + f = FTS5INDEX_QUERY_NOTOKENDATA; }else{ if( pGe ){ zTerm = (const char *)sqlite3_value_text(pGe); diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index ef0237bde4d..c2d2456dde6 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.2" -#define SQLITE_VERSION_NUMBER 3044002 -#define SQLITE_SOURCE_ID "2023-11-24 11:41:44 ebead0e7230cd33bcec9f95d2183069565b9e709bf745c9b5db65cc0cbf92c0f" +#define SQLITE_VERSION "3.45.0" +#define SQLITE_VERSION_NUMBER 3045000 +#define SQLITE_SOURCE_ID "2024-01-15 17:01:13 1066602b2b1976fe58b5150777cced894af17c803e068f5918390d6915b46e1d" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -3954,15 +3954,17 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); ** ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language -** text that describes the error, as either UTF-8 or UTF-16 respectively. +** text that describes the error, as either UTF-8 or UTF-16 respectively, +** or NULL if no error message is available. ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** -** ^The sqlite3_errstr() interface returns the English-language text -** that describes the [result code], as UTF-8. +** ^The sqlite3_errstr(E) interface returns the English-language text +** that describes the [result code] E, as UTF-8, or NULL if E is not an +** result code for which a text error message is available. ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** @@ -8037,9 +8039,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** ^(Some systems (for example, Windows 95) do not support the operation ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() -** will always return SQLITE_BUSY. The SQLite core only ever uses -** sqlite3_mutex_try() as an optimization so this is acceptable -** behavior.)^ +** will always return SQLITE_BUSY. In most cases the SQLite core only uses +** sqlite3_mutex_try() as an optimization, so this is acceptable +** behavior. The exceptions are unix builds that set the +** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working +** sqlite3_mutex_try() is required.)^ ** ** ^The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior @@ -8298,6 +8302,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ +#define SQLITE_TESTCTRL_JSON_SELFCHECK 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ @@ -12811,8 +12816,11 @@ struct Fts5PhraseIter { ** created with the "columnsize=0" option. ** ** xColumnText: -** This function attempts to retrieve the text of column iCol of the -** current document. If successful, (*pz) is set to point to a buffer +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the text of column iCol of +** the current document. If successful, (*pz) is set to point to a buffer ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, ** if an error occurs, an SQLite error code is returned and the final values @@ -12822,8 +12830,10 @@ struct Fts5PhraseIter { ** Returns the number of phrases in the current query expression. ** ** xPhraseSize: -** Returns the number of tokens in phrase iPhrase of the query. Phrases -** are numbered starting from zero. +** If parameter iCol is less than zero, or greater than or equal to the +** number of phrases in the current query, as returned by xPhraseCount, +** 0 is returned. Otherwise, this function returns the number of tokens in +** phrase iPhrase of the query. Phrases are numbered starting from zero. ** ** xInstCount: ** Set *pnInst to the total number of occurrences of all phrases within @@ -12839,12 +12849,13 @@ struct Fts5PhraseIter { ** Query for the details of phrase match iIdx within the current row. ** Phrase matches are numbered starting from zero, so the iIdx argument ** should be greater than or equal to zero and smaller than the value -** output by xInstCount(). +** output by xInstCount(). If iIdx is less than zero or greater than +** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. ** -** Usually, output parameter *piPhrase is set to the phrase number, *piCol +** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. Returns SQLITE_OK if successful, or an error -** code (i.e. SQLITE_NOMEM) if an error occurs. +** first token of the phrase. SQLITE_OK is returned if successful, or an +** error code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -12870,6 +12881,10 @@ struct Fts5PhraseIter { ** Invoking Api.xUserData() returns a copy of the pointer passed as ** the third argument to pUserData. ** +** If parameter iPhrase is less than zero, or greater than or equal to +** the number of phrases in the query, as returned by xPhraseCount(), +** this function returns SQLITE_RANGE. +** ** If the callback function returns any value other than SQLITE_OK, the ** query is abandoned and the xQueryPhrase function returns immediately. ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. @@ -12984,9 +12999,42 @@ struct Fts5PhraseIter { ** ** xPhraseNextColumn() ** See xPhraseFirstColumn above. +** +** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase iPhrase of the current +** query. Before returning, output parameter *ppToken is set to point +** to a buffer containing the requested token, and *pnToken to the +** size of this buffer in bytes. +** +** If iPhrase or iToken are less than zero, or if iPhrase is greater than +** or equal to the number of phrases in the query as reported by +** xPhraseCount(), or if iToken is equal to or greater than the number of +** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken + are both zeroed. +** +** The output text is not a copy of the query text that specified the +** token. It is the output of the tokenizer module. For tokendata=1 +** tables, this includes any embedded 0x00 and trailing data. +** +** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase hit iIdx within the +** current row. If iIdx is less than zero or greater than or equal to the +** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, +** output variable (*ppToken) is set to point to a buffer containing the +** matching document token, and (*pnToken) to the size of that buffer in +** bytes. This API is not available if the specified token matches a +** prefix query term. In that case both output variables are always set +** to 0. +** +** The output text is not a copy of the document text that was tokenized. +** It is the output of the tokenizer module. For tokendata=1 tables, this +** includes any embedded 0x00 and trailing data. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ void *(*xUserData)(Fts5Context*); @@ -13021,6 +13069,13 @@ struct Fts5ExtensionApi { int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); + + /* Below this point are iVersion>=3 only */ + int (*xQueryToken)(Fts5Context*, + int iPhrase, int iToken, + const char **ppToken, int *pnToken + ); + int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); }; /* From d42cfb5ccbc7087548a728f08f05d7edc5a9f665 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 25 Jan 2024 09:51:55 +0100 Subject: [PATCH 29/58] windows: Avoid infinite recursion with certain fonts Amends 922d195020d54d7e599d135f6a5e0338100e08f1. Another infinite recursion was found in the case of populating font families for cases where the typographical name is different from the populated name. The specific font triggering this had two "preferred name" entries in its name data. This was one for Chinese (PRC) and another for Chinese (Taiwan). Our GDI backend does not do matching based on locale, but will prefer the English if available, otherwise it will just pick the first one. The font in question does not have the English preferred name. For this particular font, we would select the Chinese (Taiwan) name as preferred and since it had not been populated, we would populate this. However, on Chinese (PRC) locale, Windows would report this according to the Chinese (PRC) name. We would once again translate this to Chinese (Taiwan) and go into an infinite recursion populating it. The quick fix is to mark the preferred family as populated before entering the recursion, so that we do not re-populate it a second time later. Ideally, the font database would match the preferred name based on locale, but since we are moving away from the GDI font database and this is already handled better with the DirectWrite database, just fixing the recursion is sufficient here. [ChangeLog][Windows] Fixed an issue where an infinite recursion could occur if the system had a font with multiple preferred names in non-English languages. Fixes: QTBUG-118238 Change-Id: I6ded369f1c908e51c0ba2ad9127538faf07e192e Reviewed-by: Lars Knoll Reviewed-by: Liang Qi (cherry picked from commit 11344f57235b5c8149d231c1331f86bcff51bd50) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 5b2f3520422f7f9096a5ce9edde56705612b5eea) (cherry picked from commit 2a2875ce6748b47272691648fdf433893e48f0ea) (cherry picked from commit 13ab0a98677d3bf94e2fd8d29d0dc607288ecb82) (cherry picked from commit bc82ff6ee2d64a67a12c40bcd5f787ba56f2cf78) --- .../windows/qwindowsfontdatabase.cpp | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index 217a968c645..8cd030b9d5a 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -1106,15 +1106,7 @@ static bool addFontToDatabase(QString familyName, writingSystems.setSupported(ws); } - // We came here from populating a different font family, so we have - // to ensure the entire typographic family is populated before we - // mark it as such inside registerFont() - if (!subFamilyName.isEmpty() - && familyName != subFamilyName - && sfp->populatedFontFamily != familyName - && !QPlatformFontDatabase::isFamilyPopulated(familyName)) { - sfp->windowsFontDatabase->populateFamily(familyName); - } + const bool wasPopulated = QPlatformFontDatabase::isFamilyPopulated(familyName); QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight, style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName)); @@ -1130,6 +1122,16 @@ static bool addFontToDatabase(QString familyName, QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold, QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName)); + // We came here from populating a different font family, so we have + // to ensure the entire typographic family is populated before we + // mark it as such inside registerFont() + if (!subFamilyName.isEmpty() + && familyName != subFamilyName + && sfp->populatedFontFamily != familyName + && !wasPopulated) { + sfp->windowsFontDatabase->populateFamily(familyName); + } + if (!subFamilyName.isEmpty() && familyName != subFamilyName) { QPlatformFontDatabase::registerFont(subFamilyName, subFamilyStyle, foundryName, weight, style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName)); From 61f7d5cf8c5cc8b30b21d96eab6d8bac8b2381a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 26 Jan 2024 16:09:55 +0100 Subject: [PATCH 30/58] PSL: add changelog entry to the suggested commit message Change-Id: I468ff1a4e9397259eda2d98f8b5bfcf7e892f10a Reviewed-by: Marc Mutz Reviewed-by: Edward Welbourne (cherry picked from commit 0db7d7e54c2399739d1e44a88a5d21997bade08b) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit a9da350b1c16802394966d3ea72dcf5c16e4348f) (cherry picked from commit 926705a360b0d329be1e61d63d81335d7f5be704) (cherry picked from commit c89fd0b0526fe526185dd24e19417070c740a9e6) (cherry picked from commit 08a27f74dec74eb280364daced74bf13b0a6f309) --- util/update_public_suffix_list.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/util/update_public_suffix_list.sh b/util/update_public_suffix_list.sh index 487ccbff077..438a757f942 100755 --- a/util/update_public_suffix_list.sh +++ b/util/update_public_suffix_list.sh @@ -115,6 +115,10 @@ run_or_die git commit -m "Update public suffix list Version $GITSHA1, fetched on $TODAY. + + +[ChangeLog][Third-Party Code] Updated the public suffix list to upstream +SHA $GITSHA1. " --edit msg "Please use topic:publicsuffix-list-$GITSHA1 when pushing." From b35aa24d3679c2d2372c4dd0b788901a8b350b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 25 Jan 2024 15:27:39 +0100 Subject: [PATCH 31/58] Fix license header for update_public_suffix_list.sh It is not a real comment. Change-Id: I0cc6930d8393f19671e417c805a645e2f99c6c24 Reviewed-by: Marc Mutz (cherry picked from commit 60d558217fe61161bf15a98d20822eff9e4b50aa) Reviewed-by: Qt Cherry-pick Bot --- util/update_public_suffix_list.sh | 54 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/util/update_public_suffix_list.sh b/util/update_public_suffix_list.sh index 438a757f942..9eec9c1042d 100755 --- a/util/update_public_suffix_list.sh +++ b/util/update_public_suffix_list.sh @@ -1,31 +1,31 @@ #!/bin/bash -/**************************************************************************** -** -** Copyright (C) 2023 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the utils of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -** -** -** -** -** -** -** -******************************************************************************/ +#/**************************************************************************** +#** +#** Copyright (C) 2023 The Qt Company Ltd. +#** Contact: https://www.qt.io/licensing/ +#** +#** This file is part of the utils of the Qt Toolkit. +#** +#** $QT_BEGIN_LICENSE:COMM$ +#** +#** Commercial License Usage +#** Licensees holding valid commercial Qt licenses may use this file in +#** accordance with the commercial license agreement provided with the +#** Software or, alternatively, in accordance with the terms contained in +#** a written agreement between you and The Qt Company. For licensing terms +#** and conditions see https://www.qt.io/terms-conditions. For further +#** information use the contact form at https://www.qt.io/contact-us. +#** +#** $QT_END_LICENSE$ +#** +#** +#** +#** +#** +#** +#** +#** +#******************************************************************************/ # This is the Qt 5.15 version of the script. The way to update the # publicsuffix-list is very different from Qt 6.5+, but this script is From cbb8025ab60aa850981da0be7691265f1525036b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 25 Jan 2024 15:27:39 +0100 Subject: [PATCH 32/58] Update public suffix list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Version 883ced078a83f9d79a98933145425c221a5e51f0, fetched on 2024-01-25. [ChangeLog][Third-Party Code] Updated the public suffix list to upstream SHA 883ced078a83f9d79a98933145425c221a5e51f0. Task-number: QTBUG-121325 Change-Id: I95e82b5c351218c1641e11e7a166ae21be2c5ad6 Reviewed-by: Edward Welbourne Reviewed-by: Marc Mutz (cherry picked from commit a17c10a63b3a86c71ebe6df54e56c9bce3ed5f18) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 036e9811d28b61f1a67a51b7157623adbe6d4eba) (cherry picked from commit 0624fb868f04be920286ed6de1c8549b8eeafd68) (cherry picked from commit 036f8858044c886cf72c048e4725c9aa0338ff14) (cherry picked from commit f3f584c32a6c109ea5eefe74a0df52a00ad24d9b) Reviewed-by: Mårten Nordheim --- src/corelib/io/qt_attribution.json | 2 +- src/corelib/io/qurltlds_p.h | 29137 ++++++++++++++------------- 2 files changed, 15398 insertions(+), 13741 deletions(-) diff --git a/src/corelib/io/qt_attribution.json b/src/corelib/io/qt_attribution.json index 24f7180250e..602d381188c 100644 --- a/src/corelib/io/qt_attribution.json +++ b/src/corelib/io/qt_attribution.json @@ -20,7 +20,7 @@ supported by Qt (by the QNetworkCookieJar class).", "Homepage": "Consult https://github.com/publicsuffix/list for the sha1 but download from ...", "Homepage": "http://publicsuffix.org/", - "Version": "0522c13180d298cc10ac9d7e5a7d88aeb1856401, fetched on 2023-10-31", + "Version": "883ced078a83f9d79a98933145425c221a5e51f0, fetched on 2024-01-30", "License": "Mozilla Public License 2.0", "LicenseFile": "PSL-LICENSE.txt", "LicenseId": "MPL-2.0", diff --git a/src/corelib/io/qurltlds_p.h b/src/corelib/io/qurltlds_p.h index dcb81ec403d..b9ebb6e9908 100644 --- a/src/corelib/io/qurltlds_p.h +++ b/src/corelib/io/qurltlds_p.h @@ -61,14022 +61,15679 @@ QT_BEGIN_NAMESPACE -static const quint16 tldCount = 9568; +static const quint16 tldCount = 9562; static const quint32 tldIndices[] = { 0, -0, -0, -6, -39, -46, -84, -98, -112, -119, -147, -161, -161, -170, -170, -177, -198, -359, -385, -405, -405, -405, -412, -412, -412, -412, -423, -430, -430, -430, -503, -510, -517, -517, -524, -524, -583, -583, -603, -603, -621, -628, -628, -628, -639, -658, -658, -665, -708, -788, -803, -830, -837, -853, -860, -860, -860, -860, -867, -867, -867, -867, -929, -929, -929, -929, -929, -935, -935, -977, -1005, +17, +33, +42, +57, +57, +57, +82, +82, +82, +82, +82, +121, +121, +162, +173, +182, +182, +195, +209, +292, +303, +308, +355, +368, +377, +388, +388, +388, +400, +400, +425, +460, +460, +460, +488, +502, +502, +560, +570, +570, +570, +570, +570, +579, +585, +585, +606, +616, +616, +634, +650, +670, +670, +680, +680, +710, +716, +720, +732, +743, +743, +775, +801, +814, +833, +833, +873, +873, +915, +925, +942, +962, +962, +972, +972, +972, +993, +1000, +1000, +1000, 1019, -1030, -1030, -1030, -1030, -1040, -1040, -1047, -1056, -1095, -1197, -1204, -1238, +1032, +1042, +1053, +1111, +1123, +1161, +1232, +1232, +1239, +1246, 1253, -1268, -1292, -1292, -1306, -1326, -1326, -1326, -1326, -1333, -1351, -1351, -1358, -1358, -1358, -1358, -1380, -1406, -1417, -1417, -1475, -1482, -1494, -1501, -1501, -1511, -1518, -1525, -1602, -1704, -1717, -1741, -1741, -1748, -1772, -1772, -1779, -1785, -1785, -1785, -1792, -1792, -1846, -1846, -1864, -1864, -1864, -1871, -1911, -1922, -1949, +1253, +1260, +1278, +1278, +1285, +1298, +1298, +1309, +1309, +1330, +1364, +1378, +1397, +1413, +1413, +1429, +1473, +1493, +1526, +1536, +1536, +1569, +1576, +1583, +1583, +1583, +1590, +1597, +1604, +1604, +1604, +1670, +1687, +1694, +1760, +1771, +1771, +1778, +1798, +1811, +1834, +1874, +1891, +1891, +1891, 1970, 1970, -1970, -1984, -1991, -1991, -1991, -1991, -1998, -2006, -2054, -2054, -2064, -2064, -2064, -2089, -2093, -2109, -2109, -2122, -2122, -2122, -2122, -2196, -2196, -2196, -2196, -2196, -2202, -2209, -2247, -2252, -2252, -2252, -2252, -2252, -2252, -2252, -2252, -2252, -2260, -2273, -2378, -2378, -2388, -2399, -2399, -2435, -2435, -2435, -2435, -2435, -2435, -2435, -2435, -2569, -2581, -2603, -2603, -2610, -2621, -2653, -2653, -2682, -2682, -2708, -2708, -2716, -2716, -2716, -2730, -2737, -2749, -2760, -2835, -2857, -2867, -2867, -2867, -2873, -2873, +2009, +2009, +2016, +2024, +2030, +2030, +2037, +2037, +2044, +2044, +2050, +2072, +2079, +2079, +2117, +2129, +2136, +2136, +2136, +2150, +2150, +2176, +2187, +2204, +2221, +2239, +2256, +2256, +2270, +2295, +2307, +2342, +2348, +2381, +2395, +2402, +2402, +2402, +2448, +2448, +2454, +2484, +2516, +2516, +2568, +2586, +2593, +2611, +2618, +2618, +2636, +2647, +2647, +2654, +2677, +2705, +2705, +2728, +2728, +2741, +2741, +2781, +2824, +2840, 2879, -2885, -2885, -2885, -2885, -2899, -2979, -2994, -3004, -3004, -3009, -3015, +2879, +2898, +2909, +2916, +2957, +2996, +3014, +3014, 3031, -3069, -3069, -3069, -3086, -3086, -3111, -3117, -3117, -3128, -3128, -3134, -3158, -3240, +3031, +3037, +3037, +3079, +3119, +3119, +3119, +3137, +3166, +3166, +3172, +3208, +3221, 3246, 3246, 3246, -3246, -3246, -3246, -3252, -3269, -3275, -3275, -3275, +3261, +3274, 3281, -3370, -3370, -3370, -3370, -3370, -3376, -3376, -3394, -3412, -3412, -3412, -3418, -3418, -3424, -3430, -3478, -3478, -3478, -3539, -3688, -3688, -3698, -3698, +3281, +3295, +3295, +3295, +3301, +3301, +3301, +3309, +3334, +3338, +3361, +3395, +3401, +3401, +3433, +3445, +3445, +3452, +3452, +3471, +3471, +3497, +3517, +3517, +3517, +3517, +3541, +3541, +3547, +3554, +3574, +3602, +3602, +3602, +3602, +3609, +3638, +3651, +3676, +3683, +3719, 3733, -3752, -3752, -3752, -3752, +3751, 3759, -3759, -3759, -3759, -3857, -3857, -3864, -3868, -3868, -3868, -3875, -3893, -3904, -3904, -3904, -3904, -3904, -3908, -3908, -3931, -3931, -3931, -3958, -4129, -4156, -4156, -4156, -4164, -4175, -4175, -4181, -4181, -4181, -4181, -4181, -4194, -4277, -4284, -4284, -4284, -4284, -4284, -4284, -4304, -4309, -4309, -4316, -4316, -4326, -4333, -4333, -4345, -4345, -4345, -4422, -4512, -4512, -4518, -4526, -4537, -4552, -4552, -4559, -4577, -4577, -4577, -4577, -4583, -4771, -4783, -4783, -4783, -4783, -4789, -4799, -4805, -4821, -4821, -4821, -4821, -4827, -4827, -4834, -4834, -4834, -4844, -4920, -5057, -5063, -5072, -5072, -5081, -5087, -5087, -5098, -5098, -5098, -5098, -5098, -5098, -5175, -5181, -5196, -5196, -5196, -5202, -5218, +3790, +3797, +3822, +3839, +3839, +3846, +3865, +3865, +3894, +3901, +3905, +3912, +3966, +3966, +3966, +4004, +4028, +4038, +4038, +4051, +4066, +4073, +4087, +4114, +4153, +4167, +4174, +4185, +4199, +4199, +4213, +4213, +4213, +4213, +4238, +4244, +4263, +4305, +4311, +4355, +4359, +4359, +4366, +4366, +4366, +4413, +4439, +4445, +4465, +4472, +4502, +4511, +4511, +4534, +4534, +4544, +4562, +4568, +4568, +4630, +4637, +4637, +4669, +4669, +4669, +4676, +4687, +4713, +4720, +4748, +4757, +4791, +4801, +4808, +4808, +4822, +4853, +4885, +4885, +4935, +4941, +4941, +4977, +5011, +5079, +5093, +5109, +5109, +5109, +5116, +5122, +5122, +5122, +5171, +5171, +5207, +5234, +5250, 5257, -5257, -5257, -5257, -5257, -5257, -5257, -5257, -5278, -5278, -5278, -5305, -5456, -5462, -5479, -5494, -5494, -5500, -5500, -5512, -5512, -5519, -5519, -5536, -5536, -5608, -5614, -5630, -5639, -5655, -5668, -5716, -5752, +5270, +5326, +5333, +5385, +5399, +5406, +5418, +5418, +5430, +5445, +5460, +5460, +5467, +5487, +5498, +5516, +5523, +5548, +5557, +5563, +5592, +5599, +5612, +5635, +5648, +5663, +5688, +5710, +5733, 5758, -5758, -5781, -5785, -5791, -5797, -5797, -5803, -5803, -5803, -5809, -5863, -5863, -5870, -5870, -5870, -5870, -5870, -5870, -5870, -5870, -5886, -5886, -5886, -5956, -5999, -6005, -6005, -6011, -6011, -6021, -6083, -6083, -6083, -6083, -6083, -6083, -6083, -6083, -6089, -6100, -6106, -6129, -6193, -6210, -6220, -6227, -6227, -6255, -6262, -6275, -6275, -6282, -6282, -6282, -6289, -6438, -6438, -6461, -6461, -6474, -6488, -6509, -6561, -6590, -6590, -6630, -6637, -6644, -6658, -6658, -6702, -6709, -6716, -6741, -6858, -6864, -6893, -6906, -6930, -6930, -6941, -6954, -6954, -6968, -6975, -6975, -6975, -7078, -7085, -7104, -7104, -7104, -7119, -7125, -7149, -7156, -7171, -7178, -7184, -7199, -7211, -7211, -7218, +5765, +5799, +5799, +5806, +5812, +5812, +5824, +5830, +5837, +5857, +5864, +5881, +5881, +5881, +5893, +5893, +5899, +5899, +5919, +5919, +5957, +5957, +5957, +5957, +5971, +5978, +5984, +6009, +6047, +6065, +6093, +6104, +6153, +6169, +6169, +6169, +6176, +6180, +6196, +6202, +6202, +6228, +6241, +6264, +6264, +6264, +6264, +6274, +6284, +6299, +6306, +6318, +6325, +6393, +6393, +6393, +6443, +6463, +6475, +6475, +6475, +6475, +6475, +6514, +6549, +6574, +6591, +6605, +6624, +6636, +6684, +6684, +6696, +6696, +6696, +6696, +6696, +6696, +6700, +6707, +6714, +6714, +6714, +6714, +6714, +6721, +6740, +6740, +6753, +6782, +6794, +6828, +6841, +6874, +6874, +6881, +6881, +6881, +6917, +6950, +6963, +6963, +6963, +6970, +6970, +7003, +7003, +7048, +7060, +7067, +7089, +7089, +7089, +7127, +7179, +7179, +7198, +7203, +7203, +7223, +7223, +7223, 7231, 7231, -7257, -7389, -7401, -7401, -7414, -7420, -7427, -7427, +7237, +7237, +7284, +7298, +7298, +7298, +7298, +7305, +7327, +7327, +7339, +7339, +7386, +7406, +7422, 7440, 7440, 7440, +7446, +7446, 7453, -7469, -7469, -7564, -7564, -7576, -7576, -7576, -7576, +7477, +7488, +7517, +7527, +7560, +7565, +7565, +7592, +7599, 7604, -7684, -7690, -7704, -7704, -7704, -7710, -7723, -7733, -7745, -7752, -7752, -7788, -7897, -7897, -7897, -7897, -7897, -7914, -7914, -7928, -7935, -7942, -7942, -7942, -7949, -8123, -8137, -8156, +7655, +7655, +7663, +7663, +7715, +7715, +7715, +7722, +7722, +7722, +7738, +7738, +7738, +7803, +7828, +7828, +7834, +7841, +7877, +7887, +7892, +7905, +7905, +7905, +7905, +7905, +7924, +7976, +7976, +8023, +8035, +8045, +8077, +8077, +8096, +8096, +8096, +8096, +8096, +8124, +8124, +8124, +8142, +8142, 8163, -8170, -8177, -8213, -8226, -8233, -8233, -8233, -8233, -8240, -8240, -8247, -8258, -8258, -8281, -8299, -8359, -8359, -8389, -8389, -8396, -8403, -8403, -8413, -8413, -8413, -8413, -8413, -8420, -8443, -8450, -8458, -8470, -8483, -8490, -8503, -8579, -8617, -8617, -8655, -8666, -8666, -8666, -8666, -8666, -8672, -8672, -8733, -8815, -8815, -8833, -8833, -8854, -8854, -8854, -8867, -8867, -8874, -8874, -8874, -8874, -8962, -8969, -8969, -8976, -8983, -8990, -9028, -9028, -9028, -9028, +8163, +8163, +8163, +8181, +8195, +8195, +8205, +8219, +8219, +8219, +8219, +8260, +8271, +8286, +8295, +8295, +8295, +8301, +8301, +8301, +8301, +8301, +8323, +8333, +8343, +8351, +8351, +8351, +8364, +8369, +8381, +8381, +8386, +8386, +8386, +8406, +8426, +8442, +8442, +8449, +8454, +8454, +8462, +8491, +8498, +8505, +8512, +8512, +8522, +8555, +8614, +8620, +8668, +8668, +8668, +8668, +8668, +8685, +8696, +8746, +8752, +8801, +8810, +8839, +8846, +8864, +8864, +8897, +8910, +8959, +8968, +8992, +8996, +9002, +9016, +9016, 9048, 9048, -9071, -9085, -9092, -9115, -9115, -9126, -9191, +9061, +9061, +9061, +9068, +9080, +9080, +9080, +9080, +9098, +9117, +9117, +9135, +9135, +9135, +9142, +9142, +9142, +9142, +9168, +9168, +9187, +9187, +9187, +9199, +9208, +9244, +9244, +9263, +9270, +9270, +9281, 9321, -9335, -9379, -9390, -9411, -9426, -9433, -9440, -9440, +9356, +9373, +9385, +9405, 9447, 9447, -9454, -9461, -9572, -9579, -9586, -9586, -9593, -9593, -9612, +9447, +9447, +9458, +9466, +9471, +9505, +9505, +9505, +9518, +9518, +9527, +9552, +9559, +9568, +9615, +9615, +9615, +9630, +9635, +9635, 9649, -9677, -9684, -9729, -9743, -9764, -9771, -9771, -9796, -9796, -9796, -9830, -9883, -9883, -9897, -9904, -9904, -9920, -9920, -9920, -9920, -9920, -9927, -9927, -9927, -10111, -10120, -10127, -10127, +9664, +9706, +9706, +9706, +9719, +9726, +9726, +9726, +9726, +9726, +9760, +9760, +9760, +9774, +9781, +9781, +9790, +9844, +9844, +9861, +9877, +9887, +9887, +9887, +9918, +9976, +9976, +9988, +9988, +9988, +10006, +10023, +10061, +10072, +10091, +10121, 10134, -10134, -10150, -10237, -10281, -10288, -10288, -10295, -10295, -10302, -10309, -10316, -10316, -10323, -10365, -10499, +10171, +10179, +10179, +10222, +10222, +10243, +10263, +10263, +10263, +10306, +10319, +10319, +10358, +10390, +10397, +10406, +10412, +10412, +10412, +10431, +10437, +10458, +10464, 10522, -10529, -10543, -10550, -10550, -10550, -10550, -10566, -10580, -10580, -10580, -10580, -10623, -10646, -10651, -10651, -10651, -10651, -10661, -10718, -10742, -10742, -10756, -10756, -10756, -10756, -10772, -10799, -10799, -10799, -10853, -10938, -10952, -10959, -10980, -11025, -11054, -11054, -11068, -11075, -11075, -11075, -11093, -11100, -11110, -11124, -11131, -11131, -11131, -11131, -11182, -11217, -11244, -11259, -11259, -11259, -11279, -11293, -11293, -11302, -11316, -11323, -11361, -11548, -11567, -11574, -11574, -11581, -11609, -11609, -11623, -11623, -11623, -11623, +10522, +10522, +10532, +10590, +10590, +10629, +10665, +10665, +10694, +10694, +10694, +10714, +10714, +10721, +10721, +10721, +10775, +10795, +10795, +10809, +10861, +10861, +10880, +10880, +10880, +10880, +10909, +10965, +10971, +10971, +10971, +10981, +10995, +10995, +10995, +11047, +11082, +11097, +11122, +11136, +11152, +11152, +11187, +11210, +11220, +11220, +11271, +11312, +11324, +11324, +11331, +11331, +11331, +11331, +11349, +11384, +11384, +11404, +11404, +11431, +11460, +11475, +11475, +11475, +11475, +11475, +11489, +11489, +11520, +11538, +11547, +11547, +11554, +11575, +11587, +11604, 11630, -11630, -11700, -11706, -11706, -11706, -11706, -11712, -11790, -11806, -11826, -11826, -11846, -11846, -11860, -11867, -11867, -11867, -11867, -11874, -11904, -12117, -12123, -12133, -12133, -12138, -12145, -12152, -12152, -12152, -12158, -12158, -12158, -12162, -12299, -12299, -12299, -12299, -12306, -12306, -12333, -12346, -12346, -12353, -12353, -12353, -12353, -12362, -12362, -12366, -12366, -12366, -12419, -12485, -12485, -12485, -12495, +11634, +11634, +11666, +11676, +11702, +11725, +11725, +11725, +11725, +11725, +11742, +11742, +11742, +11763, +11763, +11774, +11781, +11781, +11793, +11793, +11793, +11793, +11843, +11853, +11897, +11897, +11926, +11926, +11926, +11926, +11936, +11952, +11952, +11965, +11965, +11965, +11977, +11977, +11981, +11998, +12013, +12056, +12056, +12056, +12065, +12065, +12065, +12074, +12074, +12081, +12081, +12100, +12111, +12111, +12122, +12127, +12127, +12127, +12150, +12186, +12193, +12223, +12232, +12243, +12247, +12275, +12296, +12296, +12316, +12321, +12343, +12343, +12355, +12373, +12373, +12382, +12382, +12392, +12392, +12392, +12392, +12409, +12409, +12428, +12428, +12438, +12445, +12471, +12479, +12479, +12493, +12493, 12503, +12503, +12533, +12533, +12533, 12549, 12549, -12549, -12549, -12549, -12549, -12557, -12557, -12644, -12648, -12648, -12652, -12663, -12663, -12663, -12709, -12721, +12560, +12581, +12581, +12602, +12616, +12632, +12647, +12647, +12647, +12647, +12659, +12674, +12674, +12686, +12686, +12705, +12705, 12728, -12728, -12728, -12728, -12743, -12743, -12743, -12750, -12750, -12789, -12940, -12940, -12957, -12957, -12957, -12978, -12978, -12993, -12993, -12993, -12993, -13012, -13012, -13107, -13152, -13166, -13166, -13166, -13166, -13166, -13208, -13229, -13229, -13234, -13234, -13234, -13234, -13234, -13234, -13234, -13234, -13253, -13405, -13418, -13418, -13418, -13422, -13446, -13446, -13446, -13446, -13446, -13446, -13446, -13446, -13578, -13582, -13582, -13582, -13582, -13590, -13600, -13610, -13610, -13610, -13631, -13631, -13631, -13646, -13646, -13646, -13646, -13656, -13683, -13783, -13783, -13783, -13789, -13796, -13801, -13801, -13801, -13801, -13801, -13801, -13820, -13820, -13832, -13832, -13851, -13851, -13851, -13851, -13886, -13898, -13921, -13921, -13931, -13931, -13931, -13931, -13931, -13936, -13936, -13943, -14013, -14108, -14122, -14133, -14133, -14133, -14146, -14146, -14146, -14153, -14153, -14153, -14153, -14157, -14175, -14175, -14188, -14188, -14193, -14199, -14229, -14288, -14295, -14295, -14295, -14295, -14295, -14295, -14295, -14295, -14295, -14314, -14409, -14409, -14417, -14427, -14427, -14440, -14440, -14440, -14440, -14440, -14440, -14448, -14457, -14457, -14562, -14578, -14578, -14578, -14578, -14582, -14588, -14616, -14616, -14616, -14616, -14616, -14616, -14616, -14616, -14633, -14633, -14633, -14686, +12735, +12735, +12777, +12793, +12810, +12817, +12826, +12846, +12890, +12906, +12920, +12936, +12936, +12949, +12962, +12973, +13013, +13017, +13032, +13067, +13067, +13067, +13067, +13085, +13124, +13124, +13167, +13180, +13180, +13180, +13180, +13180, +13180, +13207, +13228, +13228, +13236, +13249, +13254, +13276, +13294, +13294, +13301, +13311, +13333, +13366, +13400, +13426, +13426, +13467, +13485, +13531, +13569, +13569, +13580, +13585, +13594, +13614, +13614, +13635, +13705, +13705, +13719, +13727, +13731, +13731, +13731, +13758, +13758, +13792, +13802, +13802, +13812, +13840, +13840, +13895, +13895, +13906, +13906, +13928, +13949, +13978, +13978, +13986, +13986, +13986, +14024, +14033, +14046, +14046, +14058, +14058, +14070, +14070, +14083, +14127, +14158, +14158, +14177, +14177, +14177, +14194, +14211, +14225, +14327, +14373, +14386, +14401, +14411, +14411, +14422, +14422, +14447, +14461, +14461, +14483, +14483, +14502, +14539, +14539, +14539, +14557, +14557, +14557, +14566, +14566, +14575, +14618, +14628, +14643, +14643, +14684, +14684, +14714, +14714, +14725, +14750, +14762, +14770, +14789, +14801, +14822, +14826, +14826, +14826, 14856, -14860, -14860, -14864, -14896, -14896, -14896, -14896, -14896, -14896, -14896, -14896, -14911, -14923, -14923, -14929, -14929, -14929, -14939, -14977, -15028, -15041, -15041, -15041, -15041, -15041, -15041, -15041, -15052, -15052, -15052, -15112, -15230, -15230, -15237, -15237, -15237, -15263, -15263, -15269, -15269, -15273, -15280, -15285, -15285, -15299, -15341, -15341, -15348, -15348, -15348, -15367, -15441, -15452, -15456, +14892, +14912, +14941, +14941, +14948, +14969, +14969, +14969, +14969, +14987, +14992, +15013, +15023, +15030, +15079, +15102, +15140, +15145, +15155, +15155, +15155, +15155, +15155, +15172, +15192, +15207, +15283, +15298, +15313, +15319, +15319, +15352, +15352, +15370, +15370, +15383, 15470, -15470, -15479, -15479, -15484, -15484, -15484, -15484, -15534, -15717, -15717, -15738, -15738, +15490, +15490, +15490, +15500, +15592, +15607, +15648, +15679, +15683, +15687, +15693, +15736, +15736, 15745, -15756, -15756, -15756, -15756, -15756, -15756, -15756, -15756, -15783, -15783, -15809, -15821, -15835, -15842, -15852, -15878, -15908, -15908, -15921, -15921, -15921, -15935, -15948, -15958, -15958, -15970, -16004, -16108, -16108, -16130, -16130, -16134, -16140, -16140, -16146, -16146, -16146, +15745, +15745, +15745, +15792, +15823, +15823, +15823, +15836, +15866, +15879, +15901, +15965, +16071, +16071, +16071, +16096, +16096, +16110, +16122, +16148, 16152, -16157, -16157, -16283, -16283, -16300, -16300, -16300, -16300, -16371, -16426, -16455, -16455, -16455, -16455, -16455, -16455, -16462, -16462, -16462, -16466, -16511, -16582, -16582, -16596, -16600, -16600, -16600, -16600, -16608, -16608, -16615, -16615, -16615, -16615, -16784, -16784, -16784, -16784, -16797, -16804, -16841, -16855, -16855, -16855, -16866, -16866, -16866, -16866, -16866, -16896, -16896, -16907, -16960, -17021, -17030, -17030, -17030, -17030, -17030, -17030, -17030, -17045, -17045, -17045, -17045, -17045, +16166, +16166, +16166, +16193, +16299, +16299, +16321, +16331, +16340, +16340, +16347, +16374, +16386, +16386, +16464, +16508, +16508, +16508, +16512, +16512, +16512, +16533, +16555, +16555, +16584, +16584, +16584, +16584, +16584, +16584, +16602, +16602, +16602, +16612, +16627, +16641, +16641, +16659, +16659, +16695, +16695, +16712, +16770, +16787, +16807, +16807, +16821, +16821, +16826, +16826, +16826, +16861, +16874, +16874, +16884, +16884, +16947, +16959, +16959, +16976, +16976, +16990, +16990, +17067, +17088, +17101, +17101, +17111, 17122, -17122, -17126, -17126, -17126, -17126, -17178, -17178, -17185, -17185, -17185, -17185, -17185, -17185, -17189, -17202, -17202, -17214, -17214, -17319, -17326, -17333, -17333, -17333, -17333, -17333, -17333, -17333, -17333, -17341, -17341, -17341, -17356, -17356, -17364, -17364, -17364, -17370, -17370, -17370, -17370, -17370, -17370, -17370, -17370, -17377, -17377, -17377, -17377, -17377, +17156, +17163, +17163, +17187, +17238, +17260, +17271, +17271, +17271, +17271, +17271, +17271, +17271, +17293, +17310, +17310, +17310, +17322, +17322, +17339, +17351, +17351, +17351, +17351, +17351, +17351, +17351, 17392, -17515, -17522, -17522, -17522, -17522, -17533, -17533, -17533, -17533, -17533, -17533, -17540, -17540, -17699, -17720, -17750, -17750, -17750, -17750, -17772, -17797, -17797, -17804, +17400, +17416, +17416, +17441, +17458, +17468, +17478, +17537, +17537, +17545, +17545, +17554, +17554, +17566, +17592, +17592, +17604, +17616, +17645, +17682, +17690, +17690, +17690, +17724, +17724, +17749, +17749, +17749, +17799, +17799, +17819, +17819, 17830, -17830, -17830, -17830, -17836, -17849, -17849, -17859, -17876, -18028, -18048, -18065, -18065, -18065, -18074, -18074, -18080, -18080, -18080, -18080, -18080, -18080, -18080, -18086, -18092, -18092, -18092, -18092, -18110, -18120, -18145, -18145, -18145, -18145, -18145, -18145, -18145, -18145, -18145, -18145, -18195, -18391, -18391, -18417, -18417, -18417, -18417, -18424, -18429, -18429, -18429, -18429, -18429, -18429, -18518, -18518, -18518, -18518, -18525, -18525, -18535, -18557, -18578, -18578, -18582, -18582, -18609, -18609, -18617, -18617, -18617, -18617, -18640, -18776, -18776, -18776, -18784, -18784, -18784, -18784, -18784, -18784, -18784, -18784, -18784, -18784, -18851, -18851, -18851, -18851, -18855, -18865, -18865, -18874, -18874, -18874, -18874, +17839, +17839, +17853, +17871, +17871, +17902, +17912, +17922, +17930, +17977, +17983, +18032, +18044, +18051, +18051, +18061, +18061, +18071, +18071, +18071, +18071, +18100, +18144, +18144, +18179, +18192, +18192, +18208, +18220, +18220, +18226, +18226, +18265, +18265, +18275, +18275, +18275, +18275, +18288, +18288, +18288, +18314, +18314, +18354, +18367, +18384, +18384, +18384, +18394, +18414, +18437, +18458, +18474, +18474, +18499, +18499, +18505, +18505, +18509, +18521, +18521, +18533, +18554, +18554, +18554, +18565, +18565, +18585, +18585, +18585, +18612, +18634, +18643, +18666, +18666, +18686, +18686, +18728, +18745, +18756, +18772, +18800, +18800, +18800, +18800, +18800, +18806, +18862, 18880, -18884, -18884, -18884, -18895, -18902, -18902, -18911, -19028, -19028, -19028, -19028, -19028, -19028, -19028, -19032, -19032, -19037, -19037, -19037, -19037, -19131, -19131, -19158, -19158, -19158, -19158, -19158, -19165, -19173, -19173, -19185, -19185, -19185, -19185, -19185, -19185, -19185, -19198, -19267, -19311, -19311, -19311, -19311, -19326, -19332, -19332, -19332, -19332, -19332, -19332, -19332, -19332, -19420, -19427, -19427, -19427, -19427, -19427, -19437, -19506, -19525, -19525, -19542, -19542, -19542, -19542, -19542, -19542, -19542, -19551, -19582, -19649, -19649, -19657, -19667, -19673, -19673, -19673, -19673, -19673, -19673, -19673, -19673, -19673, -19830, -19877, -19886, -19894, -19894, -19894, -19894, -19900, -19900, -19900, -19900, -19908, -19908, -19908, -19908, -19921, -19921, -19927, -19971, -20031, -20031, -20045, -20049, -20078, -20089, -20089, -20089, -20089, -20089, -20104, -20127, -20127, -20209, -20269, -20284, -20284, -20304, -20304, +18922, +18936, +18936, +18942, +18959, +18959, +18964, +18964, +19012, +19012, +19012, +19017, +19021, +19030, +19030, +19030, +19035, +19044, +19044, +19052, +19052, +19052, +19052, +19074, +19099, +19106, +19139, +19139, +19155, +19155, +19174, +19221, +19239, +19251, +19271, +19290, +19320, +19366, +19366, +19373, +19389, +19402, +19402, +19418, +19438, +19438, +19438, +19438, +19438, +19438, +19438, +19438, +19458, +19466, +19466, +19484, +19484, +19494, +19494, +19510, +19510, +19521, +19521, +19536, +19543, +19543, +19550, +19550, +19556, +19556, +19603, +19603, +19611, +19622, +19646, +19675, +19696, +19696, +19735, +19747, +19747, +19763, +19763, +19763, +19780, +19780, +19792, +19798, +19798, +19808, +19824, +19863, +19863, +19975, +19975, +19983, +19999, +20006, +20006, +20006, +20022, +20036, +20043, +20043, +20050, +20110, +20110, +20110, +20145, +20145, +20145, +20145, +20161, +20161, +20161, +20161, +20184, +20198, +20219, +20219, +20230, +20236, +20236, +20261, +20283, +20283, +20298, 20314, -20334, -20357, -20357, -20367, -20367, -20367, -20367, -20367, -20367, -20367, -20367, -20401, -20547, +20314, +20321, +20352, +20361, +20361, +20361, +20375, +20422, +20433, +20433, +20457, +20457, +20457, +20457, +20457, +20457, +20476, +20476, +20482, +20488, +20488, +20488, +20488, +20542, +20548, +20548, +20548, 20555, -20575, -20575, -20591, -20609, -20609, -20609, -20609, -20617, -20617, -20617, -20617, -20675, -20675, -20675, -20675, -20675, -20675, -20719, -20772, -20772, -20780, -20780, -20780, -20786, -20786, -20786, -20796, -20796, -20796, -20824, -20932, -20948, -20957, -20957, -20977, -20977, -20987, -20987, -20987, -20987, -21002, -21002, -21002, -21102, -21102, -21119, -21119, -21119, -21119, -21165, -21193, -21204, -21204, -21208, -21208, -21208, -21208, -21208, -21222, -21222, -21222, -21274, -21453, -21453, -21453, -21453, -21458, -21458, -21458, -21458, -21458, -21467, -21467, -21487, -21487, -21619, -21619, -21623, -21623, -21623, -21623, -21659, -21687, -21687, -21687, +20574, +20584, +20618, +20627, +20641, +20683, +20683, +20736, +20740, +20740, +20740, +20740, +20750, +20750, +20795, +20795, +20795, +20854, +20862, +20869, +20869, +20874, +20874, +20895, +20895, +20895, +20911, +20927, +20927, +20939, +20946, +20962, +20962, +20962, +21018, +21018, +21018, +21056, +21077, +21077, +21077, +21077, +21095, +21134, +21134, +21160, +21171, +21214, +21214, +21214, +21214, +21221, +21221, +21221, +21221, +21317, +21317, +21325, +21342, +21342, +21370, +21386, +21405, +21418, +21438, +21441, +21447, +21469, +21489, +21533, +21557, +21568, +21586, +21596, +21596, +21636, +21648, +21671, 21700, -21700, -21700, -21700, -21710, -21727, -21727, -21742, -21799, -21922, -21922, -21922, -21922, -21922, -21937, -21937, -21937, -21937, -21937, -21937, -21937, -21937, -22024, -22042, -22042, -22047, -22047, -22047, -22047, -22073, -22093, -22093, -22097, -22097, -22101, -22101, -22101, -22111, -22111, -22111, -22135, -22268, -22268, -22268, -22271, -22274, -22277, -22293, -22296, -22296, -22309, -22309, -22309, -22312, -22373, -22373, -22376, -22376, -22382, -22395, -22407, +21706, +21716, +21722, +21728, +21731, +21753, +21753, +21765, +21811, +21826, +21829, +21840, +21853, +21856, +21898, +21904, +21904, +21933, +21990, +21993, +21999, +22023, +22050, +22094, +22113, +22131, +22148, +22225, +22284, +22301, +22342, +22361, +22380, +22414, +22441, +22444, 22447, -22470, -22473, -22479, -22485, -22488, -22494, -22501, -22512, -22515, -22518, -22572, -22652, -22663, -22666, -22672, -22682, -22694, -22700, -22715, +22491, +22503, +22520, +22548, +22569, +22617, +22617, +22642, +22657, +22660, +22660, +22670, +22705, 22718, -22724, -22727, -22727, -22730, -22782, -22808, -22811, -22811, +22768, +22784, 22817, -22820, -22862, -22899, -22910, -22913, -22936, -22943, -22946, -22970, -22973, -22973, -22976, -22988, -23009, -23112, -23117, -23129, -23137, -23145, -23153, -23153, -23156, -23161, -23161, -23164, -23164, -23164, -23238, -23245, -23258, -23258, -23263, -23263, -23266, -23306, -23309, -23309, -23309, -23309, -23312, -23315, -23315, -23315, -23318, -23318, -23346, -23474, -23477, -23483, -23483, +22817, +22836, +22851, +22863, +22863, +22863, +22863, +22863, +22876, +22918, +22963, +22974, +22974, +22980, +22983, +22999, +22999, +22999, +23037, +23037, +23066, +23080, +23083, +23096, +23115, +23118, +23133, +23146, +23149, +23207, +23224, +23224, +23224, +23235, +23265, +23274, +23290, +23313, +23326, +23329, +23347, +23368, +23371, +23375, +23378, +23390, +23431, +23452, +23455, +23455, +23470, 23490, -23493, -23496, -23499, -23502, -23505, -23505, -23520, -23523, -23603, -23616, -23616, -23619, -23622, +23533, +23537, +23537, +23563, +23575, +23587, +23593, +23612, +23612, +23612, 23625, -23664, +23625, +23666, +23669, 23682, -23706, -23706, -23709, -23714, -23717, -23717, -23727, -23738, -23741, -23744, -23766, -23906, -23919, -23942, -23949, -23974, -23993, -24000, -24000, +23685, +23688, +23688, +23699, +23739, +23742, +23745, +23756, +23756, +23770, +23800, +23811, +23832, +23879, +23926, +23950, +23977, +23986, 24007, 24020, 24020, -24020, -24030, -24152, -24162, -24187, -24187, -24197, -24214, -24224, -24239, -24255, -24262, -24296, -24309, -24309, -24316, -24316, -24359, -24366, -24385, -24415, -24509, -24523, -24546, -24553, -24567, -24570, -24570, -24573, -24573, -24597, -24611, -24611, -24625, -24680, -24709, -24716, -24719, -24732, -24744, -24790, -24813, -24820, -24820, -24823, -24835, -24862, -24865, -24868, -24890, -24897, -24909, -24965, +24066, +24066, +24082, +24082, +24085, +24085, +24088, +24088, +24139, +24139, +24157, +24160, +24174, +24177, +24180, +24220, +24232, +24232, +24232, +24232, +24253, +24269, +24275, +24295, +24328, +24328, +24335, +24335, +24335, +24335, +24338, +24352, +24370, +24432, +24442, +24453, +24520, +24540, +24543, +24562, +24565, +24583, +24602, +24605, +24608, +24650, +24715, +24718, +24724, +24754, +24857, +24863, +24869, +24913, +24925, +24928, +25011, +25014, +25014, 25030, 25033, -25036, -25049, -25071, +25033, +25043, +25062, +25062, 25084, -25092, -25102, -25105, -25116, -25123, -25126, -25129, -25218, -25229, -25232, -25235, -25241, -25244, -25260, -25297, -25303, -25309, -25353, -25356, -25362, -25378, -25378, -25381, -25381, -25381, +25158, +25173, +25230, +25230, +25253, +25305, +25315, +25315, +25336, +25336, +25336, +25371, +25374, +25374, +25394, +25394, +25397, +25406, +25406, +25409, +25409, +25409, +25412, 25450, -25541, -25541, -25544, -25544, -25551, +25465, +25473, +25473, +25473, +25489, +25506, +25522, +25525, +25525, 25561, -25561, -25561, -25568, +25579, +25579, 25582, -25585, -25585, -25585, +25607, +25607, +25636, +25661, +25661, +25680, +25701, +25712, +25712, +25726, +25726, +25729, 25736, -25749, -25749, -25749, -25752, -25759, -25802, -25837, -25847, -25850, +25747, +25747, +25747, +25776, +25783, +25807, +25820, +25829, +25839, +25859, 25862, -25865, -25872, -25872, -25882, -25907, -25910, -25913, -25939, -26068, -26076, -26079, -26082, -26091, -26153, -26153, -26156, -26156, -26159, -26159, -26159, -26172, -26326, -26339, -26352, -26352, -26359, -26372, -26385, -26392, -26408, -26408, -26418, -26418, -26418, -26418, -26418, -26418, -26418, -26418, -26507, -26610, -26613, -26632, -26646, -26664, -26691, -26691, -26704, -26707, -26717, -26720, -26723, -26726, -26821, +25881, +25911, +25928, +25934, +25934, +25968, +25986, +26029, +26055, +26066, +26105, +26123, +26133, +26188, +26188, +26205, +26223, +26236, +26268, +26282, +26296, +26346, +26365, +26381, +26420, +26508, +26535, +26538, +26550, +26574, +26596, +26625, +26628, +26647, +26656, +26669, +26680, +26710, +26743, +26750, +26770, +26773, +26773, +26787, +26787, +26799, +26816, 26831, -26834, -26841, -26848, -26864, -26893, -26919, -26927, -26933, -26956, -26962, -26965, -26986, -27002, -27015, -27018, -27021, -27044, -27189, -27205, +26831, +26859, +26875, +26937, +26952, +26992, +27011, +27027, +27030, +27030, +27046, +27053, +27080, +27080, +27080, +27080, +27123, +27123, +27130, +27140, +27156, 27215, -27232, -27242, -27255, -27265, +27226, +27246, +27270, 27278, -27293, -27300, -27303, -27335, -27342, -27512, -27526, -27533, -27533, -27536, -27543, -27565, -27581, -27610, -27617, -27655, -27655, -27674, -27690, -27690, +27278, +27312, +27343, +27350, +27350, +27362, +27369, +27379, +27407, +27407, +27431, +27448, +27455, +27455, +27462, +27484, +27516, +27522, +27529, +27545, +27545, +27584, +27625, +27632, +27639, +27649, +27660, +27679, +27686, +27686, +27709, +27709, 27727, -27727, -27730, -27730, -27842, -27842, -27849, -27857, -27857, -27860, -27863, -27863, -27863, -27863, -27869, -27869, -27869, -27937, -27948, -27957, -27962, -27968, -27968, -27971, -28033, -28047, -28047, -28079, -28086, -28086, -28086, -28093, -28100, -28100, -28107, -28151, -28231, -28238, -28261, -28285, -28304, -28307, -28307, -28307, -28325, -28332, -28332, -28332, -28340, -28512, -28512, -28512, -28512, -28512, -28512, -28522, +27746, +27753, +27775, +27781, +27788, +27793, +27811, +27873, +27873, +27910, +27917, +27955, +27979, +27979, +27994, +28036, +28046, +28053, +28110, +28120, +28120, +28141, +28189, +28196, +28196, +28241, +28244, +28266, +28308, +28345, +28345, +28352, +28380, +28380, +28395, +28395, +28415, +28436, +28443, +28469, +28476, +28499, +28506, +28531, 28545, -28573, -28573, -28598, -28598, -28607, -28607, -28607, -28632, -28645, -28645, -28671, -28877, -28890, -28897, +28552, +28559, +28585, +28612, +28618, +28618, +28642, +28659, +28659, +28666, +28691, +28714, +28714, +28729, +28767, +28801, +28832, +28839, +28875, +28905, +28905, 28917, -28924, -28952, -28952, -28975, -28982, -28982, -28982, -28982, -28989, -29124, -29124, -29149, -29149, -29159, -29159, -29185, -29198, -29219, -29219, -29249, -29262, -29269, -29288, -29301, -29315, -29322, -29329, -29363, -29510, -29517, -29534, +28936, +28963, +28963, +28979, +28979, +28986, +29039, +29049, +29077, +29084, +29115, +29142, +29152, +29208, +29222, +29229, +29250, +29264, +29289, +29303, +29318, +29318, +29342, +29342, +29342, +29362, +29369, +29369, +29405, +29405, +29436, +29436, +29464, +29464, +29464, +29464, +29471, +29471, +29476, +29483, +29488, +29500, 29543, -29550, -29562, -29562, -29575, -29575, -29575, -29581, -29594, -29594, -29683, -29690, -29690, -29690, -29698, -29720, -29763, -29803, -29836, -29836, -29836, -29850, -29850, -29850, -29850, -29864, -29864, -29887, +29556, +29561, +29576, +29593, +29613, +29620, +29620, +29627, +29627, +29627, +29634, +29641, +29651, +29658, +29675, +29748, +29783, +29800, +29807, +29829, +29829, +29874, +29890, 29911, -30044, -30044, -30044, -30050, -30050, -30050, -30050, -30050, -30050, -30050, -30050, -30050, -30050, -30050, -30095, -30122, -30122, -30129, -30129, -30136, -30199, -30204, -30204, -30249, -30249, -30249, -30258, -30258, -30258, -30258, -30258, -30298, -30314, -30314, -30321, -30321, -30321, -30345, -30345, -30353, -30353, +29918, +29918, +29937, +29949, +29949, +29967, +30032, +30066, +30076, +30104, +30104, +30104, +30121, +30154, +30154, +30177, +30193, +30193, +30208, +30222, +30272, +30272, +30279, +30315, +30355, 30362, -30362, -30362, -30362, -30402, -30402, -30402, -30402, -30415, -30415, +30376, +30413, 30438, -30497, -30511, -30537, -30556, -30556, -30575, -30575, -30575, -30592, -30605, -30605, -30645, -30705, -30717, -30717, -30724, -30728, -30728, -30735, -30748, -30748, -30748, -30748, -30762, -30794, -30808, -30812, -30844, -30844, -30851, -30865, -30871, -30902, -30941, -30960, -30969, -30976, -30983, -30997, -31002, -31002, -31009, -31016, -31075, -31143, -31143, -31192, -31199, -31224, -31234, -31234, -31234, -31234, +30457, +30516, +30523, +30533, +30612, +30621, +30648, +30656, +30685, +30697, +30715, +30732, +30784, +30848, +30855, +30877, +30888, +30888, +30905, +30932, +30946, +30978, +30978, +31032, +31039, +31053, +31060, +31082, +31128, +31128, +31155, +31155, +31155, +31195, +31195, +31195, +31195, +31202, +31202, +31222, +31222, +31230, 31241, -31248, -31248, -31248, -31414, -31432, -31450, -31450, -31455, -31455, -31509, -31541, -31559, -31566, -31581, -31581, -31581, -31581, -31581, -31590, -31597, -31597, -31648, -31656, -31656, -31656, -31663, -31684, -31707, -31707, -31714, -31714, -31714, -31721, -31721, -31725, -31857, -31857, -31866, -31870, -31870, -31878, -31885, -31914, -31946, -31946, -31951, -31951, -31957, -31957, -31962, -31971, -31997, -31997, +31241, +31241, +31308, +31320, +31327, +31327, +31327, +31354, +31375, +31399, +31424, +31431, +31448, +31469, +31469, +31476, +31487, +31504, +31534, +31534, +31593, +31593, +31593, +31593, +31593, +31593, +31598, +31619, +31632, +31647, +31658, +31705, +31731, +31752, +31759, +31780, +31817, +31817, +31821, +31825, +31830, +31830, +31830, +31830, +31836, +31860, +31869, +31869, +31887, +31887, +31887, +31887, +31894, +31919, +31924, +31924, +31924, +31958, +31968, +31968, +31977, +31989, +32000, +32000, 32007, -32220, -32220, -32220, -32220, -32227, -32239, -32239, -32239, -32246, -32253, -32260, -32260, -32287, -32342, -32349, -32349, -32356, -32356, -32363, -32380, -32458, -32487, -32487, -32505, -32505, -32512, -32512, -32519, -32527, -32527, -32534, -32591, -32792, -32792, -32803, -32803, -32810, -32815, -32815, -32815, -32815, -32826, -32826, -32826, -32832, -32894, -32907, -32935, -32935, -32942, -32951, -32968, -32981, -32998, -32998, -32998, -32998, -33007, -33007, -33007, -33007, -33007, -33007, +32024, +32038, +32064, +32069, +32069, +32085, +32085, +32096, +32118, +32118, +32130, +32137, +32165, +32165, +32204, +32217, +32234, +32242, +32264, +32314, +32327, +32334, +32334, +32343, +32343, +32359, +32359, +32385, +32385, +32385, +32420, +32420, +32420, +32420, +32468, +32468, +32506, +32506, +32506, +32523, +32569, +32569, +32569, +32576, +32576, +32576, +32576, +32604, +32612, +32612, +32632, +32666, +32683, +32728, +32749, +32749, +32749, +32756, +32756, +32765, +32807, +32807, +32807, +32817, +32837, +32837, +32856, +32875, +32875, +32875, +32914, +32914, +32914, +32921, +32921, +32938, +32956, +33021, +33021, +33050, +33064, 33075, -33207, -33207, -33207, -33214, -33221, -33230, -33230, -33237, -33237, -33244, -33244, -33244, -33244, -33376, -33383, -33389, -33396, -33403, -33416, -33431, -33431, -33431, -33431, -33438, -33438, -33445, -33452, -33459, -33478, -33478, -33478, -33528, -33612, -33624, -33631, -33638, -33638, +33102, +33102, +33102, +33102, +33109, +33109, +33122, +33145, +33164, +33164, +33171, +33171, +33171, +33171, +33187, +33187, +33187, +33195, +33195, +33268, +33277, +33277, +33277, +33281, +33281, +33297, +33297, +33297, +33297, +33313, +33320, +33320, +33320, +33333, +33333, +33368, +33387, +33409, +33413, +33417, +33430, +33430, +33446, +33455, +33467, +33472, +33498, +33498, +33527, +33537, +33547, +33565, +33602, +33602, +33617, +33617, +33633, 33645, -33652, -33659, -33659, -33666, -33666, +33662, 33673, -33687, -33724, -33737, -33744, -33748, -33748, -33757, -33787, -33833, -33838, -33845, -33869, -33888, -33906, -33913, -33922, -33922, -33922, -33922, -33966, -34019, -34023, -34041, -34045, -34061, -34067, -34067, -34067, -34067, -34067, -34067, -34067, -34067, -34276, -34276, -34276, -34276, -34283, -34306, -34348, +33681, +33698, +33698, +33705, +33719, +33726, +33754, +33754, +33783, +33793, +33843, +33868, +33868, +33876, +33876, +33876, +33925, +33936, +33947, +33947, +33947, +33965, +33986, +33986, +33986, +33986, +34050, +34089, +34089, +34098, +34112, +34124, +34128, +34173, +34173, +34173, +34173, +34194, +34209, +34209, +34228, +34263, +34267, +34275, +34282, 34353, -34360, -34372, -34372, -34379, -34379, -34379, -34386, -34403, -34403, -34410, -34433, -34495, -34511, +34376, +34400, +34428, +34441, +34441, +34512, 34549, -34568, -34575, -34575, -34575, -34575, -34588, -34595, -34595, -34601, -34601, -34626, -34630, -34630, -34630, -34630, -34630, -34630, -34642, +34549, +34567, +34567, +34577, +34598, +34616, +34627, +34635, +34635, +34657, +34657, +34666, +34671, 34678, 34678, +34678, +34678, +34685, 34706, -34710, -34710, -34710, -34710, -34710, -34710, -34710, -34732, -34931, -34964, -34975, -34989, -34996, -35021, -35021, -35033, -35033, -35033, -35033, -35033, -35040, -35156, -35163, -35192, -35197, -35197, -35197, -35241, -35287, -35301, -35308, -35315, -35315, -35329, -35336, -35336, -35350, -35357, -35357, -35397, -35423, -35430, +34746, +34751, +34751, +34774, +34774, +34784, +34807, +34819, +34819, +34835, +34835, +34913, +34913, +34913, +34932, +34951, +34951, +34956, +34974, +34974, +34992, +35003, +35026, +35031, +35053, +35059, +35098, +35108, +35114, +35139, +35149, +35162, +35181, +35181, +35190, +35209, +35222, +35222, +35222, +35222, +35222, +35226, +35226, +35226, +35226, +35251, +35251, +35302, +35302, +35302, +35302, +35351, +35351, +35387, +35387, +35387, +35387, +35391, +35424, +35440, 35462, 35462, -35469, -35469, -35469, -35476, -35476, -35476, -35486, -35502, -35502, -35532, -35585, -35585, -35585, -35585, -35585, -35620, -35678, -35696, -35696, -35739, -35739, -35746, -35746, -35746, -35746, -35746, -35753, -35802, -35913, -35939, -35946, -35946, -35958, +35498, +35505, +35505, +35505, +35505, +35520, +35529, +35545, +35545, +35555, +35562, +35562, +35594, +35594, +35621, +35621, +35640, +35646, +35646, +35646, +35659, +35659, +35680, +35744, +35751, +35751, +35777, +35796, +35796, +35796, +35810, +35822, +35836, +35842, +35858, +35858, +35901, +35901, +35901, +35901, 35965, 35965, -35965, -35972, -35976, -35976, -35976, -35976, -36051, -36069, -36075, -36075, -36087, -36094, -36160, -36203, -36203, -36203, -36203, -36203, -36207, -36207, -36216, -36216, -36216, -36216, -36236, -36324, -36324, -36331, -36343, -36343, -36371, -36371, -36371, -36371, -36371, -36377, -36383, -36383, -36537, +35973, +35986, +35986, +35986, +36000, +36006, +36014, +36014, +36031, +36045, +36045, +36045, +36057, +36066, +36066, +36066, +36066, +36083, +36083, +36088, +36088, +36102, +36109, +36120, +36120, +36143, +36147, +36147, +36166, +36177, +36202, +36217, +36242, +36278, +36278, +36278, +36293, +36293, +36322, +36334, +36334, +36334, +36334, +36334, +36334, +36369, +36369, +36376, +36398, +36445, +36469, +36476, +36511, +36518, +36535, +36577, 36584, -36584, -36584, -36598, -36598, 36676, -36686, -36686, -36686, -36693, -36693, -36693, -36693, -36693, -36730, -36737, -36737, -36807, -36941, -36941, -36941, -36941, -36969, -37008, -37008, -37008, -37008, -37008, -37008, -37008, -37008, -37156, -37165, -37165, -37165, -37169, -37184, -37193, -37224, -37239, -37239, -37239, -37239, -37243, -37243, -37243, -37243, -37243, -37261, -37297, +36676, +36676, +36676, +36683, +36706, +36752, +36752, +36784, +36798, +36805, +36812, +36857, +36881, +36881, +36881, +36888, +36895, +36906, +36906, +36916, +36923, +36954, +36961, +36961, +36986, +37011, +37034, +37057, +37090, +37105, +37146, +37217, +37240, +37284, +37302, +37338, +37352, +37352, +37352, +37375, +37391, +37398, +37402, +37409, +37420, +37455, +37455, +37472, 37504, -37510, -37526, -37526, -37526, -37526, -37526, -37526, -37526, -37526, -37534, -37534, -37534, -37549, -37555, -37564, -37564, -37564, -37564, -37564, -37570, -37583, -37583, -37583, -37587, -37594, -37594, -37603, -37607, -37607, -37607, -37635, -37713, -37724, -37724, -37724, -37724, -37724, -37724, -37724, -37724, -37728, -37728, -37728, -37728, -37809, -37836, -37836, -37836, -37842, -37842, -37865, -37898, -37898, -37898, -37924, -37924, -37924, -37934, -37938, -37961, -37961, -37961, -38027, -38113, +37523, +37551, +37567, +37567, +37620, +37620, +37627, +37645, +37671, +37699, +37699, +37727, +37743, +37743, +37781, +37781, +37781, +37781, +37781, +37792, +37799, +37816, +37816, +37816, +37822, +37822, +37834, +37847, +37852, +37887, +37894, +37894, +37905, +37909, +37909, +37916, +37916, +37923, +37936, +37951, +37963, +37970, +38017, +38022, +38022, +38070, +38070, +38087, +38087, +38094, +38101, +38119, 38126, -38126, -38126, -38126, -38126, -38126, -38126, -38126, -38126, -38126, -38126, -38130, +38146, +38153, +38153, +38171, +38171, +38178, +38193, +38200, +38206, +38218, 38225, 38225, 38225, -38225, -38225, -38225, -38241, -38260, -38272, -38272, -38272, -38272, -38285, -38285, -38285, -38307, -38307, -38312, -38334, -38391, -38397, -38397, -38397, -38397, -38397, -38397, -38397, -38397, -38397, -38397, -38397, -38397, -38477, -38501, -38501, -38501, -38501, -38501, -38510, -38523, -38530, -38545, -38581, -38581, -38588, -38588, -38588, -38597, -38597, -38597, -38597, -38736, -38736, -38736, -38742, -38750, +38238, +38245, +38296, +38303, +38352, +38352, +38358, +38370, +38370, +38421, +38421, +38421, +38435, +38442, +38455, +38467, +38484, +38503, +38536, +38540, +38540, +38540, +38540, +38556, +38556, +38556, +38556, +38572, +38618, +38618, +38634, +38634, +38634, +38634, +38654, +38661, +38710, +38710, +38717, +38752, 38771, 38771, -38780, -38780, -38788, -38795, -38795, -38813, -38823, -38823, -38823, -38823, -38834, -38834, -38870, +38785, +38785, +38808, +38832, +38871, +38878, +38891, 38898, -38898, -38898, -38908, -38914, -38914, -38914, -38914, -38926, -38926, -38926, -38966, -39044, -39044, -39060, -39060, -39070, -39070, -39070, -39070, -39074, -39074, -39074, -39074, -39074, -39148, -39148, -39154, -39154, -39154, -39154, -39182, -39240, -39240, -39240, -39250, -39250, -39250, -39264, -39264, -39274, -39274, -39274, -39362, -39464, -39464, -39493, -39493, -39493, -39493, -39493, -39493, -39493, -39493, -39493, -39493, -39493, -39500, -39500, -39500, -39500, -39500, -39500, -39500, -39522, -39522, -39522, -39532, -39532, -39532, -39532, -39532, -39532, -39532, -39532, -39549, -39670, -39687, -39694, -39694, -39746, -39746, -39746, -39746, -39746, -39746, -39751, -39776, -39776, -39791, -39791, -39791, -39795, -39795, -39795, -39816, -39831, -39831, -39831, -39831, -39831, -39831, -39831, -39841, -39852, -39852, -39863, -39899, -40034, -40034, -40034, -40034, -40054, -40054, -40054, -40054, -40054, -40054, -40063, -40063, -40063, -40188, -40272, -40278, -40278, -40283, -40294, -40294, -40333, -40333, -40333, -40359, -40359, -40359, -40359, -40359, -40369, -40369, -40369, -40402, -40508, -40508, -40515, -40519, -40542, -40542, -40546, -40546, -40546, -40546, -40546, -40546, -40569, -40741, -40741, -40741, -40741, -40741, -40741, -40741, -40790, -40796, -40796, -40812, -40812, -40812, -40812, -40812, -40823, -40823, -40829, -40837, -40956, -40973, -41009, -41009, -41020, -41028, -41028, -41038, -41038, -41042, -41042, -41042, -41042, -41056, -41056, -41067, -41067, -41067, -41078, -41088, -41088, -41088, -41088, -41098, -41098, -41098, +38905, +38923, +38923, +38923, +38930, +38961, +38968, +38994, +39018, +39018, +39062, +39076, +39086, +39097, +39109, +39122, +39132, +39132, +39132, +39139, +39152, +39152, +39176, +39202, +39209, +39237, +39237, +39244, +39251, +39251, +39258, +39258, +39265, +39272, +39285, +39299, +39328, +39342, +39364, +39401, +39401, +39405, +39405, +39411, +39438, +39480, +39480, +39507, +39513, +39513, +39513, +39541, +39553, +39553, +39587, +39609, +39609, +39615, +39680, +39697, +39726, +39737, +39750, +39775, +39775, +39811, +39818, +39857, +39866, +39873, +39886, +39916, +39923, +39930, +39947, +39982, +39988, +39988, +40011, +40018, +40044, +40051, +40057, +40072, +40072, +40072, +40090, +40090, +40106, +40106, +40146, +40146, +40210, +40210, +40225, +40238, +40238, +40245, +40252, +40258, +40258, +40286, +40296, +40306, +40313, +40313, +40351, +40351, +40358, +40403, +40410, +40417, +40424, +40431, +40463, +40476, +40483, +40525, +40595, +40629, +40629, +40656, +40656, +40673, +40690, +40709, +40709, +40715, +40745, +40774, +40778, +40785, +40827, +40843, +40861, +40885, +40892, +40892, +40899, +40912, +40919, +40924, +40931, +40938, +41047, +41076, +41076, +41091, 41105, 41105, -41105, -41105, -41105, -41129, -41290, -41290, -41300, -41304, -41312, -41312, -41312, -41312, -41312, -41312, -41312, -41333, -41333, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41361, -41415, -41530, -41530, -41530, -41530, -41530, -41530, -41530, -41530, -41530, -41538, -41538, -41538, -41538, -41642, -41642, -41642, -41642, -41650, -41650, -41660, -41700, -41700, -41700, -41710, -41710, -41710, -41728, -41728, -41765, -41772, -41772, -41821, -41942, -41942, -41942, -41950, -41950, -41984, -41984, -41984, -41984, -41984, -41984, -41990, -41990, -41990, -41990, -41990, -41990, -41990, -41990, +41131, +41162, +41174, +41181, +41190, +41190, +41194, +41225, +41225, +41262, +41295, +41295, +41319, +41319, +41319, +41328, +41342, +41349, +41360, +41360, +41377, +41396, +41396, +41424, +41456, +41456, +41468, +41508, +41525, +41543, +41543, +41552, +41552, +41552, +41552, +41552, +41552, +41552, +41552, +41567, +41577, +41577, +41596, +41603, +41603, +41603, +41621, +41639, +41639, +41659, +41659, +41659, +41659, +41659, +41692, +41692, +41692, +41692, +41692, +41712, +41730, +41751, +41751, +41770, +41770, +41770, +41783, +41801, +41809, +41816, +41834, +41853, +41853, +41853, +41866, +41866, +41866, +41866, +41902, +41943, +41975, +41975, +41975, 41996, -42002, -42002, -42002, -42002, -42002, -42002, -42002, -42002, -42002, -42002, -42002, -42021, -42102, -42114, -42160, -42167, -42167, -42167, -42167, -42167, -42167, -42167, -42167, -42167, -42167, -42244, -42244, +42013, +42040, +42051, +42064, +42087, +42087, +42087, +42106, +42126, +42182, +42196, +42203, +42203, +42246, 42253, -42263, -42270, -42278, -42293, -42315, -42323, -42323, -42353, -42353, -42353, -42353, -42353, -42365, -42365, -42365, -42397, -42516, -42526, +42272, +42272, +42298, +42343, +42343, +42343, +42372, +42419, +42456, +42462, +42480, +42493, +42518, +42529, 42535, 42535, -42544, -42544, -42544, -42544, -42544, -42544, -42544, -42559, -42563, -42782, +42535, +42535, +42555, +42567, +42581, +42616, +42616, +42626, +42662, +42685, +42685, +42740, +42740, +42766, +42794, 42798, -42804, -42804, -42804, -42804, -42846, -42896, -42896, -42919, -42947, -42947, -42947, -42947, -42947, -42958, -42958, -42972, -43009, -43150, -43150, -43172, -43176, -43176, -43176, -43176, -43176, -43176, -43176, -43176, -43176, -43176, -43227, -43233, -43233, -43233, -43233, -43233, +42798, +42798, +42809, +42839, +42839, +42839, +42844, +42854, +42854, +42869, +42879, +42929, +42988, +42997, +43003, +43014, +43025, +43059, +43059, +43108, +43108, +43108, +43118, +43136, +43152, +43168, +43185, +43219, +43234, +43234, +43241, +43241, +43241, +43253, +43253, 43257, -43275, -43275, -43275, -43275, -43275, -43275, -43275, +43257, +43257, +43257, +43257, +43267, 43285, -43285, -43285, -43294, -43359, -43462, -43468, -43468, -43468, -43468, -43480, -43480, -43487, -43487, -43501, -43508, -43508, -43508, -43508, -43508, -43508, -43508, -43518, -43518, -43556, -43573, -43573, -43573, -43573, +43295, +43361, +43361, +43361, +43378, +43397, +43397, +43397, +43418, +43418, +43418, +43428, +43428, +43428, +43436, +43451, +43456, +43488, +43488, +43488, +43488, +43488, +43504, +43504, +43522, +43522, +43540, +43547, +43547, +43570, +43570, +43570, +43570, +43576, 43583, -43592, -43592, -43592, -43613, -43613, -43613, -43660, -43884, -43884, -43884, -43903, -43903, +43590, +43618, +43618, +43629, +43643, +43663, +43670, +43709, +43744, +43759, +43787, +43879, +43885, +43934, +43934, +43940, 43945, -43945, -43952, -43952, -43952, -43952, -43952, -43958, -44106, -44114, -44122, -44122, -44122, -44122, -44135, -44183, +43965, +43972, +43998, +43998, +44015, +44031, +44057, +44057, +44057, +44057, +44073, +44073, +44086, +44137, +44189, 44196, -44196, -44196, -44196, -44196, -44196, -44196, -44216, -44216, -44216, -44216, -44349, -44355, -44355, -44361, -44387, -44387, -44387, -44387, -44387, -44387, -44387, -44387, -44395, -44504, -44504, -44516, -44516, -44516, -44516, -44516, -44572, -44572, -44572, -44610, -44610, -44610, -44620, -44630, -44630, -44630, -44630, -44646, -44691, -44708, -44729, -44743, -44771, -44771, -44771, +44215, +44215, +44260, +44260, +44260, +44260, +44264, +44270, +44270, +44313, +44324, +44354, +44379, +44379, +44386, +44408, +44458, +44481, +44481, +44481, +44481, +44481, +44481, +44481, +44481, +44488, +44520, +44538, +44571, +44571, +44591, +44598, +44604, +44615, +44625, +44638, +44638, +44638, +44657, +44674, +44692, +44692, +44692, +44737, +44758, +44758, 44775, -44775, -44775, -44798, -44798, -44798, -44858, -44870, -44870, -44874, -44874, -44887, -44887, -44900, -44923, -44923, -44923, -44923, -44923, -44923, -44923, -44923, -44923, -44933, -44933, -45072, -45084, -45084, -45084, -45084, -45084, -45084, -45084, -45084, -45084, -45084, -45084, -45084, -45236, -45236, -45236, -45236, -45236, -45236, -45243, +44784, +44801, +44801, +44801, +44812, +44826, +44834, +44852, +44864, +44864, +44879, +44886, +44886, +44886, +44886, +44893, +44893, +44897, +44897, +44942, +44961, +44968, +44975, +44996, +44996, +45003, +45003, +45016, +45016, +45016, +45080, +45093, +45093, +45108, +45108, +45143, +45152, +45159, +45159, +45171, +45184, +45211, +45248, 45255, -45266, -45266, -45271, -45271, -45271, -45271, -45271, -45282, -45282, -45282, -45331, -45515, -45530, -45547, -45553, -45553, -45570, -45575, -45575, -45575, -45575, -45575, -45575, -45584, -45617, -45617, -45623, -45623, -45623, -45623, -45665, -45698, -45710, -45710, -45715, -45715, -45715, -45715, -45715, -45722, -45722, -45722, -45753, -45855, -45855, -45861, -45861, -45861, -45868, -45874, -45874, -45874, -45874, -45874, -45874, -45874, -45989, -45989, -46000, -46000, -46000, -46009, -46054, -46083, -46089, -46089, -46113, -46113, -46113, -46124, -46124, -46124, -46124, -46124, -46197, -46331, -46343, -46343, -46343, -46343, -46343, -46343, -46343, -46343, -46343, -46343, -46343, -46343, -46401, -46408, -46415, -46415, -46415, -46415, -46483, -46545, -46545, -46545, -46563, -46563, -46578, -46578, -46578, -46578, -46578, -46578, -46623, -46702, -46702, -46707, -46714, -46714, -46728, -46728, -46728, -46728, -46736, -46736, -46736, -46751, -46843, -46843, -46843, -46843, -46865, -46872, -46882, +45255, +45295, +45310, +45317, +45352, +45412, +45412, +45426, +45471, +45495, +45495, +45511, +45518, +45523, +45529, +45535, +45535, +45552, +45558, +45583, +45583, +45583, +45606, +45612, +45641, +45659, +45659, +45659, +45714, +45714, +45752, +45766, +45776, +45789, +45789, +45789, +45805, +45842, +45886, +45886, +45886, +45886, +45886, +45898, +45916, +45930, +45951, +45969, +45969, +45999, +46011, +46024, +46024, +46042, +46073, +46080, +46080, +46080, +46080, +46111, +46131, +46141, +46190, +46213, +46226, +46226, +46226, +46226, +46226, +46245, +46245, +46245, +46272, +46279, +46334, +46371, +46432, +46453, +46453, +46459, +46484, +46498, +46498, +46498, +46506, +46506, +46506, +46523, +46523, +46523, +46542, +46549, +46573, +46579, +46593, +46600, +46600, +46616, +46640, +46640, +46647, +46681, +46693, +46703, +46719, +46719, +46730, +46747, +46747, +46761, +46761, +46809, +46809, +46828, +46828, +46828, +46828, +46828, +46838, +46838, +46838, +46838, +46860, +46860, +46899, +46923, +46923, +46923, +46923, 46930, -46951, -46951, -46951, -46951, -46951, -46958, -46958, -46958, -46958, -46958, -47017, -47172, -47172, -47179, -47179, -47179, -47190, -47190, -47190, -47190, -47207, -47207, -47226, -47258, -47276, -47283, -47290, -47290, -47290, -47297, -47303, -47357, -47380, -47380, -47380, -47380, -47387, -47387, -47397, -47417, -47417, -47417, -47442, -47540, -47559, -47576, -47593, -47593, -47593, -47593, -47600, -47600, -47606, -47606, -47618, -47618, -47721, -47752, -47761, -47761, -47761, -47767, -47810, -47856, -47866, -47866, -47876, -47876, -47876, -47883, -47883, -47883, -47883, -47883, -47972, -48046, -48046, -48056, -48056, -48056, -48087, -48087, -48087, -48094, -48094, -48108, -48108, -48108, -48136, -48140, -48140, -48140, -48140, -48140, -48149, -48168, -48179, -48179, -48179, -48179, -48179, -48179, -48179, -48191, -48191, -48208, -48261, -48460, -48460, -48467, -48467, -48474, -48474, -48474, -48474, -48474, -48474, -48474, -48492, -48499, -48557, -48564, -48564, -48564, -48571, -48571, -48580, -48613, -48643, -48643, -48667, -48667, -48667, -48667, -48667, -48667, -48667, -48689, -48718, -48839, -48839, -48846, -48846, -48854, -48871, -48871, +46939, +46939, +46956, +46999, +47084, +47084, +47084, +47091, +47091, +47099, +47110, +47110, +47125, +47142, +47201, +47201, +47224, +47268, +47268, +47279, +47279, +47279, +47310, +47344, +47344, +47348, +47364, +47402, +47413, +47429, +47443, +47461, +47496, +47496, +47512, +47512, +47550, +47571, +47615, +47625, +47638, +47669, +47676, +47683, +47695, +47719, +47814, +47845, +47862, +47874, +47874, +47887, +47898, +47898, +47933, +47940, +47940, +47940, +47981, +47995, +48002, +48020, +48041, +48041, +48048, +48048, +48103, +48113, +48120, +48127, +48141, +48180, +48234, +48234, +48241, +48241, +48253, +48260, +48260, +48278, +48315, +48315, +48334, +48354, +48354, +48354, +48361, +48368, +48375, +48386, +48397, +48412, +48462, +48483, +48483, +48516, +48578, +48578, +48603, +48636, +48636, +48673, +48673, +48673, +48682, +48682, +48744, +48754, +48762, +48804, +48855, +48878, 48885, -48885, -48893, -48893, -48893, -48893, -48977, -48990, -48990, -48990, -48990, -48997, -49013, -49087, -49114, -49114, -49148, -49153, -49153, -49168, -49168, -49168, -49168, -49199, -49220, -49415, -49429, -49439, -49439, -49439, -49453, -49460, -49478, -49487, -49487, -49487, -49487, -49487, -49555, -49555, -49555, -49555, -49555, -49566, -49576, -49613, -49623, -49630, +48896, +48896, +48896, +48896, +48917, +48973, +48985, +48985, +48996, +48996, +48996, +48996, +48996, +49010, +49042, +49042, +49042, +49042, +49042, +49042, +49053, +49053, +49064, +49092, +49106, +49106, +49106, +49106, +49123, +49142, +49184, +49211, +49221, +49221, +49221, +49228, +49250, +49250, +49266, +49266, +49266, +49285, +49316, +49316, +49316, +49316, +49332, +49339, +49368, +49384, +49384, +49384, +49403, +49420, +49420, +49428, +49466, +49489, +49489, +49547, +49563, +49563, +49563, +49563, +49598, +49603, +49614, +49614, +49614, +49635, +49635, +49644, +49654, 49668, -49682, -49696, -49703, -49703, -49716, -49716, -49716, -49805, -49886, -49886, -49886, +49668, +49687, +49687, +49693, +49693, +49698, +49739, +49771, +49780, +49780, +49803, +49822, +49822, +49822, +49822, +49822, +49840, +49873, +49873, +49885, 49900, 49900, -49922, -49922, -49922, -49922, -49922, -49929, -49929, -49929, -50054, -50071, -50078, -50078, -50078, -50086, -50102, -50126, -50156, -50156, -50156, -50163, -50163, -50179, -50179, -50186, -50186, -50186, -50242, -50368, -50375, -50382, -50382, -50382, -50392, -50392, -50392, -50392, +49912, +49912, +49926, +49926, +49961, +49974, +49974, +49980, +49980, +49989, +50006, +50011, +50018, +50018, +50018, +50073, +50073, +50091, +50091, +50155, +50182, +50191, +50211, +50211, +50231, +50231, +50231, +50254, +50270, +50270, +50270, +50290, +50301, +50301, +50301, +50301, +50301, +50323, +50345, +50345, +50370, +50370, 50399, 50399, -50404, -50404, -50457, -50457, -50487, -50487, -50487, -50496, -50522, -50587, -50595, -50599, -50599, -50599, -50599, -50599, -50599, -50614, -50614, -50634, -50680, -50835, -50835, -50845, -50855, -50855, -50895, -50895, -50902, -50915, -50915, -50915, -50915, -50915, -51070, -51083, -51093, -51093, -51099, -51104, -51114, -51149, -51161, -51161, -51161, -51161, -51168, -51175, -51180, -51190, -51197, -51197, +50417, +50417, +50433, +50433, +50433, +50459, +50459, +50498, +50515, +50590, +50590, +50594, +50594, +50658, +50690, +50690, +50697, +50697, +50722, +50733, +50733, +50765, +50790, +50806, +50821, +50831, +50866, +50885, +50907, +50907, +50971, +50978, +50978, +51005, +51022, +51022, +51022, +51043, +51049, +51110, +51110, +51117, +51142, 51214, -51274, -51274, -51288, -51294, -51294, -51294, -51294, -51301, -51301, -51301, -51308, -51308, -51325, -51447, -51447, -51447, -51447, -51447, -51447, -51464, -51486, -51506, -51506, -51523, -51523, -51535, -51535, -51535, -51535, -51535, -51535, -51560, -51698, -51698, -51698, -51698, -51698, -51710, -51710, -51710, -51710, -51720, -51720, -51720, -51720, -51754, -51758, -51758, -51768, -51768, -51768, -51774, -51835, -51835, -51835, -51835, -51841, -51841, -51850, -51857, -51857, -51862, -51862, -51900, -51969, -51969, -51969, -51976, -51976, -51992, -52003, -52035, -52040, -52040, -52040, -52040, -52040, -52116, -52116, -52116, -52116, -52123, -52123, -52137, -52203, -52225, -52225, -52225, -52225, -52225, -52225, -52225, -52225, -52232, -52232, -52255, -52335, -52335, -52344, -52344, -52351, -52351, -52351, -52358, -52358, -52358, -52358, -52358, -52358, -52457, -52457, -52457, -52457, -52457, -52457, -52533, -52595, +51243, +51243, +51272, +51279, +51295, +51295, +51330, +51351, +51366, +51393, +51400, +51410, +51410, +51410, +51436, +51468, +51468, +51468, +51516, +51524, +51524, +51529, +51529, +51553, +51567, +51567, +51577, +51595, +51595, +51595, +51629, +51643, +51676, +51676, +51676, +51676, +51699, +51714, +51741, +51741, +51771, +51779, +51779, +51779, +51779, +51806, +51815, +51853, +51874, +51890, +51910, +51929, +51962, +51962, +51970, +52037, +52064, +52115, +52148, +52169, +52194, +52218, +52218, +52245, +52261, +52271, +52271, +52279, +52279, +52305, +52305, +52305, +52305, +52305, +52321, +52321, +52321, +52348, +52377, +52377, +52377, +52377, +52377, +52386, +52403, +52428, +52428, +52469, +52469, +52469, +52524, +52539, +52539, +52553, +52558, +52569, +52569, +52581, +52598, 52614, 52614, -52628, -52628, -52628, -52628, -52628, -52628, -52635, -52643, +52619, +52619, +52631, +52639, +52650, +52657, +52657, +52657, 52671, -52743, -52754, -52766, -52775, -52793, -52798, -52798, -52798, -52808, -52808, -52808, -52808, -52808, -52849, -52849, -52849, -52849, -52849, -52857, -52863, -52889, -52899, -52899, -52904, -52904, -52904, -52904, -52904, -52915, -52915, -52923, -52923, -53003, -53023, -53047, -53047, -53055, -53070, -53070, -53070, -53070, -53076, -53084, -53092, -53092, -53214, -53225, -53225, -53225, -53225, -53249, -53268, -53285, -53296, -53296, -53332, -53356, -53356, -53356, -53356, -53356, -53356, -53356, -53391, -53447, -53457, -53486, -53504, -53512, -53512, -53512, -53518, -53518, -53518, -53518, -53518, -53518, -53596, -53596, -53596, -53596, -53596, -53596, -53596, -53624, -53634, -53634, -53646, -53646, -53653, -53653, -53661, -53680, -53680, -53680, -53716, -53843, -53843, -53851, -53858, -53864, -53864, -53864, -53864, -53864, -53864, -53864, -53864, -53864, -53910, -53910, -53916, -53916, -53924, -53931, -53931, -53957, -53965, -53981, -53991, -53991, -53999, -53999, -53999, -54009, -54009, -54009, -54042, -54204, -54204, -54212, -54212, -54212, -54218, -54218, -54218, -54218, -54231, -54231, -54231, -54231, -54308, -54352, -54352, -54363, -54371, -54381, -54399, -54420, -54458, -54469, -54482, -54482, -54482, -54482, -54482, -54482, -54482, -54496, -54516, -54643, -54659, -54659, -54667, -54667, -54687, -54687, -54687, -54691, -54697, -54697, -54697, -54697, -54827, -54833, -54833, -54833, -54833, -54854, -54854, -54876, -54894, -54894, -54894, -54900, -54900, -54904, -54915, -54915, -54915, -54915, -54965, -55064, -55064, -55064, -55073, -55073, -55095, -55095, -55095, -55095, -55110, -55110, -55110, -55110, -55242, -55252, -55252, -55252, -55252, -55252, -55270, -55270, -55270, -55270, -55295, -55295, -55295, -55295, -55308, -55308, -55308, -55308, -55389, -55447, -55447, -55458, -55465, -55465, -55465, -55471, -55471, -55478, -55484, -55484, -55484, -55484, -55656, -55656, -55656, -55656, -55656, -55656, -55729, -55729, -55729, -55729, -55740, -55740, -55740, -55740, -55740, -55789, -55789, -55798, -55858, -55975, -55986, -55986, -55986, -55992, -55992, -55992, -55992, -55992, -55992, -55992, -55992, -55992, -56095, -56113, -56127, -56127, -56127, -56136, -56136, -56171, -56175, -56175, -56175, -56181, -56181, -56197, -56197, -56197, -56197, -56208, -56247, -56379, -56379, -56379, -56379, -56379, -56385, -56385, -56385, -56392, -56392, -56392, -56392, -56392, -56455, -56455, -56455, -56455, -56455, -56461, -56480, -56498, -56505, -56505, -56505, -56505, -56518, -56518, -56518, -56518, -56518, -56518, -56579, -56684, -56684, -56691, -56691, -56691, -56691, -56691, -56691, -56691, -56691, -56691, -56698, -56718, -56758, -56758, -56770, -56770, -56770, -56770, -56781, -56802, -56802, -56802, -56802, -56802, -56802, -56802, -56802, -56816, -56816, -56828, -56838, -56988, -56988, -56988, -56988, -56988, -56993, -57008, -57019, -57019, -57019, -57019, -57019, -57019, +52671, +52691, +52691, +52691, +52713, +52799, +52816, +52816, +52816, +52869, +52919, +52934, +52953, +52953, +52953, +53006, +53048, +53124, +53144, +53152, +53152, +53152, +53152, +53159, +53216, +53221, +53221, +53232, +53271, +53287, +53287, +53287, +53292, +53309, +53309, +53316, +53350, +53401, +53422, +53422, +53451, +53456, +53465, +53481, +53491, +53491, +53491, +53491, +53521, +53532, +53541, +53541, +53559, +53566, +53566, +53583, +53602, +53611, +53623, +53637, +53666, +53685, +53685, +53692, +53692, +53725, +53725, +53779, +53779, +53800, +53813, +53813, +53834, +53841, +53841, +53862, +53898, +53905, +53905, +53925, +53943, +53963, +53963, +53968, +53980, +53995, +54024, +54024, +54033, +54051, +54051, +54051, +54091, +54091, +54091, +54091, +54108, +54126, +54184, +54194, +54210, +54210, +54226, +54284, +54299, +54299, +54312, +54337, +54361, +54394, +54412, +54412, +54412, +54423, +54456, +54498, +54498, +54498, +54498, +54510, +54510, +54510, +54510, +54510, +54531, +54531, +54551, +54577, +54586, +54586, +54630, +54639, +54654, +54654, +54664, +54684, +54684, +54717, +54717, +54724, +54742, +54762, +54778, +54778, +54794, +54807, +54807, +54826, +54826, +54831, +54831, +54831, +54831, +54850, +54850, +54850, +54850, +54850, +54850, +54850, +54870, +54920, +54920, +54920, +54971, +54971, +54971, +54971, +54971, +54971, +54978, +54978, +54978, +54978, +54992, +55016, +55016, +55058, +55075, +55090, +55123, +55133, +55133, +55133, +55146, +55182, +55209, +55216, +55240, +55258, +55258, +55274, +55289, +55289, +55325, +55337, +55344, +55344, +55348, +55357, +55376, +55416, +55431, +55436, +55453, +55453, +55480, +55508, +55535, +55542, +55542, +55542, +55572, +55572, +55611, +55621, +55650, +55650, +55669, +55674, +55681, +55688, +55688, +55694, +55705, +55714, +55735, +55735, +55735, +55744, +55744, +55744, +55744, +55780, +55854, +55884, +55914, +55919, +55919, +55950, +55960, +55960, +55960, +55968, +55981, +55981, +55998, +55998, +56018, +56059, +56065, +56083, +56083, +56110, +56139, +56139, +56211, +56211, +56211, +56211, +56228, +56240, +56260, +56260, +56294, +56294, +56294, +56306, +56338, +56407, +56426, +56437, +56437, +56443, +56453, +56509, +56509, +56509, +56509, +56515, +56539, +56546, +56546, +56546, +56584, +56602, +56602, +56622, +56634, +56652, +56660, +56674, +56674, +56729, +56729, +56729, +56750, +56788, +56788, +56793, +56793, +56793, +56793, +56813, +56835, +56873, +56896, +56944, +56980, +57001, +57032, +57051, +57061, +57061, +57073, +57073, +57082, +57092, +57092, +57092, +57104, +57115, +57115, +57115, 57121, -57125, -57125, -57125, -57132, -57132, -57172, -57221, -57228, -57228, -57228, -57228, -57228, -57238, -57243, -57243, -57243, -57249, -57319, -57466, +57133, +57133, +57133, +57153, +57183, +57198, +57198, +57216, +57232, +57248, +57259, +57296, +57316, +57316, +57322, +57333, +57351, +57367, +57375, +57419, +57419, +57431, +57441, +57441, +57460, 57476, -57485, -57485, -57485, -57492, -57492, -57498, +57495, +57495, 57511, -57526, -57526, -57526, -57539, -57621, -57621, -57657, -57657, -57657, -57657, -57671, -57692, -57692, -57692, -57723, -57723, -57723, -57723, -57723, -57746, -57746, -57746, -57759, -57931, -57931, -57931, -57931, -57931, -57931, -57931, -57949, -57949, -57949, -57956, -57956, -57956, -58072, -58129, -58138, -58142, -58142, -58155, -58167, -58185, -58198, -58208, -58208, -58214, -58221, -58246, -58246, -58258, -58266, -58266, -58298, -58452, -58452, -58452, -58452, -58469, -58477, -58477, -58483, -58483, -58483, -58489, -58489, -58503, -58591, -58605, -58616, -58616, -58626, -58626, -58635, -58666, -58688, -58688, -58697, -58697, -58697, -58697, -58697, -58697, -58697, -58697, -58710, -58760, -58760, -58767, -58772, -58772, -58793, -58793, -58793, -58793, -58793, -58793, -58793, -58793, -58889, -58889, -58889, -58896, -58896, -58896, -58896, -58896, -58903, -58913, -58929, -58929, -58929, -58929, -58929, -58943, -58943, -58943, -58961, -59083, -59083, -59090, -59090, -59090, -59090, -59090, -59090, -59097, -59097, -59097, -59097, -59097, -59208, -59221, -59241, -59241, -59241, -59247, -59263, -59298, -59298, -59298, -59308, -59308, -59308, -59308, -59308, -59308, -59313, -59313, -59339, -59520, -59520, -59526, -59526, -59526, -59526, -59526, -59526, -59526, -59548, -59548, -59548, -59548, -59601, -59601, -59601, -59601, -59601, -59601, -59653, -59677, -59694, -59694, -59739, -59739, -59754, -59754, -59754, -59765, -59765, -59765, -59786, -59939, -59939, -59946, -59946, -59946, -59955, -59955, -59955, -59955, -59955, -59955, -59955, -59955, -60013, -60013, -60013, -60013, -60013, -60013, -60054, -60079, -60089, -60089, -60099, -60099, -60099, -60105, -60105, -60105, -60105, -60105, -60114, -60268, -60268, -60281, -60294, -60294, -60294, -60294, -60294, -60310, -60310, -60310, -60310, -60310, -60450, -60456, -60456, -60456, -60456, -60456, -60456, -60487, -60515, -60515, -60515, -60515, -60528, -60528, -60528, -60528, -60528, -60544, -60572, -60619, -60643, -60655, -60655, -60684, -60702, -60702, -60702, -60702, -60702, -60702, -60702, -60702, -60856, -60862, +57511, +57521, +57521, +57521, +57531, +57558, +57603, +57603, +57603, +57609, +57627, +57662, +57668, +57677, +57677, +57685, +57685, +57696, +57711, +57721, +57743, +57765, +57782, +57782, +57789, +57789, +57789, +57789, +57811, +57811, +57811, +57828, +57844, +57844, +57844, +57886, +57891, +57918, +57918, +57918, +57918, +57926, +57930, +57967, +57967, +57973, +57973, +58001, +58036, +58070, +58070, +58070, +58076, +58084, +58084, +58098, +58124, +58140, +58147, +58166, +58183, +58230, +58238, +58238, +58255, +58267, +58292, +58302, +58320, +58320, +58335, +58335, +58372, +58372, +58372, +58401, +58421, +58432, +58444, +58450, +58468, +58468, +58486, +58486, +58520, +58535, +58535, +58535, +58535, +58545, +58554, +58568, +58617, +58617, +58630, +58678, +58684, +58701, +58701, +58701, +58701, +58701, +58739, +58739, +58739, +58746, +58746, +58803, +58823, +58823, +58823, +58853, +58871, +58952, +58963, +58963, +58970, +58970, +58988, +58997, +59013, +59018, +59025, +59025, +59031, +59044, +59063, +59069, +59069, +59127, +59146, +59146, +59146, +59168, +59168, +59179, +59179, +59191, +59207, +59219, +59258, +59265, +59315, +59315, +59315, +59320, +59320, +59320, +59320, +59350, +59367, +59377, +59423, +59423, +59438, +59488, +59488, +59494, +59494, +59507, +59540, +59540, +59540, +59540, +59540, +59540, +59578, +59618, +59630, +59639, +59639, +59733, +59733, +59751, +59751, +59766, +59783, +59783, +59790, +59798, +59804, +59854, +59854, +59869, +59869, +59875, +59875, +59895, +59895, +59934, +59961, +59961, +59961, +59967, +59973, +59973, +59999, +60008, +60008, +60008, +60036, +60036, +60036, +60046, +60060, +60060, +60060, +60068, +60086, +60086, +60096, +60096, +60117, +60159, +60204, +60228, +60228, +60241, +60241, +60297, +60313, +60319, +60319, +60389, +60396, +60396, +60396, +60396, +60412, +60412, +60452, +60452, +60477, +60489, +60509, +60509, +60521, +60541, +60550, +60559, +60559, +60571, +60597, +60631, +60646, +60657, +60663, +60663, +60672, +60701, +60701, +60709, +60715, +60715, +60757, +60768, +60768, +60768, +60768, +60795, +60805, +60805, +60805, +60805, +60805, +60852, +60867, +60867, +60867, +60867, +60867, 60882, -60882, -60882, -60882, -60888, -60924, -60952, -60952, -60964, -60964, -60976, -60976, -60976, -60988, -60988, -60999, -61042, -61121, -61127, -61139, -61139, -61154, -61154, -61154, +60898, +60898, +60913, +60913, +60932, +61031, +61047, +61064, +61064, +61078, +61078, +61110, +61142, +61142, +61142, 61167, 61167, 61167, 61167, -61167, -61167, -61179, -61187, -61187, -61193, 61199, -61199, -61233, -61272, -61272, -61272, -61272, -61272, -61272, -61280, -61296, -61307, -61307, -61307, -61320, -61519, -61519, -61527, -61527, -61541, -61541, -61541, -61541, -61541, -61541, -61541, -61541, -61541, -61613, -61625, -61646, -61646, -61662, -61671, -61704, -61716, -61716, -61716, +61218, +61218, +61247, +61254, +61290, +61290, +61290, +61290, +61301, +61301, +61301, +61301, +61301, +61336, +61342, +61342, +61349, +61349, +61370, +61370, +61393, +61425, +61442, +61442, +61468, +61496, +61502, +61502, +61502, +61512, +61525, +61525, +61542, +61595, +61640, +61684, +61710, +61710, 61737, -61737, -61742, -61742, -61742, -61742, -61742, -61751, -61762, -61900, -61900, -61917, -61917, +61750, +61786, +61786, +61803, +61889, +61889, +61889, +61908, +61914, +61938, 61953, -61953, -61953, -61953, -61953, -61965, -61965, -61965, -61965, -62067, -62067, -62067, -62067, -62067, +61972, +62009, +62033, +62039, +62039, +62057, +62063, 62074, -62105, -62111, -62111, -62111, -62128, -62128, -62128, -62128, -62128, -62128, -62128, -62128, -62140, -62264, -62264, -62281, -62281, -62281, -62297, -62297, -62297, -62297, -62297, -62297, -62297, -62305, -62412, -62412, -62426, -62426, -62426, -62426, -62432, -62460, -62472, -62472, -62484, -62484, -62484, -62484, -62484, -62494, -62494, -62494, -62519, -62712, -62712, -62712, -62712, -62718, -62727, -62727, -62727, -62727, -62727, -62727, -62727, -62727, -62880, +62093, +62113, +62113, +62119, +62119, +62125, +62125, +62146, +62159, +62159, +62165, +62199, +62216, +62225, +62225, +62231, +62237, +62237, +62237, +62237, +62265, +62278, +62317, +62323, +62323, +62323, +62323, +62323, +62339, +62359, +62388, +62394, +62394, +62394, +62400, +62406, +62416, +62416, +62447, +62447, +62475, +62475, +62491, +62491, +62531, +62531, +62531, +62531, +62559, +62572, +62586, +62601, +62601, +62601, +62625, +62635, +62658, +62658, +62670, +62682, +62703, +62703, +62709, +62716, +62736, +62775, +62785, +62790, +62796, +62796, +62813, +62828, +62845, +62853, +62853, +62853, +62874, 62887, -62887, -62887, -62887, -62887, -62923, -62965, -62977, -62977, -63005, -63005, -63005, -63005, -63005, -63005, -63005, -63018, -63029, -63145, -63145, -63174, -63186, -63202, -63221, -63221, -63221, -63221, -63221, -63227, -63227, -63227, -63332, -63332, -63342, -63342, -63342, -63348, -63348, -63369, -63376, -63376, -63381, -63381, -63381, -63397, -63397, -63417, -63417, -63417, +62893, +62909, +62922, +62971, +62971, +63013, +63013, +63021, +63021, +63053, +63087, +63150, +63150, +63150, +63160, +63166, +63166, +63166, +63177, +63212, +63243, +63243, +63243, +63243, +63243, +63243, +63243, +63243, +63252, +63263, +63269, +63269, +63269, +63275, +63289, +63301, +63301, +63316, +63316, +63316, +63316, +63335, +63391, +63413, +63439, 63445, -63489, -63497, -63497, -63503, -63503, -63521, -63521, -63528, -63528, -63535, -63535, -63535, -63535, -63584, -63584, -63584, -63590, -63590, -63590, -63644, -63661, -63661, -63661, -63672, -63672, -63679, -63679, -63687, -63699, -63699, -63699, -63770, -63806, -63826, -63826, -63834, -63883, -63883, -63883, -63883, -63883, -63883, -63883, -63883, -63883, -64042, -64042, -64048, -64048, -64055, -64075, +63445, +63457, +63457, +63472, +63472, +63472, +63494, +63500, +63545, +63545, +63557, +63557, +63580, +63676, +63682, +63711, +63718, +63731, +63750, +63750, +63771, +63799, +63822, +63822, +63849, +63880, +63903, +63910, +63929, +63929, +63936, +63942, +63955, +63955, +63955, +64014, +64020, +64020, +64040, +64051, +64067, +64082, +64104, +64104, 64110, -64134, 64141, 64141, -64151, -64151, -64176, -64176, -64183, -64190, -64190, -64190, -64254, -64271, -64271, -64285, -64285, -64285, +64152, +64159, +64208, +64231, +64231, +64231, +64286, +64286, 64310, -64325, -64325, -64325, -64331, -64331, -64331, -64342, -64444, -64497, -64497, -64497, -64497, -64503, -64513, -64525, +64329, +64360, +64360, +64391, +64391, +64397, +64397, +64410, +64410, +64427, +64434, +64434, +64454, +64454, +64454, +64454, +64454, +64463, +64463, +64469, +64469, +64492, +64492, +64521, 64532, -64532, -64542, -64542, -64542, -64542, -64542, -64542, -64542, -64542, -64560, -64647, -64647, -64647, -64647, -64679, -64679, -64679, -64679, -64679, -64679, -64679, -64679, -64679, -64706, -64706, -64747, -64747, -64754, -64759, -64769, -64803, -64809, -64816, -64816, -64816, -64816, -64816, -64816, -64824, -64831, -64831, -64859, -65020, -65026, -65043, -65043, -65049, -65049, -65049, -65055, -65055, -65055, +64590, +64605, +64633, +64663, +64695, +64701, +64707, +64707, +64720, +64745, +64752, +64766, +64776, +64791, +64791, +64813, +64823, +64823, +64823, +64829, +64853, +64853, +64884, +64884, +64884, +64884, +64893, +64903, +64925, +64934, +64958, +64958, +64958, +64965, +64978, +64999, +65018, +65024, +65031, +65046, 65061, -65061, -65061, -65088, -65088, -65101, -65101, -65101, -65101, -65138, -65144, -65151, -65151, -65151, -65151, -65151, -65151, -65151, -65162, -65162, -65162, +65095, +65114, +65114, +65137, +65148, +65148, +65209, 65226, -65319, -65319, -65319, -65319, -65335, -65335, -65335, -65335, -65335, -65343, -65343, -65343, -65343, -65466, -65528, -65556, -65556, -65561, -65561, -65567, -65613, -65654, -65654, -65654, -65654, -65654, -65654, -65654, -65672, -65672, -65672, -65725, -65810, -65816, -65816, -65816, -65816, -65822, -65822, -65834, -65834, -65834, -65834, -65834, -65834, -65935, -65935, -65935, -65935, -65942, -65948, -65956, -65976, -65993, -65993, -65993, -65993, -66002, -66002, -66011, -66011, -66011, -66011, -66077, -66244, -66244, -66244, -66254, -66254, -66259, -66259, -66259, -66259, -66259, -66259, -66259, -66259, -66393, -66399, -66399, -66399, -66405, -66405, -66405, -66443, -66455, -66455, -66460, -66460, -66460, -66460, -66460, -66460, -66460, -66460, -66492, -66618, -66618, -66635, -66640, -66657, -66681, -66681, -66681, -66681, -66692, -66692, -66692, -66692, -66765, -66765, -66765, -66765, -66771, -66771, -66797, -66837, -66837, -66837, -66837, -66837, -66837, -66837, -66837, -66837, -66837, -66837, -66925, -67018, -67029, -67046, -67046, -67046, -67051, -67051, -67057, -67057, -67057, -67057, -67057, -67057, -67147, -67147, -67147, -67147, -67147, -67147, -67157, -67171, -67171, -67178, -67188, -67188, -67188, -67188, -67188, -67188, -67188, -67188, -67263, -67331, -67331, -67341, -67341, -67357, -67369, -67369, -67369, -67369, -67369, -67369, -67369, -67369, -67404, -67404, -67404, -67404, -67409, -67417, -67433, -67475, -67475, -67475, -67475, -67481, -67481, -67481, -67481, -67491, -67491, -67491, -67505, -67599, -67599, -67606, -67606, -67612, -67623, -67623, -67629, -67629, -67629, -67635, -67635, -67635, -67791, -67809, -67809, -67809, -67809, -67809, -67827, -67849, -67866, +65226, +65264, +65275, +65286, +65292, +65292, +65305, +65305, +65315, +65315, +65338, +65338, +65354, +65361, +65361, +65361, +65361, +65373, +65373, +65382, +65397, +65404, +65431, +65437, +65454, +65454, +65472, +65486, +65486, +65492, +65510, +65516, +65516, +65516, +65541, +65541, +65541, +65541, +65550, +65591, +65591, +65591, +65612, +65643, +65666, +65666, +65685, +65685, +65691, +65691, +65703, +65713, +65727, +65733, +65749, +65749, +65759, +65839, +65870, +65885, +65891, +65918, +65937, +65951, +65951, +65967, +65973, +65979, +65979, +66030, +66079, +66088, +66088, +66088, +66107, +66113, +66129, +66184, +66184, +66184, +66207, +66255, +66271, +66313, +66313, +66323, +66340, +66350, +66370, +66370, +66404, +66404, +66404, +66411, +66427, +66438, +66438, +66438, +66438, +66448, +66462, +66473, +66473, +66501, +66501, +66501, +66536, +66536, +66536, +66536, +66536, +66536, +66536, +66536, +66536, +66536, +66536, +66582, +66582, +66599, +66608, +66624, +66624, +66624, +66631, +66656, +66656, +66679, +66679, +66701, +66728, +66751, +66758, +66792, +66814, +66814, +66814, +66860, +66903, +66903, +66903, +66919, +66919, +66919, +66926, +66989, +67022, +67074, +67090, +67121, +67121, +67121, +67132, +67197, +67197, +67205, +67224, +67250, +67266, +67282, +67282, +67282, +67295, +67295, +67311, +67322, +67322, +67329, +67348, +67348, +67348, +67348, +67368, +67395, +67395, +67419, +67428, +67428, +67449, +67463, +67463, +67470, +67487, +67515, +67534, +67534, +67534, +67576, +67576, +67590, +67609, +67632, +67632, +67632, +67642, +67675, +67688, +67693, +67700, +67713, +67713, +67744, +67771, +67797, +67816, +67824, +67824, +67831, +67851, +67851, +67851, +67856, +67869, 67880, -67910, -67910, -67910, -67910, -67910, -67935, -67951, -67951, -67995, -68105, -68117, -68117, -68117, -68172, -68172, -68186, -68193, -68198, -68198, -68198, -68198, -68198, -68210, -68210, -68227, -68227, -68227, -68227, -68245, -68253, -68267, -68267, -68293, -68293, -68293, -68293, -68293, -68293, -68293, -68293, -68321, -68458, -68472, -68489, -68489, -68489, -68489, -68489, -68489, -68489, -68489, -68489, -68489, -68489, -68703, -68774, -68781, -68797, -68797, -68797, -68829, -68863, -68878, -68878, -68878, -68878, -68878, -68878, -68888, -68907, -68907, -68907, -68916, -69034, -69047, -69054, -69061, -69061, -69068, -69068, -69068, -69068, -69068, -69068, -69075, -69075, -69147, -69154, -69166, -69166, -69166, -69166, -69172, +67890, +67890, +67890, +67914, +67914, +67968, +67968, +67975, +67985, +67997, +67997, +68012, +68012, +68012, +68062, +68062, +68094, +68094, +68128, +68137, +68153, +68153, +68178, +68190, +68190, +68190, +68190, +68200, +68241, +68241, +68260, +68260, +68260, +68260, +68270, +68270, +68270, +68270, +68286, +68318, +68318, +68318, +68325, +68349, +68349, +68358, +68376, +68376, +68402, +68439, +68481, +68490, +68490, +68490, +68508, +68508, +68521, +68534, +68574, +68606, +68606, +68606, +68644, +68644, +68672, +68691, +68713, +68742, +68742, +68752, +68752, +68752, +68752, +68752, +68789, +68789, +68789, +68837, +68837, +68837, +68837, +68847, +68883, +68934, +68955, +68955, +68972, +68972, +68972, +68982, +68982, +69000, +69012, +69026, +69026, +69031, +69051, +69071, +69071, +69071, +69071, +69109, +69109, +69109, +69109, +69109, +69125, +69133, +69133, +69133, +69133, +69133, +69133, +69189, 69197, 69197, -69206, -69218, -69218, -69218, -69218, -69218, -69218, -69218, -69218, -69255, -69418, -69418, -69418, -69418, -69418, -69425, -69425, -69425, -69425, -69425, -69425, -69425, -69430, -69488, -69497, -69497, -69502, -69502, -69509, -69517, -69537, -69537, -69537, -69537, -69537, -69546, -69546, -69566, -69586, -69586, -69586, -69612, -69656, -69656, -69686, -69686, -69693, -69700, -69726, -69726, -69726, -69734, -69744, -69752, -69752, -69923, -69923, -69952, -69952, -69952, -69952, -69958, -69979, +69235, +69247, +69247, +69259, +69294, +69294, +69294, +69314, +69325, +69377, +69399, +69420, +69431, +69536, +69547, +69547, +69547, +69559, +69559, +69559, +69582, +69582, +69582, +69582, +69599, +69638, +69638, +69648, +69648, +69667, +69667, +69687, +69721, +69721, +69748, +69748, +69748, +69748, +69777, +69798, +69798, +69807, +69822, +69832, +69832, +69840, +69847, +69847, +69847, +69855, +69855, +69863, +69863, +69863, +69875, +69875, +69908, +69927, +69927, +69932, +69932, +69932, +69932, +69932, +69960, +69960, +69976, +69990, 69997, 69997, -70007, -70007, -70007, -70007, -70007, -70007, -70007, -70007, -70073, -70208, -70215, -70240, -70248, -70262, -70274, -70274, -70274, -70274, -70274, -70274, -70274, -70274, -70353, -70353, -70353, -70353, -70353, -70353, -70361, -70372, -70392, -70392, -70392, -70392, -70392, -70392, -70399, -70411, -70411, -70411, -70479, -70565, -70565, -70565, -70565, -70565, -70580, -70580, -70580, -70580, -70587, -70596, -70596, -70596, -70755, -70771, -70771, -70777, -70777, -70777, -70792, +69997, +70008, +70031, +70052, +70052, +70066, +70102, +70102, +70111, +70111, +70127, +70127, +70151, +70151, +70168, +70175, +70196, +70214, +70260, +70300, +70309, +70309, +70309, +70318, +70318, +70318, +70325, +70354, +70368, +70379, +70400, +70420, +70429, +70449, +70449, +70465, +70491, +70507, +70507, +70538, +70538, +70571, +70571, +70571, +70601, +70601, +70601, +70601, +70601, +70613, +70613, +70674, +70674, +70732, +70732, +70779, 70814, -70814, -70814, -70828, -70828, -70828, -70842, -70842, -70842, -70842, -70842, -70876, -70992, -70992, -71002, -71002, -71002, -71024, -71024, -71024, -71024, -71024, -71024, -71024, -71024, -71212, -71255, -71255, -71255, -71262, -71262, -71262, -71303, -71312, -71317, +70861, +70861, +70918, +70931, +70974, +70974, +70974, +70986, +71001, +71039, +71044, +71062, +71127, +71139, +71146, +71177, +71177, +71193, +71193, +71215, +71215, +71215, +71231, +71231, +71236, +71236, +71248, +71248, +71248, +71248, +71300, 71337, -71344, -71344, -71344, -71344, -71377, -71377, -71377, -71390, -71575, -71581, -71591, -71591, -71591, -71591, -71591, -71591, -71591, -71591, -71591, -71591, -71591, -71661, -71670, -71670, -71670, -71670, -71670, -71686, -71686, +71361, +71386, +71420, +71420, +71420, +71453, +71453, +71453, +71488, +71507, +71515, +71527, +71537, +71537, +71537, +71589, +71589, +71608, +71631, +71631, +71631, +71643, +71649, +71688, 71700, -71700, -71700, -71700, -71700, -71700, -71710, -71738, -71748, -71766, -71804, -72022, -72029, -72046, -72046, -72053, -72053, -72053, -72053, -72053, -72053, -72053, -72053, -72053, -72107, -72112, -72119, -72119, -72124, -72124, -72134, -72148, -72164, -72174, -72174, -72174, -72174, -72174, -72174, -72184, -72184, -72195, -72259, -72402, -72402, -72416, -72422, -72422, -72430, -72430, -72430, -72430, -72439, -72460, -72486, -72486, +71715, +71715, +71715, +71715, +71715, +71715, +71715, +71715, +71745, +71745, +71745, +71750, +71750, +71750, +71750, +71750, +71768, +71818, +71833, +71861, +71861, +71873, +71873, +71873, +71889, +71889, +71908, +71908, +71914, +71942, +71942, +71953, +71953, +71976, +71991, +71991, +72003, +72003, +72003, +72019, +72033, +72069, +72069, +72085, +72129, +72129, +72161, +72205, +72240, +72290, +72322, +72334, +72346, +72346, +72395, +72437, +72437, +72437, +72458, +72513, +72520, +72520, +72533, 72533, 72545, -72556, -72556, -72582, -72582, -72621, -72651, -72663, -72663, +72545, +72558, +72565, +72565, +72565, +72565, +72565, +72585, +72590, +72590, +72608, +72608, +72608, +72608, +72664, 72677, -72677, -72677, -72677, -72687, -72696, -72696, -72719, -72774, -72842, -72842, -72854, -72854, -72854, -72854, -72854, -72854, -72861, -72861, -72861, -72861, -72861, -72861, -72867, -72880, -72880, -72880, -72880, -72890, -72900, -72947, -72947, -72947, -72947, -72960, -72960, -72960, -72960, -72960, -72960, -73045, -73100, -73117, -73117, -73122, -73122, -73122, -73122, -73122, -73122, -73122, -73122, -73142, -73151, -73195, +72682, +72711, +72721, +72730, +72730, +72752, +72752, +72775, +72787, +72794, +72794, +72838, +72864, +72891, +72891, +72907, +72922, +72935, +72935, +72966, +72991, +72991, +72991, +72991, +72998, +73031, +73057, +73062, +73071, +73097, +73113, +73127, +73127, +73127, +73140, +73140, +73173, +73183, +73193, +73217, +73229, +73229, 73236, -73236, -73236, -73243, -73243, -73243, +73254, +73254, +73262, +73262, +73262, +73262, +73274, +73274, 73291, 73291, 73291, -73291, -73315, -73315, -73315, -73315, -73326, -73326, -73326, -73353, -73527, -73527, -73527, -73527, -73534, -73534, -73534, -73534, -73534, -73534, -73534, -73534, -73534, -73739, -73739, -73739, -73739, -73739, -73746, -73746, -73805, -73857, -73857, -73869, -73869, -73869, -73869, -73869, -73879, -73879, -73879, -73916, -73965, -73965, -73982, -73982, -73997, -73997, -73997, -73997, -73997, -73997, -73997, -73997, -73997, -74012, -74012, -74012, -74012, -74012, -74012, -74012, -74053, -74060, -74060, -74070, -74070, -74070, -74070, -74070, -74083, -74117, -74117, -74192, -74267, -74267, -74267, -74267, -74267, -74267, -74267, -74267, -74280, -74280, -74280, -74280, -74288, -74403, -74403, -74403, -74403, -74403, -74403, -74413, -74426, -74433, -74433, -74442, -74442, -74442, -74450, -74450, -74459, -74459, -74459, -74470, -74630, -74630, -74630, -74630, -74630, -74649, -74663, -74663, -74670, -74670, -74670, -74681, -74681, -74729, -74729, -74729, -74729, -74729, -74749, -74764, -74787, -74819, -74819, -74829, -74829, -74829, -74829, -74829, -74857, -74857, -74857, -74934, -75062, -75062, -75087, -75087, -75087, -75106, -75106, -75106, -75106, -75106, -75106, -75106, -75106, -75233, -75244, -75258, -75258, -75258, -75272, -75303, -75311, -75336, -75336, -75344, -75344, -75344, -75356, -75356, -75367, -75367, -75367, -75403, -75528, -75528, -75548, -75548, -75548, -75572, -75572, -75572, -75572, -75572, -75572, -75572, -75572, -75715, -75727, -75727, -75727, -75727, -75727, -75745, -75804, -75819, -75819, -75819, -75819, -75819, -75832, -75832, -75854, -75854, -75854, -75880, -76011, -76011, -76029, -76029, -76045, -76054, -76054, -76054, -76054, -76062, -76062, -76062, -76069, -76147, -76147, -76147, -76147, -76147, -76147, -76147, -76203, -76223, -76223, -76223, -76223, -76223, +73298, +73316, +73316, +73343, +73350, +73350, +73359, +73359, +73359, +73398, +73405, +73430, +73430, +73457, +73472, +73495, +73495, +73515, +73551, +73551, +73563, +73571, +73571, +73606, +73612, +73647, +73647, +73674, +73683, +73703, +73727, +73747, +73763, +73782, +73782, +73793, +73834, +73834, +73844, +73863, +73863, +73863, +73875, +73894, +73927, +73936, +73955, +73955, +73988, +74023, +74039, +74051, +74051, +74051, +74051, +74058, +74069, +74087, +74099, +74137, +74137, +74137, +74156, +74175, +74186, +74198, +74209, +74225, +74235, +74266, +74294, +74304, +74304, +74324, +74366, +74366, +74429, +74429, +74447, +74490, +74490, +74513, +74513, +74539, +74571, +74593, +74625, +74646, +74657, +74657, +74657, +74671, +74671, +74680, +74690, +74721, +74731, +74760, +74767, +74782, +74810, +74878, +74878, +74878, +74885, +74905, +74905, +74928, +74928, +74957, +74976, +74976, +74983, +74990, +75002, +75002, +75015, +75049, +75049, +75066, +75066, +75073, +75073, +75085, +75085, +75085, +75091, +75091, +75133, +75163, +75177, +75177, +75177, +75177, +75177, +75198, +75198, +75235, +75248, +75288, +75294, +75310, +75330, +75330, +75355, +75355, +75355, +75375, +75394, +75412, +75412, +75412, +75424, +75448, +75484, +75484, +75495, +75495, +75507, +75517, +75524, +75524, +75570, +75577, +75577, +75599, +75623, +75623, +75680, +75680, +75720, +75734, +75750, +75750, +75785, +75785, +75796, +75796, +75806, +75822, +75828, +75861, +75861, +75898, +75898, +75904, +75904, +75904, +75968, +75981, +75991, +76028, +76028, +76057, +76057, +76068, +76075, +76102, +76118, +76118, +76126, +76126, +76146, +76151, +76151, +76151, +76163, +76181, +76181, +76210, +76229, 76234, 76234, -76234, -76234, -76234, -76261, -76375, -76382, -76389, -76389, -76395, -76401, -76401, -76401, -76401, -76408, -76408, -76408, -76408, -76499, -76499, -76516, -76516, -76516, -76516, -76547, -76612, -76612, -76612, -76612, -76612, -76612, -76612, -76612, -76626, -76626, -76626, -76643, -76727, -76727, -76760, -76760, -76760, -76767, -76767, -76767, -76767, -76772, -76772, -76772, -76772, -76833, -76849, -76849, -76849, -76854, -76854, -76886, +76248, +76271, +76302, +76341, +76341, +76364, +76403, +76403, +76411, +76418, +76428, +76470, +76490, +76497, +76534, +76589, +76601, +76601, +76601, +76622, +76637, +76676, +76702, +76719, +76719, +76719, +76741, +76741, +76741, +76782, +76799, +76812, +76819, +76826, +76826, +76826, +76853, +76859, +76884, +76884, +76884, +76899, +76899, 76909, -76928, -76928, -76928, -76928, -76928, -76928, -76928, -76942, -76942, -76954, -76967, -77062, -77062, -77062, -77068, -77096, -77110, -77110, -77110, -77110, -77110, -77110, -77110, -77110, -77248, -77248, -77264, -77264, -77264, -77264, +76909, +76917, +76924, +76948, +77011, +77011, +77011, +77011, +77018, +77018, +77018, +77025, +77041, +77054, +77082, +77082, +77082, +77092, +77109, +77119, +77119, +77119, +77158, +77177, +77183, +77193, +77238, +77268, +77268, 77274, -77305, -77322, -77322, -77332, -77332, -77348, -77355, -77355, -77369, -77369, -77387, -77409, -77584, -77584, -77584, -77584, -77599, -77614, -77614, -77614, -77614, -77614, -77620, -77620, -77620, -77666, -77687, -77687, -77687, -77694, -77694, -77694, -77694, -77711, -77711, -77722, -77722, -77722, -77733, -77733, -77743, -77743, -77743, -77772, -77890, -77900, -77925, -77925, -77947, -77947, -77947, -77953, -77953, -77953, -77953, +77274, +77280, +77280, +77280, +77301, +77301, +77309, +77319, +77319, +77319, +77319, +77340, +77385, +77385, +77385, +77404, +77437, +77437, +77453, +77453, +77453, +77453, +77463, +77463, +77489, +77499, +77499, +77515, +77537, +77537, +77596, +77596, +77616, +77621, +77656, +77656, +77673, +77673, +77697, +77697, +77697, +77702, +77702, +77708, +77731, +77731, +77731, +77731, +77731, +77738, +77747, +77765, +77771, +77771, +77781, +77802, +77802, +77831, +77831, +77845, +77877, +77877, +77895, +77945, +77955, +77955, 77976, 77976, -78132, -78140, -78140, -78140, -78147, -78147, -78162, -78187, -78214, -78214, -78214, -78214, -78214, -78214, -78221, -78221, -78221, -78221, -78265, -78365, -78365, -78394, -78394, -78404, -78410, -78410, -78410, -78410, +77997, +77997, +78020, +78020, +78047, +78055, +78055, +78064, +78070, +78076, +78076, +78128, +78154, +78198, +78198, +78198, +78215, +78215, +78226, +78241, +78241, +78279, +78294, +78294, +78294, +78294, +78319, +78319, +78335, +78352, +78372, +78372, +78389, +78389, +78405, +78405, +78405, 78419, 78419, -78426, -78426, -78538, -78544, -78544, -78544, +78463, +78463, +78463, +78480, +78493, +78493, +78535, 78552, 78552, -78586, -78650, -78656, -78691, -78691, -78696, -78703, -78703, -78710, -78710, -78723, -78733, -78754, -78819, -78825, -78825, -78825, -78835, -78835, -78835, -78835, -78835, -78835, -78842, -78854, -78854, -78982, -78982, -79010, -79010, -79010, -79023, -79040, -79046, +78587, +78593, +78624, +78624, +78624, +78624, +78660, +78670, +78680, +78693, +78708, +78716, +78750, +78750, +78765, +78778, +78795, +78804, +78817, +78817, +78817, +78840, +78850, +78850, +78861, +78878, +78893, +78893, +78909, +78947, +78985, +78985, +78985, +78999, +79018, +79027, +79035, +79035, +79053, +79066, +79066, +79066, +79084, 79084, 79084, -79094, -79094, -79094, -79094, 79101, -79127, -79127, -79127, -79153, +79101, +79119, +79133, +79140, +79162, +79162, +79162, 79206, -79212, -79212, -79218, -79234, -79246, -79253, -79259, -79266, -79266, -79266, -79266, -79284, -79427, -79427, -79427, -79427, -79427, -79427, -79433, -79480, -79502, -79502, -79526, -79536, -79536, -79536, -79536, -79544, -79544, -79544, -79595, -79720, -79720, -79720, -79727, -79727, -79733, -79733, -79733, -79733, -79733, -79742, -79742, -79742, -79916, -79916, -79916, -79916, -79916, -79916, -80005, -80022, -80044, -80044, -80049, -80049, -80049, -80056, -80056, -80062, -80062, -80062, -80107, -80203, -80203, -80217, -80225, -80225, -80238, -80238, -80238, -80238, -80238, -80238, -80238, +79206, +79216, +79276, +79303, +79303, +79303, +79303, +79303, +79303, +79303, +79315, +79315, +79347, +79356, +79370, +79370, +79370, +79376, +79376, +79376, +79376, +79391, +79391, +79391, +79391, +79403, +79403, +79415, +79455, +79461, +79461, +79474, +79494, +79500, +79500, +79500, +79523, +79535, +79535, +79535, +79558, +79591, +79591, +79591, +79591, +79601, +79601, +79608, +79608, +79621, +79621, +79621, +79621, +79621, +79628, +79634, +79634, +79644, +79662, +79696, +79712, +79712, +79746, +79772, +79812, +79822, +79822, +79834, +79834, +79834, +79877, +79896, +79896, +79896, +79896, +79896, +79910, +79910, +79910, +80002, +80027, +80042, +80042, +80042, +80042, +80051, +80064, +80073, +80094, +80114, +80114, +80114, +80114, +80114, +80114, +80141, +80181, +80181, +80208, +80218, +80241, +80241, +80241, 80246, -80297, -80339, -80360, -80360, -80360, -80360, -80369, +80252, +80294, +80300, +80308, +80308, +80308, +80308, +80308, +80318, +80318, +80318, +80318, +80340, +80340, +80366, +80366, +80366, +80366, +80366, +80366, +80366, +80384, +80403, +80430, +80430, +80430, +80436, +80436, +80436, 80448, -80486, -80486, -80517, -80517, -80517, -80526, -80526, -80548, -80548, +80460, +80460, +80492, +80503, +80503, +80544, +80544, 80555, -80606, -80667, -80667, -80674, -80674, -80683, +80555, +80578, +80578, +80591, +80591, +80591, +80614, +80614, +80625, +80632, +80662, +80662, +80675, 80697, -80697, -80697, -80703, -80703, -80703, -80703, -80703, -80716, -80760, -80784, -80784, -80784, -80784, -80784, -80844, -80844, -80844, -80849, -80857, -80857, -80857, -80857, -80857, -80857, -80857, -80875, -81026, -81031, -81041, -81049, -81049, -81049, -81049, -81049, -81049, -81049, -81049, -81049, -81049, -81160, -81169, -81169, -81176, -81183, -81183, -81189, -81248, -81270, -81270, -81275, -81275, -81275, -81275, -81282, -81282, -81282, -81291, -81312, -81431, -81431, -81455, -81455, -81455, -81455, -81470, -81470, -81470, -81470, -81470, -81470, -81470, -81579, -81627, -81627, -81627, -81627, -81627, -81633, -81653, -81653, -81662, -81662, -81677, -81684, -81684, +80721, +80771, +80771, +80776, +80783, +80783, +80783, +80783, +80783, +80814, +80828, +80834, +80842, +80856, +80856, +80904, +80920, +80938, +80958, +80958, +80989, +80996, +81003, +81017, +81017, +81054, +81061, +81068, +81090, +81104, +81104, +81114, +81127, +81134, +81141, +81148, +81166, +81166, +81179, +81194, +81230, +81230, +81265, +81297, +81316, +81323, +81330, +81375, +81387, +81422, +81422, +81422, +81422, +81458, +81469, +81488, +81506, +81506, +81540, +81594, +81600, +81626, +81645, +81652, +81652, +81671, +81678, 81695, -81710, -81710, -81722, -81770, -81891, -81891, -81891, -81891, -81891, -81891, -81891, -81891, -81891, -81901, -81901, -81901, -81901, -82008, -82008, -82008, -82008, -82021, -82032, -82079, -82110, +81701, +81720, +81726, +81736, +81742, +81742, +81771, +81805, +81829, +81829, +81829, +81829, +81829, +81829, +81829, +81829, +81829, +81843, +81843, +81843, +81861, +81887, +81904, +81904, +81911, +81924, +81924, +81939, +81966, +82029, +82029, +82062, +82089, +82101, 82117, -82117, -82124, -82124, -82124, -82137, -82149, -82165, -82165, -82165, -82207, -82414, -82414, -82414, -82414, -82421, -82421, -82421, -82421, -82421, -82421, -82421, -82421, -82421, -82441, -82441, -82441, +82161, +82168, +82174, +82187, +82187, +82203, +82217, +82234, +82259, +82259, +82273, +82273, +82286, +82316, +82316, +82323, +82323, +82349, +82355, +82355, +82381, +82394, +82438, 82448, 82448, -82455, -82466, -82512, -82524, -82524, -82524, -82524, -82524, -82524, -82540, -82559, -82559, -82559, -82585, -82700, -82700, -82707, -82715, -82715, -82715, -82715, -82715, -82715, -82715, -82726, -82726, -82726, -82859, -82865, -82865, -82865, -82865, -82865, -82898, -82924, -82938, -82945, -82945, -82945, -82945, -82945, -82945, -82945, -82945, -82945, -82982, -83135, -83135, -83135, -83148, -83148, -83148, -83148, -83148, -83148, -83148, -83148, -83148, -83163, -83319, -83319, -83319, -83319, -83319, -83319, -83350, -83374, -83381, -83381, -83392, -83392, -83397, -83397, -83397, -83397, -83397, -83397, -83441, -83511, -83511, -83518, -83518, -83518, -83531, -83531, -83531, -83531, -83537, -83537, -83537, -83537, +82461, +82489, +82489, +82502, +82502, +82561, +82568, +82601, +82601, +82608, +82608, +82615, +82622, +82672, +82672, +82678, +82710, +82746, +82752, +82785, +82785, +82816, +82847, +82861, +82861, +82879, +82897, +82914, +82914, +82965, +82965, +82972, +82972, +82979, +82991, +82991, +83029, +83047, +83093, +83093, +83100, +83130, +83137, +83153, +83153, +83153, +83171, +83178, +83178, +83185, +83212, +83219, +83236, +83276, +83276, +83276, +83276, +83276, +83289, +83335, +83351, +83371, +83378, +83400, +83412, +83468, +83480, +83487, +83501, +83528, +83563, +83579, +83579, +83588, +83588, +83603, +83616, +83616, 83623, -83623, -83623, -83623, -83623, -83623, -83642, -83679, -83679, -83679, -83689, -83689, -83689, -83689, -83689, -83698, -83698, -83708, -83749, -83901, -83901, -83909, -83909, -83909, +83650, +83657, +83671, +83678, +83678, +83715, +83727, +83767, +83808, +83815, +83828, +83835, +83848, +83848, +83885, +83885, +83902, 83921, 83921, 83921, 83921, 83921, -83921, -83921, -83921, -83979, -83979, -83986, -83986, -83986, -84004, -84048, -84048, -84048, -84048, -84063, -84063, -84068, -84075, -84075, -84075, -84080, -84092, +83934, +83953, +83967, +83982, +84007, +84017, +84027, +84044, +84051, +84079, +84079, +84115, +84115, 84136, -84319, -84319, -84327, -84332, -84358, -84363, -84363, -84363, -84363, -84370, -84370, -84382, -84382, -84476, -84476, -84483, -84483, -84483, -84483, -84492, -84502, -84502, -84509, -84509, -84509, -84509, -84509, -84509, -84519, -84519, -84519, +84150, +84194, +84194, +84230, +84230, +84230, +84237, +84244, +84251, +84258, +84258, +84278, +84293, +84293, +84300, +84306, +84312, +84321, +84321, +84339, +84378, +84378, +84419, +84431, +84431, +84431, +84431, +84431, +84437, +84459, +84469, +84488, +84497, +84497, +84522, 84528, -84668, -84668, -84668, -84668, -84668, -84700, -84700, -84700, -84700, -84700, -84700, -84700, -84700, -84788, -84788, -84788, -84788, -84788, -84796, -84816, -84840, -84862, -84862, -84872, -84872, -84872, -84872, -84872, -84872, -84872, -84872, -84919, -85066, -85066, -85073, -85073, -85073, -85082, -85082, -85082, -85082, -85089, -85089, -85089, -85089, -85105, -85163, -85172, -85172, -85172, -85172, -85203, -85276, -85288, -85303, -85303, -85303, -85323, -85323, -85323, -85330, -85330, -85330, -85386, -85503, -85510, -85510, -85510, -85515, -85522, -85530, -85530, -85535, -85535, -85535, -85554, -85567, -85588, -85595, -85595, -85595, -85595, -85595, -85612, -85643, -85643, -85643, -85643, -85643, -85643, -85643, -85643, -85652, -85652, -85652, -85713, -85730, -85730, -85730, -85730, -85730, -85750, -85750, -85757, -85757, -85757, -85757, -85757, -85757, -85887, -85887, -85887, -85887, -85901, -85910, -85927, -86006, -86031, -86031, -86031, -86031, -86031, -86031, -86038, -86038, -86038, -86038, -86084, -86222, -86222, -86234, -86243, -86243, -86251, -86262, -86262, -86262, -86262, -86262, -86283, -86288, -86320, +84528, +84528, +84545, +84573, +84587, +84594, +84607, +84627, +84643, +84643, +84643, +84643, +84648, +84655, +84655, +84662, +84715, +84715, +84715, +84731, +84738, +84763, +84770, +84777, +84795, +84795, +84850, +84857, +84857, +84857, +84873, +84892, +84911, +84911, +84918, +84949, +84958, +85013, +85013, +85046, +85058, +85081, +85108, +85108, +85118, +85139, +85189, +85189, +85198, +85216, +85222, +85233, +85240, +85240, +85247, +85289, +85324, +85324, +85331, +85340, +85340, +85368, +85374, +85410, +85452, +85468, +85486, +85507, +85550, +85585, +85609, +85609, +85615, +85615, +85637, +85637, +85637, +85646, +85688, +85688, +85727, +85727, +85749, +85790, +85877, +85877, +85877, +85893, +85921, +85943, +85943, +85951, +85951, +85951, +85959, +85980, +85991, +85991, +85991, +86002, +86010, +86010, +86017, +86024, +86024, +86024, +86071, +86077, +86077, +86092, +86102, +86102, +86108, +86108, +86120, +86141, +86157, +86157, +86167, +86199, +86199, +86217, +86217, +86254, +86265, +86273, +86280, +86299, +86315, +86315, +86331, 86342, -86342, -86342, -86342, -86342, -86390, -86431, -86459, -86466, -86493, -86493, -86500, -86500, -86505, -86505, -86505, -86505, -86540, -86720, -86720, -86737, -86744, -86744, -86749, -86749, -86749, -86749, -86749, -86749, -86749, -86749, -86820, -86826, -86826, -86833, -86840, -86840, -86847, -86862, -86897, -86897, -86904, -86904, -86920, -86920, -86920, -86953, -86963, -86974, +86358, +86373, +86396, +86405, +86432, +86453, +86458, +86488, +86488, +86504, +86511, +86511, +86546, +86569, +86583, +86583, +86583, +86596, +86596, +86612, +86634, +86662, +86671, +86671, +86676, +86707, +86707, +86745, +86745, +86745, +86745, +86789, +86805, +86805, +86805, +86812, +86812, +86812, +86841, +86841, +86841, +86878, +86878, +86878, +86878, +86878, +86886, +86921, +86931, +86931, +86931, +86939, +86946, 86992, -87124, -87124, -87124, +86998, +86998, +86998, +87020, +87020, +87040, +87040, +87040, +87053, +87053, +87068, +87076, +87076, +87076, +87076, +87076, +87093, +87126, 87133, -87140, -87168, -87168, -87184, -87184, -87184, -87184, -87191, -87191, -87274, -87281, -87281, -87281, -87281, -87304, -87349, -87400, -87423, -87423, -87423, -87423, -87430, -87430, -87430, -87430, -87430, -87430, -87439, -87516, -87522, -87538, -87538, -87538, -87571, -87571, -87571, -87571, -87587, -87587, -87587, -87587, -87663, -87668, -87696, -87696, -87696, -87703, -87703, -87743, -87763, -87763, -87779, -87779, -87779, -87786, -87786, -87786, -87786, -87786, -87798, -87943, -87949, -87956, -87964, -87971, -87971, -87980, -87980, -87980, -87987, -87987, -87987, -87987, -88091, -88132, -88132, -88132, -88132, -88132, -88148, -88155, -88177, -88177, -88177, -88177, -88177, -88201, -88218, -88218, -88218, -88225, +87133, +87149, +87149, +87156, +87180, +87195, +87215, +87229, +87260, +87312, +87335, +87392, +87414, +87427, +87427, +87441, +87441, +87451, +87451, +87451, +87467, +87472, +87472, +87488, +87488, +87488, +87508, +87508, +87508, +87508, +87539, +87549, +87566, +87620, +87638, +87648, +87648, +87673, +87708, +87719, +87738, +87738, +87758, +87758, +87767, +87789, +87789, +87789, +87789, +87797, +87807, +87807, +87823, +87823, +87829, +87898, +87912, +87912, +87912, +87912, +87950, +87950, +87957, +87973, +87973, +87973, +88006, +88006, +88006, +88006, +88006, +88006, +88022, +88062, +88093, +88093, +88093, +88103, +88103, +88114, +88122, +88122, +88130, +88182, +88191, +88207, +88207, +88238, +88257, +88257, 88278, -88355, -88355, -88355, -88355, -88367, -88367, +88309, +88325, +88344, +88361, +88361, +88361, +88361, +88361, +88361, +88361, 88375, -88375, -88375, -88375, -88375, -88375, -88375, -88553, -88553, -88567, -88567, -88567, -88567, -88586, -88598, -88628, -88628, -88651, -88651, -88651, -88651, -88651, -88678, -88678, -88678, -88717, -88826, -88833, -88851, -88851, -88865, -88865, -88865, -88873, -88873, -88873, -88873, -88873, -88880, -89013, -89019, -89019, -89033, -89033, -89039, -89039, -89075, -89082, -89082, -89100, -89100, -89107, -89115, -89122, -89138, -89138, -89149, -89205, -89338, -89338, -89346, -89346, -89346, -89360, -89360, -89360, -89367, -89367, -89367, -89367, -89367, -89403, -89409, -89428, -89428, -89428, -89428, -89444, -89475, -89489, -89489, -89520, -89520, -89529, -89542, -89542, -89542, -89542, -89554, -89598, -89724, -89745, -89745, -89745, -89772, -89772, -89772, -89780, -89794, -89794, -89804, -89804, -89804, -89985, -89992, -90007, -90007, -90034, -90034, -90065, -90106, -90123, -90123, -90139, -90139, -90145, -90153, -90153, -90185, -90185, -90185, -90237, -90300, -90300, -90300, -90300, -90300, -90300, -90300, -90300, -90300, -90318, -90318, -90327, -90333, -90467, -90473, -90473, -90473, -90473, -90473, -90473, -90500, -90509, -90509, -90509, -90509, -90509, -90509, -90509, -90523, -90523, -90523, -90540, -90658, -90658, -90697, -90697, -90697, -90697, -90697, -90697, -90697, -90697, -90697, -90697, -90697, -90822, -90822, -90822, -90834, -90834, -90834, +88380, +88380, +88380, +88385, +88399, +88418, +88436, +88436, +88446, +88458, +88479, +88489, +88489, +88512, +88520, +88566, +88590, +88595, +88595, +88595, +88626, +88626, +88643, +88643, +88663, +88684, +88684, +88699, +88715, +88724, +88724, +88740, +88740, +88748, +88748, +88805, +88805, +88815, +88815, +88825, +88835, +88835, +88856, +88856, +88866, +88898, +88967, +88976, +89007, +89035, +89043, +89055, +89063, +89095, +89103, +89129, +89165, +89165, +89179, +89218, +89239, +89337, +89337, +89342, +89342, +89384, +89384, +89395, +89408, +89418, +89439, +89439, +89458, +89458, +89546, +89575, +89595, +89602, +89621, +89621, +89639, +89681, +89705, +89715, +89739, +89749, +89749, +89802, +89809, +89837, +89845, +89853, +89853, +89873, +89873, +89873, +89879, +89935, +89942, +89942, +90006, +90032, +90032, +90041, +90041, +90041, +90089, +90089, +90094, +90102, +90102, +90110, +90144, +90152, +90160, +90172, +90191, +90200, +90200, +90221, +90231, +90287, +90287, +90309, +90328, +90328, +90346, +90346, +90353, +90375, +90404, +90441, +90452, +90549, +90568, +90638, +90659, +90696, +90696, +90696, +90696, +90706, +90732, 90834, +90848, 90857, -90857, -90857, -90884, -90884, -90902, -90902, -90902, -90902, -90902, -90902, -90913, -90956, -90963, -90963, -90969, -90987, -90987, -90997, -90997, -91015, -91015, -91015, -91022, -91022, -91050, -91050, -91050, -91050, -91057, -91066, -91082, -91146, -91146, -91146, -91146, -91152, -91169, -91191, -91191, -91214, -91214, -91214, -91251, -91397, -91403, -91403, -91403, -91403, -91426, -91426, -91426, -91439, -91444, -91444, -91467, -91473, -91553, -91559, -91559, -91559, -91559, -91559, -91575, -91575, -91575, -91575, -91588, -91588, -91604, -91604, -91604, -91625, -91625, -91625, -91648, +90878, +90878, +90903, +90914, +90924, +90978, +90985, +91009, +91042, +91042, +91070, +91087, +91087, +91107, +91107, +91139, +91153, +91180, +91180, +91230, +91230, +91244, +91252, +91262, +91270, +91278, +91278, +91278, +91291, +91304, +91320, +91370, +91381, +91394, +91394, +91428, +91453, +91470, +91477, +91477, +91477, +91485, +91505, +91505, +91505, +91523, +91523, +91523, +91571, +91571, +91607, +91615, +91643, +91643, +91643, +91660, +91660, +91674, 91688, -91688, -91702, -91710, -91710, -91710, -91710, -91710, -91710, -91710, -91710, -91710, -91710, -91784, -91784, -91784, -91784, -91784, -91794, -91804, -91810, -91810, -91810, -91810, -91810, -91810, -91810, -91810, -91835, -91835, -91835, -91850, -92008, -92022, -92043, -92043, -92043, -92043, -92043, -92043, -92043, -92043, -92043, -92043, -92050, -92102, -92102, -92102, -92102, -92102, -92102, -92102, +91703, +91703, +91739, +91767, +91767, +91799, +91818, +91829, +91829, +91829, +91837, +91843, +91843, +91868, +91868, +91868, +91868, +91868, +91888, +91888, +91888, +91888, +91919, +91954, +91954, +91954, +91970, +91979, +91984, +91984, +92001, +92001, +92026, +92026, +92038, +92055, +92055, +92072, +92077, +92083, +92091, 92140, -92147, -92147, -92152, -92152, -92152, -92152, -92152, -92152, -92152, -92160, -92185, +92140, +92181, +92188, +92208, +92279, 92284, -92290, -92307, -92313, -92313, -92313, -92313, -92313, -92313, -92313, -92313, -92313, -92320, -92477, -92515, -92515, -92515, -92515, -92515, -92521, -92556, -92564, -92564, -92564, -92564, -92564, -92584, -92584, -92584, -92584, -92584, +92294, +92294, +92327, +92327, +92337, +92392, +92392, +92419, +92427, +92455, +92461, +92461, +92461, +92479, +92505, +92505, +92531, +92531, +92560, +92577, +92577, +92586, +92595, +92595, +92622, +92653, 92665, -92733, -92754, -92769, -92769, -92777, -92797, -92797, -92797, -92797, -92797, -92806, -92806, -92812, -92979, -92986, -92986, -92986, -92996, -92996, -92996, -93047, -93058, -93058, -93058, -93058, -93058, -93058, -93058, -93067, -93067, -93078, -93107, -93201, -93201, -93208, -93208, -93218, -93218, -93218, -93218, -93218, -93218, -93218, -93218, -93218, -93244, -93287, -93299, -93299, -93299, -93312, -93322, -93359, -93359, -93359, -93384, -93390, -93390, -93390, -93395, +92685, +92696, +92696, +92738, +92738, +92758, +92807, +92818, +92836, +92836, +92836, +92844, +92844, +92856, +92856, +92856, +92862, +92862, +92880, +92880, +92929, +92968, +92991, +92991, +92991, +92991, +93005, +93005, +93005, +93023, +93030, +93066, +93096, +93096, +93096, +93115, +93145, +93159, +93187, +93211, +93226, +93251, +93251, +93251, +93251, +93260, +93267, +93282, +93282, +93282, +93282, +93345, +93350, +93350, +93364, +93372, +93393, +93393, 93406, -93414, -93414, -93447, -93561, -93569, -93577, -93582, -93582, -93582, -93582, -93582, -93582, -93582, -93582, -93582, -93582, -93802, -93829, -93829, -93829, -93843, -93843, -93863, -93888, -93911, -93919, -93942, -93942, -93950, -93950, -93950, -93970, -93970, -93982, -93982, -94090, -94090, -94116, -94116, -94116, -94116, -94116, -94116, -94116, -94116, -94116, -94116, -94116, -94204, -94210, -94230, -94230, -94230, -94230, -94289, -94333, -94333, -94333, -94333, -94333, -94333, -94333, -94342, -94342, -94342, -94355, -94365, -94427, -94427, -94427, -94427, -94427, -94447, -94447, -94447, -94447, -94447, -94447, -94455, -94455, -94549, -94559, -94559, -94559, -94559, -94559, -94574, -94580, -94580, -94580, -94594, -94601, -94607, -94607, -94607, -94619, -94619, -94619, -94651, -94797, -94797, -94797, -94813, -94813, -94813, -94813, -94813, -94813, -94813, -94813, -94813, -94813, -94921, -94927, -94952, -94952, -94952, -94952, -94952, -94991, -94991, -94991, -94991, -94991, -94998, -94998, -94998, -95005, -95005, -95005, -95005, -95137, -95137, -95137, -95137, -95137, -95146, -95146, -95146, -95146, -95146, -95146, -95146, -95159, -95285, -95285, -95285, -95285, -95285, -95285, -95285, -95309, -95316, -95316, -95323, -95323, -95323, -95323, -95333, -95344, -95344, -95344, -95383, -95473, -95479, -95489, -95489, -95513, -95513, -95513, -95513, -95513, -95513, -95513, -95513, -95513, -95654, -95662, -95683, -95683, -95692, -95700, -95745, -95768, -95812, -95812, -95820, -95820, -95820, -95820, -95820, -95820, -95820, -95820, -95844, -95940, -95940, -95958, -95958, -95958, -95972, -95972, -95972, -95972, -95972, -95972, -95972, -95972, -96050, -96056, -96056, -96063, -96070, -96070, -96080, -96086, -96110, -96110, -96110, -96110, -96110, -96110, -96110, -96119, -96119, -96119, -96172, -96260, -96270, -96270, -96270, -96270, -96270, -96270, -96270, -96270, -96270, -96270, -96270, -96270, -96375, -96381, -96381, -96381, -96381, -96385, -96405, -96439, -96453, -96453, -96453, -96453, -96458, -96458, -96458, -96465, -96465, -96465, -96499, -96657, -96657, -96664, -96664, -96664, -96664, -96664, -96664, -96664, -96664, -96664, -96664, -96664, -96818, -96818, +93425, +93425, +93425, +93431, +93442, +93468, +93468, +93468, +93530, +93530, +93530, +93560, +93570, +93579, +93600, +93616, +93616, +93616, +93638, +93646, +93646, +93646, +93653, +93653, +93661, +93661, +93691, +93714, +93714, +93714, +93714, +93714, +93751, +93799, +93826, +93826, +93826, +93826, +93826, +93849, +93855, +93861, +93894, +93929, +93935, +93935, +93935, +93947, +93947, +93947, +93960, +93979, +93985, +94004, +94023, +94055, +94072, +94092, +94092, +94102, +94113, +94122, +94122, +94148, +94156, +94171, +94236, +94236, +94236, +94257, +94257, +94310, +94317, +94322, +94322, +94322, +94329, +94337, +94360, +94360, +94383, +94395, +94445, +94465, +94465, +94465, +94465, +94483, +94502, +94531, +94593, +94593, +94599, +94618, +94624, +94654, +94665, +94686, +94712, +94712, +94743, +94766, +94766, +94774, +94774, +94801, +94828, +94828, +94845, +94845, +94845, +94880, +94894, +94894, +94901, +94901, +94917, +94924, +94989, +94989, +94989, +94989, +95014, +95038, +95038, +95068, +95076, +95097, +95153, +95165, +95215, +95221, +95250, +95281, +95281, +95337, +95352, +95373, +95385, +95385, +95402, +95402, +95402, +95402, +95425, +95446, +95452, +95478, +95486, +95486, +95486, +95486, +95492, +95508, +95528, +95528, +95555, +95566, +95566, +95566, +95575, +95591, +95665, +95665, +95677, +95685, +95704, +95704, +95704, +95710, +95710, +95725, +95725, +95725, +95765, +95765, +95785, +95815, +95828, +95828, +95877, +95902, +95919, +95919, +95953, +95953, +96013, +96013, +96041, +96053, +96053, +96093, +96093, +96106, +96106, +96112, +96218, +96234, +96255, +96255, +96255, +96255, +96310, +96331, +96331, +96331, +96371, +96387, +96404, +96421, +96440, +96440, +96445, +96461, +96492, +96492, +96504, +96504, +96504, +96521, +96553, +96576, +96576, +96583, +96583, +96583, +96599, +96619, +96619, +96637, +96646, +96646, +96696, +96719, +96719, +96719, +96727, +96727, +96727, +96757, +96757, +96779, +96779, +96779, +96796, +96816, 96822, 96822, -96827, -96827, -96846, -96945, -96977, -96977, -96982, -96982, -96982, -96982, -96990, -97003, -97003, -97016, -97052, -97184, -97184, -97184, -97188, -97188, -97188, -97188, -97199, -97199, -97199, -97199, -97199, +96822, +96822, +96828, +96859, +96859, +96859, +96920, +96927, +96941, +96952, +96952, +96999, +97024, +97036, +97036, +97049, +97049, +97049, +97049, +97065, +97100, +97108, +97108, +97108, +97108, +97121, +97157, 97207, -97217, -97217, -97239, -97239, -97239, -97239, -97249, -97276, -97293, -97303, -97334, -97334, -97334, -97334, -97334, -97338, -97338, -97338, -97382, -97537, -97537, -97544, -97551, -97572, -97572, -97572, -97572, -97572, -97578, -97578, -97578, -97588, -97737, -97737, -97737, -97737, -97742, -97749, -97789, -97833, -97844, -97844, -97849, -97849, -97849, -97849, -97859, -97859, -97859, -97859, -97888, -98068, -98088, -98108, -98115, -98123, -98129, -98129, -98133, -98150, -98150, -98150, -98171, -98171, -98299, -98299, -98306, -98315, -98320, -98320, -98339, -98430, -98430, -98430, -98435, -98435, -98435, -98444, -98444, -98444, -98444, -98444, -98511, -98632, -98632, -98632, -98632, -98632, -98632, -98632, -98632, -98632, -98632, -98632, -98632, -98632, -98667, -98667, -98674, -98674, -98674, -98674, -98731, -98804, -98804, -98804, -98809, -98809, -98809, -98809, -98823, -98846, -98846, -98846, -98955, -99131, -99142, -99169, -99169, -99177, -99177, -99177, -99177, -99189, -99189, -99189, -99189, -99196, -99247, -99247, -99247, -99247, -99255, -99255, -99295, -99330, -99356, -99356, -99363, -99363, -99370, -99370, -99370, -99370, -99370, -99376, -99427, -99535, -99547, -99547, -99547, -99547, -99555, -99555, -99563, -99563, -99563, -99574, -99574, -99578, -99672, -99672, -99688, -99688, -99688, -99688, -99697, -99746, -99765, -99765, -99788, -99788, -99799, -99799, -99799, -99799, -99806, -99806, -99849, -99951, -99964, -99964, -99969, -99996, -99996, -99996, -99996, -99996, -99996, -99996, -100003, -100003, -100219, -100233, -100233, -100233, -100233, -100237, -100250, -100270, -100270, -100290, -100309, -100309, -100316, -100346, -100346, -100355, -100355, -100355, -100374, -100514, -100514, -100523, -100523, -100531, -100541, -100541, -100545, -100545, -100545, -100545, -100545, -100545, -100677, -100681, -100681, -100681, -100681, -100693, -100711, -100743, -100769, -100769, -100779, -100779, -100786, -100786, -100786, -100786, -100786, -100786, -100805, -100941, -100957, -100957, -100970, +97242, +97242, +97248, +97248, +97328, +97337, +97337, +97348, +97386, +97409, +97421, +97441, +97465, +97465, +97465, +97465, +97512, +97529, +97529, +97529, +97529, +97529, +97563, +97581, +97600, +97621, +97621, +97621, +97631, +97631, +97631, +97652, +97660, +97660, +97660, +97666, +97677, +97677, +97677, +97677, +97689, +97723, +97734, +97744, +97750, +97769, +97784, +97828, +97867, +97887, +97901, +97901, +97919, +97950, +97956, +97976, +97976, +97998, +97998, +98005, +98033, +98033, +98039, +98039, +98093, +98093, +98093, +98127, +98167, +98167, +98181, +98181, +98181, +98217, +98224, +98249, +98249, +98283, +98319, +98343, +98404, +98414, +98432, +98452, +98461, +98477, +98477, +98488, +98488, +98525, +98536, +98558, +98603, +98603, +98615, +98647, +98663, +98663, +98681, +98697, +98697, +98707, +98707, +98707, +98714, +98714, +98718, +98759, +98759, +98779, +98779, +98779, +98787, +98808, +98815, +98815, +98837, +98837, +98851, +98851, +98851, +98909, +98923, +98938, +98951, +98984, +99030, +99050, +99050, +99056, +99060, +99060, +99074, +99112, +99112, +99133, +99133, +99145, +99145, +99163, +99163, +99181, +99181, +99204, +99204, +99217, +99217, +99223, +99230, +99241, +99303, +99323, +99398, +99424, +99424, +99424, +99424, +99431, +99442, +99480, +99543, +99543, +99550, +99564, +99581, +99651, +99658, +99665, +99665, +99679, +99723, +99730, +99739, +99739, +99754, +99767, +99793, +99837, +99850, +99857, +99864, +99902, +99915, +99939, +99939, +99957, +100043, +100050, +100050, +100057, +100064, +100071, +100078, +100078, +100139, +100139, +100147, +100166, +100191, +100225, +100236, +100260, +100286, +100311, +100319, +100319, +100326, +100363, +100382, +100403, +100403, +100403, +100410, +100420, +100451, +100462, +100518, +100524, +100560, +100583, +100583, +100601, +100610, +100610, +100610, +100610, +100610, +100623, +100623, +100650, +100650, +100650, +100650, +100650, +100696, +100703, +100703, +100710, +100717, +100734, +100837, +100846, +100846, +100853, +100853, +100876, +100917, +100917, +100924, +100931, +100938, +100952, +100971, +100971, 100977, -100977, -100977, -100977, -100977, -100985, -100985, -100997, -100997, -101051, -101051, -101051, -101051, -101056, +101000, +101000, +101000, +101000, +101015, +101015, +101015, +101032, +101048, +101067, 101073, +101080, +101098, 101115, -101157, -101157, -101157, -101157, -101157, -101174, -101184, -101184, -101196, -101196, -101208, -101249, -101356, -101362, -101369, -101381, -101381, +101138, +101138, +101150, +101150, +101150, +101150, +101170, +101178, +101197, +101204, +101228, +101277, +101305, +101372, 101386, -101386, -101386, -101386, -101386, -101386, -101386, -101386, -101424, -101424, -101438, -101438, -101442, -101442, -101456, -101474, -101474, -101474, -101479, -101479, -101484, -101484, -101484, -101496, -101496, -101507, -101547, -101700, -101700, -101707, -101707, -101711, -101735, -101735, -101735, -101735, -101735, -101735, -101735, -101735, -101824, -101824, -101828, -101828, -101833, -101833, -101843, +101405, +101412, +101420, +101427, +101427, +101434, +101471, +101478, +101514, +101525, +101557, +101561, +101588, +101630, +101641, +101657, +101672, +101715, +101722, +101722, +101729, +101740, +101746, +101779, +101779, +101779, +101803, +101803, +101821, +101831, +101838, 101859, -101868, -101868, -101880, -101880, -101895, -101899, -101899, -101908, -101908, -101925, -101995, -102084, -102107, -102107, -102107, -102119, -102119, -102119, -102119, -102119, -102125, -102125, -102125, -102125, -102324, -102324, -102324, -102324, -102324, -102324, -102339, -102397, -102397, -102397, -102410, -102410, -102410, -102417, -102417, -102417, -102417, -102417, -102424, -102564, -102570, -102587, -102595, -102595, -102610, -102610, -102610, -102610, -102620, -102620, -102620, -102620, -102773, -102812, -102812, -102812, -102812, -102812, -102816, -102850, -102868, -102868, -102879, -102879, -102879, -102879, -102879, -102879, -102879, -102879, -102937, -103001, -103001, -103008, -103028, -103028, -103028, -103028, -103028, -103028, -103028, -103028, -103028, -103028, -103123, -103123, -103127, -103127, -103127, -103127, -103137, -103153, -103153, -103153, -103153, -103157, -103157, -103157, -103157, -103170, -103170, -103170, -103192, -103294, -103294, -103298, -103298, -103298, -103307, -103307, -103307, -103312, -103312, -103312, -103312, -103316, -103320, -103331, -103331, -103331, -103335, +101869, +101877, +101919, +101926, +101957, +101981, +101996, +102003, +102010, +102018, +102040, +102062, +102069, +102069, +102069, +102094, +102101, +102140, +102150, +102150, +102155, +102163, +102191, +102228, +102243, +102250, +102282, +102289, +102296, +102296, +102334, +102334, +102384, +102400, +102408, +102433, +102448, +102448, +102462, +102511, +102518, +102545, +102566, +102579, +102598, +102617, +102675, +102682, +102688, +102712, +102721, +102721, +102721, +102745, +102745, +102752, +102752, +102774, +102808, +102828, +102828, +102844, +102892, +102892, +102912, +102928, +102953, +102973, +103000, +103000, +103012, +103021, +103021, +103031, +103031, +103031, +103031, +103056, +103063, +103063, +103079, +103086, +103086, +103097, +103142, +103142, +103154, +103179, +103205, +103228, +103238, +103238, +103238, +103264, +103288, +103288, +103306, +103306, +103306, +103306, +103315, 103339, -103354, -103364, -103364, -103378, -103378, -103378, -103378, -103378, -103378, -103378, -103378, -103382, -103388, -103450, -103450, -103457, -103457, -103488, -103503, -103503, -103503, -103503, -103526, -103533, -103533, -103533, -103711, -103717, -103730, -103740, -103740, -103740, -103740, -103773, -103822, -103822, -103822, -103822, -103833, -103833, -103833, -103867, -103867, -103880, -103956, -104019, -104032, -104039, -104039, -104058, -104058, -104058, -104058, -104065, -104065, -104065, -104072, -104072, -104157, -104164, -104168, -104168, -104172, -104179, -104179, -104204, -104225, -104225, -104225, -104225, -104241, -104241, -104241, -104241, -104241, -104254, -104284, -104382, -104382, -104382, -104382, -104387, -104403, -104403, -104403, -104403, -104424, -104434, -104434, -104434, -104501, -104501, -104501, -104501, -104501, -104506, -104506, -104530, -104530, -104530, -104572, -104572, -104577, -104577, -104577, -104591, -104591, -104591, -104625, -104725, -104736, -104754, -104776, -104776, +103339, +103339, +103362, +103372, +103428, +103438, +103461, +103471, +103471, +103471, +103480, +103480, +103524, +103524, +103524, +103524, +103568, +103610, +103634, +103651, +103680, +103680, +103694, +103701, +103701, +103701, +103775, +103782, +103801, +103826, +103850, +103850, +103886, +103886, +103909, +103918, +103926, +103926, +103931, +103982, +103993, +104000, +104044, +104051, +104095, +104102, +104109, +104127, +104134, +104162, +104162, +104183, +104261, +104261, +104268, +104275, +104280, +104297, +104304, +104337, +104351, +104363, +104363, +104373, +104441, +104453, +104460, +104493, +104617, +104617, +104653, +104653, +104715, +104715, +104715, +104752, 104784, -104784, -104784, -104784, -104784, -104784, -104784, -104784, -104904, -104904, -104904, -104904, -104904, -104909, -104918, -104949, -104968, -104968, -104989, -104993, -104993, -104993, -104993, -105006, -105006, -105018, -105044, +104798, +104798, +104798, +104814, +104814, +104814, +104814, +104833, +104833, +104859, +104859, +104859, +104859, +104907, +104926, +104933, +104943, +104943, +104943, +104986, +105042, +105049, +105068, +105095, +105095, +105103, 105120, -105126, -105126, -105126, -105126, -105126, -105126, -105126, -105126, -105126, -105126, -105126, -105126, -105186, -105198, -105198, -105198, -105198, -105198, -105224, -105236, -105236, -105236, -105236, -105236, -105236, -105243, -105243, -105243, -105243, -105264, -105283, -105328, -105356, -105369, -105369, -105369, -105369, -105369, -105369, -105369, -105376, -105376, -105376, -105376, -105573, -105584, -105584, -105584, -105593, -105600, -105611, -105676, -105717, -105717, -105725, -105725, -105725, -105732, -105732, -105732, -105732, -105742, -105779, -105825, -105825, -105860, -105872, -105909, -105942, -105942, -105954, -105954, +105120, +105129, +105136, +105136, +105140, +105140, +105140, +105158, +105162, +105162, +105162, +105162, +105169, +105169, +105175, +105193, +105193, +105193, +105193, +105206, +105206, +105215, +105215, +105215, +105268, +105279, +105311, +105324, +105333, +105333, +105355, +105375, +105401, +105413, +105413, +105436, +105443, +105447, +105447, +105447, +105447, +105462, +105473, +105473, +105473, +105473, +105480, +105501, +105501, +105524, +105529, +105548, +105558, +105558, +105580, +105592, +105592, +105592, +105592, +105613, +105623, +105672, +105686, +105696, +105712, +105720, +105749, +105774, +105774, +105800, +105811, +105811, +105816, +105849, +105857, +105857, +105868, +105894, +105931, 105966, -105966, -105978, -105978, -106107, -106165, -106180, -106180, -106184, -106184, -106184, -106237, -106256, -106256, -106286, -106286, -106293, -106293, -106300, -106311, -106311, -106318, -106375, +106016, +106016, +106016, +106022, +106029, +106041, +106062, +106109, +106120, +106133, +106149, +106170, +106211, +106211, +106239, +106239, +106239, +106273, +106280, +106280, +106291, +106298, +106298, +106310, +106324, +106371, +106371, +106398, +106409, +106426, 106477, -106483, -106483, -106506, -106510, -106510, -106510, -106549, -106549, -106549, -106549, -106556, -106556, -106556, -106565, -106565, -106565, -106565, -106577, -106592, -106631, -106648, -106648, -106648, -106660, -106676, +106477, +106477, +106477, +106477, +106477, +106498, +106498, +106511, +106511, +106516, +106548, +106558, +106558, +106558, +106558, +106590, +106609, +106658, +106658, 106683, -106683, -106722, -106722, -106722, -106770, -106889, -106889, -106889, -106893, -106893, -106893, -106893, -106893, -106893, -106900, -106900, -106900, -106907, -106981, +106725, +106732, +106736, +106736, +106736, +106736, +106736, +106746, +106746, +106755, +106766, +106809, +106809, +106821, +106821, +106821, +106821, +106821, +106841, +106841, +106841, +106877, +106877, +106877, +106915, +106939, +106939, +106955, +106955, +106955, 106981, 106991, 106991, -106991, -106991, -107006, -107061, -107080, -107080, -107091, -107091, -107091, -107091, -107091, +107025, +107049, +107049, +107049, +107049, +107049, +107049, +107065, +107065, +107065, +107072, +107081, 107103, 107103, -107110, -107144, -107229, -107260, -107260, -107270, -107289, -107289, -107289, -107289, -107289, -107289, -107289, -107289, -107289, -107399, -107406, -107406, -107406, -107406, -107406, -107438, -107470, -107470, -107474, -107524, -107524, -107524, -107524, -107524, -107540, -107540, -107540, -107635, -107792, -107799, -107799, -107809, -107852, -107852, -107852, -107852, -107852, -107859, -107859, -107859, -107859, -107892, -107892, -107892, -107892, -107892, -107904, +107103, +107103, +107103, +107120, +107120, +107120, +107120, +107131, +107166, +107179, +107190, +107190, +107199, +107199, +107207, +107220, +107234, +107244, +107249, +107249, +107249, +107249, +107262, +107286, +107300, +107300, +107300, +107300, +107310, +107338, +107348, +107358, +107408, +107408, +107451, +107513, +107555, +107566, +107566, +107566, +107566, +107582, +107597, +107597, +107597, +107597, +107597, +107628, +107638, +107646, +107660, +107673, +107673, +107685, +107685, +107685, +107691, +107691, +107696, +107728, +107728, +107728, +107728, +107728, +107797, +107806, +107806, +107806, +107822, +107838, +107838, +107862, +107889, +107889, +107905, 107914, -107919, -107919, -107919, -107940, -107940, -107952, -107952, -107952, -107975, -107975, -107975, -107996, -108090, -108090, -108090, -108097, -108138, -108158, -108158, -108158, -108169, -108175, -108175, -108187, -108187, -108218, -108218, +107927, +107934, +107934, +107947, +107947, +107947, +107947, +107947, +107956, +107956, +107961, +107971, +107978, +107978, +107995, +107995, +108006, +108024, +108060, +108069, +108069, +108069, +108069, +108082, +108091, +108125, +108125, +108157, +108219, 108232, -108232, -108232, -108232, -108258, -108258, -108258, -108265, -108280, -108280, -108310, -108321, -108321, -108321, -108321, +108242, +108248, +108260, +108278, +108290, +108302, +108306, +108323, +108323, +108323, 108332, -108405, -108544, -108558, -108587, -108587, +108332, +108332, +108374, +108421, +108451, +108451, +108473, +108473, +108516, +108534, +108534, +108534, +108550, +108550, +108567, +108567, +108574, +108574, +108574, +108574, +108579, +108579, 108596, 108596, 108596, 108596, 108596, -108608, -108608, -108615, -108622, -108649, -108665, -108665, -108665, -108665, -108677, -108677, -108747, -108759, -108772, -108793, -108793, -108793, -108793, -108812, +108596, +108611, +108611, +108618, +108618, +108618, +108632, +108683, +108687, +108707, +108717, +108717, +108730, +108750, +108750, +108750, +108764, +108785, +108789, 108831, -108831, -108852, -108876, -108992, -109001, -109027, -109027, -109065, -109109, -109109, -109109, -109109, -109109, -109109, -109109, -109116, -109182, -109194, -109194, -109194, -109206, -109213, -109227, -109243, -109255, -109255, -109283, -109283, -109283, -109295, -109295, -109313, -109313, -109313, -109334, -109513, -109531, -109538, -109538, -109538, -109558, -109570, -109574, -109598, -109598, -109598, -109598, -109610, -109725, -109725, -109725, -109725, -109725, -109736, -109743, -109747, -109773, -109803, -109816, -109816, -109816, -109835, -109854, -109861, -109861, -109861, -109890, -110009, -110016, -110033, -110033, -110050, -110050, -110050, -110050, -110050, -110050, -110050, -110050, -110050, -110190, -110204, -110204, -110204, -110204, -110221, -110221, -110277, -110277, -110277, -110277, -110277, -110286, -110309, -110309, -110325, -110325, -110332, -110353, -110481, -110481, -110522, -110532, +108846, +108881, +108881, +108906, +108906, +108906, +108906, +108926, +108926, +108926, +108972, +108972, +108972, +108986, +108986, +108986, +109077, +109102, +109131, +109216, +109216, +109236, +109297, +109297, +109319, +109319, +109319, +109319, +109319, +109330, +109351, +109351, +109377, +109377, +109377, +109395, +109395, +109418, +109418, +109418, +109418, +109441, +109441, +109441, +109451, +109470, +109470, +109470, +109470, +109474, +109474, +109509, +109509, +109509, +109509, +109588, +109597, +109625, +109625, +109639, +109655, +109655, +109664, +109680, +109680, +109728, +109760, +109760, +109772, +109772, +109772, +109798, +109810, +109817, +109825, +109825, +109825, +109842, +109859, +109859, +109864, +109908, +109908, +109923, +109934, +109934, +109934, +109963, +109963, +109977, +110007, +110007, +110026, +110026, +110076, +110094, +110094, +110104, +110104, +110115, +110115, +110122, +110147, +110147, +110160, +110187, +110187, +110187, +110187, +110199, +110199, +110220, +110229, +110241, +110301, +110322, +110326, +110326, +110336, +110341, +110341, +110341, +110360, +110360, +110360, +110360, +110360, +110365, +110391, +110441, +110441, +110463, +110475, +110475, +110475, +110488, +110498, +110504, +110504, 110539, -110544, -110551, -110551, -110551, -110551, -110551, -110551, -110568, -110732, -110732, -110736, -110736, -110736, -110736, -110743, -110773, -110773, -110773, -110795, -110795, -110820, -110820, -110820, -110831, -110831, -110853, -110864, -110951, -110951, -110951, -110951, -110951, -110972, -110976, -110976, -110976, -110976, -110976, -110976, -111002, -111208, -111214, -111221, -111221, -111230, -111230, -111230, -111286, -111286, -111286, -111286, -111286, -111286, -111297, -111297, -111297, -111304, -111304, -111315, -111412, -111412, -111416, -111416, -111416, -111416, -111416, -111416, -111416, -111416, -111416, -111416, -111416, -111537, -111537, -111537, -111545, -111545, -111545, -111555, -111601, -111624, -111624, -111624, -111624, -111632, -111632, -111632, -111663, -111663, -111663, -111704, -111918, -111918, -111925, -111944, -111952, -111979, -111979, -111979, -111979, -111979, -111979, -112000, -112000, -112136, -112151, -112151, -112151, -112151, -112151, -112180, -112227, -112249, +110565, +110565, +110581, +110588, +110588, +110595, +110595, +110602, +110645, +110661, +110690, +110711, +110711, +110711, +110711, +110726, +110726, +110738, +110738, +110746, +110754, +110796, +110817, +110843, +110892, +110892, +110900, +110921, +110921, +110939, +110949, +110955, +110955, +110981, +111018, +111034, +111034, +111048, +111057, +111057, +111057, +111086, +111092, +111112, +111112, +111112, +111128, +111144, +111153, +111170, +111203, +111232, +111232, +111272, +111276, +111290, +111300, +111338, +111345, +111354, +111367, +111367, +111399, +111407, +111447, +111480, +111487, +111501, +111594, +111630, +111636, +111657, +111657, +111681, +111691, +111691, +111691, +111705, +111733, +111733, +111733, +111756, +111765, +111765, +111819, +111855, +111855, +111868, +111874, +111874, +111914, +111914, +111914, +111934, +111967, +111993, +112002, +112031, +112031, +112068, +112075, +112082, +112082, +112137, +112137, +112156, +112186, +112186, +112186, +112186, +112213, +112231, +112231, +112231, +112239, 112268, -112288, -112288, -112288, -112288, -112288, -112288, -112288, -112288, -112319, -112386, -112404, -112404, -112404, -112404, -112410, -112410, -112410, -112410, -112410, -112410, -112428, -112428, -112590, -112639, -112659, -112659, -112659, -112659, -112659, -112694, -112694, -112694, -112694, -112707, -112715, -112722, -112730, -112766, -112766, -112779, -112874, -113023, -113032, -113032, -113040, -113040, -113056, -113056, -113056, -113077, -113082, -113082, -113082, -113089, -113139, -113139, -113151, -113151, -113151, -113167, -113177, -113213, -113213, -113213, -113230, -113230, -113236, -113236, -113236, -113253, -113253, -113259, -113325, -113427, -113427, -113440, -113448, -113448, -113463, -113463, -113463, -113463, -113463, -113463, -113472, -113481, -113589, -113589, -113589, -113589, -113589, -113589, -113635, -113665, -113665, -113665, -113665, -113665, -113665, -113665, -113665, -113675, -113675, -113682, -113739, -113827, -113836, -113850, -113850, -113870, -113889, -113889, -113889, -113889, -113889, -113889, -113889, -113889, -113908, -113912, -113912, -113912, -113912, -113912, -113922, -113954, -113954, -113954, -113964, -113964, -113980, -113997, -113997, -113997, -113997, -114008, -114061, -114138, -114144, -114154, -114154, -114154, -114154, -114154, -114154, -114154, +112268, +112279, +112298, +112298, +112309, +112321, +112336, +112336, +112336, +112346, +112350, +112361, +112361, +112361, +112369, +112377, +112377, +112418, +112418, +112418, +112468, +112468, +112468, +112488, +112488, +112502, +112509, +112526, +112554, +112554, +112554, +112592, +112596, +112613, +112627, +112696, +112781, +112804, +112873, +112913, +112913, +112920, +112931, +112931, +112947, +112976, +112991, +112997, +112997, +113022, +113073, +113103, +113114, +113123, +113123, +113130, +113153, +113221, +113221, +113255, +113271, +113290, +113290, +113290, +113290, +113309, +113368, +113368, +113368, +113411, +113423, +113445, +113445, +113445, +113553, +113564, +113576, +113598, +113650, +113677, +113677, +113677, +113677, +113687, +113693, +113693, +113698, +113698, +113698, +113711, +113728, +113743, +113753, +113753, +113753, +113753, +113753, +113753, +113764, +113779, +113786, +113786, +113792, +113798, +113798, +113798, +113798, +113798, +113804, +113819, +113819, +113819, +113819, +113843, +113843, +113843, +113894, +113919, +113928, +113940, +113959, +113959, +113977, +113977, +113983, +113983, +114005, +114005, +114005, +114021, +114035, +114077, +114093, +114093, +114131, +114131, +114131, +114131, +114137, 114169, -114169, -114169, -114169, -114187, -114187, -114187, -114187, -114197, -114197, -114208, -114214, -114214, -114214, -114224, -114224, -114224, -114224, -114224, -114238, -114238, -114238, -114262, -114370, -114376, -114406, -114406, +114182, +114182, +114196, +114196, +114196, +114215, +114230, +114243, +114250, +114250, +114269, +114269, +114331, +114331, +114331, +114331, +114331, +114331, +114331, +114331, +114331, +114343, +114358, +114358, +114364, +114392, 114417, -114417, -114417, -114417, -114417, -114417, -114417, -114417, -114417, -114508, -114514, -114526, -114526, -114526, -114562, -114566, -114598, -114624, -114624, -114640, -114640, -114655, -114662, -114662, -114695, -114695, -114695, -114717, -114803, -114826, -114833, -114833, -114833, -114844, -114844, -114844, -114844, -114844, -114844, -114844, -114850, -114936, -114936, -114936, -114936, -114936, -114936, -115003, -115069, -115069, -115069, -115085, -115085, -115093, -115093, -115093, -115115, -115115, -115115, -115168, -115264, +114433, +114439, +114446, +114454, +114472, +114484, +114490, +114553, +114560, +114604, +114604, +114613, +114613, +114623, +114623, +114623, +114623, +114635, +114660, +114660, +114660, +114718, +114724, +114724, +114743, +114756, +114776, +114790, +114790, +114790, +114810, +114897, +114897, +114906, +114906, +114917, +114923, +114923, +114953, +114962, +114999, +114999, +114999, +114999, +115005, +115012, +115012, +115030, +115030, +115040, +115060, +115104, +115112, +115136, +115171, +115171, +115191, +115209, +115227, +115262, 115276, -115286, -115286, -115286, -115286, -115286, -115286, -115286, -115286, -115286, -115286, -115286, -115546, -115561, -115561, -115561, -115561, -115568, -115568, -115594, -115620, -115620, -115630, -115630, -115641, -115641, -115651, -115651, -115651, -115651, -115700, -115845, -115863, -115887, -115887, -115887, -115894, -115894, -115894, -115894, -115894, -115894, -115894, -115894, -115984, -115984, -115984, -115984, -115984, -115984, -116004, -116015, -116015, -116015, -116020, -116020, -116020, -116033, -116033, -116033, -116033, -116033, -116033, -116174, -116174, -116184, -116184, -116192, -116192, -116192, -116192, -116211, -116215, -116223, -116223, -116223, -116255, -116261, -116272, -116272, -116272, -116272, -116287, -116311, -116311, -116319, -116332, -116332, -116332, -116332, -116332, -116332, -116332, -116332, -116374, -116500, -116500, -116500, -116506, -116521, -116521, -116521, -116521, -116521, -116527, -116527, -116527, -116527, -116813, -116813, -116817, -116824, -116824, -116824, -116864, -116927, +115284, +115284, +115319, +115319, +115338, +115388, +115388, +115388, +115388, +115403, +115415, +115415, +115415, +115432, +115485, +115502, +115502, +115502, +115502, +115502, +115502, +115502, +115502, +115502, +115519, +115528, +115528, +115534, +115565, +115586, +115664, +115685, +115685, +115748, +115748, +115763, +115768, +115768, +115768, +115825, +115839, +115839, +115848, +115854, +115869, +115869, +115892, +115900, +115900, +115900, +115908, +115942, +115950, +115950, +115976, +115982, +115999, +116021, +116021, +116021, +116041, +116041, +116041, +116060, +116088, +116088, +116088, +116088, +116104, +116143, +116143, +116143, +116143, +116165, +116169, +116183, +116183, +116194, +116194, +116219, +116219, +116244, +116254, +116254, +116254, +116254, +116275, +116292, +116292, +116299, +116350, +116395, +116395, +116422, +116422, +116442, +116450, +116467, +116476, +116482, +116492, +116492, +116492, +116512, +116512, +116566, +116594, +116604, +116640, +116665, +116712, +116712, +116720, +116733, +116733, +116733, +116749, +116749, +116761, +116782, +116802, +116802, +116802, +116802, +116825, +116831, +116841, +116879, +116879, +116885, +116885, +116885, +116901, +116901, +116901, +116907, +116923, 116933, -116933, -116955, -116959, -116959, -116959, -116966, -116966, -116966, -116966, -117004, -117097, -117097, -117107, -117107, -117119, -117119, -117119, -117119, -117119, -117119, -117119, -117119, -117123, -117151, -117151, -117178, -117182, -117190, -117190, -117206, -117272, -117282, -117282, -117327, -117327, -117331, -117331, -117331, -117335, -117335, -117335, -117353, -117522, -117522, -117540, -117540, -117540, -117540, -117540, -117540, -117540, -117540, -117540, -117540, -117540, -117767, -117821, -117821, -117821, -117821, -117821, -117845, -117875, -117881, -117881, -117881, -117881, -117898, -117898, -117908, -117908, -117908, -117912, -117912, -117982, -117986, -117990, -117990, -118005, -118005, -118005, -118005, -118005, -118005, -118005, -118005, -118005, -118102, -118106, -118122, -118122, -118146, -118146, -118156, -118205, -118216, -118216, -118216, -118216, -118216, -118216, -118216, -118225, -118225, -118225, -118252, -118370, -118376, -118376, -118385, -118385, -118430, -118430, -118430, -118430, -118430, -118430, -118448, -118448, -118585, -118585, -118585, -118585, -118594, -118594, -118617, -118649, +116942, +116968, +116968, +117006, +117006, +117006, +117006, +117006, +117027, +117048, +117064, +117093, +117167, +117167, +117175, +117193, +117202, +117213, +117213, +117252, +117294, +117294, +117307, +117307, +117325, +117341, +117351, +117358, +117358, +117366, +117366, +117378, +117378, +117378, +117390, +117426, +117477, +117485, +117526, +117547, +117556, +117556, +117565, +117565, +117607, +117631, +117631, +117631, +117631, +117649, +117682, +117682, +117682, +117682, +117692, +117711, +117711, +117741, +117746, +117778, +117778, +117791, +117791, +117791, +117791, +117809, +117819, +117819, +117819, +117844, +117949, +117974, +118018, +118057, +118057, +118065, +118065, +118065, +118075, +118087, +118092, +118092, +118098, +118115, +118121, +118144, +118168, +118180, +118180, +118221, +118271, +118309, +118322, +118322, +118322, +118328, +118328, +118347, +118347, +118378, +118388, +118392, +118404, +118404, +118425, +118425, +118425, +118435, +118485, +118514, +118524, +118535, +118549, +118549, +118549, +118562, +118562, +118599, +118599, +118606, +118606, +118610, +118610, +118610, +118652, 118656, -118672, -118672, -118672, -118672, -118672, -118672, -118672, -118672, -118672, -118685, -118827, -118827, -118837, -118837, -118837, -118845, -118845, -118845, -118845, -118854, -118854, -118854, -118860, -118975, -118975, -118975, -118975, -118975, -118975, -119025, -119064, -119064, -119064, -119064, -119064, -119064, -119064, -119064, -119064, -119064, -119064, -119076, -119141, -119162, -119169, -119185, -119185, -119185, -119185, -119185, -119185, -119185, -119185, -119185, -119185, -119308, -119308, -119308, -119308, -119308, -119308, -119346, -119377, -119412, -119412, -119412, -119412, -119412, -119412, -119412, -119419, -119419, -119419, -119453, -119547, -119547, -119553, -119553, -119569, -119591, -119591, -119591, -119591, -119591, -119591, -119591, -119591, -119701, -119701, -119705, -119705, -119705, -119705, -119705, -119744, -119744, -119744, -119761, -119765, -119765, -119765, -119780, -119791, -119791, -119791, -119798, -119856, -119877, -119877, -119877, -119877, -119954, -119954, +118665, +118684, +118736, +118746, +118746, +118746, +118752, +118752, +118756, +118792, +118792, +118796, +118833, +118856, +118918, +118952, +118952, +118977, +118994, +119012, +119012, +119037, +119037, +119037, +119049, +119049, +119086, +119086, +119086, +119091, +119091, +119102, +119126, +119126, +119126, +119133, +119133, +119148, +119161, +119200, +119200, +119200, +119200, +119200, +119221, +119268, +119268, +119268, +119282, +119314, +119320, +119351, +119368, +119368, +119381, +119381, +119462, +119462, +119462, +119512, +119512, +119516, +119516, +119516, +119516, +119516, +119526, +119544, +119544, +119544, +119615, +119615, +119629, +119666, +119678, +119687, +119720, +119720, +119737, +119737, +119747, +119755, +119755, +119755, +119787, +119787, +119787, +119812, +119844, +119855, +119855, +119855, +119862, +119862, +119862, +119862, +119862, +119885, +119920, +119920, +119929, +119929, 119973, -119973, -119973, -119973, -119973, -119973, -120070, -120070, -120088, -120092, -120092, -120092, -120092, -120112, -120125, -120129, -120134, -120134, -120141, -120141, -120158, +119995, +120013, +120013, +120019, +120019, +120036, +120036, +120036, +120056, +120077, +120077, +120105, +120105, +120105, +120119, +120119, +120172, 120176, -120176, -120189, -120247, -120327, -120333, -120333, -120375, -120375, -120390, -120390, -120390, -120390, -120390, -120390, -120390, -120390, -120441, -120441, -120441, -120441, -120441, -120441, -120463, -120525, -120525, -120525, -120554, -120554, -120554, -120564, -120576, -120576, -120576, -120576, -120648, -120738, -120738, -120750, -120750, -120750, -120755, -120755, -120755, -120755, -120764, -120764, -120764, -120764, -120883, -120929, -120929, -120929, -120929, -120929, -120951, -120958, -120974, -120974, -120974, -120974, -120974, -120974, -120974, -120994, -120994, -120994, +120188, +120194, +120201, +120201, +120212, +120229, +120229, +120229, +120250, +120264, +120264, +120302, +120302, +120337, +120337, +120337, +120345, +120357, +120357, +120357, +120373, +120373, +120373, +120373, +120406, +120421, +120421, +120421, +120421, +120431, +120450, +120459, +120475, +120475, +120475, +120529, +120548, +120560, +120569, +120595, +120595, +120607, +120607, +120611, +120633, +120633, +120692, +120692, +120702, +120702, +120702, +120742, +120749, +120758, +120778, +120827, +120827, +120863, +120863, +120871, +120890, +120936, +120936, +120965, +120978, +121038, +121038, +121038, +121038, +121042, +121042, +121042, +121042, +121050, 121057, -121128, -121128, -121145, -121145, -121145, -121145, -121145, -121145, -121145, -121145, -121145, -121145, -121145, -121202, -121214, -121214, -121214, -121214, -121214, -121230, -121248, -121253, -121253, -121253, -121253, -121253, -121253, -121253, -121253, -121253, -121253, -121314, -121414, -121414, -121414, -121421, -121421, -121421, -121428, -121435, -121435, -121460, -121460, -121469, -121476, -121610, -121610, -121610, -121610, -121617, -121631, +121064, +121064, +121076, +121126, +121126, +121126, +121157, +121157, +121162, +121162, +121162, +121170, +121170, +121198, +121217, +121217, +121217, +121231, +121241, +121260, +121260, +121284, +121289, +121289, +121289, +121289, +121348, +121352, +121361, +121368, +121378, +121382, +121427, +121495, +121508, +121517, +121534, +121550, +121550, +121550, +121550, +121557, +121566, +121634, +121634, +121634, +121642, +121642, 121650, -121725, -121732, -121732, -121752, -121759, -121766, -121780, -121780, -121789, -121796, -121803, -121858, -121982, -121996, -122003, -122010, -122017, -122032, -122032, -122032, -122032, -122046, +121667, +121700, +121706, +121706, +121742, +121742, +121756, +121774, +121805, +121815, +121815, +121815, +121815, +121829, +121885, +121885, +121885, +121929, +121929, +121939, +121949, +121961, +122011, +122011, +122011, +122015, +122037, 122053, -122053, -122053, -122094, -122101, -122116, -122116, -122116, -122116, -122116, -122129, -122155, -122166, -122200, -122200, -122207, -122207, -122207, -122217, -122224, -122224, -122258, -122394, -122394, -122394, -122401, -122408, -122425, -122425, -122432, -122439, -122439, -122446, -122446, -122446, -122446, -122457, -122457, -122457, -122457, -122457, -122489, -122507, -122507, -122507, -122520, -122520, -122520, -122527, -122527, -122527, -122534, -122534, -122561, -122681, -122694, -122701, -122707, -122707, -122721, -122721, -122721, -122728, -122735, -122735, -122735, +122089, +122089, +122102, +122125, +122144, +122178, +122219, +122253, +122288, +122288, +122315, +122315, +122315, +122325, +122339, +122393, +122420, +122427, +122437, +122447, +122468, +122468, +122505, +122505, +122505, +122523, +122523, +122523, +122523, +122523, +122523, +122545, +122563, +122563, +122583, +122583, +122608, +122608, +122608, +122608, +122608, +122615, +122632, +122632, +122632, +122642, +122652, +122652, +122652, +122670, +122706, +122722, 122742, -122805, -122850, -122850, -122857, -122857, -122876, -122886, -122927, -122934, -122934, -122934, -122941, -122948, -122948, -122955, -122955, -122962, -122969, -122969, -123098, -123098, -123141, -123148, -123155, -123162, -123169, -123176, -123176, -123183, -123196, -123196, -123203, -123398, -123405, -123435, -123435, -123449, -123463, -123484, -123514, -123538, -123553, -123557, -123570, -123570, -123584, -123584, -123617, -123624, -123631, -123691, -123914, -123929, -123936, -123958, -123974, -123974, -123974, -123981, -123981, -123995, +122761, +122795, +122795, +122810, +122815, +122846, +122906, +122906, +122918, +122931, +122931, +122937, +122956, +122989, +122989, +123038, +123038, +123064, +123101, +123140, +123150, +123150, +123150, +123175, +123224, +123224, +123224, +123251, +123251, +123251, +123301, +123301, +123312, +123312, +123348, +123348, +123372, +123372, +123372, +123372, +123390, +123390, +123445, +123445, +123452, +123458, +123458, +123490, +123490, +123490, +123490, +123490, +123505, +123505, +123512, +123544, +123554, +123575, +123596, +123629, +123629, +123656, +123756, +123760, +123760, +123760, +123820, +123820, +123829, +123843, +123843, +123843, +123853, +123873, +123885, +123885, +123902, +123902, +123902, +123902, +123930, +123930, +123950, +123950, +123980, +123980, 124002, -124002, -124002, -124056, -124063, -124080, -124087, -124094, -124101, -124123, -124184, -124206, -124206, -124230, -124237, -124251, +124024, +124043, +124112, +124112, +124128, +124139, +124163, +124174, +124209, +124209, +124209, 124258, -124265, -124265, 124285, -124285, -124353, -124443, -124443, -124450, -124457, -124470, -124484, -124491, -124513, -124513, -124520, -124527, -124534, -124541, -124654, -124666, -124688, -124688, -124701, -124709, -124716, -124812, -124823, -124837, -124860, -124867, -124881, -124888, -124898, -124898, -124905, -124905, -124949, -125030, -125039, -125046, +124290, +124290, +124290, +124297, +124309, +124309, +124355, +124371, +124371, +124379, +124379, +124379, +124426, +124426, +124438, +124479, +124504, +124521, +124521, +124546, +124546, +124556, +124589, +124589, +124589, +124589, +124631, +124642, +124664, +124664, +124664, +124664, +124664, +124678, +124702, +124702, +124702, +124748, +124753, +124773, +124773, +124785, +124785, +124785, +124817, +124841, +124841, +124855, +124855, +124895, +124895, +124895, +124895, +124910, +124920, +124920, +124920, +124945, +124991, +125024, +125033, +125033, +125049, 125064, -125064, -125071, -125071, -125088, -125088, -125088, -125088, -125088, -125095, -125200, -125213, -125213, -125220, -125234, -125241, -125258, -125318, -125341, -125348, -125358, -125365, +125087, +125087, +125087, +125109, +125120, +125128, +125138, +125138, +125148, +125160, +125171, +125171, +125181, +125181, +125181, +125191, +125197, +125217, +125217, +125227, +125227, +125242, +125250, +125262, +125312, +125346, +125373, 125381, -125381, -125395, -125408, -125412, -125419, -125456, -125582, -125605, -125636, -125643, -125669, -125679, -125679, -125679, -125715, -125732, -125732, -125732, -125739, -125912, -125925, -125925, -125925, -125932, -125953, -125988, -126020, -126043, -126043, -126043, -126043, -126043, -126043, -126043, -126043, -126043, -126054, -126119, -126267, -126280, -126294, -126308, -126315, -126338, -126353, -126380, +125396, +125413, +125418, +125418, +125426, +125426, +125468, +125468, +125468, +125484, +125484, +125484, +125484, +125506, +125510, +125510, +125510, +125530, +125530, +125545, +125545, +125545, +125545, +125555, +125569, +125594, +125594, +125603, +125603, +125645, +125674, +125719, +125731, +125750, +125779, +125779, +125789, +125832, +125842, +125842, +125842, +125842, +125855, +125855, +125855, +125855, +125855, +125873, +125873, +125940, +125957, +125978, +125978, +125978, +125978, +126000, +126009, +126009, +126028, +126028, +126036, +126057, +126078, +126097, +126111, +126128, +126128, +126134, +126134, +126153, +126166, +126166, +126173, +126195, +126216, +126216, +126216, +126216, +126286, +126286, +126292, +126292, +126292, +126316, +126316, +126326, +126326, +126366, 126387, -126394, -126394, -126394, -126425, -126609, -126623, -126630, -126630, -126637, -126644, -126668, -126689, -126710, -126725, -126740, -126746, -126760, -126774, -126781, -126781, -126788, -126795, -126834, -126933, -126947, -126961, -126968, -126975, -126982, -126989, -127003, -127003, -127010, -127010, -127017, -127024, -127097, -127106, -127122 +126387, +126451, +126460, +126460, +126460, +126460, +126467, +126503, +126529, +126529, +126551, +126567, +126567, +126567, +126597, +126597, +126597, +126602, +126621, +126628, +126628, +126639, +126675, +126686, +126686, +126686, +126695, +126751, +126762, +126762, +126806, +126857, +126874, +126886, +126948, +126948, +126948, +126956, +126956, +126984, +126984, +127001, +127015, +127027, +127046, +127046 }; static const char *tldData[] = { -"hs.kr\0" -"net.ms\0cc.me.us\0lib.ne.us\0com.vc\0" -"net.mt\0" -"sa.gov.au\0net.mu\0com.ve\0*.transurl.be\0" -"net.mv\0net.nf\0" -"net.mw\0net.ng\0" -"net.mx\0" -"net.my\0net.ni\0com.uy\0com.vi\0" -"net.mz\0com.uz\0" -"turek.pl\0" -"com.vn\0" -"sykkylven.no\0cpa.pro\0" -"tokai.aichi.jp\0kamifurano.hokkaido.jp\0shibetsu.hokkaido.jp\0minamiawaji.hyogo.jp\0kamaishi.iwate.jp\0hakone.kanagawa.jp\0nagaoka.niigata.jp\0yaita.tochigi.jp\0tank.jp\0" -"yk.ca\0\xd1\x81\xd0\xb0\xd0\xbc\xd0\xb0\xd1\x80\xd0\xb0.\xd1\x80\xd1\x83\xd1\x81\0" -"riobranco.br\0net.nr\0" -"com.vu\0" -"university\0" -"net.nz\0" -"net.om\0ap-northeast-1.elasticbeanstalk.com\0workisboring.com\0applinzi.com\0" -"amazon\0" -"hzc.io\0" -"net.pa\0" -"lib.nj.us\0com.ws\0inc\0news\0notebook.eu-west-3.sagemaker.aws\0" -"net.pe\0lima-city.de\0" -"ing\0homelinux.org\0" -"net.ph\0" -"net.pk\0ink\0" -"net.pl\0umig.gov.pl\0" -"net.pn\0" -"meland.no\0nesna.no\0s\xc3\xb8r-varanger.no\0""611.to\0" -"hyogo.jp\0matsuyama.ehime.jp\0nishitosa.kochi.jp\0arao.kumamoto.jp\0hinode.tokyo.jp\0" -"net.qa\0krym.ua\0" -"rr.gov.br\0net.pr\0am.leg.br\0" -"net.ps\0" -"int\0net.pt\0next\0" -"com.ye\0" -"net.py\0" -"s3.sa-east-1.amazonaws.com\0from-ar.com\0from-ok.com\0gleeze.com\0" -"fi.cr\0" -"b.ssl.fastly.net\0static.land\0lima-city.at\0" -"safe\0sochi.su\0*.transurl.eu\0" -"*.gateway.dev\0" -"net.eu.org\0" -"\xe7\xb6\xb2\xe7\xbb\x9c.hk\0" -"com.zm\0" -"camau.vn\0" -"vgs.no\0hl.no\0gangaviika.no\0aarborte.no\0" -"kamioka.akita.jp\0minamiechizen.fukui.jp\0mito.ibaraki.jp\0hikawa.shimane.jp\0fakefur.jp\0*.northflank.app\0" -"net.sa\0" -"rs.gov.br\0sc.gov.br\0net.sb\0ynh.fr\0" -"net.sc\0philips\0" -"net.sd\0schmidt\0" -"insurance\0office\0net.ru\0" -"net.rw\0net.sg\0" -"net.sh\0lima-city.ch\0" -"net.sl\0" -"lpusercontent.com\0" -"net.so\0" -"net.ss\0user.party.eus\0" -"net.st\0eating-organic.net\0" -"healthcare\0" -"ssl.origin.cdn77-secure.org\0myfirewall.org\0s3.teckids.org\0" -"net.th\0" -"net.sy\0play\0" -"net.tj\0" -"wielun.pl\0" -"net.tm\0" -"net.tn\0" -"medicina.bo\0osoyro.no\0midtre-gauldal.no\0divttasvuotna.no\0vestvagoy.no\0net.to\0" -"hanawa.fukushima.jp\0hiratsuka.kanagawa.jp\0oguni.kumamoto.jp\0kitaaiki.nagano.jp\0ogose.saitama.jp\0sharp\0" -"net.ua\0nokia\0" -"aparecida.br\0net.tr\0jcb\0" -"net.tt\0" -"forgot.her.name\0mcpe.me\0" -"net.tw\0" -"irish\0" -"net.uk\0" -"s3-accesspoint-fips.us-west-2.amazonaws.com\0cafjs.com\0" -"ed.ao\0*.on-k3s.io\0" -"repair\0" -"lib.la.us\0net.vc\0hughes\0kerryproperties\0" -"taa.it\0ist\0" -"net.ve\0bible\0test-iserv.de\0" -"*.user.localcert.dev\0" -"net.uy\0net.vi\0" -"net.uz\0" -"net.vn\0" -"tinn.no\0" -"yaotsu.gifu.jp\0achi.nagano.jp\0yashio.saitama.jp\0" -"ap.leg.br\0" -"lakas.hu\0net.vu\0hlx.page\0" -"itv\0" -"\xe5\x98\x89\xe9\x87\x8c\xe5\xa4\xa7\xe9\x85\x92\xe5\xba\x97\0" -"ed.ci\0suzuki\0" -"emrstudio-prod.ap-southeast-1.amazonaws.com\0sa.com\0*.ocp.customer-oci.com\0" -"ed.cr\0" -"net.ws\0" -"fi.it\0forlicesena.it\0map.fastlylb.net\0" -"sale\0" -"intl.tn\0" -"mjondalen.no\0" -"kochi.jp\0\xe6\xbb\x8b\xe8\xb3\x80.jp\0otaki.chiba.jp\0moseushi.hokkaido.jp\0namegawa.saitama.jp\0ritto.shiga.jp\0inagi.tokyo.jp\0" -"rn.gov.br\0" -"apartments\0" -"net.ye\0cymru\0c66.me\0site.transip.me\0" -"webcam\0s3-website-us-west-1.amazonaws.com\0webview-assets.cloud9.us-west-2.amazonaws.com\0is-a-bookkeeper.com\0isa-hockeynut.com\0nyaa.am\0" -"er.in\0epson\0" -"cloud-fr1.unispace.io\0" -"net.za\0" -"jeonnam.kr\0" -"studio.eu-north-1.sagemaker.aws\0" -"wa.au\0guam.gu\0latrobe\0schule\0" -"rsc.cdn77.org\0homedns.org\0" -"holiday\0" -"*.transurl.nl\0" -"net.zm\0" -"thanhhoa.vn\0" -"g\xc3\xa1ls\xc3\xa1.no\0" -"sue.fukuoka.jp\0tomari.hokkaido.jp\0takazaki.miyazaki.jp\0murakami.niigata.jp\0" -"zaporizhzhia.ua\0zp.ua\0" -"ro.gov.br\0" -"co.ae\0" -"co.ag\0" -"bosch\0" -"international\0" -"co.am\0webview-assets.aws-cloud9.eu-west-2.amazonaws.com\0mydrobo.com\0wpmucdn.com\0" -"*.database.run\0" -"co.ao\0jio\0" -"zara\0" -"co.bb\0" -"gu.us\0k12.fl.us\0" -"co.at\0mediocampidano.it\0nuoro.it\0land\0" -"stuff-4-sale.org\0" -"co.bi\0demo.datacenter.fi\0" -"co.bj\0" -"czeladz.pl\0" -"co.bn\0" -"eidsberg.no\0notodden.no\0" -"tajimi.gifu.jp\0asahi.ibaraki.jp\0ogawa.ibaraki.jp\0ochi.kochi.jp\0kashiwara.osaka.jp\0" -"co.ca\0" -"co.bw\0" -"*.svc.firenet.ch\0" -"co.ci\0" -"co.cl\0" -"co.cm\0analytics-gateway.ap-south-1.amazonaws.com\0jelastic.team\0caracal.mythic-beasts.com\0" -"co.cr\0" -"prato.it\0ibxos.it\0" -"staging.onred.one\0" -"us.ax\0" -"co.cz\0" -"co.dk\0" -"kppsp.gov.pl\0jll\0sarl\0khplay.nl\0myspreadshop.nl\0" -"\xc3\xa5""fjord.no\0oppeg\xc3\xa5rd.no\0salat.no\0sorreisa.no\0myspreadshop.no\0" -"ed.jp\0mitane.akita.jp\0futtsu.chiba.jp\0higashi.fukuoka.jp\0toyotsu.fukuoka.jp\0shintoku.hokkaido.jp\0sayo.hyogo.jp\0kamikitayama.nara.jp\0kamimine.saga.jp\0" -"df.gov.br\0" -"primetel.cloud\0*.magentosite.cloud\0" -"ggee\0""123minsida.se\0" -"luxury\0" -"s3-website.eu-central-1.amazonaws.com\0from-or.com\0sphinx.mythic-beasts.com\0servemp3.com\0""1kapp.com\0" -"tattoo\0" -"jmp\0" -"dni.us\0" -"sites.static.land\0" -"square7.de\0" -"jnj\0" -"sos.pl\0myspreadshop.pl\0" -"inder\xc3\xb8y.no\0nord-aurdal.no\0" -"\xe5\xb1\xb1\xe6\xa2\xa8.jp\0shibukawa.gunma.jp\0uryu.hokkaido.jp\0gyokuto.kumamoto.jp\0agematsu.nagano.jp\0nara.nara.jp\0seirou.niigata.jp\0honjo.saitama.jp\0hagi.yamaguchi.jp\0otsuki.yamanashi.jp\0" -"dnepropetrovsk.ua\0yalta.ua\0" -"nome.pt\0" -"loginto.me\0" -"co.gg\0" -"co.gl\0global\0" -"emrappui-prod.ap-northeast-2.amazonaws.com\0s3-website.ap-southeast-4.amazonaws.com\0" -"garden\0" -"jot\0myspreadshop.it\0" -"save\0" -"\xe7\xbd\x91\xe5\xba\x97\0" -"co.gy\0joy\0" -"\xe5\x85\xac\xe7\x9b\x8a\0" -"uppo.gov.pl\0" -"fr\xc3\xa6na.no\0fr\xc3\xb8ya.no\0malvik.no\0overhalla.no\0seljord.no\0stj\xc3\xb8rdal.no\0tromso.no\0" -"asahikawa.hokkaido.jp\0nishiokoppe.hokkaido.jp\0tsuchiura.ibaraki.jp\0nogi.tochigi.jp\0pya.jp\0" -"rehab\0" -"flights\0" -"co.id\0kred\0" -"co.hu\0parti.se\0" -"\xe5\x95\x86\xe5\xba\x97\0" -"tkmaxx\0square7.ch\0" -"co.il\0" -"co.im\0auth.ap-northeast-2.amazoncognito.com\0auth.eu-west-3.amazoncognito.com\0s3.dualstack.ap-south-1.amazonaws.com\0s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com\0is-a-nascarfan.com\0" -"bj.cn\0co.in\0" -"co.ir\0" -"k12.va.us\0" -"co.it\0" -"co.je\0jambyl.su\0" -"archi\0" -"idv.hk\0" -"danang.vn\0" -"accident-investigation.aero\0l\xc3\xb8""dingen.no\0nore-og-uvdal.no\0saxo\0for-our.info\0" -"co.jp\0daisen.akita.jp\0hongo.hiroshima.jp\0susaki.kochi.jp\0oseto.nagasaki.jp\0yao.osaka.jp\0haga.tochigi.jp\0shingu.wakayama.jp\0frenchkiss.jp\0" -"bc.ca\0" +"noshiro.akita.jp\0" +"k12.dc.us\0rs.ba\0" "fbxos.fr\0" -"merckmsd\0" -"co.ke\0" -"ed.pw\0blog\0" -"emrappui-prod.us-west-2.amazonaws.com\0s3.ap-east-1.amazonaws.com\0from-de.com\0" -"us.in\0" -"*.moonscale.io\0" -"co.kr\0" -"co.lc\0k12.ut.us\0" -"carboniaiglesias.it\0ch.it\0vc.it\0gb.net\0" -"oum.gov.pl\0gdansk.pl\0" -"sld.do\0sand\xc3\xb8y.no\0tolga.no\0" -"akita.akita.jp\0sodegaura.chiba.jp\0wakasa.fukui.jp\0gujo.gifu.jp\0mizunami.gifu.jp\0esashi.hokkaido.jp\0minamata.kumamoto.jp\0saitama.saitama.jp\0netlify.app\0" -"co.ma\0" -"fnd.br\0se.gov.br\0" -"co.ls\0diamonds\0" -"co.me\0" -"co.mg\0us.kg\0" -"mod.gi\0" -"*.sch.uk\0temasek\0" -"execute-api.eu-north-1.amazonaws.com\0vfs.cloud9.sa-east-1.amazonaws.com\0" -"ca.in\0" -"pantheonsite.io\0" -"stcgroup\0" -"school.na\0co.na\0" -"imdb\0theater\0" -"wv.us\0plus\0notebook.us-gov-west-1.sagemaker.aws\0" -"lucania.it\0ca.it\0adobeio-static.net\0" -"co.mu\0" -"co.mw\0marketing\0eu.org\0" -"kfh\0" -"co.ni\0" -"co.mz\0" -"co.nl\0" -"co.no\0" -"\xe5\xa4\xa7\xe9\x98\xaa.jp\0*.sapporo.jp\0chita.aichi.jp\0imizu.toyama.jp\0" -"arq.br\0" -"co.nz\0school.nz\0" -"co.om\0emrappui-prod.us-east-1.amazonaws.com\0servebbs.com\0hostedpi.com\0" -"s3-accesspoint.cn-north-1.amazonaws.com.cn\0" -"video\0" -"us.na\0" -"k12.tn.us\0" -"urbinopesaro.it\0""16-b.it\0user.srcf.net\0storage.yandexcloud.net\0" -"co.pl\0" -"storj.farm\0" -"co.pn\0" -"f\xc3\xb8rde.no\0kraanghke.no\0" -"okinawa.jp\0ikeda.fukui.jp\0shimonita.gunma.jp\0gokase.miyazaki.jp\0" -"amica\0kia\0\xd1\x80\xd1\x83\xd1\x81\0" -"manaus.br\0" -"org.ac\0" -"org.ae\0blue\0myspreadshop.se\0" -"org.af\0" -"org.ag\0co.pw\0" -"org.ai\0" -"org.al\0" -"org.am\0kim\0execute-api.ap-east-1.amazonaws.com\0*.ap-northeast-1.airflow.amazonaws.com\0s3.eu-south-1.amazonaws.com\0from-nj.com\0*.stg-builder.code.com\0" -"id.firewalledreplit.co\0" -"org.ba\0ca.na\0" -"org.ar\0org.bb\0" -"cc.fl.us\0enterprises\0" -"livorno.it\0reggio-emilia.it\0tn.it\0static-access.net\0" -"org.au\0tas.edu.au\0dyn-vpn.de\0" -"pimienta.org\0q-a.eu.org\0cable-modem.org\0" -"org.bh\0" -"org.bi\0" -"org.az\0org.bj\0" -"sa.gov.pl\0bieszczady.pl\0wroclaw.pl\0zarow.pl\0" -"org.bm\0" -"org.bn\0" -"org.bo\0j\xc3\xb8lster.no\0co.ro\0" -"omigawa.chiba.jp\0sasaguri.fukuoka.jp\0ina.ibaraki.jp\0toride.ibaraki.jp\0omi.niigata.jp\0shonai.yamagata.jp\0whitesnow.jp\0" -"cv.ua\0" -"org.br\0experts-comptables.fr\0" -"org.bs\0co.rs\0" -"org.bt\0adult.ht\0aero.tt\0" -"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0" -"org.bw\0co.rw\0" -"org.ci\0safety\0" -"org.bz\0" -"s3-website.us-east-1.amazonaws.com\0s3-accesspoint-fips.us-west-1.amazonaws.com\0from-ky.com\0reservd.com\0" -"org.cn\0" -"org.co\0*.on-rio.io\0" -"engineer\0sener\0" -"wa.us\0" -"al.it\0verbania.it\0co.st\0" -"org.cu\0" -"org.cv\0aero.mv\0" -"org.cw\0" -"co.th\0" -"org.cy\0ferrari\0" -"co.sz\0co.tj\0" -"atm.pl\0" -"org.dm\0co.tm\0" -"org.do\0m\xc3\xa1tta-v\xc3\xa1rjjat.no\0" -"konan.aichi.jp\0tako.chiba.jp\0kunimi.fukushima.jp\0nakagyo.kyoto.jp\0wakuya.miyagi.jp\0iijima.nagano.jp\0niimi.okayama.jp\0oops.jp\0""2-d.jp\0" -"uz.ua\0co.ua\0" -"org.ec\0loans\0" -"co.tt\0" -"org.ee\0" -"org.eg\0co.ug\0" -"org.dz\0co.tz\0" -"co.uk\0police.uk\0" -"museum\0*.us-east-2.airflow.amazonaws.com\0s3-accesspoint.eu-west-3.amazonaws.com\0canva-apps.com\0" -"sa.ngrok.io\0" -"org.es\0co.us\0cc.wy.us\0ch.tc\0" -"org.et\0trentinsud-tirol.it\0cremona.it\0forl\xc3\xac-cesena.it\0sp.it\0venezia.it\0noho.st\0" -"co.ve\0" -"*.webhare.dev\0" -"co.vi\0" -"org.fj\0co.uz\0" -"\xe3\x82\xbb\xe3\x83\xbc\xe3\x83\xab\0" -"swidnica.pl\0" -"org.fm\0" -"author.aero\0austrheim.no\0finn\xc3\xb8y.no\0" -"kyoto.jp\0shiwa.iwate.jp\0kisosaki.mie.jp\0tome.miyagi.jp\0notogawa.shiga.jp\0fujikawa.shizuoka.jp\0storipress.app\0" -"org.ge\0tozsde.hu\0" -"org.gg\0idv.tw\0" -"org.gh\0" -"org.gi\0" -"org.gl\0" -"s3-accesspoint.ap-south-1.amazonaws.com\0s3-accesspoint-fips.dualstack.us-gov-east-1.amazonaws.com\0s3.us-gov-west-1.amazonaws.com\0dontexist.com\0from-nv.com\0sells-for-less.com\0" -"org.gn\0xihuan\0" -"\xe5\x80\x8b\xe4\xba\xba.\xe9\xa6\x99\xe6\xb8\xaf\0immo\0" -"org.gp\0" -"sld.pa\0" -"org.gr\0" -"americanexpress\0bauhaus\0""123miweb.es\0" -"org.gt\0si.it\0" -"org.gu\0" -"org.gy\0" -"org.hk\0" -"suwalki.pl\0" -"org.hn\0quangnam.vn\0kpn\0" -"egersund.no\0al.no\0" -"kahoku.ishikawa.jp\0niyodogawa.kochi.jp\0taku.saga.jp\0bona.jp\0" -"det.br\0\xe0\xb9\x80\xe0\xb8\x99\xe0\xb9\x87\xe0\xb8\x95.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"org.ht\0" -"org.hu\0" -"\xe5\x95\x86\xe6\xa5\xad.tw\0" -"org.il\0" -"org.im\0platter-app.com\0" -"org.in\0" -"2038.io\0" -"hoplix.shop\0" -"org.iq\0co.za\0" -"org.ir\0" -"org.is\0ca.us\0" -"bas.it\0trentinsuedtirol.it\0valled-aosta.it\0krd\0lat\0myfritz.net\0krellian.net\0" -"act.edu.au\0org.je\0ezproxy.kuleuven.be\0" -"t.bg\0law\0is-a-chef.org\0collegefan.org\0" -"hra.health\0" -"co.zm\0" -"club.aero\0org.jo\0gs.vf.no\0averoy.no\0lund.no\0valer.hedmark.no\0" -"saitama.jp\0iiyama.nagano.jp\0ikeda.nagano.jp\0kumejima.okinawa.jp\0misasa.tottori.jp\0" -"bsb.br\0maringa.br\0" -"whm.fr-par.scw.cloud\0" -"org.kg\0co.zw\0" -"org.ki\0" -"org.km\0s3-ap-northeast-2.amazonaws.com\0s3-accesspoint.dualstack.us-west-2.amazonaws.com\0" -"org.kn\0" -"org.kp\0" -"org.la\0" -"org.lb\0" -"org.lc\0az.us\0cc.vt.us\0myspreadshop.es\0" -"m.bg\0org.kw\0hamburg\0" -"org.ky\0myspreadshop.fi\0" -"pro.az\0org.kz\0" -"org.lk\0" -"bialystok.pl\0olkusz.pl\0" -"angiang.vn\0" -"asnes.no\0aurskog-h\xc3\xb8land.no\0hasvik.no\0rennesoy.no\0groks-the.info\0" -"tsuruga.fukui.jp\0hakodate.hokkaido.jp\0kizu.kyoto.jp\0himeshima.oita.jp\0kounosu.saitama.jp\0nishiizu.shizuoka.jp\0shimoda.shizuoka.jp\0" -"org.ma\0\xd1\x81\xd1\x80\xd0\xb1\0" -"def.br\0pro.br\0cci.fr\0org.lr\0myspreadshop.fr\0" -"org.ls\0lds\0" -"k8s.pl-waw.scw.cloud\0" -"org.me\0finance\0" -"org.lv\0" -"org.mg\0" -"org.ly\0" -"org.mk\0" -"org.ml\0" -"emrappui-prod.eu-south-1.amazonaws.com\0emrnotebooks-prod.us-east-2.amazonaws.com\0serveexchange.com\0scrysec.com\0" -"org.mn\0" -"org.mo\0" -"org.na\0" -"org.ms\0as.us\0tn.us\0" -"trentinostirol.it\0piacenza.it\0org.mt\0" -"tas.gov.au\0org.mu\0in-vpn.de\0" -"org.mv\0" -"f.bg\0org.mw\0org.ng\0tr.eu.org\0my-firewall.org\0" -"org.mx\0cat.ax\0" -"pro.cy\0org.my\0org.ni\0" -"org.mz\0" -"realestate.pl\0wiw.gov.pl\0" -"bokn.no\0even\xc3\xa1\xc5\xa1\xc5\xa1i.no\0gjesdal.no\0" -"kamisu.ibaraki.jp\0tokai.ibaraki.jp\0torahime.shiga.jp\0" -"rec.br\0org.nr\0" -"pro.ec\0" -"myspreadshop.ie\0" -"org.nz\0" -"org.om\0emrstudio-prod.ap-northeast-3.amazonaws.com\0s3.dualstack.af-south-1.amazonaws.com\0webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com\0is-a-chef.com\0is-a-financialadvisor.com\0" -"guardian\0" -"rec.co\0" -"org.pa\0" -"al.us\0lib.co.us\0" -"sic.it\0campobasso.it\0saotome.st\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0atl.jelastic.vps-host.net\0myspreadshop.at\0" -"org.pe\0armenia.su\0termez.su\0myspreadshop.be\0" -"org.pf\0" -"org.ph\0" -"pro.fj\0" -"org.pk\0" -"org.pl\0" -"org.pn\0" -"logistics.aero\0info\0birkenes.no\0lardal.no\0" -"asakawa.fukushima.jp\0izumi.kagoshima.jp\0matsubara.osaka.jp\0miyoshi.saitama.jp\0soka.saitama.jp\0tsuga.tochigi.jp\0yamanashi.yamanashi.jp\0" -"org.qa\0myspreadshop.ca\0" -"org.pr\0" -"org.ps\0csx.cc\0" -"org.pt\0" -"myspreadshop.ch\0" -"org.py\0fin.ci\0" -"s3-me-south-1.amazonaws.com\0vipsinaapp.com\0" -"*.elb.amazonaws.com.cn\0" -"nico\0" -"lib.ct.us\0" -"pv.it\0rieti.it\0direct\0scot\0dattolocal.net\0senseering.net\0" -"theatre\0myspreadshop.de\0" -"tuxfamily.org\0" -"myspreadshop.dk\0" -"piw.gov.pl\0starachowice.pl\0" -"algard.no\0fla.no\0hemne.no\0porsanger.no\0vega.no\0org.ro\0" -"takata.fukuoka.jp\0kanra.gunma.jp\0nanao.ishikawa.jp\0misato.saitama.jp\0nerima.tokyo.jp\0" -"org.sa\0pub.sa\0" -"org.sb\0" -"fin.ec\0org.rs\0org.sc\0" -"pro.ht\0org.sd\0functions.fnc.fr-par.scw.cloud\0" -"org.se\0filegear-gb.me\0org.ru\0" -"org.rw\0org.sg\0" -"org.sh\0" -"homeoffice.gov.uk\0" -"org.sl\0" -"pgfog.com\0" -"pro.in\0org.sn\0" -"org.so\0" -"org.ss\0cc.tx.us\0llc\0studio.ap-east-1.sagemaker.aws\0" -"po.it\0org.st\0""4.azurestaticapps.net\0" -"dyndns.ddnss.de\0ivanovo.su\0" -"org.sv\0fly.dev\0" -"org.sy\0\xe9\xa6\x99\xe6\xa0\xbc\xe9\x87\x8c\xe6\x8b\x89\0" -"org.sz\0org.tj\0" -"ustka.pl\0" -"org.tm\0\xd7\xa7\xd7\x95\xd7\x9d\0" -"org.tn\0" -"gs.ah.no\0hornindal.no\0loppa.no\0org.to\0" -"fukushima.jp\0iwate.jp\0yachiyo.chiba.jp\0rishirifuji.hokkaido.jp\0ashiya.hyogo.jp\0kitakami.iwate.jp\0iida.nagano.jp\0kawai.nara.jp\0neyagawa.osaka.jp\0kazo.saitama.jp\0higashiizu.shizuoka.jp\0llp\0" -"ns.ca\0org.ua\0sb.ua\0" -"org.tr\0" -"org.tt\0" -"*.vps.myjino.ru\0ybo.science\0" -"org.tw\0org.ug\0" -"org.uk\0" -"sa-east-1.elasticbeanstalk.com\0*.oci.customer-oci.com\0is-a-doctor.com\0" -"crown\0" -"actor\0" -"lib.vi.us\0org.vc\0\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0notebook-fips.us-gov-east-1.sagemaker.aws\0" -"in-the-band.net\0" -"org.ve\0in-berlin.de\0" -"ae.org\0is-saved.org\0" -"org.uy\0org.vi\0" -"org.uz\0" -"org.vn\0" -"gs.aa.no\0iveland.no\0\xc3\xb8rsta.no\0" -"toyokawa.aichi.jp\0rebun.hokkaido.jp\0hirono.iwate.jp\0kuwana.mie.jp\0shima.mie.jp\0kushima.miyazaki.jp\0otsu.shiga.jp\0tokushima.tokushima.jp\0akiruno.tokyo.jp\0nakayama.yamagata.jp\0ichikawamisato.yamanashi.jp\0greater.jp\0" -"nl.ca\0" -"ce.leg.br\0" -"gift\0" -"org.vu\0" -"\xe5\x85\xab\xe5\x8d\xa6\0" -"nl.ci\0" -"lol\0" -"s3-website.eu-south-2.amazonaws.com\0s3-fips.us-east-2.amazonaws.com\0analytics-gateway.ap-southeast-1.amazonaws.com\0is-an-entertainer.com\0" -"pro.na\0" -"k12.or.us\0lib.tn.us\0org.ws\0" -"cam.it\0pa.it\0" -"pro.mv\0" -"resto.bj\0" -"lpl\0" -"navigation.aero\0svalbard.no\0gs.svalbard.no\0lerdal.no\0" -"kota.aichi.jp\0shizuoka.shizuoka.jp\0yamada.toyama.jp\0rsvp\0capoo.jp\0" -"co.events\0" -"limited\0" -"2000.hu\0lanbib.se\0org.ye\0nike\0translated.page\0" -"conn.uk\0" -"pro.om\0s3-eu-central-1.amazonaws.com\0*.digitaloceanspaces.com\0ocelot.mythic-beasts.com\0" -"man\0" -"map\0" -"org.za\0mba\0" -"ancona.it\0privatizehealthinsurance.net\0org.yt\0" -"vladimir.su\0" -"rec.nf\0" -"for-better.biz\0" -"org.zm\0" -"bearalvahki.no\0laakesvuemie.no\0bar.pro\0" -"kamikawa.hyogo.jp\0kouyama.kagoshima.jp\0minamiashigara.kanagawa.jp\0chijiwa.nagasaki.jp\0tsunan.niigata.jp\0sumida.tokyo.jp\0fujikawa.yamanashi.jp\0blush.jp\0" -"ba.gov.br\0pro.pr\0" -"t.se\0reise\0iopsys.se\0" -"org.zw\0kaas.gg\0" -"raffleentry.org.uk\0" -"execute-api.us-east-1.amazonaws.com\0s3-object-lambda.ap-south-2.amazonaws.com\0impertrixcdn.com\0" -"s3-object-lambda.cn-north-1.amazonaws.com.cn\0" -"hasura-app.io\0" -"friulivgiulia.it\0trentinosuedtirol.it\0ltd\0" -"vic.gov.au\0hisamitsu\0" -"5.bg\0" -"tr\xc3\xa6na.no\0vefsn.no\0" -"oumu.hokkaido.jp\0sobetsu.hokkaido.jp\0isen.kagoshima.jp\0satsumasendai.kagoshima.jp\0kagamino.okayama.jp\0otaki.saitama.jp\0koto.shiga.jp\0tochigi.tochigi.jp\0" -"ui.nabu.casa\0" -"med\0" -"m.se\0vladimir.ru\0lk3.ru\0" -"emrappui-prod.af-south-1.amazonaws.com\0s3-object-lambda.ap-southeast-4.amazonaws.com\0iamallama.com\0is-a-geek.com\0homesecuritypc.com\0" -"men\0" -"weather\0" -"k12.ok.us\0" -"dynv6.net\0" -"cleaning\0duckdns.org\0" -"architectes.bj\0" -"kontum.vn\0" -"r\xc3\xb8yken.no\0skaun.no\0rec.ro\0" -"tahara.aichi.jp\0yatomi.aichi.jp\0karumai.iwate.jp\0takahashi.okayama.jp\0minoh.osaka.jp\0bookonline.app\0" -"ox.rs\0" -"pro.tt\0" -"f.se\0" -"j.layershift.co.uk\0" -"from-wv.com\0" -"app.banzaicloud.io\0" -"k12.mn.us\0nexus\0loginline.services\0" -"laspezia.it\0" -"karelia.su\0my-vigor.de\0" -"uk.eu.org\0" -"pohl\0" -"pro.vn\0" -"skedsmokorset.no\0berg.no\0roros.no\0s\xc3\xb8ndre-land.no\0deatnu.no\0vads\xc3\xb8.no\0" -"ne.jp\0oto.fukuoka.jp\0horokanai.hokkaido.jp\0higashiyoshino.nara.jp\0iruma.saitama.jp\0topaz.ne.jp\0" -"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x81\xd1\x80\xd0\xb1\0" -"goiania.br\0" -"sch.ae\0ne.ke\0" -"\xe5\x85\xac\xe5\x8f\xb8\0" -"mil\0" -"dyndns-remote.com\0" -"leadpages.co\0" -"bofa\0" -"ne.kr\0" -"k12.nm.us\0lib.al.us\0lib.sc.us\0" -"valleaosta.it\0mn.it\0pistoia.it\0mit\0debian.net\0thruhere.net\0" -"rec.ve\0" -"fin.tn\0haiduong.vn\0" -"nl.no\0bo.nordland.no\0gjerstad.no\0n\xc3\xa5\xc3\xa5mesjevuemie.no\0r\xc3\xb8yrvik.no\0skjervoy.no\0s\xc3\xb8rfold.no\0gallo\0" -"lviv.ua\0" -"am.gov.br\0" -"uk.oxa.cloud\0" -"schwarz\0" -"lundbeck\0" -"s3.ap-southeast-1.amazonaws.com\0cf-ipfs.com\0from-md.com\0gotdns.com\0is-a-personaltrainer.com\0ddnsgeek.com\0" -"instantcloud.cn\0" -"mlb\0" -"pa.us\0" -"homedepot\0seat\0serveftp.net\0" -"shell\0cistron.nl\0" -"caa.aero\0journalist.aero\0gs.jan-mayen.no\0gjerdrum.no\0" -"toei.aichi.jp\0happou.akita.jp\0hanamigawa.chiba.jp\0taiki.hokkaido.jp\0nishinomiya.hyogo.jp\0ofunato.iwate.jp\0asahi.nagano.jp\0ina.nagano.jp\0itoman.okinawa.jp\0taishi.osaka.jp\0" -"mma\0" -"mls\0" -"eu.encoway.cloud\0kuleuven.cloud\0" -"elementor.cool\0" -"mytabit.com\0" -"promo\0" -"musica.ar\0" -"notebook.ap-northeast-2.sagemaker.aws\0" -"toscana.it\0edgesuite.net\0is-a-chef.net\0syncloud.it\0" -"barsy.online\0" -"bielawa.pl\0" -"musica.bo\0\xc3\xb8stre-toten.no\0ringerike.no\0sandnes.no\0verran.no\0" -"isa.kagoshima.jp\0ibaraki.osaka.jp\0ogasawara.tokyo.jp\0kawahara.tottori.jp\0mamurogawa.yamagata.jp\0narusawa.yamanashi.jp\0" -"imb.br\0" -"erotika.hu\0moe\0ravendb.me\0" -"ne.pw\0" -"moi\0" -"\xe6\x97\xb6\xe5\xb0\x9a\0" -"seek\0" -"ltd.co.im\0mom\0" -"nic.in\0s3.cn-northwest-1.amazonaws.com.cn\0" -"\xd1\x83\xd0\xba\xd1\x80\0" -"cc.pr.us\0cog.mi.us\0" -"sth.ac.at\0li.it\0macerata.it\0traniandriabarletta.it\0akamaiedge-staging.net\0" -"nsw.edu.au\0" -"mov\0" -"is-a-geek.org\0" -"infiniti\0" -"work\0" -"davvenj\xc3\xa1rga.no\0s\xc3\xb8mna.no\0vanylven.no\0forumz.info\0" -"gunma.jp\0kagawa.jp\0isshiki.aichi.jp\0misato.akita.jp\0chikugo.fukuoka.jp\0fukagawa.hokkaido.jp\0manno.kagawa.jp\0bungotakada.oita.jp\0karatsu.saga.jp\0fujimi.saitama.jp\0iwakuni.yamaguchi.jp\0" -"cnt.br\0ap.gov.br\0nab\0" -"sch.id\0" -"extraspace\0" -"s3.eu-west-1.amazonaws.com\0" -"bluebite.io\0g.vbrplsbx.io\0" -"now-dns.top\0" -"school.za\0nba\0" -"sch.ir\0" -"k12.ky.us\0" -"kr.it\0tempioolbia.it\0bond\0" -"allstate\0trade\0synology-ds.de\0" -"paris.eu.org\0" -"localzone.xyz\0" -"tlon.network\0" -"ap.gov.pl\0" -"bayern\0porn\0" -"sch.jo\0gs.of.no\0donna.no\0smola.no\0" -"saijo.ehime.jp\0miyawaka.fukuoka.jp\0minamiyamashiro.kyoto.jp\0ohira.tochigi.jp\0taito.tokyo.jp\0raindrop.jp\0" -"etc.br\0ruhr\0go.leg.br\0" -"msd\0" -"horse\0" -"ne.ug\0" -"ne.tz\0" -"book\0" -"s3-object-lambda.af-south-1.amazonaws.com\0vfs.cloud9.ap-northeast-3.amazonaws.com\0jcloud-ver-jpc.ik-server.com\0wafflecell.com\0" -"lego\0sandcats.io\0" -"ne.us\0paroch.k12.ma.us\0games\0locus\0studio.ap-southeast-1.sagemaker.aws\0" -"post\0cloudaccess.net\0buyshouses.net\0cloudfunctions.net\0" -"g\xc3\xbcnstigliefern.de\0in-dsl.de\0" -"sch.lk\0" -"mtn\0" -"askim.no\0bamble.no\0gaivuotna.no\0randaberg.no\0" -"niigata.jp\0kamikawa.hokkaido.jp\0fukuroi.shizuoka.jp\0kokubunji.tokyo.jp\0" -"\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0mtr\0" -"nec\0" -"club.tw\0" -"sch.ly\0" -"emrstudio-prod.ap-southeast-2.amazonaws.com\0s3.dualstack.ap-east-1.amazonaws.com\0s3-accesspoint.eu-central-2.amazonaws.com\0s3-fips.us-gov-west-1.amazonaws.com\0fldrv.com\0" -"ing.pa\0stada\0" -"rocher\0" -"mn.us\0studio.us-east-1.sagemaker.aws\0" -"milano.it\0net\0" -"sch.ng\0new\0" -"kmpsp.gov.pl\0zgorzelec.pl\0nfl\0" -"daknong.vn\0" -"amli.no\0trysil.no\0vestre-toten.no\0here-for-more.info\0" -"\xe7\xa6\x8f\xe4\xba\x95.jp\0asuke.aichi.jp\0koga.fukuoka.jp\0shikaoi.hokkaido.jp\0" -"lutsk.ua\0" -"us.platform.sh\0" -"s3-object-lambda.ap-southeast-3.amazonaws.com\0us-west-1.elasticbeanstalk.com\0" -"ngo\0" -"cc.nv.us\0lib.or.us\0notebook.sa-east-1.sagemaker.aws\0" -"rar.ve\0" -"nhk\0" -"przeworsk.pl\0" -"dongthap.vn\0" -"date.fukushima.jp\0koga.ibaraki.jp\0hioki.kagoshima.jp\0shibata.miyagi.jp\0kawakami.nara.jp\0maibara.shiga.jp\0" -"sch.qa\0" -"agr.br\0" -"geek.nz\0" -"geekgalaxy.com\0" -"arts.co\0" -"weber\0" -"nic.tj\0" -"narvik.no\0zero\0" -"numata.gunma.jp\0kamigori.hyogo.jp\0miyako.iwate.jp\0uchinomi.kagawa.jp\0kamo.kyoto.jp\0yorii.saitama.jp\0kaminoyama.yamagata.jp\0" -"sch.sa\0" -"prvcy.page\0" -"nhs.uk\0" -"auth.il-central-1.amazoncognito.com\0s3.dualstack.ap-northeast-2.amazonaws.com\0webview-assets.aws-cloud9.us-east-1.amazonaws.com\0from-ri.com\0reserve-online.com\0" -"gz.cn\0delhi.in\0io.in\0" -"sch.so\0cust.prod.thingdust.io\0" -"sch.ss\0ky.us\0cc.nh.us\0" -"fvg.it\0trentinoaadige.it\0" -"sch.tf\0" -"poivron.org\0accesscam.org\0" -"ubank\0" -"wodzislaw.pl\0" -"gialai.vn\0" -"arte.bo\0halsa.no\0" -"mihama.fukui.jp\0furubira.hokkaido.jp\0nishiwaki.hyogo.jp\0nabari.mie.jp\0saga.saga.jp\0matsue.shimane.jp\0atami.shizuoka.jp\0koge.tottori.jp\0gonna.jp\0sblo.jp\0" -"kr.ua\0\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x80\xd1\x83\xd1\x81\0" -"bio.br\0macapa.br\0" -"brand.se\0" -"io.kg\0" -"gs.cn\0" -"tokyo\0" -"lib.ny.us\0leclerc\0" -"naples.it\0" -"pages.it.hs-heilbronn.de\0" -"consultant.aero\0selje.no\0skierva.no\0veg\xc3\xa5rshei.no\0" -"higashiura.aichi.jp\0oirase.aomori.jp\0owani.aomori.jp\0kyonan.chiba.jp\0kagamiishi.fukushima.jp\0shirakawa.fukushima.jp\0otoineppu.hokkaido.jp\0nishiazai.shiga.jp\0suginami.tokyo.jp\0\xd0\xbc\xd0\xbe\xd1\x81\xd0\xba\xd0\xb2\xd0\xb0\0run.app\0" -"fst.br\0salvador.br\0tel.tr\0" -"sch.wf\0" -"dvag\0" -"s3-website.af-south-1.amazonaws.com\0s3-website.ap-southeast-1.amazonaws.com\0ddnsfree.com\0" -"nic.za\0" -"lib.mn.us\0" -"bozen.it\0myeffect.net\0" -"capitalone\0kaluga.su\0" -"now\0" -"bharti\0j.scaleforce.com.cy\0" -"netbank\0" -"etne.no\0davvenjarga.no\0" -"!city.yokohama.jp\0mizumaki.fukuoka.jp\0yoshioka.gunma.jp\0iwanai.hokkaido.jp\0kikonai.hokkaido.jp\0nobeoka.miyazaki.jp\0kikugawa.shizuoka.jp\0" -"organic\0" -"s3-accesspoint.us-east-2.amazonaws.com\0discordsays.com\0from-fl.com\0" -"nra\0" -"lancaster\0" -"dynu.net\0" -"xy.ax\0" -"obi\0" -"oia.gov.pl\0" -"sch.zm\0" -"galsa.no\0" -"kushiro.hokkaido.jp\0togitsu.nagasaki.jp\0hayashima.okayama.jp\0okegawa.saitama.jp\0mitaka.tokyo.jp\0takahata.yamagata.jp\0" -"nrw\0" -"sexy\0" -"auth.ap-northeast-1.amazoncognito.com\0s3-fips.us-west-1.amazonaws.com\0from-mt.com\0from-nd.com\0" -"fh-muenster.io\0spacekit.io\0" -"mar.it\0" -"arts.ve\0" -"potager.org\0" -"kiengiang.vn\0" -"bahccavuotna.no\0hagebostad.no\0l\xc3\xb8renskog.no\0muosat.no\0s\xc3\xb8r-aurdal.no\0" -"\xe5\x85\xb5\xe5\xba\xab.jp\0bifuka.hokkaido.jp\0toga.toyama.jp\0" -"management\0ntt\0" -"place\0" -"s3-accesspoint.ca-central-1.amazonaws.com\0dyndns-ip.com\0is-a-teacher.com\0simplesite.com\0" -"maison\0" -"lib.me.us\0" -"\xeb\x8b\xb7\xec\xbb\xb4\0fastvps.host\0cloud.jelastic.open.tim.it\0""5.azurestaticapps.net\0" -"navoi.su\0my-wan.de\0" -"fedorapeople.org\0" -"hanam.vn\0" -"b\xc3\xb8mlo.no\0oppegard.no\0skjak.no\0" -"ama.aichi.jp\0ichinohe.iwate.jp\0minowa.nagano.jp\0musashino.tokyo.jp\0" -"asso.fr\0" -"vacations\0" -"smart\0" -"execute-api.me-central-1.amazonaws.com\0emrappui-prod.me-central-1.amazonaws.com\0s3.us-gov-east-1.amazonaws.com\0likes-pie.com\0eu.meteorapp.com\0*.paywhirl.com\0" -"emrstudio-prod.cn-northwest-1.amazonaws.com.cn\0" -"carrd.co\0" -"asso.gp\0" -"ge.it\0" -"netflix\0" -"polkowice.pl\0" -"io.vn\0" -"aircraft.aero\0hemsedal.no\0orland.no\0arts.ro\0" -"ono.fukui.jp\0ishigaki.okinawa.jp\0aizumi.tokushima.jp\0\xe3\x82\xb3\xe3\x83\xa0\0" -"freebox-os.fr\0" -"nyc\0" -"asso.ht\0k8s.fr-par.scw.cloud\0" -"uber.space\0" -"\xd0\xba\xd0\xb0\xd1\x82\xd0\xbe\xd0\xbb\xd0\xb8\xd0\xba\0" -"affinitylottery.org.uk\0" -"s3-accesspoint.dualstack.ap-southeast-2.amazonaws.com\0theworkpc.com\0herokussl.com\0" -"protection\0s3-website.dualstack.cn-north-1.amazonaws.com.cn\0" -"readthedocs.io\0" -"lacaixa\0redumbrella\0" -"lib.ks.us\0" -"trentinosudtirol.it\0" -"nsw.au\0cafe\0bplaced.de\0" -"hopto.org\0" -"gloppen.no\0leikanger.no\0s\xc3\xb8rum.no\0" -"\xe5\x8d\x83\xe8\x91\x89.jp\0\xe4\xba\xac\xe9\x83\xbd.jp\0\xe5\xb2\xa1\xe5\xb1\xb1.jp\0noboribetsu.hokkaido.jp\0shakotan.hokkaido.jp\0shiroishi.miyagi.jp\0miyota.nagano.jp\0fukudomi.saga.jp\0nyuzen.toyama.jp\0" -"avianca\0" -"huissier-justice.fr\0" -"voorloper.cloud\0" -"naturbruksgymn.se\0" -"asso.ci\0" -"emrappui-prod.me-south-1.amazonaws.com\0za.com\0pleskns.com\0" -"ia.us\0notebook.ap-southeast-4.sagemaker.aws\0" -"calabria.it\0ven.it\0fg.it\0is-a-geek.net\0iliadboxos.it\0" -"arts.nf\0" -"dy.fi\0" -"zp.gov.pl\0" -"oygarden.no\0jur.pro\0ferrero\0" -"umaji.kochi.jp\0tanabe.kyoto.jp\0taiwa.miyagi.jp\0kosai.shizuoka.jp\0tonami.toyama.jp\0s3.isk01.sakurastorage.jp\0" -"\xd1\x81\xd0\xbe\xd1\x87\xd0\xb8.\xd1\x80\xd1\x83\xd1\x81\0" -"\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0" -"scalebook.scw.cloud\0" -"\xe9\xa3\x9e\xe5\x88\xa9\xe6\xb5\xa6\0" -"asso.dz\0soc.dz\0" -"s3-accesspoint.ap-northeast-1.amazonaws.com\0s3-fips.dualstack.us-east-2.amazonaws.com\0servegame.com\0" -"virtualserver.io\0" -"singles\0notebook-fips.us-east-2.sagemaker.aws\0" -"lodi.it\0pictet\0supabase.net\0" -"insure\0one\0" -"ong\0" -"uw.gov.pl\0onl\0" -"trainer.aero\0transporte.bo\0fylkesbibl.no\0nesseby.no\0" -"rokunohe.aomori.jp\0hirata.fukushima.jp\0koshimizu.hokkaido.jp\0suzaka.nagano.jp\0niiza.saitama.jp\0sayama.saitama.jp\0hachioji.tokyo.jp\0arida.wakayama.jp\0deci.jp\0icurus.jp\0pussycat.jp\0" -"lgbt\0" -"helsinki\0" -"royal-commission.uk\0" -"auth.eu-south-1.amazoncognito.com\0s3-accesspoint.ap-south-2.amazonaws.com\0s3-accesspoint-fips.dualstack.us-gov-west-1.amazonaws.com\0" -"ooo\0" -"notebook.me-central-1.sagemaker.aws\0" -"trentinos-tirol.it\0lecco.it\0" -"serveftp.org\0" -"statebank\0" -"katowice.pl\0call\0" -"orangecloud.tn\0" -"gs.hm.no\0langevag.no\0bjarkoy.no\0sk\xc3\xa1nit.no\0vindafjord.no\0" -"chiryu.aichi.jp\0furano.hokkaido.jp\0tarumizu.kagoshima.jp\0yamanouchi.nagano.jp\0kawanishi.nara.jp\0higashichichibu.saitama.jp\0" -"alsace\0na4u.ru\0" -"emrnotebooks-prod.ca-central-1.amazonaws.com\0s3-object-lambda.eu-south-2.amazonaws.com\0" -"dr.in\0calvinklein\0" -"camp\0" -"aosta.it\0futuremailing.at\0" -"software\0lelux.site\0" -"org\0" -"pay\0" -"leczna.pl\0" -"politica.bo\0nordkapp.no\0" -"kawara.fukuoka.jp\0amagasaki.hyogo.jp\0ino.kochi.jp\0hara.nagano.jp\0kusu.oita.jp\0higashiyodogawa.osaka.jp\0kitayama.wakayama.jp\0angry.jp\0" -"ac\0" -"ad\0" -"ae\0" -"af\0\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86\0" -"ag\0" -"ai\0ybo.party\0" -"al\0" -"am\0myasustor.com\0from-wi.com\0servep2p.com\0*.vultrobjects.com\0" -"ao\0" -"aq\0ba\0" -"ar\0bb\0doctor\0" -"as\0cc.id.us\0" -"at\0cesena-forli.it\0vv.it\0schokokeks.net\0" -"au\0be\0myhome-server.de\0" -"bf\0" -"aw\0bg\0" -"ax\0bh\0" -"bi\0" -"az\0bj\0" -"soc.lk\0" -"cieszyn.pl\0" -"bm\0" -"bn\0" -"exchange.aero\0bo\0b\xc3\xa5""d\xc3\xa5""ddj\xc3\xa5.no\0eidfjord.no\0sigdal.no\0" -"biei.hokkaido.jp\0chigasaki.kanagawa.jp\0chiyoda.tokyo.jp\0supersale.jp\0bambina.jp\0" -"ca\0corsica\0" -"br\0" -"bs\0cc\0" -"bt\0cd\0ott\0" -"shacknet.nu\0" -"bv\0cf\0" -"bw\0cg\0panel.gg\0" -"ch\0" -"by\0ci\0" -"bz\0" -"cl\0" -"cm\0s3.dualstack.eu-west-3.amazonaws.com\0from-tx.com\0" -"cn\0volkswagen\0supabase.in\0" -"co\0" -"dr.na\0" -"cr\0" -"k12.dc.us\0studio.me-south-1.sagemaker.aws\0" -"ct.it\0lucca.it\0pet\0memset.net\0ts.net\0" -"cu\0de\0care\0" -"cv\0" -"cw\0is-a-celticsfan.org\0" -"cx\0ovh\0" -"cy\0" -"cz\0dj\0usr.cloud.muni.cz\0" -"dk\0" -"dm\0" -"quangtri.vn\0" -"do\0dyr\xc3\xb8y.no\0aaa.pro\0" -"miyagi.jp\0munakata.fukuoka.jp\0kawamata.fukushima.jp\0yokawa.hyogo.jp\0okawa.kochi.jp\0matsumoto.nagano.jp\0" -"casa\0" -"contagem.br\0" -"ec\0cars\0" -"publ.pt\0" -"ee\0case\0" -"eg\0" -"cash\0" -"dz\0" -"webview-assets.cloud9.eu-central-1.amazonaws.com\0siiites.com\0blogsyte.com\0" -"coupon\0" -"bitbucket.io\0" -"java\0" -"es\0" -"et\0trentino-suedtirol.it\0phd\0jc.neen.it\0" -"eu\0" -"fi\0" -"fj\0" -"fm\0" -"fo\0kr\xc3\xa5""anghke.no\0h\xc3\xa1""bmer.no\0" -"nagasaki.jp\0gamagori.aichi.jp\0futaba.fukushima.jp\0horonobe.hokkaido.jp\0edogawa.tokyo.jp\0namerikawa.toyama.jp\0mikawa.yamagata.jp\0" -"ga\0" -"fr\0gb\0" -"gd\0pid\0" -"ge\0" -"gf\0" -"gg\0" -"gh\0" -"gi\0" -"service.gov.uk\0" -"gl\0" -"gm\0s3-accesspoint.dualstack.af-south-1.amazonaws.com\0from-mn.com\0app.render.com\0" -"gn\0green\0pin\0" -"gp\0" -"gq\0" -"gr\0" -"gs\0studio.ap-northeast-3.sagemaker.aws\0" -"gt\0padua.it\0va.it\0" -"gu\0asso.re\0karaganda.su\0" -"gw\0" -"gmbh\0" -"gy\0" -"hk\0grp.lk\0" -"ketrzyn.pl\0" -"hm\0" -"hn\0" -"tananger.no\0kl\xc3\xa6""bu.no\0" -"kurate.fukuoka.jp\0nakasatsunai.hokkaido.jp\0omiya.saitama.jp\0arai.shizuoka.jp\0shioya.tochigi.jp\0kiyose.tokyo.jp\0mitou.yamaguchi.jp\0floppy.jp\0" -"cloudns.asia\0" -"ce.gov.br\0recife.br\0hr\0" -"gov.ac\0" -"ht\0id\0*.sensiosite.cloud\0" -"ac.ae\0gov.ae\0hu\0ie\0" -"gov.af\0" -"tjmaxx\0" -"mediatech.by\0" -"gov.al\0il\0" -"im\0emrstudio-prod.ap-northeast-2.amazonaws.com\0s3.eu-west-3.amazonaws.com\0ap-southeast-3.elasticbeanstalk.com\0from-sd.com\0" -"in\0durban\0" -"io\0b-data.io\0supabase.co\0" -"gov.ba\0iq\0" -"gov.ar\0gov.bb\0ir\0" -"gov.as\0is\0" -"ac.at\0it\0bo.it\0" -"gov.au\0ac.be\0je\0" -"gov.bf\0" -"shaw\0app.os.stg.fedoraproject.org\0" -"gov.bh\0faith\0" -"gov.az\0" -"rzgw.gov.pl\0sdn.gov.pl\0pomorze.pl\0radom.pl\0" -"gov.bm\0" -"gov.bn\0haugiang.vn\0" -"jo\0her\xc3\xb8y.m\xc3\xb8re-og-romsdal.no\0" -"jp\0ayagawa.kagawa.jp\0hanno.saitama.jp\0yatsuka.shimane.jp\0minami-alps.yamanashi.jp\0halfmoon.jp\0" -"\xd0\xb1\xd0\xb8\xd0\xb7.\xd1\x80\xd1\x83\xd1\x81\0" -"caxias.br\0gov.br\0dr.tr\0" -"gov.bs\0" -"gov.bt\0gov.cd\0" -"ke\0" -"kg\0" -"gov.by\0ac.ci\0ki\0hyundai\0" -"gov.bz\0\xe5\xbe\xae\xe5\x8d\x9a\0" -"gov.cl\0idf.il\0" -"gov.cm\0km\0s3-ap-east-1.amazonaws.com\0is-a-musician.com\0" -"ac.cn\0gov.cn\0sn.cn\0kn\0london\0" -"gov.co\0" -"kp\0" -"e164.arpa\0la\0" -"ac.cr\0kr\0lb\0" -"lc\0asso.nc\0cc.ga.us\0lib.hi.us\0motorcycles\0pnc\0" -"vao.it\0padova.it\0ts.it\0" -"gov.cu\0" -"kw\0" -"gov.cx\0xbox\0" -"ac.cy\0gov.cy\0ky\0li\0academy\0" -"kz\0" -"lk\0" -"grajewo.pl\0podhale.pl\0" -"gov.dm\0" -"bacgiang.vn\0" -"passenger-association.aero\0gov.do\0va.no\0\xc3\xa5s.no\0selbu.no\0" -"ueno.gunma.jp\0tarama.okinawa.jp\0kakinoki.shimane.jp\0schoolbus.jp\0" -"ma\0" -"lr\0" -"gov.ec\0ls\0mc\0" -"lt\0md\0prod\0jele.cloud\0" -"gov.ee\0lu\0me\0" -"lv\0prof\0" -"gov.eg\0mg\0" -"mh\0" -"ly\0charity\0" -"gov.dz\0" -"mk\0" -"ml\0" -"execute-api.ap-northeast-3.amazonaws.com\0is-a-photographer.com\0is-uberleet.com\0kozow.com\0" -"mn\0yamaxun\0" -"mo\0" -"mp\0" -"mq\0na\0" -"mr\0" -"ms\0nc\0k12.ar.us\0" -"gov.et\0aq.it\0ba.it\0mt\0cloudfront.net\0" -"mu\0ne\0" -"mv\0nf\0" -"mw\0ng\0from-me.org\0is-very-bad.org\0ro.eu.org\0" -"mx\0" -"my\0ni\0" -"ac.fj\0gov.fj\0mz\0" -"nl\0" -"democracia.bo\0no\0\xc3\xa5l.no\0ostre-toten.no\0oyer.no\0skiptvet.no\0skanit.no\0" -"oita.jp\0shimogo.fukushima.jp\0otobe.hokkaido.jp\0ayabe.kyoto.jp\0minamiizu.shizuoka.jp\0skr.jp\0" -"nr\0" -"gov.gd\0" -"gov.ge\0nu\0" -"gov.gh\0" -"gov.gi\0taipei\0" -"nz\0" -"om\0auth-fips.us-west-2.amazoncognito.com\0analytics-gateway.ap-southeast-2.amazonaws.com\0webview-assets.cloud9.us-east-2.amazonaws.com\0myspreadshop.com\0" -"ac.gn\0gov.gn\0" -"pa\0" -"gov.gr\0" -"ct.us\0notebook.us-gov-east-1.sagemaker.aws\0" -"te.it\0teramo.it\0serveminecraft.net\0" -"gov.gu\0pe\0" -"pf\0" -"asso.eu.org\0" -"ph\0" -"gov.gy\0" -"gov.hk\0pk\0" -"pl\0um.gov.pl\0rawa-maz.pl\0" -"pm\0" -"pn\0" -"tysnes.no\0pro\0cloudns.pro\0" -"shisui.chiba.jp\0nishi.fukuoka.jp\0maebashi.gunma.jp\0hannan.osaka.jp\0gotemba.shizuoka.jp\0unazuki.toyama.jp\0coolblog.jp\0lovesick.jp\0" -"qa\0shia\0" -"pr\0" -"ps\0" -"ac.id\0pt\0" -"szex.hu\0gov.ie\0house\0pru\0myfast.space\0filegear-de.me\0mcdir.me\0" -"pw\0" -"py\0" -"ac.il\0gov.il\0" -"ac.im\0asso.km\0s3-accesspoint.ap-southeast-3.amazonaws.com\0s3-accesspoint.dualstack.us-gov-east-1.amazonaws.com\0saves-the-whales.com\0health-carereform.com\0" -"ac.in\0gov.in\0" -"wixstudio.io\0" -"gov.iq\0" -"ac.ir\0gov.ir\0" -"gov.is\0rocks\0" -"gov.it\0" -"re\0sellfy.store\0" -"si.eu.org\0" -"nombre.bo\0salud.bo\0gov.jo\0bod\xc3\xb8.no\0bremanger.no\0hyllestad.no\0s\xc3\xa1l\xc3\xa1t.no\0ullensvang.no\0ro\0" -"ac.jp\0kani.gifu.jp\0takamatsu.kagawa.jp\0shichikashuku.miyagi.jp\0kitaura.miyazaki.jp\0moroyama.saitama.jp\0" -"sa\0" -"ribeirao.br\0sb\0pub\0" -"asso.mc\0rs\0sc\0" -"sd\0linkyard.cloud\0" -"ac.ke\0ru\0se\0orange\0ddns.me\0" -"gov.kg\0rw\0sg\0" -"sh\0" -"gov.ki\0si\0" -"sj\0" -"sk\0" -"sl\0" -"gov.km\0sm\0s3-object-lambda.ap-northeast-1.amazonaws.com\0demo.jelastic.com\0firewall-gateway.com\0" -"gov.kn\0sn\0" -"so\0" -"gov.kp\0" -"gov.la\0" -"ac.kr\0gov.lb\0sr\0" -"gov.lc\0ss\0tc\0va.us\0k12.ak.us\0" -"pug.it\0benevento.it\0st\0td\0" -"su\0cbre\0" -"sv\0tf\0" -"y.bg\0gov.kw\0tg\0genting\0" -"sx\0th\0" -"sy\0" -"agro.bj\0gov.kz\0sz\0tj\0" -"gov.lk\0ac.lk\0tk\0" -"us.gov.pl\0tl\0" -"tm\0" -"tn\0" -"agro.bo\0trogstad.no\0to\0" -"ogata.akita.jp\0hiranai.aomori.jp\0ichihara.chiba.jp\0nantan.kyoto.jp\0azumino.nagano.jp\0kinokawa.wakayama.jp\0nishikawa.yamagata.jp\0peewee.jp\0rgr.jp\0" -"gov.ma\0ac.ma\0ua\0" -"gov.lr\0tr\0" -"ac.ls\0gov.ls\0pwc\0" -"gov.lt\0tt\0" -"ac.me\0gov.me\0" -"gov.lv\0tv\0" -"gov.mg\0tw\0ug\0" -"bc.platform.sh\0" -"gov.ly\0" -"tz\0" -"gov.mk\0uk\0independent-review.uk\0" -"gov.ml\0" -"emrstudio-prod.me-south-1.amazonaws.com\0emrappui-prod.us-gov-west-1.amazonaws.com\0s3-us-east-2.amazonaws.com\0webview-assets.cloud9.eu-west-2.amazonaws.com\0googlecode.com\0" -"gov.mn\0hs.run\0" -"gov.mo\0" -"va\0" -"gov.mr\0" -"gov.ms\0us\0cc.wi.us\0vc\0" -"vallee-aoste.it\0" -"gov.mu\0ac.mu\0ve\0homelink.one\0" -"gov.mv\0" -"r.bg\0ac.mw\0gov.mw\0gov.ng\0vg\0sk.eu.org\0" -"gov.my\0ac.ni\0uy\0vi\0" -"ac.mz\0gov.mz\0uz\0" -"psse.gov.pl\0kepno.pl\0tgory.pl\0gov.nl\0" -"vn\0" -"chiba.jp\0obu.aichi.jp\0nikaho.akita.jp\0yamada.fukuoka.jp\0tamaki.mie.jp\0ouda.nara.jp\0yaese.okinawa.jp\0sunnyday.jp\0" -"gov.nr\0" -"guitars\0" -"vu\0" -"wf\0" -"ac.nz\0" -"gov.om\0s3-us-gov-west-1.amazonaws.com\0is-an-actress.com\0dsmynas.com\0" -"foundation\0" -"dyn53.io\0" -"shop\0" -"ac.pa\0" -"ws\0" -"friuli-v-giulia.it\0ri.it\0\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4\0map.fastly.net\0edu.scot\0" -"keymachine.de\0" -"k.bg\0fishing\0show\0game-host.org\0" -"gov.ph\0" -"gov.pk\0" -"gov.pl\0" -"gov.pn\0" -"nesoddtangen.no\0gjovik.no\0snoasa.no\0med.pro\0" -"akabira.hokkaido.jp\0biratori.hokkaido.jp\0kasaoka.okayama.jp\0hatogaya.saitama.jp\0" -"gov.qa\0" -"gov.pr\0ac.pr\0es.leg.br\0" -"gov.ps\0fantasyleague.cc\0" -"gov.pt\0*.rss.my.id\0" -"ye\0" -"linkyard-cloud.ch\0" -"gov.py\0" -"capital\0" -"s3-website.il-central-1.amazonaws.com\0s3-website.dualstack.us-east-1.amazonaws.com\0s3-deprecated.us-east-2.amazonaws.com\0webview-assets.cloud9.ap-southeast-1.amazonaws.com\0" -"gen.mi.us\0" -"roma.it\0yt\0edgekey.net\0" -"wa.gov.au\0eero-stage.online\0" -"d.bg\0ru.eu.org\0se.eu.org\0" -"press.cy\0" -"limanowa.pl\0homesklep.pl\0" -"zm\0stockholm\0" -"brumunddal.no\0mer\xc3\xa5ker.no\0" -"\xe5\xaf\x8c\xe5\xb1\xb1.jp\0gonohe.aomori.jp\0kamisunagawa.hokkaido.jp\0takino.hyogo.jp\0noda.iwate.jp\0kita.kyoto.jp\0miyada.nagano.jp\0nozawaonsen.nagano.jp\0omachi.nagano.jp\0izu.shizuoka.jp\0tachikawa.tokyo.jp\0kainan.wakayama.jp\0" -"gov.sa\0te.ua\0" -"gov.sb\0" -"ac.rs\0gov.rs\0gov.sc\0" -"gov.sd\0" -"ac.se\0ac.ru\0gov.ru\0mcdir.ru\0" -"ac.rw\0gov.rw\0gov.sg\0zw\0" -"gov.sh\0" -"gov.sl\0" -"emrappui-prod.ap-southeast-2.amazonaws.com\0emrnotebooks-prod.us-west-2.amazonaws.com\0s3-accesspoint.dualstack.eu-north-1.amazonaws.com\0" -"gov.so\0rodeo\0jp.ngrok.io\0" -"\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0" -"gov.ss\0cc.ut.us\0lib.vt.us\0" -"homeunix.net\0" -"wanggou\0in-butter.de\0" -"dyndns.org\0is-a-bruinsfan.org\0" -"gov.sx\0ac.th\0" -"gov.sy\0" -"ac.sz\0ac.tj\0gov.tj\0" -"arvo.network\0" -"waw.pl\0gov.tl\0" -"gov.tm\0" -"gov.tn\0" -"giehtavuoatna.no\0sm\xc3\xb8la.no\0gov.to\0" -"kazuno.akita.jp\0tohnosho.chiba.jp\0yamatokoriyama.nara.jp\0nishihara.okinawa.jp\0kita.osaka.jp\0tozawa.yamagata.jp\0saloon.jp\0privatelink.snowflake.app\0" -"gov.ua\0" -"go.gov.br\0gov.tr\0" -"partners\0" -"gov.tt\0" -"tech.orange\0" -"gov.tw\0ac.ug\0" -"ac.tz\0" -"ac.uk\0gov.uk\0" -"s3-accesspoint-fips.dualstack.us-west-2.amazonaws.com\0s3-website.us-west-2.amazonaws.com\0" -"design\0" -"shiksha\0" -"gyeongnam.kr\0grainger\0" -"gov.vc\0studio.ap-southeast-2.sagemaker.aws\0" -"tuscany.it\0valle-aosta.it\0pt.it\0""64-b.it\0" -"gov.ve\0grozny.su\0virtual-user.de\0" -"*.dapps.earth\0" -"baseball\0lidl\0" -"ac.vn\0gov.vn\0laocai.vn\0" -"parachuting.aero\0eid.no\0" -"anjo.aichi.jp\0fujioka.gunma.jp\0natori.miyagi.jp\0nanjo.okinawa.jp\0osakasayama.osaka.jp\0iwafune.tochigi.jp\0hacca.jp\0kill.jp\0nobushi.jp\0" -"tools\0" -"nx.cn\0studio.cn-northwest-1.sagemaker.com.cn\0" -"\xe7\xb6\xb2\xe7\xb5\xa1.\xe9\xa6\x99\xe6\xb8\xaf\0*.sys.qcx.io\0" -"tienda\0" -"gov.ws\0" -"campidanomedio.it\0ravenna.it\0akamaiorigin.net\0azure-mobile.net\0" -"life\0" -"altervista.org\0cloudns.org\0is-very-sweet.org\0" -"assur.bj\0" -"trader.aero\0aurland.no\0masoy.no\0vang.no\0" -"hichiso.gifu.jp\0" -"qsl.br\0" -"fie.ee\0gov.ye\0grozny.ru\0" -"ebiz.tw\0" -"property\0" -"vfs.cloud9.ap-northeast-2.amazonaws.com\0" -"ac.za\0gov.za\0" -"freeddns.us\0pointto.us\0" -"umb.it\0forli-cesena.it\0clickrising.net\0selfip.net\0uni5.net\0" -"itau\0penza.su\0" -"store.nf\0deno-staging.dev\0" -"bmoattachments.org\0" -"prequalifyme.today\0" -"auto.pl\0gmina.pl\0" -"ac.zm\0gov.zm\0" -"heroy.nordland.no\0karasjok.no\0melhus.no\0" -"nango.fukushima.jp\0kijo.miyazaki.jp\0otari.nagano.jp\0o0o0.jp\0" -"zhytomyr.ua\0" -"edu.ac\0" -"red\0" -"edu.af\0" -"ac.zw\0gov.zw\0" -"nh-serv.co.uk\0" -"edu.al\0london.cloudapps.digital\0" -"sakuratan.com\0" -"ren\0" -"\xe6\x94\xbf\xe5\xba\x9c.\xe9\xa6\x99\xe6\xb8\xaf\0radio\0in.ngrok.io\0" -"edu.ba\0" -"edu.ar\0edu.bb\0" -"ri.us\0" -"blackbaudcdn.net\0cdn-edges.net\0" -"edu.au\0qld.edu.au\0onred.one\0bukhara.su\0" -"deno.dev\0iserv.dev\0" -"shopping\0" -"edu.bh\0" -"edu.bi\0" -"edu.az\0edu.bj\0" -"silk\0" -"edu.bm\0" -"edu.bn\0" -"edu.bo\0pueblo.bo\0jorpeland.no\0\xc3\xb8ystre-slidre.no\0sorfold.no\0" -"aibetsu.hokkaido.jp\0muko.kyoto.jp\0nichinan.tottori.jp\0littlestar.jp\0" -"edu.br\0jampa.br\0leg.br\0\xe0\xb8\xa8\xe0\xb8\xb6\xe0\xb8\x81\xe0\xb8\xa9\xe0\xb8\xb2.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"edu.bs\0" -"edu.bt\0trafficplex.cloud\0" -"y.se\0like\0" -"edu.ci\0" -"edu.bz\0" -"s3-accesspoint.dualstack.eu-west-1.amazonaws.com\0s3-fips.dualstack.us-gov-west-1.amazonaws.com\0webview-assets.aws-cloud9.ca-central-1.amazonaws.com\0est-le-patron.com\0" -"edu.cn\0bss.design\0" -"edu.co\0utwente.io\0" -"sina\0" -"lib.ar.us\0mus.mi.us\0notebook.eu-south-2.sagemaker.aws\0" -"trentin-suedtirol.it\0taranto.it\0" -"edu.cu\0georgia.su\0" -"edu.cv\0" -"edu.cw\0cooking\0" -"zgora.pl\0" -"edu.dm\0" -"research.aero\0edu.do\0gs.rl.no\0and\xc3\xb8y.no\0tysv\xc3\xa6r.no\0" -"hiho.jp\0" -"edu.ec\0" -"fnc.fr-par.scw.cloud\0" -"edu.ee\0r.se\0dscloud.me\0" -"edu.eg\0" -"edu.dz\0" -"ril\0" -"auth.us-west-1.amazoncognito.com\0emrstudio-prod.ca-central-1.amazonaws.com\0s3.ap-south-1.amazonaws.com\0cloud.nospamproxy.com\0it.com\0" -"limo\0rio\0" -"rip\0" -"monster\0" -"edu.es\0" -"edu.et\0catania.it\0gorizia.it\0" -"dyn-berlin.de\0schulplattform.de\0" -"3.bg\0" -"money\0" -"link\0" -"lubin.pl\0" -"edu.fm\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa4\xae\xe0\xa5\x8d\0" -"siljan.no\0" -"shizuoka.jp\0\xe5\xb2\xa9\xe6\x89\x8b.jp\0kyowa.akita.jp\0saigawa.fukuoka.jp\0kitashiobara.fukushima.jp\0choyo.kumamoto.jp\0yokkaichi.mie.jp\0kobayashi.miyazaki.jp\0tawaramoto.nara.jp\0shijonawate.osaka.jp\0chizu.tottori.jp\0kai.yamanashi.jp\0" -"edu.gd\0" -"edu.ge\0k.se\0" -"edu.gh\0" -"edu.gi\0" -"pol.dz\0" -"edu.gl\0\xd7\x99\xd7\xa9\xd7\x95\xd7\x91.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0" -"emrstudio-prod.us-gov-west-1.amazonaws.com\0sinaapp.com\0" -"edu.gn\0" -"edu.gp\0" -"edu.gr\0" -"cc.sc.us\0express\0" -"edu.gt\0trentin-sued-tirol.it\0trentinos\xc3\xbc""d-tirol.it\0monzabrianza.it\0trieste.it\0" -"edu.gu\0store.ve\0cloud66.zone\0" -"sellsyourhome.org\0" -"edu.gy\0" -"edu.hk\0" -"agro.pl\0" -"edu.hn\0" -"slattum.no\0\xc3\xa5mot.no\0inderoy.no\0mandal.no\0skien.no\0casino\0" -"aomori.jp\0katagami.akita.jp\0minokamo.gifu.jp\0imakane.hokkaido.jp\0kasuga.hyogo.jp\0omitama.ibaraki.jp\0mochizuki.nagano.jp\0unzen.nagasaki.jp\0itoigawa.niigata.jp\0kurashiki.okayama.jp\0babymilk.jp\0secret.jp\0" -"barsy.club\0" -"edu.ht\0" -"d.se\0" -"gitpage.si\0" -"email\0" -"webview-assets.cloud9.eu-west-3.amazonaws.com\0firebaseapp.com\0" -"ln.cn\0edu.in\0" -"reservd.disrec.thingdust.io\0" -"edu.iq\0" -"seoul.kr\0" -"edu.is\0k12.mt.us\0" -"edu.it\0ms.it\0" -"site\0balashov.su\0" -"mckinsey\0" -"educator.aero\0edu.jo\0vossevangen.no\0aure.no\0eidskog.no\0gildeskal.no\0" -"aioi.hyogo.jp\0itako.ibaraki.jp\0kinko.kagoshima.jp\0yokosuka.kanagawa.jp\0mihama.mie.jp\0toyota.yamaguchi.jp\0kosuge.yamanashi.jp\0boo.jp\0" -"drr.ac\0" -"pol.ht\0" -"press.se\0" -"edu.kg\0" -"edu.ki\0" -"edu.km\0s3.dualstack.eu-west-1.amazonaws.com\0vfs.cloud9.eu-south-1.amazonaws.com\0*.linodeobjects.com\0mazeplay.com\0*.quipelements.com\0" -"edu.kn\0" -"mango\0" -"edu.kp\0" -"edu.la\0" -"ms.kr\0edu.lb\0" -"edu.lc\0lanxess\0" -"edu.kw\0" -"edu.ky\0" -"edu.kz\0" -"edu.lk\0" -"miasta.pl\0sanok.pl\0" -"kvalsund.no\0meraker.no\0molde.no\0snasa.no\0store.ro\0" -"takayama.gunma.jp\0hokuryu.hokkaido.jp\0yokoze.saitama.jp\0itano.tokushima.jp\0girly.jp\0" -"mykolaiv.ua\0" -"edu.lr\0" -"edu.ls\0" -"edu.me\0" -"edu.lv\0" -"edu.mg\0" -"edu.ly\0" -"edu.mk\0" -"edu.ml\0futbol\0" -"s3.dualstack.us-east-1.amazonaws.com\0" -"me.in\0edu.mn\0" -"edu.mo\0" -"sap\0" -"ulsan.kr\0" -"edu.ms\0eaton.mi.us\0airbus\0sas\0" -"lu.it\0me.it\0edu.mt\0store.st\0cloudycluster.net\0" -"live\0" -"edu.mv\0" -"edu.mw\0edu.ng\0ee.eu.org\0" -"edu.mx\0nerdpol.ovh\0" -"edu.my\0edu.ni\0sbi\0" -"edu.mz\0" -"hdfcbank\0" -"media.aero\0b\xc3\xa5tsfjord.no\0hitra.no\0tysvar.no\0" -"bando.ibaraki.jp\0takaharu.miyazaki.jp\0ariake.saga.jp\0" -"sca\0" -"jor.br\0edu.nr\0scb\0" -"sbs\0" -"*.statics.cloud\0" -"me.ke\0" -"edu.om\0emrappui-prod.ap-southeast-3.amazonaws.com\0emrappui-prod.us-gov-east-1.amazonaws.com\0*.ap-northeast-2.airflow.amazonaws.com\0s3.dualstack.il-central-1.amazonaws.com\0s3-website.me-central-1.amazonaws.com\0" -"edu.pa\0" -"gyeonggi.kr\0jeonbuk.kr\0" -"oh.us\0notebook.eu-central-1.sagemaker.aws\0" -"gold\0" -"edu.pe\0" -"edu.pf\0golf\0" -"edu.ph\0" -"edu.pk\0" -"edu.pl\0wegrow.pl\0" -"edu.pn\0" -"jevnaker.no\0sunndal.no\0" -"wakayama.jp\0kamagaya.chiba.jp\0higashi.okinawa.jp\0messerli.app\0" -"press.ma\0edu.qa\0" -"barueri.br\0joinville.br\0tec.br\0edu.pr\0" -"edu.ps\0productions\0" -"edu.pt\0" -"\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0" -"edu.py\0" -"black\0" -"from-ma.com\0serveftp.com\0" -"run\0" -"oristano.it\0" -"e12.ve\0redstone\0myspreadshop.com.au\0" -"sew\0cloud.fedoraproject.org\0" -"sex\0" -"bjark\xc3\xb8y.no\0utsira.no\0" -"lg.jp\0*.kobe.jp\0sukagawa.fukushima.jp\0seranishi.hiroshima.jp\0minamioguni.kumamoto.jp\0nagasu.kumamoto.jp\0kiho.mie.jp\0yomitan.okinawa.jp\0hamatama.saga.jp\0shimonoseki.yamaguchi.jp\0kikirara.jp\0versus.jp\0" -"edu.sa\0nikolaev.ua\0\xd1\x81\xd0\xbf\xd0\xb1.\xd1\x80\xd1\x83\xd1\x81\0" -"edu.sb\0sfr\0" -"edu.rs\0edu.sc\0" -"edu.sd\0" -"rwe\0codeberg.page\0edu.ru\0" -"edu.sg\0goog\0" -"edu.sl\0" -"s3-us-west-2.amazonaws.com\0s3-fips.us-gov-east-1.amazonaws.com\0is-a-blogger.com\0withgoogle.com\0jcloud.ik-server.com\0" -"edu.sn\0" -"it.ao\0edu.so\0backplaneapp.io\0" -"jeep\0" -"edu.ss\0nj.us\0studio.us-west-1.sagemaker.aws\0" -"reggio-calabria.it\0edu.st\0jls-sto1.elastx.net\0" -"novecore.site\0" -"edu.sv\0" -"dating\0" -"edu.sy\0shouji\0" -"edu.tj\0" -"swiebodzin.pl\0" -"edu.tm\0" -"gs.nt.no\0leirvik.no\0nord-fron.no\0edu.to\0" -"kamikoani.akita.jp\0fem.jp\0" -"edu.ua\0" -"maceio.br\0sampa.br\0edu.tr\0nc.tr\0" -"edu.tt\0" -"edu.tw\0" -"\xe3\x81\xbf\xe3\x82\x93\xe3\x81\xaa\0" -"campaign.gov.uk\0" -"amsterdam\0est-a-la-maison.com\0" -"s3-accesspoint.dualstack.cn-north-1.amazonaws.com.cn\0" -"ms.us\0nc.us\0cc.or.us\0edu.vc\0hermes\0" -"friuli-vegiulia.it\0foggia.it\0futurehosting.at\0ipifony.net\0" -"edu.ve\0adygeya.su\0" -"homeunix.org\0is-a-candidate.org\0in-vpn.org\0" -"edu.uy\0" -"edu.vn\0" -"fredrikstad.no\0krokstadelva.no\0fet.no\0troms\xc3\xb8.no\0" -"ikeda.hokkaido.jp\0rankoshi.hokkaido.jp\0aki.kochi.jp\0minamisanriku.miyagi.jp\0nagano.nagano.jp\0yuasa.wakayama.jp\0" -"cherkasy.ua\0\xd0\xbe\xd0\xb1\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" -"pol.tr\0" -"urown.cloud\0" -"edu.vu\0" -"church\0" -"ski\0" -"s3-website.dualstack.eu-central-1.amazonaws.com\0s3-eu-west-1.amazonaws.com\0" -"seven\0servers.run\0" -"me.so\0" -"ngrok.pizza\0" -"tur.ar\0" -"me.ss\0cc.ok.us\0edu.ws\0notebook.ap-southeast-3.sagemaker.aws\0me.tc\0" -"vibo-valentia.it\0twmail.net\0*.futurecms.at\0" -"sky\0" -"softbank\0" -"tjome.no\0tran\xc3\xb8y.no\0" -"*.sendai.jp\0oiso.kanagawa.jp\0yatsushiro.kumamoto.jp\0chichibu.saitama.jp\0yono.saitama.jp\0" -"tur.br\0" -"accountants\0" -"edu.ye\0adygeya.ru\0webhop.me\0" -"me.tz\0" -"me.uk\0" -"emrstudio-prod.us-east-2.amazonaws.com\0s3-object-lambda.me-south-1.amazonaws.com\0s3-sa-east-1.amazonaws.com\0webview-assets.cloud9.us-west-1.amazonaws.com\0" -"s3-accesspoint.cn-northwest-1.amazonaws.com.cn\0" -"alt.za\0edu.za\0" -"me.us\0notebook-fips.us-east-1.sagemaker.aws\0studio.me-central-1.sagemaker.aws\0" -"sytes.net\0" -"racing\0" -"pinb.gov.pl\0podlasie.pl\0pomorskie.pl\0" -"edu.zm\0" -"accident-prevention.aero\0etnedal.no\0evenes.no\0haugesund.no\0lebesby.no\0" -"ehime.jp\0sakai.fukui.jp\0naie.hokkaido.jp\0tsurugi.ishikawa.jp\0atsugi.kanagawa.jp\0tsuno.kochi.jp\0maniwa.okayama.jp\0sakegawa.yamagata.jp\0" -"s3-website.nl-ams.scw.cloud\0" -"git-pages.rit.edu\0diskstation.me\0me.vu\0" -"s3-website.dualstack.ap-northeast-2.amazonaws.com\0s3-fips-us-gov-west-1.amazonaws.com\0analytics-gateway.eu-west-1.amazonaws.com\0tuleap-partners.com\0" -"repl.run\0" -"spa\0" -"store.bb\0solar\0" -"cc.nm.us\0" -"piedmont.it\0campidano-medio.it\0" -"diskstation.eu\0" -"soy\0" -"mincom.tn\0lincoln\0" -"hokksund.no\0karasjohka.no\0s\xc3\xb8gne.no\0" -"\xe9\xa6\x99\xe5\xb7\x9d.jp\0naka.ibaraki.jp\0takahagi.ibaraki.jp\0motoyama.kochi.jp\0udono.mie.jp\0nichinan.miyazaki.jp\0nakano.nagano.jp\0ogawa.nagano.jp\0gushikami.okinawa.jp\0sano.tochigi.jp\0wakayama.wakayama.jp\0kofu.yamanashi.jp\0" -"lg.ua\0" -"riopreto.br\0tab\0" -"kiwi.nz\0" -"amscompute.com\0" -"gx.cn\0" -"*.s5y.io\0" -"im.it\0" -"togliatti.su\0" -"tax\0" -"agency\0" -"store.dk\0" -"srl\0" -"consulting.aero\0dyndns.info\0" -"\xe9\xb9\xbf\xe5\x85\x90\xe5\xb3\xb6.jp\0*.nagoya.jp\0akkeshi.hokkaido.jp\0adachi.tokyo.jp\0onflashdrive.app\0" -"vinnica.ua\0" -"tci\0" -"s3.dualstack.ca-central-1.amazonaws.com\0neat-url.com\0paas.hosted-by-previder.com\0" -"ha.cn\0gen.in\0jpmorgan\0skin\0" -"delta\0" -"cc.mo.us\0lib.ok.us\0stc\0" -"cesenaforl\xc3\xac.it\0flynnhosting.net\0" -"cn.eu.org\0diskstation.org\0" -"jcloud.kz\0" -"tdk\0" -"oke.gov.pl\0mazowsze.pl\0" -"noticias.bo\0ardal.no\0modalen.no\0rakkestad.no\0sandefjord.no\0vik.no\0" -"\xe6\xb2\x96\xe7\xb8\x84.jp\0hokuto.hokkaido.jp\0isehara.kanagawa.jp\0muika.niigata.jp\0ashikaga.tochigi.jp\0" -"chernihiv.ua\0" -"tel\0" -"s3-accesspoint.dualstack.ap-northeast-3.amazonaws.com\0on-aptible.com\0appspot.com\0myshopify.com\0" -"washtenaw.mi.us\0" -"friulive-giulia.it\0" -"ashgabad.su\0" -"hockey\0toray\0" -"travel.pl\0szczytno.pl\0" -"cern\0" -"hoyanger.no\0skj\xc3\xa5k.no\0" -"inazawa.aichi.jp\0tara.saga.jp\0shiki.saitama.jp\0cranky.jp\0" -"gc.ca\0" -"emrnotebooks-prod.ap-east-1.amazonaws.com\0s3.dualstack.ap-south-2.amazonaws.com\0" -"yn.cn\0vision\0vlaanderen\0" -"cc.ma.us\0" -"udine.it\0thd\0" -"tec.ve\0" -"ngrok-free.dev\0" -"\xe5\x95\x86\xe6\xa0\x87\0selfip.org\0gen.ng\0ybo.review\0" -"alipay\0" -"opole.pl\0" -"nara.jp\0tenei.fukushima.jp\0ninomiya.kanagawa.jp\0watari.miyagi.jp\0mimata.miyazaki.jp\0ikoma.nara.jp\0yakumo.shimane.jp\0sakaiminato.tottori.jp\0" -"beats\0" -"desa.id\0" -"*.spectrum.myjino.ru\0" -"belau.pw\0" -"oldnavy\0" -"gen.nz\0" -"\xd7\xa6\xd7\x94\xd7\x9c.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0" -"giize.com\0" -"\xd8\xa8\xd8\xa7\xd8\xb2\xd8\xa7\xd8\xb1\0" -"studio.ap-northeast-2.sagemaker.aws\0" -"eastus2.azurestaticapps.net\0" -"cy.eu.org\0" -"eu.ax\0" -"stargard.pl\0" -"kristiansand.no\0mo\xc3\xa5reke.no\0naustdal.no\0" -"kaneyama.fukushima.jp\0sunagawa.hokkaido.jp\0seihi.nagasaki.jp\0user.webaccel.jp\0" -"adv.br\0belem.br\0" -"travel.tt\0" -"tjx\0" -"vfs.cloud9.af-south-1.amazonaws.com\0vfs.cloud9.ca-central-1.amazonaws.com\0" -"yahoo\0" -"k12.ga.us\0cc.ks.us\0ventures\0" -"sondrio.it\0trento.it\0blogspot.co.at\0""1.azurestaticapps.net\0" -"cz.eu.org\0" -"restaurant.bj\0" -"ic.gov.pl\0" -"championship.aero\0modelling.aero\0gratangen.no\0aknoluokta.no\0kvinnherad.no\0namdalseid.no\0" -"!city.kawasaki.jp\0gose.nara.jp\0mitsue.nara.jp\0shimada.shizuoka.jp\0kahoku.yamagata.jp\0ube.yamaguchi.jp\0" -"\xe0\xb8\x98\xe0\xb8\xb8\xe0\xb8\xa3\xe0\xb8\x81\xe0\xb8\xb4\xe0\xb8\x88.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"stream\0" -"cuneo.it\0dynalias.net\0" -"dk.eu.org\0" -"ha.no\0sn\xc3\xa5""ase.no\0" -"togo.aichi.jp\0kui.hiroshima.jp\0assabu.hokkaido.jp\0ogawara.miyagi.jp\0karuizawa.nagano.jp\0tagami.niigata.jp\0sakai.osaka.jp\0" -"if.ua\0lugansk.ua\0" -"gen.tr\0" -"priv.instances.scw.cloud\0nodes.k8s.nl-ams.scw.cloud\0" -"buzz\0" -"\xe5\xae\xb6\xe9\x9b\xbb\0barsyonline.co.uk\0" -"wpdevcloud.com\0" -"top\0" -"systems\0myddns.rocks\0" -"faststacks.net\0" -"\xe7\xbd\x91\xe7\xb5\xa1.hk\0" -"olsztyn.pl\0" -"hagiang.vn\0" -"pors\xc3\xa1\xc5\x8bgu.no\0r\xc3\xb8""d\xc3\xb8y.no\0stranda.no\0" -"saga.jp\0oharu.aichi.jp\0yachimata.chiba.jp\0kashiba.nara.jp\0tokamachi.niigata.jp\0taketa.oita.jp\0toyono.osaka.jp\0fujiyoshida.yamanashi.jp\0" -"s3.nl-ams.scw.cloud\0" -"\xda\x80\xd8\xa7\xd8\xb1\xd8\xaa\0" -"*.dev.adobeaemcloud.com\0*.compute.amazonaws.com\0s3-us-gov-east-1.amazonaws.com\0webview-assets.cloud9.ap-east-1.amazonaws.com\0" -"salon\0emrappui-prod.cn-north-1.amazonaws.com.cn\0co.education\0direct.quickconnect.cn\0" -"cisco\0" -"vana\0" -"dabur\0hair\0" -"fe.it\0wien.funkfeuer.at\0torproject.net\0" -"training\0de.eu.org\0js.org\0" -"lebork.pl\0" -"oslo.no\0fuossko.no\0h\xc3\xb8ylandet.no\0" -"toyohashi.aichi.jp\0ohi.fukui.jp\0kawasaki.miyagi.jp\0shimabara.nagasaki.jp\0koto.tokyo.jp\0catfood.jp\0noor.jp\0" -"enf.br\0" -"ubs\0" -"exposed\0blogspot.co.id\0" -"trv\0" -"blogspot.co.il\0de.cool\0" -"auth-fips.us-west-1.amazoncognito.com\0s3-accesspoint.ap-southeast-2.amazonaws.com\0s3-accesspoint.eu-north-1.amazonaws.com\0webview-assets.aws-cloud9.us-west-2.amazonaws.com\0" -"lom.it\0trentino-aadige.it\0en.it\0massa-carrara.it\0" -"gripe\0" -"webredirect.org\0" -"uzs.gov.pl\0" -"koeln\0" -"lier.no\0" -"shimokitayama.nara.jp\0toyonaka.osaka.jp\0okuizumo.shimane.jp\0aridagawa.wakayama.jp\0*.beget.app\0boyfriend.jp\0telebit.app\0" -"luhansk.ua\0osaka\0" -"foz.br\0gru.br\0santamaria.br\0gouv.fr\0" -"restaurant\0" -"city.hu\0" -"\xe7\xb5\x84\xe7\xb9\x94.tw\0" -"tui\0" -"herokuapp.com\0" -"lolipop.io\0" -"gwangju.kr\0" -"k12.wy.us\0" -"myftp.org\0" -"adv.mz\0" -"meldal.no\0time.no\0weibo\0" -"tokushima.jp\0yokaichiba.chiba.jp\0taka.hyogo.jp\0kochi.kochi.jp\0fukuchiyama.kyoto.jp\0kin.okinawa.jp\0tadaoka.osaka.jp\0makinohara.shizuoka.jp\0nakamichi.yamanashi.jp\0" -"es.gov.br\0" -"tvs\0" -"gouv.ht\0" -"cust.retrosnub.co.uk\0" -"s3.me-south-1.amazonaws.com\0" -"mj\xc3\xb8ndalen.no\0aseral.no\0hapmir.no\0hoylandet.no\0lom.no\0" -"yamanashi.jp\0aisai.aichi.jp\0matsudo.chiba.jp\0onjuku.chiba.jp\0kutchan.hokkaido.jp\0urasoe.okinawa.jp\0minato.tokyo.jp\0" -"gouv.ci\0" -"s3-website-us-east-1.amazonaws.com\0is-a-caterer.com\0is-an-anarchist.com\0fastvps-server.com\0ktistory.com\0" -"alibaba\0" -"christmas\0" -"trentino-alto-adige.it\0potenza.it\0vt.it\0" -"ca.eu.org\0" -"flt.cloud.muni.cz\0" -"kwpsp.gov.pl\0mup.gov.pl\0kolobrzeg.pl\0" -"own.pm\0" -"jessheim.no\0bygland.no\0tjeldsund.no\0\xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\0" -"keisen.fukuoka.jp\0iwaki.fukushima.jp\0wassamu.hokkaido.jp\0kuchinotsu.nagasaki.jp\0niigata.niigata.jp\0sadist.jp\0stripper.jp\0" -"origins\0" -"fhsk.se\0degree\0homesense\0reliance\0" -"click\0" -"fl.us\0" -"cr.it\0" -"fauske.no\0radoy.no\0" -"ashoro.hokkaido.jp\0ikusaka.nagano.jp\0yufu.oita.jp\0komatsushima.tokushima.jp\0aarp\0" -"\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" -"ma.gov.br\0slg.br\0\xe0\xb8\xad\xe0\xb8\x87\xe0\xb8\x84\xe0\xb9\x8c\xe0\xb8\x81\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"quebec\0" -"s3.dualstack.ap-southeast-4.amazonaws.com\0vfs.cloud9.us-west-2.amazonaws.com\0" -"pstmn.io\0" -"base.shop\0" -"per.la\0" -"brother\0" -"lib.id.us\0haus\0" -"imperia.it\0in-vpn.net\0" -"hs.zone\0" -"tunk.org\0servegame.org\0hk.org\0" -"szczecin.pl\0" -"g\xc3\xa1\xc5\x8bgaviika.no\0skanland.no\0uno\0" -"\xe6\x84\x9b\xe7\x9f\xa5.jp\0miyoshi.aichi.jp\0kumano.hiroshima.jp\0uruma.okinawa.jp\0gamo.shiga.jp\0chofu.tokyo.jp\0hino.tottori.jp\0wnext.app\0" -"pramerica\0" -"greta.fr\0" -"forte.id\0" -"blogspot.co.uk\0" -"uol\0" -"emrstudio-prod.me-central-1.amazonaws.com\0s3-website.dualstack.eu-south-1.amazonaws.com\0s3-accesspoint-fips.us-east-1.amazonaws.com\0s3-accesspoint-fips.dualstack.us-west-1.amazonaws.com\0dyndns-wiki.com\0pro.typeform.com\0" -"tj.cn\0travel.in\0" -"bingo\0" -"wy.us\0notebook.ca-central-1.sagemaker.aws\0" -"marche.it\0bt.it\0caserta.it\0tranibarlettaandria.it\0" -"per.nf\0shiftcrypto.dev\0" -"joburg\0cd.eu.org\0twmail.org\0" -"oow.gov.pl\0" -"tuyenquang.vn\0" -"conference.aero\0kragero.no\0tromsa.no\0" -"shikatsu.aichi.jp\0yamato.fukushima.jp\0ushiku.ibaraki.jp\0yugawara.kanagawa.jp\0watarai.mie.jp\0shikama.miyagi.jp\0ryuoh.shiga.jp\0yazu.tottori.jp\0" -"art.br\0natal.br\0tc.br\0" -"ups\0" -"s3-object-lambda.eu-west-1.amazonaws.com\0dynns.com\0" -"ah.cn\0" -"business\0juegos\0noip.us\0" -"bozen-sudtirol.it\0" -"\xe6\x95\x99\xe8\x82\xb2.hk\0" -"hanoi.vn\0" -"art.do\0vf.no\0hattfjelldal.no\0lillesand.no\0direct.quickconnect.to\0" -"tsugaru.aomori.jp\0murata.miyagi.jp\0joetsu.niigata.jp\0higashiizumo.shimane.jp\0nishikatsura.yamanashi.jp\0" -"dp.ua\0" -"brasilia.me\0" -"cya.gg\0" -"godaddy\0miami\0" -"art.dz\0" -"\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\0" -"notebook.ap-southeast-1.sagemaker.aws\0" -"av.it\0perugia.it\0" -"online.th\0" -"aland.fi\0" -"oschr.gov.pl\0nysa.pl\0" -"ruovat.no\0songdalen.no\0omasvuotna.no\0strand.no\0" -"nagano.jp\0katsuyama.fukui.jp\0mishima.fukushima.jp\0taishin.fukushima.jp\0yawara.ibaraki.jp\0soo.kagoshima.jp\0nakagawa.nagano.jp\0ooshika.nagano.jp\0hasami.nagasaki.jp\0matsubushi.saitama.jp\0takashima.shiga.jp\0yamanobe.yamagata.jp\0" -"cloudsite.builders\0" -"kommunalforbund.se\0blogspot.co.ke\0tcp4.me\0" -"per.sg\0" -"total\0" -"s3.af-south-1.amazonaws.com\0s3-website.eu-south-1.amazonaws.com\0s3-eu-west-3.amazonaws.com\0ap-southeast-1.elasticbeanstalk.com\0est-mon-blogueur.com\0" -"wix.run\0" -"jele.io\0" -"nsn.us\0vt.us\0" -"ao.it\0build\0chat\0vet\0fastlylb.net\0serveblog.net\0" -"able\0tuva.su\0" -"beskidy.pl\0sopot.pl\0" -"yamagata.jp\0honjo.akita.jp\0inzai.chiba.jp\0ginan.gifu.jp\0shimotsuma.ibaraki.jp\0yuki.ibaraki.jp\0kudoyama.wakayama.jp\0heavy.jp\0verse.jp\0" -"cr.ua\0" -"citic\0" -"art.ht\0vip.jelastic.cloud\0" -"omg.lol\0" -"execute-api.eu-central-1.amazonaws.com\0s3.eu-central-2.amazonaws.com\0streamlitapp.com\0js.wpenginepowered.com\0" -"definima.io\0" -"la-spezia.it\0olbiatempio.it\0ss.it\0from-la.net\0kirara.st\0" -"endoftheinternet.org\0is-a-patsfan.org\0" -"\xe4\xba\x9a\xe9\xa9\xac\xe9\x80\x8a\0" -"\xe7\xb5\x84\xe7\xb9\x94.hk\0" -"production.aero\0" -"uchiko.ehime.jp\0oji.nara.jp\0urawa.saitama.jp\0" -"ck.ua\0*.awdev.ca\0" -"cuiaba.br\0niteroi.br\0" -"koobin.events\0" -"s3-website.fr-par.scw.cloud\0" -"vig\0" -"govt.nz\0blogspot.co.nz\0" -"emrnotebooks-prod.ap-northeast-1.amazonaws.com\0drayddns.com\0" -"gouv.sn\0vin\0" -"vip\0" -"pfizer\0tatar\0" -"feste-ip.net\0" -"cologne\0virtualuser.de\0" -"bentre.vn\0" -"onomichi.hiroshima.jp\0fukusaki.hyogo.jp\0anan.nagano.jp\0izumozaki.niigata.jp\0tainai.niigata.jp\0usuki.oita.jp\0mihama.wakayama.jp\0mints.ne.jp\0" -"\xd0\xb0\xd0\xba.\xd1\x81\xd1\x80\xd0\xb1\0" -"execute-api.me-south-1.amazonaws.com\0auth.us-west-2.amazoncognito.com\0s3-website.ap-south-2.amazonaws.com\0s3-object-lambda.ap-southeast-1.amazonaws.com\0" -"villas\0" -"sardegna.it\0" -"vic.edu.au\0" -"w.bg\0" -"kwp.gov.pl\0" -"ah.no\0audnedaln.no\0mel\xc3\xb8y.no\0nordreisa.no\0ski.no\0" -"\xe7\xa7\x8b\xe7\x94\xb0.jp\0!city.kobe.jp\0shichinohe.aomori.jp\0isesaki.gunma.jp\0wakkanai.hokkaido.jp\0namegata.ibaraki.jp\0yamashina.kyoto.jp\0ishinomaki.miyagi.jp\0nishikata.tochigi.jp\0oshima.yamaguchi.jp\0" -"zakarpattia.ua\0" -"fortal.br\0psi.br\0" -"ua.rs\0" -"video.hu\0noip.me\0" -"sncf\0" -"istanbul\0" -"ddnsking.com\0x0.com\0temp-dns.com\0" -"audio\0" -"tx.us\0lib.fl.us\0tec.mi.us\0noticeable.news\0" -"rn.it\0lon-1.paas.massivegrid.net\0" -"tashkent.su\0" -"p.bg\0" -"art.pl\0" -"gliding.aero\0aa.no\0sor-fron.no\0" -"kusatsu.gunma.jp\0yachiyo.ibaraki.jp\0fujisawa.iwate.jp\0joboji.iwate.jp\0saiki.oita.jp\0takaoka.toyama.jp\0" -"av.tr\0" -"its.me\0" -"nowtv\0" -"s3.dualstack.eu-west-2.amazonaws.com\0s3-accesspoint.dualstack.us-gov-west-1.amazonaws.com\0gr.com\0servehalflife.com\0" -"editorx.io\0" -"daegu.kr\0" -"cc.de.us\0notebook.eu-central-2.sagemaker.aws\0" -"firenze.it\0rg.it\0principe.st\0" -"smile\0" -"i.bg\0\xeb\x8b\xb7\xeb\x84\xb7\0blogdns.org\0" -"selfip.biz\0" -"trading.aero\0flor\xc3\xb8.no\0askoy.no\0l\xc3\xa1hppi.no\0s\xc3\xb8r-odal.no\0dynamic-dns.info\0" -"honai.ehime.jp\0minamifurano.hokkaido.jp\0yonabaru.okinawa.jp\0ogano.saitama.jp\0izumo.shimane.jp\0misato.shimane.jp\0izunokuni.shizuoka.jp\0" -"zhitomir.ua\0" -"gouv.km\0vfs.cloud9.eu-west-3.amazonaws.com\0api.stdlib.com\0" -"art.sn\0" -"n4t.co\0" -"cc.vi.us\0lib.wa.us\0chtr.k12.ma.us\0studio.eu-central-1.sagemaker.aws\0" -"piemonte.it\0agrigento.it\0vercelli.it\0akamaiorigin-staging.net\0" -"b.bg\0dynalias.org\0" -"123kotisivu.fi\0" -"arna.no\0fedje.no\0holmestrand.no\0tr\xc3\xb8gstad.no\0" -"*.kawasaki.jp\0toyota.aichi.jp\0yamatsuri.fukushima.jp\0ngrok-free.app\0vercel.app\0" -"b.br\0" -"mil.ac\0" -"mil.ae\0nov.ru\0" -"grocery\0" -"mil.al\0gouv.ml\0" -"notaires.km\0auth-fips.us-east-1.amazoncognito.com\0s3.ca-central-1.amazonaws.com\0from-oh.com\0" -"mil.ba\0blogspot.co.za\0" -"mil.ar\0" -"lib.dc.us\0" -"friulivegiulia.it\0monza-brianza.it\0dnsalias.net\0" -"aktyubinsk.su\0nov.su\0" -"mil.az\0" -"union.aero\0mil.bo\0gs.tm.no\0n\xc3\xa6r\xc3\xb8y.no\0s\xc3\xb8r-fron.no\0aca.pro\0" -"semboku.akita.jp\0nishiaizu.fukushima.jp\0kaita.hiroshima.jp\0fujishiro.ibaraki.jp\0kuji.iwate.jp\0makurazaki.kagoshima.jp\0saikai.nagasaki.jp\0sagae.yamagata.jp\0" -"mil.br\0" -"plesk.page\0" -"mil.by\0directory\0" -"!www.ck\0lug.org.uk\0" -"mil.cl\0dental\0cloudapps.digital\0" -"thingdustdata.com\0" -"mil.cn\0" -"mil.co\0" -"walter\0" -"shoes\0" -"pr.it\0suedtirol.it\0consulado.st\0""6.azurestaticapps.net\0" -"mordovia.su\0barsy.site\0" -"mil.cy\0" -"cyon.link\0" -"kalisz.pl\0poznan.pl\0" -"mil.do\0baidar.no\0sund.no\0" -"akita.jp\0nisshin.aichi.jp\0tsushima.aichi.jp\0naganohara.gunma.jp\0ohda.shimane.jp\0taiji.wakayama.jp\0" -"ivano-frankivsk.ua\0" -"prd.fr\0ma.leg.br\0" -"mil.ec\0solutions\0" -"mil.eg\0" -"of.by\0" -"lugs.org.uk\0" -"*.eu-west-3.airflow.amazonaws.com\0s3.dualstack.eu-south-1.amazonaws.com\0ooguy.com\0townnews-staging.com\0" -"s3.cn-north-1.amazonaws.com.cn\0" -"ghost.io\0" -"lamer\0" -"lib.ca.us\0lib.ut.us\0properties\0co.business\0" -"valdaosta.it\0avellino.it\0imamat\0cdn77-ssl.net\0" -"in-brb.de\0" -"ch.eu.org\0" -"mil.fj\0" -"civilaviation.aero\0entertainment.aero\0dep.no\0holtalen.no\0navuotna.no\0namsos.no\0tj\xc3\xb8me.no\0" -"chikujo.fukuoka.jp\0miura.kanagawa.jp\0tsukui.kanagawa.jp\0itabashi.tokyo.jp\0" -"mg.gov.br\0" -"mil.ge\0merseine.nu\0mordovia.ru\0" -"mil.gh\0" -"parliament.nz\0" -"s3.eu-south-2.amazonaws.com\0" -"win\0" -"cc.ar.us\0" -"mil.gt\0ot.it\0pd.it\0" -"troitsk.su\0" -"oirm.gov.pl\0" -"mil.hn\0phuyen.vn\0" -"spjelkavik.no\0vevelstad.no\0barrell-of-knowledge.info\0" -"hiroshima.jp\0!city.sendai.jp\0omuta.fukuoka.jp\0izumizaki.fukushima.jp\0mizusawa.iwate.jp\0kadogawa.miyazaki.jp\0tsubame.niigata.jp\0asahi.toyama.jp\0oishida.yamagata.jp\0mimoza.jp\0s3.isk02.sakurastorage.jp\0" -"lel.br\0" -"mil.id\0" -"vm.bytemark.co.uk\0" -"travel\0" -"prd.km\0execute-api.eu-west-1.amazonaws.com\0simple-url.com\0" -"mil.in\0" -"mil.iq\0" -"cc.ak.us\0" -"campania.it\0trentinos\xc3\xbc""dtirol.it\0" -"info.gu\0firestone\0abkhazia.su\0" -"i.ng\0\xd9\x85\xd9\x88\xd8\xb1\xd9\x8a\xd8\xaa\xd8\xa7\xd9\x86\xd9\x8a\xd8\xa7\0" -"\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\0" -"mil.jo\0aejrie.no\0narviika.no\0" -"itakura.gunma.jp\0shimodate.ibaraki.jp\0amakusa.kumamoto.jp\0kameoka.kyoto.jp\0sakyo.kyoto.jp\0matsusaka.mie.jp\0lolitapunk.jp\0" -"seg.br\0" -"info.ht\0" -"info.hu\0w.se\0wme\0" -"mil.kg\0prd.mg\0" -"jewelry\0" -"mil.km\0s3-website.ap-east-1.amazonaws.com\0selfip.com\0googleapis.com\0withyoutube.com\0" -"info.in\0loan\0" -"mil.kr\0" -"hdfc\0cloud66.ws\0" -"info.et\0reggiocalabria.it\0adobeioruntime.net\0myamaze.net\0myspreadshop.net\0" -"of.je\0g\xc3\xbcnstigbestellen.de\0" -"8.bg\0engineering\0is-very-nice.org\0" -"i.ph\0" -"info.fj\0mil.kz\0" -"backan.vn\0baclieu.vn\0daklak.vn\0" -"kvits\xc3\xb8y.no\0modum.no\0" -"mie.jp\0inatsuki.fukuoka.jp\0ukiha.fukuoka.jp\0aizuwakamatsu.fukushima.jp\0sanda.hyogo.jp\0shingu.hyogo.jp\0aikawa.kanagawa.jp\0iwanuma.miyagi.jp\0kashiwazaki.niigata.jp\0higashimurayama.tokyo.jp\0lomo.jp\0" -"chernovtsy.ua\0" -"palmas.br\0" -"p.se\0mytis.ru\0" -"mil.lv\0" -"mil.mg\0cloud.goog\0" -"\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb8\0" -"s3-website.dualstack.ap-northeast-1.amazonaws.com\0is-a-democrat.com\0" -"schaeffler\0" -"k12.oh.us\0" -"trentin-s\xc3\xbc""d-tirol.it\0no.it\0bar2.net\0" -"jele.site\0" -"mil.mv\0" -"1.bg\0mil.ng\0wow\0at.eu.org\0dynserv.org\0" -"info.cx\0mc.ax\0" -"mil.my\0mil.ni\0" -"mil.mz\0" -"shoparena.pl\0" -"tksat.bo\0mil.no\0amot.no\0aurskog-holand.no\0jondal.no\0oppdal.no\0rodoy.no\0solund.no\0sula.no\0" -"akune.kagoshima.jp\0geisei.kochi.jp\0sakaki.nagano.jp\0iwade.wakayama.jp\0cocotte.jp\0" -"info.ec\0gifts\0" -"i.se\0cbg.ru\0glitch.me\0" -"mil.nz\0" -"emrstudio-prod.us-west-1.amazonaws.com\0webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com\0ap-east-1.elasticbeanstalk.com\0" -"6g.in\0gujarat.in\0" -"taobao\0" -"info.bb\0" -"pr.us\0k12.mo.us\0" -"*.bd\0liguria.it\0info.at\0" -"info.au\0mil.pe\0framer.website\0" -"mil.ph\0" -"info.az\0info.bj\0" -"mil.pl\0" -"info.bo\0fhs.no\0of.no\0bo.telemark.no\0lorenskog.no\0rdv.to\0" -"iizuka.fukuoka.jp\0fukuyama.hiroshima.jp\0wajima.ishikawa.jp\0sukumo.kochi.jp\0kitamoto.saitama.jp\0higashikurume.tokyo.jp\0undo.jp\0" -"mil.qa\0" -"ecn.br\0" -"b.se\0sohu\0" -"mil.py\0" -"*.ck\0" -"execute-api.eu-south-2.amazonaws.com\0dyndns-work.com\0" -"info.co\0cust.dev.thingdust.io\0" -"frontier\0" -"lib.ak.us\0wtc\0mircloud.us\0" -"trentino-sudtirol.it\0alessandria.it\0na.it\0global.prod.fastly.net\0" -"fujitsu\0" -"wtf\0" -"swinoujscie.pl\0" -"hatinh.vn\0phutho.vn\0" -"drobak.no\0drangedal.no\0sk\xc3\xa5nland.no\0sn\xc3\xa5sa.no\0" -"higashinaruse.akita.jp\0kamogawa.chiba.jp\0sekigahara.gifu.jp\0kunitomi.miyazaki.jp\0sakuho.nagano.jp\0kouhoku.saga.jp\0ouchi.saga.jp\0inami.wakayama.jp\0flier.jp\0" -"avoues.fr\0" -"twmail.cc\0" -"konyvelo.hu\0mil.ru\0eurodir.ru\0nohost.me\0" -"mil.rw\0" -"mil.sh\0coach\0" -"s3-accesspoint.dualstack.ap-northeast-2.amazonaws.com\0s3-website.ap-southeast-2.amazonaws.com\0s3-object-lambda.ca-central-1.amazonaws.com\0is-an-artist.com\0" -"onion\0olayan\0" -"lpages.co\0" -"mx.na\0" -"*.er\0" -"k12.ma.us\0" -"mil.st\0akamaiedge.net\0definima.net\0" -"online\0zone\0" -"mil.sy\0" -"mil.tj\0" -"*.fk\0" -"mielec.pl\0" -"mil.tm\0" -"hemnes.no\0mil.to\0" -"kasukabe.saitama.jp\0warabi.saitama.jp\0kaminokawa.tochigi.jp\0" -"teo.br\0mil.tr\0" -"tours\0" -"mil.tw\0" -"mil.tz\0" -"tabitorder.co.il\0" -"s3-accesspoint.dualstack.eu-south-2.amazonaws.com\0br.com\0from-ms.com\0from-nc.com\0homeunix.com\0is-a-green.com\0u2.xnbay.com\0" -"k12.md.us\0mil.vc\0" -"mc.it\0pesarourbino.it\0" -"mil.ve\0khakassia.su\0" -"song\0is-lost.org\0" -"mil.uy\0citi\0" -"andasuolo.no\0tonsberg.no\0" -"mihama.aichi.jp\0hidaka.hokkaido.jp\0kyotanabe.kyoto.jp\0shinanomachi.nagano.jp\0sanjo.niigata.jp\0kadoma.osaka.jp\0ichikai.tochigi.jp\0thick.jp\0" -"mircloud.ru\0" -"city\0sony\0" -"*.sa-east-1.airflow.amazonaws.com\0" -"xin\0" -"kuokgroup\0" -"nv.us\0" -"bologna.it\0bozen-suedtirol.it\0westeurope.azurestaticapps.net\0" -"forex\0" -"jozi.biz\0" -"inc.hk\0" -"*.jm\0" -"movimiento.bo\0\xc3\xa1laheadju.no\0gamvik.no\0" -"asago.hyogo.jp\0kariwa.niigata.jp\0minamidaito.okinawa.jp\0ota.tokyo.jp\0" -"yachts\0" -"mil.ye\0mcpre.ru\0" -"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0" -"mymailer.com.tw\0daemon.panel.gg\0" -"*.kh\0" -"emrstudio-prod.eu-west-1.amazonaws.com\0s3.amazonaws.com\0dev-myqnapcloud.com\0" -"mil.za\0" -"kids.us\0lexus\0" -"le.it\0monza.it\0*.cryptonomic.net\0from-ny.net\0mysecuritycamera.net\0" -"diskussionsbereich.de\0" -"mil.zm\0" -"alaheadju.no\0fosnes.no\0" -"miyazaki.jp\0kasugai.aichi.jp\0tobe.ehime.jp\0hirokawa.fukuoka.jp\0yashiro.hyogo.jp\0" -"samsclub\0" -"report\0" -"mil.zw\0" -"*.mm\0execute-api.ap-southeast-4.amazonaws.com\0auth.us-east-2.amazoncognito.com\0hotelwithflight.com\0" -"nh.us\0notebook.me-south-1.sagemaker.aws\0studio.ap-northeast-1.sagemaker.aws\0" -"pmn.it\0trentino-stirol.it\0andriabarlettatrani.it\0ogliastra.it\0" -"info.ve\0cloudns.eu\0" -"go.dyndns.org\0" -"\xe6\x9b\xb8\xe7\xb1\x8d\0" -"info.vn\0" -"evje-og-hornnes.no\0raisa.no\0" -"shingo.aomori.jp\0aya.miyazaki.jp\0ikeda.osaka.jp\0shinagawa.tokyo.jp\0*.np\0" -"poltava.ua\0" -"notaires.fr\0" -"\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0" -"uk.primetel.cloud\0" -"guge\0" -"gotdns.ch\0" -"execute-api.ap-northeast-1.amazonaws.com\0" -"pioneer\0" -"vegas\0" -"ny-1.paas.massivegrid.net\0" -"nt.edu.au\0" -"*.pg\0" -"mragowo.pl\0" -"info.tn\0" -"minamiminowa.nagano.jp\0shimamoto.osaka.jp\0kozagawa.wakayama.jp\0iide.yamagata.jp\0" -"kyiv.ua\0ternopil.ua\0" -"feira.br\0g12.br\0info.tr\0" -"info.tt\0" -"space\0hopto.me\0" -"gucci\0" -"info.tz\0" -"sandvik\0" -"s3.dualstack.eu-north-1.amazonaws.com\0s3-fips-us-gov-east-1.amazonaws.com\0from-ut.com\0sells-for-u.com\0x.mythic-beasts.com\0" -"cloudns.in\0" -"kg.kr\0verm\xc3\xb6gensberater\0" -"cc.ny.us\0lib.pa.us\0" -"valle-d-aosta.it\0" -"id.au\0love\0" -"is-a-soxfan.org\0au.eu.org\0be.eu.org\0" -"banamex\0\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xa0\xe0\xa4\xa8\0" -"hurum.no\0\xc3\xb8yer.no\0rauma.no\0info.ro\0" -"okagaki.fukuoka.jp\0higashimatsuyama.saitama.jp\0cheap.jp\0" -"crimea.ua\0" -"9guacu.br\0anani.br\0mg.leg.br\0" -"hotels\0cloudns.cc\0" -"info.sd\0" -"jp.kg\0" -"emrnotebooks-prod.ap-northeast-3.amazonaws.com\0ru.com\0dattoweb.com\0dopaas.com\0" -"valle-daosta.it\0blogdns.net\0" -"lima.zone\0" -"c.cdn77.org\0" -"iki.fi\0" -"info.pk\0" -"info.pl\0sko.gov.pl\0" -"aerobatic.aero\0forsand.no\0halden.no\0" -"*.yokohama.jp\0takko.aomori.jp\0higashikagawa.kagawa.jp\0yamato.kanagawa.jp\0katano.osaka.jp\0kamisato.saitama.jp\0help\0jellybean.jp\0" -"info.pr\0" -"events\0" -"jp.md\0" -"s3-fips.dualstack.us-gov-east-1.amazonaws.com\0" -"gv.ao\0" -"info.na\0" -"broker\0" -"gv.at\0\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4\0in.net\0" -"forsale\0" -"info.mv\0info.nf\0" -"bg.eu.org\0" -"info.ni\0" -"is.gov.pl\0" -"groundhandling.aero\0nord-odal.no\0" -"funabashi.chiba.jp\0tsu.mie.jp\0ebino.miyazaki.jp\0matsukawa.nagano.jp\0yuzawa.niigata.jp\0mizuho.tokyo.jp\0inami.toyama.jp\0shirahama.wakayama.jp\0kawanishi.yamagata.jp\0" -"info.nr\0" -"chase\0" -"a\xc3\xa9roport.ci\0" -"emrnotebooks-prod.eu-south-1.amazonaws.com\0ca-central-1.elasticbeanstalk.com\0" -"execute-api.cn-northwest-1.amazonaws.com.cn\0" -"barsy.shop\0" -"info.la\0" -"mutual.ar\0" -"cc.mt.us\0cc.nd.us\0" -"trentinosud-tirol.it\0" -"realestate\0pokrovsk.su\0schulserver.de\0" -"vercel.dev\0" -"dnsalias.org\0" -"thainguyen.vn\0" -"arendal.no\0giske.no\0" -"!city.sapporo.jp\0daiwa.hiroshima.jp\0yamato.kumamoto.jp\0ranzan.saitama.jp\0koshu.yamanashi.jp\0under.jp\0ngrok.app\0*.developer.app\0" -"khmelnitskiy.ua\0" -"info.ls\0" -"*.landing.myjino.ru\0" -"xxx\0" -"go.ci\0" -"forum\0webview-assets.aws-cloud9.me-south-1.amazonaws.com\0space-to-rent.com\0mydobiss.com\0homesecuritymac.com\0alpha-myqnapcloud.com\0" -"zj.cn\0" -"go.cr\0id.ir\0busan.kr\0" -"dellogliastra.it\0spot\0" -"here\0my-router.de\0" -"xerox\0" -"xyz\0" -"co.network\0" -"berlev\xc3\xa5g.no\0evenassi.no\0kviteseid.no\0oster\xc3\xb8y.no\0" -"osakikamijima.hiroshima.jp\0joso.ibaraki.jp\0chihayaakasaka.osaka.jp\0tosu.saga.jp\0shinjo.yamagata.jp\0" -"catholic\0" -"info.ke\0boutique\0guru\0" -"off.ai\0info.ki\0" -"emrappui-prod.ca-central-1.amazonaws.com\0analytics-gateway.us-east-1.amazonaws.com\0ap-northeast-2.elasticbeanstalk.com\0serveirc.com\0" -"\xe0\xa4\x95\xe0\xa5\x89\xe0\xa4\xae\0" -"fed.us\0industries\0" -"tele.amune.org\0hr.eu.org\0" +"\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0" +"vr.it\0itano.tokushima.jp\0" +"execute-api.ca-central-1.amazonaws.com\0" +"lib.or.us\0s3-us-gov-east-1.amazonaws.com\0" +"tochigi.jp\0" +"\xc3\xb8yer.no\0" "\xe3\x82\xb0\xe3\x83\xbc\xe3\x82\xb0\xe3\x83\xab\0" -"aero\0maintenance.aero\0gj\xc3\xb8vik.no\0\xc3\xb8rskog.no\0porsangu.no\0barrel-of-knowledge.info\0" -"ikata.ehime.jp\0hakata.fukuoka.jp\0suzu.ishikawa.jp\0jeez.jp\0" -"goupile.fr\0" -"clinic\0" -"id.lv\0" -"\xe7\xa7\xbb\xe5\x8a\xa8\0" -"id.ly\0" -"emrnotebooks-prod.me-central-1.amazonaws.com\0s3-accesspoint.dualstack.ap-south-2.amazonaws.com\0s3.dualstack.ap-southeast-1.amazonaws.com\0vfs.cloud9.us-west-1.amazonaws.com\0" -"k12.gu.us\0pvt.k12.ma.us\0notebook.ap-northeast-3.sagemaker.aws\0cloudns.us\0" -"camdvr.org\0" -"nieruchomosci.pl\0lezajsk.pl\0opoczno.pl\0pulawy.pl\0" -"cnpy.gdn\0" -"federation.aero\0r\xc3\xa5holt.no\0lavangen.no\0nesset.no\0steigen.no\0" -"kurume.fukuoka.jp\0ibaraki.ibaraki.jp\0furukawa.miyagi.jp\0shintomi.miyazaki.jp\0nagatoro.saitama.jp\0kouzushima.tokyo.jp\0" -"kherson.ua\0" -"go.id\0" -"s3.dualstack.us-west-1.amazonaws.com\0s3-object-lambda.us-west-1.amazonaws.com\0from-sc.com\0smushcdn.com\0" -"fj.cn\0creditunion\0" -"\xe5\x85\xac\xe5\x8f\xb8.\xe9\xa6\x99\xe6\xb8\xaf\0" -"discover\0" -"go.it\0eastasia.azurestaticapps.net\0" -"you\0" -"es.ax\0" -"activetrail.biz\0" -"hoabinh.vn\0" -"repbody.aero\0hm.no\0hamaroy.no\0risor.no\0" -"go.jp\0chosei.chiba.jp\0tobetsu.hokkaido.jp\0suifu.ibaraki.jp\0maizuru.kyoto.jp\0aoki.nagano.jp\0takaishi.osaka.jp\0kudamatsu.yamaguchi.jp\0" -"go.ke\0" -"\xd8\xb9\xd8\xb1\xd8\xa8\0" -"emrstudio-prod.ap-northeast-1.amazonaws.com\0co.com\0from-pr.com\0" -"go.kr\0" -"cc.la.us\0lib.mi.us\0" -"trapani.it\0za.net\0" -"ryukyu\0" -"dscloud.mobi\0" -"h\xc3\xa6gebostad.no\0kongsvinger.no\0kv\xc3\xa6""fjord.no\0rost.no\0snaase.no\0" -"kanegasaki.iwate.jp\0odawara.kanagawa.jp\0nishiarita.saga.jp\0akagi.shimane.jp\0fujikawaguchiko.yamanashi.jp\0" -"adm.br\0" -"\xe7\x82\xb9\xe7\x9c\x8b\0" -"\xd7\x9e\xd7\x9e\xd7\xa9\xd7\x9c.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0" -"dattolocal.com\0is-gone.com\0is-slick.com\0" -"us.ngrok.io\0" -"bnpparibas\0" -"napoli.it\0palermo.it\0" -"tarnobrzeg.pl\0" +"misugi.mie.jp\0" +"auth.eu-central-1.amazoncognito.com\0analytics-gateway.ap-northeast-1.amazonaws.com\0" +"twmail.net\0" +"room\0" +"travel.in\0shimofusa.chiba.jp\0kyowa.hokkaido.jp\0" +"familyds.com\0" +"shiga.jp\0" +"enebakk.no\0" "soctrang.vn\0" -"d\xc3\xb8nna.no\0" -"\xe7\xbe\xa4\xe9\xa6\xac.jp\0*.kitakyushu.jp\0kitagata.gifu.jp\0shinto.gunma.jp\0ebetsu.hokkaido.jp\0takinoue.hokkaido.jp\0yoka.hyogo.jp\0ando.nara.jp\0nakano.tokyo.jp\0flop.jp\0" -"fage\0" -"maif\0sakura.tv\0" -"\xd9\x87\xd9\x85\xd8\xb1\xd8\xa7\xd9\x87\0" -"*.us-east-1.airflow.amazonaws.com\0webview-assets.cloud9.sa-east-1.amazonaws.com\0myactivedirectory.com\0" -"yun\0" -"\xe4\xbd\x9b\xe5\xb1\xb1\0" -"id.us\0studio.ca-central-1.sagemaker.aws\0" -"sicily.it\0trentins\xc3\xbc""dtirol.it\0bozen-s\xc3\xbc""dtirol.it\0" -"circle\0" -"africa.bj\0" -"talk\0" -"id.vn\0" -"askvoll.no\0aver\xc3\xb8y.no\0fuoisku.no\0gaular.no\0karmoy.no\0guovdageaidnu.no\0" -"hirosaki.aomori.jp\0sakae.chiba.jp\0okawa.fukuoka.jp\0kuzumaki.iwate.jp\0kikuchi.kumamoto.jp\0takatsuki.shiga.jp\0shimane.shimane.jp\0fujieda.shizuoka.jp\0" -"\xe0\xb8\x84\xe0\xb8\xad\xe0\xb8\xa1\0" -"*.nom.br\0" -"bir.ru\0" -"go.pw\0" -"\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0" -"family\0xfinity\0" -"fail\0hotmail\0" -"s3-accesspoint.dualstack.eu-west-3.amazonaws.com\0pixolino.com\0securitytactics.com\0" -"boxfuse.io\0cust.disrec.thingdust.io\0" -"1337.pictures\0" -"fc.it\0knx-server.net\0" -"us.eu.org\0mysecuritycamera.org\0" -"kartuzy.pl\0lubartow.pl\0" -"express.aero\0" -"takahama.aichi.jp\0fukushima.hokkaido.jp\0tsubetsu.hokkaido.jp\0yoichi.hokkaido.jp\0nomi.ishikawa.jp\0kiyokawa.kanagawa.jp\0ginoza.okinawa.jp\0tsuwano.shimane.jp\0johana.toyama.jp\0" -"\xd2\x9b\xd0\xb0\xd0\xb7\0cloudns.pw\0" -"gsj.bz\0" -"airkitapps.com\0s3-website.dualstack.ap-southeast-1.amazonaws.com\0webview-assets.cloud9.ap-northeast-1.amazonaws.com\0" -"s3-accesspoint.dualstack.cn-northwest-1.amazonaws.com.cn\0" -"ngrok.io\0" -"zip\0" -"es.kr\0author\0" -"gv.vc\0""0e.vc\0" -"scrapper-site.net\0" -"krasnodar.su\0" -"*.lcl.dev\0" -"go.th\0" -"\xe9\x80\x9a\xe8\xb2\xa9\0" -"avocats.bj\0go.tj\0test.tj\0" -"wios.gov.pl\0" -"info.zm\0" -"software.aero\0klabu.no\0vadso.no\0" -"rikuzentakata.iwate.jp\0fujisawa.kanagawa.jp\0kunisaki.oita.jp\0unnan.shimane.jp\0moka.tochigi.jp\0nakagawa.tokushima.jp\0higashiyamato.tokyo.jp\0mail-box.ne.jp\0" -"cs.keliweb.cloud\0" -"bolt.hu\0" -"go.ug\0" -"go.tz\0" -"mytabit.co.il\0" -"s3-object-lambda.ap-southeast-2.amazonaws.com\0*.customer-oci.com\0yali.mythic-beasts.com\0" -"post.in\0nikon\0" -"telebit.io\0" -"shangrila\0" -"cc.in.us\0" -"venice.it\0firewall-gateway.net\0" -"compare\0my-gateway.de\0" -"catering\0" -"kvanangen.no\0" -"kariya.aichi.jp\0kozaki.chiba.jp\0iwata.shizuoka.jp\0" -"slz.br\0" -"fans\0" -"movie\0test.ru\0msk.ru\0" -"webview-assets.aws-cloud9.ap-east-1.amazonaws.com\0webview-assets.cloud9.eu-west-1.amazonaws.com\0" -"tra.kp\0" -"msk.su\0" -"ngrok.dev\0" -"home.dyndns.org\0" -"zpisdn.gov.pl\0" -"kommune.no\0oya.to\0" -"kawai.iwate.jp\0ninohe.iwate.jp\0zama.kanagawa.jp\0ine.kyoto.jp\0iizuna.nagano.jp\0sanagochi.tokushima.jp\0kawaiishop.jp\0chu.jp\0" -"abc.br\0" -"vxl.sh\0" -"emrstudio-prod.eu-central-1.amazonaws.com\0s3-object-lambda.ap-east-1.amazonaws.com\0from-mi.com\0qualifioapp.com\0" -"onporter.run\0" -"sekd1.beebyteapp.io\0" -"tv.bb\0" -"ga.us\0k12.wi.us\0" -"friuli-ve-giulia.it\0vr.it\0gov.scot\0" -"il.eu.org\0" -"farm\0" -"tv.bo\0fjell.no\0ringebu.no\0" -"shirakawa.gifu.jp\0shinichi.hiroshima.jp\0fudai.iwate.jp\0yusuhara.kochi.jp\0oyamazaki.kyoto.jp\0marumori.miyagi.jp\0kumatori.osaka.jp\0tondabayashi.osaka.jp\0ogawa.saitama.jp\0readymade.jp\0" -"tv.br\0" -"company\0nog.community\0" -"*.amplifyapp.com\0jpn.com\0app.lmpm.com\0operaunite.com\0" -"cc.hi.us\0lib.ia.us\0notebook.us-west-1.sagemaker.aws\0" -"trentinsudtirol.it\0fast\0" -"audible\0spdns.eu\0" -"doomdns.org\0isa-geek.org\0hu.eu.org\0ie.eu.org\0" -"taxi\0yodobashi\0" -"skoczow.pl\0" -"m\xc3\xa5s\xc3\xb8y.no\0s\xc3\xa1lat.no\0" -"towada.aomori.jp\0kanna.gunma.jp\0mikasa.hokkaido.jp\0kamiamakusa.kumamoto.jp\0misaki.okayama.jp\0nanyo.yamagata.jp\0handcrafted.jp\0clerk.app\0hippy.jp\0holy.jp\0" -"zlg.br\0" -"mortgage\0" -"emrappui-prod.ap-southeast-1.amazonaws.com\0shopitsite.com\0" -"photos\0notebook.ap-south-1.sagemaker.aws\0" -"ci.it\0fermo.it\0rimini.it\0" -"srht.site\0" -"bloomberg\0" -"e4.cz\0" -"gs.fm.no\0" -"fukuoka.jp\0chikushino.fukuoka.jp\0bandai.fukushima.jp\0meiwa.gunma.jp\0hitachi.ibaraki.jp\0tadotsu.kagawa.jp\0chikuma.nagano.jp\0utsunomiya.tochigi.jp\0upper.jp\0" -"am.br\0pvh.br\0" -"scholarships\0" -"ent.platform.sh\0" -"execute-api.il-central-1.amazonaws.com\0s3-website.eu-west-1.amazonaws.com\0vfs.cloud9.us-east-2.amazonaws.com\0from-al.com\0members.linode.com\0" -"sx.cn\0" -"mol.it\0br.it\0cb.it\0square7.net\0" -"*.platformsh.site\0ybo.trade\0" -"\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\x89\0" -"thuathienhue.vn\0" -"kongsberg.no\0stor-elvdal.no\0" -"hiroo.hokkaido.jp\0kunitachi.tokyo.jp\0velvet.jp\0" -"odesa.ua\0zaporizhzhe.ua\0" -"aeroport.fr\0" -"nl-ams-1.baremetal.scw.cloud\0" -"komforb.se\0coffee\0" -"tv.im\0emrnotebooks-prod.ap-southeast-1.amazonaws.com\0s3-website.dualstack.ap-south-1.amazonaws.com\0s3-object-lambda.us-east-1.amazonaws.com\0jdevcloud.com\0" -"tv.in\0" -"firewalledreplit.co\0" -"codes\0" -"tv.it\0west1-us.cloudjiffy.net\0to.gt\0" -"ddnss.de\0spdns.de\0dynvpn.de\0" -"wmcloud.org\0" -"lamborghini\0" -"pruszkow.pl\0" -"hungyen.vn\0" -"aeroclub.aero\0workinggroup.aero\0torsken.no\0" -"\xe8\x8c\xa8\xe5\x9f\x8e.jp\0shimizu.hokkaido.jp\0saito.miyazaki.jp\0hiji.oita.jp\0anan.tokushima.jp\0" -"dn.ua\0" -"not.br\0club\0" -"nom.ad\0android\0" -"nom.ag\0tv.kg\0" -"from-hi.com\0" -"fashion\0" -"group\0" -"rs.ba\0" -"wi.us\0k12.as.us\0k12.tx.us\0cruises\0" -"vall\xc3\xa9""e-d-aoste.it\0asti.it\0at.it\0to.it\0" -"orx.biz\0" -"*.alces.network\0" -"karpacz.pl\0" -"airport.aero\0" -"\xe6\x84\x9b\xe5\xaa\x9b.jp\0higashishirakawa.gifu.jp\0toki.gifu.jp\0kiso.nagano.jp\0shimosuwa.nagano.jp\0usa.oita.jp\0yonaguni.okinawa.jp\0nakaniikawa.toyama.jp\0chuo.yamanashi.jp\0platform0.app\0edgecompute.app\0typedream.app\0" -"isla.pr\0" -"ravendb.cloud\0" -"execute-api.us-gov-east-1.amazonaws.com\0from-pa.com\0outsystemscloud.com\0" -"sc.cn\0am.in\0" -"nom.co\0mock.pstmn.io\0" -"tv.na\0barcelona\0" -"computer\0" -"notebook.eu-west-1.sagemaker.aws\0" -"barclaycard\0" -"gr.eu.org\0pubtls.org\0" -"erni\0" -"sonla.vn\0" -"alesund.no\0" -"motosu.gifu.jp\0annaka.gunma.jp\0shiranuka.hokkaido.jp\0minamiuonuma.niigata.jp\0sakado.saitama.jp\0hamamatsu.shizuoka.jp\0but.jp\0girlfriend.jp\0" -"pa.gov.br\0bel.tr\0" -"smartlabeling.scw.cloud\0at.md\0to.md\0" -"photography\0" -"s3-website-us-west-2.amazonaws.com\0eu-south-1.elasticbeanstalk.com\0us-gov-east-1.elasticbeanstalk.com\0" -"kinder\0" -"nom.es\0ann-arbor.mi.us\0staples\0" -"ta.it\0" -"no-ip.org\0za.org\0" -"stjordal.no\0" -"kihoku.ehime.jp\0tachiarai.fukuoka.jp\0nanmoku.gunma.jp\0shiojiri.nagano.jp\0kunigami.okinawa.jp\0habikino.osaka.jp\0sakura.ne.jp\0" -"pb.gov.br\0nom.fr\0" -"itcouldbewor.se\0" -"citadel\0" -"s3.dualstack.sa-east-1.amazonaws.com\0is-a-llama.com\0isa-geek.com\0servehumour.com\0servequake.com\0pagexl.com\0" -"cleverapps.io\0" -"ut.us\0" -"valledaosta.it\0wpmudev.host\0" -"murmansk.su\0" -"httpbin.org\0" -"krakow.pl\0" -"froya.no\0knowsitall.info\0" -"yurihonjo.akita.jp\0higashihiroshima.hiroshima.jp\0kawakita.ishikawa.jp\0tenri.nara.jp\0tokashiki.okinawa.jp\0ama.shimane.jp\0kakegawa.shizuoka.jp\0shishikui.tokushima.jp\0arakawa.tokyo.jp\0chicappa.jp\0" -"tv.sd\0" -"agrar.hu\0" -"emrnotebooks-prod.sa-east-1.amazonaws.com\0*.awsapprunner.com\0us.com\0dyndns-blog.com\0from-ct.com\0is-a-painter.com\0is-a-socialist.com\0is-into-cartoons.com\0" -"reisen\0" -"notebook.il-central-1.sagemaker.aws\0" -"t3l3p0rt.net\0homeip.net\0community-pro.net\0" -"dyn-ip24.de\0" -"u.bg\0boldlygoingnowhere.org\0" -"tiengiang.vn\0" -"ciencia.bo\0" -"ozora.hokkaido.jp\0takasago.hyogo.jp\0higashiomi.shiga.jp\0matsuzaki.shizuoka.jp\0yonago.tottori.jp\0funahashi.toyama.jp\0" -"tv.tr\0\xe0\xb8\x97\xe0\xb8\xab\xe0\xb8\xb2\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"kerryhotels\0" -"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8b\xe0\xa4\xa4\0" -"lib.ee\0sc.ke\0bd.se\0" -"tv.tz\0" -"nom.km\0s3-accesspoint-fips.us-gov-east-1.amazonaws.com\0hu.com\0is-a-republican.com\0servecounterstrike.com\0" -"*.otap.co\0" -"sc.kr\0" -"bolzano-altoadige.it\0" -"kindle\0" -"n.bg\0" -"pp.az\0myftp.biz\0" -"bedzin.pl\0lublin.pl\0" -"gs.bu.no\0budejju.no\0frei.no\0" -"\xe5\xb3\xb6\xe6\xa0\xb9.jp\0yahiko.niigata.jp\0soja.okayama.jp\0" -"sumy.ua\0" -"sc.ls\0" -"airforce\0exchange\0" -"nom.mg\0" -"\xe8\xb4\xad\xe7\x89\xa9\0" -"execute-api.eu-south-1.amazonaws.com\0from-ga.com\0" -"cheap\0" -"nom.nc\0cc.dc.us\0notebook.ap-northeast-1.sagemaker.aws\0" -"bolzano.it\0re.it\0" -"g.bg\0at.vg\0" -"nom.ni\0" -"network\0" -"wsse.gov.pl\0" -"broker.aero\0\xc3\xa5lesund.no\0bardu.no\0b\xc3\xb8.telemark.no\0gausdal.no\0royrvik.no\0" -"nahari.kochi.jp\0taketomi.okinawa.jp\0" -"edeka\0\xd0\xbc\xd0\xb8\xd1\x80.\xd1\x80\xd1\x83\xd1\x81\0" -"frogans\0" -"fr-par-2.baremetal.scw.cloud\0s3.fr-par.scw.cloud\0" -"unicom\0s3-accesspoint-fips.dualstack.us-east-2.amazonaws.com\0s3-accesspoint.us-gov-east-1.amazonaws.com\0is-an-engineer.com\0is-with-theband.com\0*.r.appspot.com\0" -"pb.ao\0" -"nom.pa\0" -"re.kr\0wolterskluwer\0" -"studio.us-gov-east-1.sagemaker.aws\0" -"or.at\0umbria.it\0cricket\0" -"nom.pe\0" -"mc.eu.org\0" -"or.bi\0paas.datacenter.fi\0" -"gok.pk\0" -"nom.pl\0" -"ballooning.aero\0paragliding.aero\0rl.no\0gs.tr.no\0nes.akershus.no\0" -"hachijo.tokyo.jp\0" -"pharmacien.fr\0" -"riik.ee\0pri.ee\0reklam.hu\0" -"\xd8\xa7\xd9\x84\xd8\xb9\xd9\x84\xd9\x8a\xd8\xa7\xd9\x86\0" -"or.ci\0" -"\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0" -"s3-accesspoint.dualstack.eu-south-1.amazonaws.com\0s3-accesspoint.eu-south-1.amazonaws.com\0dnsdojo.com\0" -"auction\0s3.dualstack.cn-northwest-1.amazonaws.com.cn\0" -"or.cr\0" -"lib.de.us\0" -"myfast.host\0" -"nom.re\0" -"lt.eu.org\0" -"cargo.aero\0nom.ro\0" -"sera.hiroshima.jp\0yasuoka.nagano.jp\0kaizuka.osaka.jp\0oguni.yamagata.jp\0fool.jp\0kilo.jp\0" -"flap.id\0pub.instances.scw.cloud\0" -"s3.eu-west-2.amazonaws.com\0" -"beagleboard.io\0cust.testing.thingdust.io\0" -"natura\0" -"star\0" -"lib.va.us\0" -"edgeapp.net\0""2.azurestaticapps.net\0" -"nt.au\0" -"r2.dev\0" -"pisz.pl\0" -"nom.tm\0" -"gs.st.no\0\xc3\xa5snes.no\0vagan.no\0" -"shiga.jp\0kitakata.fukushima.jp\0takehara.hiroshima.jp\0kamoenai.hokkaido.jp\0sasayama.hyogo.jp\0yabu.hyogo.jp\0kamo.niigata.jp\0machida.tokyo.jp\0obanazawa.yamagata.jp\0" -"nt.ca\0" -"pi.gov.br\0jab.br\0" -"cloud\0" -"sc.ug\0" -"sc.tz\0" -"getmyip.com\0net-freaks.com\0" -"shiftedit.io\0" -"sc.us\0studio.us-west-2.sagemaker.aws\0" -"pi.it\0" -"nom.ve\0" -"klodzko.pl\0" -"crew.aero\0gjemnes.no\0kv\xc3\xa6nangen.no\0volda.no\0law.pro\0selfip.info\0" -"shitara.aichi.jp\0takayama.gifu.jp\0inagawa.hyogo.jp\0tajiri.osaka.jp\0genkai.saga.jp\0namaste.jp\0" -"or.id\0ponpes.id\0" -"surgery\0" -"s3-accesspoint.dualstack.ap-southeast-4.amazonaws.com\0s3.dualstack.me-south-1.amazonaws.com\0eu-west-2.elasticbeanstalk.com\0" -"nm.cn\0norton\0s3-object-lambda.cn-northwest-1.amazonaws.com.cn\0", - -"*.azurecontainer.io\0repl.co\0" -"ltda\0" -"oy.lc\0" -"balsan-suedtirol.it\0bulsan-s\xc3\xbc""dtirol.it\0or.it\0" -"north-kazakhstan.su\0mel.cloudlets.com.au\0" -"konin.pl\0lukow.pl\0" -"gs.sf.no\0barum.no\0marnardal.no\0nannestad.no\0rygge.no\0" -"or.jp\0ikawa.akita.jp\0chikuho.fukuoka.jp\0misugi.mie.jp\0otaki.nagano.jp\0daito.osaka.jp\0" -"nf.ca\0" -"or.ke\0" -"enscaled.sg\0" -"s3-website.ap-northeast-3.amazonaws.com\0s3-object-lambda.me-central-1.amazonaws.com\0servesarcasm.com\0" -"nom.za\0" -"or.kr\0" -"fitness\0" -"edgekey-staging.net\0" -"firmdale\0mycd.eu\0" -"pharmacy\0" -"commbank\0" -"akrehamn.no\0alvdal.no\0hol.no\0luroy.no\0nordre-land.no\0ringsaker.no\0" -"oguchi.aichi.jp\0takahama.fukui.jp\0omotego.fukushima.jp\0ibigawa.gifu.jp\0kanazawa.ishikawa.jp\0miyazaki.miyazaki.jp\0aga.niigata.jp\0katsushika.tokyo.jp\0doshi.yamanashi.jp\0" -"panasonic\0" -"u.se\0" -"emrstudio-prod.us-east-1.amazonaws.com\0s3-accesspoint.ap-southeast-4.amazonaws.com\0webview-assets.cloud9.ap-northeast-3.amazonaws.com\0" -"mo.cn\0" -"or.na\0" -"monza-e-della-brianza.it\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4\0" -"or.mu\0store\0" -"6.bg\0" -"bykle.no\0malselv.no\0webhop.info\0" -"kitagawa.kochi.jp\0aso.kumamoto.jp\0togakushi.nagano.jp\0omura.nagasaki.jp\0ina.saitama.jp\0yasugi.shimane.jp\0hirogawa.wakayama.jp\0" -"pe.gov.br\0kep.tr\0" -"jobs\0" -"ca.reclaim.cloud\0" -"n.se\0pp.se\0george\0pp.ru\0" -"mycloud.by\0" -"us-gov-west-1.elasticbeanstalk.com\0pagespeedmobilizer.com\0point2this.com\0" -"ninja\0" -"k12.nv.us\0lima-city.rocks\0" -"frosinone.it\0isa-geek.net\0kicks-ass.net\0" -"br\xc3\xb8nn\xc3\xb8ysund.no\0loab\xc3\xa1t.no\0\xc3\xb8ygarden.no\0skierv\xc3\xa1.no\0vestre-slidre.no\0ilovecollege.info\0" -"sabae.fukui.jp\0heguri.nara.jp\0takatsuki.osaka.jp\0oyama.tochigi.jp\0oshino.yamanashi.jp\0boy.jp\0" -"visa\0pp.ua\0" -"poa.br\0pa.leg.br\0" -"g.se\0" -"or.pw\0" -"s3-object-lambda.il-central-1.amazonaws.com\0is-a-techie.com\0us-4.evennode.com\0rhcloud.com\0" -"k12.ne.us\0" -"meinforum.net\0" -"red.sv\0" -"mk.eu.org\0" -"control.aero\0nt.no\0beardu.no\0bjugn.no\0b\xc3\xa1hcavuotna.no\0hareid.no\0harstad.no\0" -"kanie.aichi.jp\0oizumi.gunma.jp\0sumoto.hyogo.jp\0tosashimizu.kochi.jp\0" -"pb.leg.br\0" -"sandvikcoromant\0" -"filegear.me\0" -"qc.com\0from-id.com\0is-an-actor.com\0" -"viva\0" -"jeju.kr\0" -"k12.nh.us\0glass\0" -"mo.it\0urbino-pesaro.it\0no-ip.net\0bar1.net\0" -"or.th\0" -"pa.gov.pl\0" -"haram.no\0vivo\0" -"kamakura.kanagawa.jp\0nagasaki.nagasaki.jp\0okayama.okayama.jp\0ome.tokyo.jp\0fukumitsu.toyama.jp\0" -"coz.br\0" -"adult\0" -"nalchik.ru\0" -"or.ug\0" -"or.tz\0" -"team\0execute-api.ap-south-2.amazonaws.com\0emrstudio-prod.eu-north-1.amazonaws.com\0de.com\0dyndns-home.com\0us-3.evennode.com\0fastly-edge.com\0try-snowplow.com\0" -"5g.in\0internet.in\0" -"or.us\0minisite.ms\0" -"messina.it\0creditcard\0" -"apple\0nalchik.su\0" -"loginline.dev\0" -"fr.eu.org\0lu.eu.org\0me.eu.org\0" -"bydgoszcz.pl\0jaworzno.pl\0" -"\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4\xe0\xb1\x8d\0" -"dgca.aero\0press.aero\0sel.no\0recht.pro\0nt.ro\0" -"\xe5\x9f\xbc\xe7\x8e\x89.jp\0higashimatsushima.miyagi.jp\0komagane.nagano.jp\0iheya.okinawa.jp\0minato.osaka.jp\0haibara.shizuoka.jp\0" -"\xd0\xbe\xd0\xb4.\xd1\x81\xd1\x80\xd0\xb1\0" -"nodes.k8s.pl-waw.scw.cloud\0s3-website.pl-waw.scw.cloud\0" -"worse-than.tv\0" -"sci.eg\0" -"tech\0" -"wixsite.com\0" -"stage.nodeart.io\0" -"ok.us\0platterp.us\0" -"auspost\0" -"airkitapps.eu\0" -"lv.eu.org\0freedesktop.org\0" -"dielddanuorri.no\0avocat.pro\0" -"\xe6\x9d\xb1\xe4\xba\xac.jp\0\xe9\xab\x98\xe7\x9f\xa5.jp\0hachirogata.akita.jp\0kumakogen.ehime.jp\0jinsekikogen.hiroshima.jp\0mashiki.kumamoto.jp\0sado.niigata.jp\0kanan.osaka.jp\0" -"kiev.ua\0od.ua\0" -"pr.gov.br\0med.br\0" -"emrnotebooks-prod.eu-west-1.amazonaws.com\0s3-accesspoint.dualstack.ap-south-1.amazonaws.com\0s3-website.me-south-1.amazonaws.com\0s3.dualstack.us-west-2.amazonaws.com\0us-east-1.elasticbeanstalk.com\0us-2.evennode.com\0" -"\xe7\xbd\x91\xe7\xbb\x9c.cn\0caravan\0datsun\0emrnotebooks-prod.cn-north-1.amazonaws.com.cn\0" -"nid.io\0" -"discourse.group\0" -"k12.la.us\0analytics\0*.owo.codes\0" -"friulivenezia-giulia.it\0biella.it\0" -"*.uberspace.de\0" +"sc.cn\0bihoro.hokkaido.jp\0" +"is-a-player.com\0enterprisecloud.nu\0" +"godo.gifu.jp\0fussa.tokyo.jp\0" +"gildesk\xc3\xa5l.no\0" +"s3-accesspoint-fips.dualstack.us-gov-west-1.amazonaws.com\0" +"vivian.jp\0" +"salat.no\0" +"to.gt\0" +"psc.br\0sango.nara.jp\0" "\xe5\x80\x8b\xe4\xba\xba.hk\0" -"warszawa.pl\0\xe5\xb9\xbf\xe4\xb8\x9c\0" -"ulvik.no\0" -"shinshiro.aichi.jp\0yanaizu.fukushima.jp\0shari.hokkaido.jp\0kawanishi.hyogo.jp\0iwama.ibaraki.jp\0asaka.saitama.jp\0daa.jp\0" -"chernigov.ua\0" -"ggf.br\0" -"med.ec\0" -"med.ee\0" -"\xe6\x96\xb0\xe9\x97\xbb\0" -"emrnotebooks-prod.us-gov-east-1.amazonaws.com\0gentapps.com\0blogspot.com\0" -"anquan\0" -"eu.ngrok.io\0" -"nm.us\0" -"lc.it\0meet\0dynathome.net\0" -"curv.dev\0" -"wmflabs.org\0" -"ballangen.no\0leangaviika.no\0r\xc3\xa5""de.no\0" -"obama.fukui.jp\0tamakawa.fukushima.jp\0minakami.gunma.jp\0tomakomai.hokkaido.jp\0inashiki.ibaraki.jp\0hakui.ishikawa.jp\0toyo.kochi.jp\0chino.nagano.jp\0hidaka.saitama.jp\0" -"cruise\0" -"cool\0" -"s3-website-ap-southeast-1.amazonaws.com\0us-1.evennode.com\0" -"capetown\0" -"coop\0" -"jaguar\0" -"d.gv.vc\0" -"credit\0kinghost.net\0" -"abudhabi\0" -"\xe7\xbd\x91\xe7\xbb\x9c.hk\0\xe7\xbb\x84\xe7\xb9\x94.hk\0" -"rzeszow.pl\0tychy.pl\0" -"holt\xc3\xa5len.no\0leirfjord.no\0" -"kagoshima.jp\0\xe7\xa6\x8f\xe5\xb2\xa1.jp\0nakadomari.aomori.jp\0" -"cng.br\0flog.br\0saobernardo.br\0" -"med.ht\0" -"ras.ru\0" -"\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0better-than.tv\0" -"chintai\0" -"m\xc4\x81ori.nz\0" -"hosp.uk\0" -"emrappui-prod.ap-east-1.amazonaws.com\0s3-accesspoint.dualstack.eu-central-2.amazonaws.com\0s3-object-lambda.eu-west-3.amazonaws.com\0appspacehosted.com\0vs.mythic-beasts.com\0" -"reservd.testing.thingdust.io\0" -"mo.us\0" -"varese.it\0akamai.net\0" -"folionetwork.site\0" -"kr.eu.org\0" -"bodo.no\0krodsherad.no\0kafjord.no\0lyngen.no\0sokndal.no\0tysfjord.no\0" -"tochigi.jp\0\xe5\xba\x83\xe5\xb3\xb6.jp\0hitachiota.ibaraki.jp\0kashima.ibaraki.jp\0kitadaito.okinawa.jp\0tamayu.shimane.jp\0yura.wakayama.jp\0abu.yamaguchi.jp\0" -"\xe6\x94\xbf\xe5\x8a\xa1\0" -"mus.br\0vlog.br\0pi.leg.br\0" -"markets\0" -"barsy.support\0" -"kustanai.ru\0" -"s3-accesspoint.dualstack.eu-west-2.amazonaws.com\0framercanvas.com\0rackmaze.com\0" -"courses\0" -"nhlfan.net\0" -"kustanai.su\0goip.de\0" -"ngo.lk\0" -"unicloud.pl\0" -"economia.bo\0industria.bo\0gs.mr.no\0rissa.no\0\xc4\x8d\xc3\xa1hcesuolo.no\0acct.pro\0" -"fukui.jp\0kitaakita.akita.jp\0kawaue.gifu.jp\0suzuka.mie.jp\0taki.mie.jp\0agano.niigata.jp\0" -"meme\0dnsfor.me\0" -"med.ly\0" -"maori.nz\0" -"s3.ap-south-2.amazonaws.com\0s3-accesspoint.us-west-1.amazonaws.com\0analytics-gateway.eu-central-1.amazonaws.com\0vfs.cloud9.ap-east-1.amazonaws.com\0cechire.com\0" -"\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0" -"ju.mp\0" -"ma.us\0\xd8\xa8\xd9\x8a\xd8\xaa\xd9\x83\0" -"siena.it\0broke-it.net\0" -"col.ng\0ngo.ng\0" -"*.telebit.xyz\0" -"government.aero\0grane.no\0tokke.no\0" -"fuso.aichi.jp\0nanporo.hokkaido.jp\0shirosato.ibaraki.jp\0sagamihara.kanagawa.jp\0tsuyama.okayama.jp\0showa.yamanashi.jp\0" -"jele.club\0" -"games.hu\0news.hu\0menu\0" -"med.om\0auth.me-south-1.amazoncognito.com\0s3-accesspoint-fips.dualstack.ca-central-1.amazonaws.com\0s3-accesspoint.me-central-1.amazonaws.com\0vfs.cloud9.eu-north-1.amazonaws.com\0from-va.com\0" -"hk.cn\0notebook.cn-north-1.sagemaker.com.cn\0" -"med.pa\0" -"trentin-sud-tirol.it\0trentin-sudtirol.it\0" -"lenug.su\0" -"surf\0" -"plumbing\0ufcfan.org\0" -"ngo.ph\0" -"winb.gov.pl\0kobierzyce.pl\0med.pl\0" -"samnanger.no\0" -"inuyama.aichi.jp\0tsumagoi.gunma.jp\0nemuro.hokkaido.jp\0shibecha.hokkaido.jp\0toya.hokkaido.jp\0samukawa.kanagawa.jp\0uda.nara.jp\0yakage.okayama.jp\0sennan.osaka.jp\0satte.saitama.jp\0perma.jp\0" -"ks.ua\0" -"gov.nc.tr\0" -"vfs.cloud9.ap-southeast-2.amazonaws.com\0discourse.team\0miniserver.com\0" -"bihar.in\0" -"ks.us\0lib.nv.us\0" -"isteingeek.de\0" -"\xe7\xae\x87\xe4\xba\xba.hk\0" -"po.gov.pl\0psp.gov.pl\0\xe4\xb8\x96\xe7\x95\x8c\0" -"*.user.fm\0" -"ninhthuan.vn\0akdn\0" -"herad.no\0ovre-eiker.no\0\xc3\xb8vre-eiker.no\0" -"yotsukaido.chiba.jp\0kasuya.fukuoka.jp\0ogaki.gifu.jp\0chitose.hokkaido.jp\0ryugasaki.ibaraki.jp\0tamatsukuri.ibaraki.jp\0shizukuishi.iwate.jp\0myoko.niigata.jp\0izena.okinawa.jp\0minano.saitama.jp\0nagahama.shiga.jp\0theshop.jp\0" -"med.sa\0" -"udi.br\0pe.leg.br\0" -"med.sd\0" -"s3-website.us-gov-west-1.amazonaws.com\0hobby-site.com\0" -"qpon\0" -"studio\0" -"teva\0" -"lib.mo.us\0" -"alto-adige.it\0" -"catholic.edu.au\0" -"*.stg.dev\0" -"warmia.pl\0" -"langson.vn\0" -"bronnoysund.no\0kirkenes.no\0langev\xc3\xa5g.no\0svelvik.no\0vegarshei.no\0" -"tarui.gifu.jp\0kiryu.gunma.jp\0tomioka.gunma.jp\0kimobetsu.hokkaido.jp\0tanohata.iwate.jp\0matsuda.kanagawa.jp\0motegi.tochigi.jp\0aogashima.tokyo.jp\0" -"bib.br\0est.pr\0" -"boats\0" -"science\0" -"security\0" -"\xd8\xa7\xd8\xaa\xd8\xb5\xd8\xa7\xd9\x84\xd8\xa7\xd8\xaa\0za.bz\0" -"independent-commission.uk\0" -"s3-accesspoint-fips.ca-central-1.amazonaws.com\0" -"business.in\0" -"tickets.io\0" -"in-addr.arpa\0camera\0pizza\0" -"k12.il.us\0cc.md.us\0lib.mt.us\0lib.nd.us\0" -"andriatranibarletta.it\0""2ix.at\0" -"guide\0lotte\0" -"kicks-ass.org\0" -"\xe7\xb5\x84\xe7\xbb\x87.hk\0" -"kutno.pl\0" -"vinhphuc.vn\0indie.porn\0" -"aukra.no\0bronnoy.no\0klepp.no\0ivgu.no\0sor-odal.no\0lotto\0" -"fukui.fukui.jp\0higashiagatsuma.gunma.jp\0ayase.kanagawa.jp\0watson.jp\0" -"campinas.br\0" -"2ix.ch\0" -"xz.cn\0" -"loginline.io\0" -"lib.nm.us\0" -"modena.it\0" -"luxe\0website\0*.cloudera.site\0bryansk.su\0""2ix.de\0" -"h\xc3\xa4kkinen.fi\0" -"deporte.bo\0h\xc3\xb8nefoss.no\0stj\xc3\xb8rdalshalsen.no\0farsund.no\0jolster.no\0stokke.no\0somna.no\0" -"hakuba.nagano.jp\0ito.shizuoka.jp\0kushimoto.wakayama.jp\0" -"kropyvnytskyi.ua\0" -"jprs\0" -"wellbeingzone.co.uk\0" -"memorial\0" -"s3-accesspoint-fips.us-east-2.amazonaws.com\0" -"s3.dualstack.cn-north-1.amazonaws.com.cn\0" -"ngo.za\0" -"latina.it\0intuit\0r.cdn77.net\0beta.tailscale.net\0" -"earth\0*.bzz.dapps.earth\0" -"gorlice.pl\0" -"stat.no\0stavern.no\0roan.no\0" -"higashi.fukushima.jp\0oshu.iwate.jp\0ozu.kumamoto.jp\0tagajo.miyagi.jp\0oyodo.nara.jp\0tamano.okayama.jp\0iwatsuki.saitama.jp\0toda.saitama.jp\0ichiba.tokushima.jp\0nagai.yamagata.jp\0" -"expert\0" -"s3-accesspoint.eu-central-1.amazonaws.com\0s3-website.sa-east-1.amazonaws.com\0s3-object-lambda.us-east-2.amazonaws.com\0s3-website.us-gov-east-1.amazonaws.com\0vfs.cloud9.us-east-1.amazonaws.com\0mytuleap.com\0" -"soccer\0" -"andria-trani-barletta.it\0monzaedellabrianza.it\0podzone.net\0" -"git-repos.de\0svn-repos.de\0opensocial.site\0byen.site\0" -"certmgr.org\0" -"pr.gov.pl\0" -"bahcavuotna.no\0elverum.no\0skedsmo.no\0" -"\xe5\xae\xae\xe5\x9f\x8e.jp\0kagoshima.kagoshima.jp\0settsu.osaka.jp\0" -"odo.br\0pr.leg.br\0" -"*.banzai.cloud\0" -"aivencloud.com\0" -"lombardia.it\0mantova.it\0monzaebrianza.it\0" -"act.au\0" -"spdns.org\0" -"ostroleka.pl\0" -"\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xaa\xe0\xaf\x82\xe0\xae\xb0\xe0\xaf\x8d\0" -"b\xc3\xa1jddar.no\0fl\xc3\xa5.no\0hobol.no\0r\xc3\xa1hkker\xc3\xa1vju.no\0lesja.no\0midsund.no\0vikna.no\0" -"\xe5\x92\x8c\xe6\xad\x8c\xe5\xb1\xb1.jp\0tsushima.nagasaki.jp\0ojiya.niigata.jp\0okutama.tokyo.jp\0her.jp\0" -"\xd8\xa7\xd8\xb1\xd8\xa7\xd9\x85\xd9\x83\xd9\x88\0" -"channel\0" -"commune.am\0execute-api.eu-west-3.amazonaws.com\0cn.com\0uy.com\0is-a-landscaper.com\0beta.bounty-full.com\0remotewd.com\0" -"lib.ky.us\0" -"catanzaro.it\0" -"secure\0" -"clothing\0" -"univ.bj\0" -"slask.pl\0" -"kvitsoy.no\0" -"noheji.aomori.jp\0koori.fukushima.jp\0kasai.hyogo.jp\0oi.kanagawa.jp\0takamori.kumamoto.jp\0obuse.nagano.jp\0kawazu.shizuoka.jp\0yaizu.shizuoka.jp\0wajiki.tokushima.jp\0" -"priv.hu\0rocky.page\0" -"on-the-web.tv\0" -"bip.sh\0" -"api.gov.uk\0" -"s3-accesspoint-fips.us-gov-west-1.amazonaws.com\0" -"gyeongbuk.kr\0dealer\0" -"viajes\0watches\0" -"friuliveneziagiulia.it\0" -"l-o-g-i-n.de\0fuettertdasnetz.de\0" -"es.eu.org\0" -"mw.gov.pl\0ecommerce-shop.pl\0" -"equipment.aero\0works.aero\0andebu.no\0lindesnes.no\0vaapste.no\0bci.dnstrace.pro\0" -"chiyoda.gunma.jp\0ora.gunma.jp\0nonoichi.ishikawa.jp\0otsuchi.iwate.jp\0tomigusuku.okinawa.jp\0shinjuku.tokyo.jp\0tabuse.yamaguchi.jp\0" -"chirurgiens-dentistes.fr\0" -"dance\0vps.mcdir.ru\0" -"execute-api.af-south-1.amazonaws.com\0s3.eu-north-1.amazonaws.com\0s3-website.dualstack.us-west-2.amazonaws.com\0is-a-student.com\0" -"republican\0" -"*.on-acorn.io\0" -"simplesite.gr\0" -"studio.sa-east-1.sagemaker.aws\0" -"bari.it\0" -"customer.speedpartner.de\0" -"trading\0" -"cloudns.biz\0" -"malbork.pl\0" -"mosjoen.no\0enebakk.no\0namsskogan.no\0" -"aomori.aomori.jp\0chonan.chiba.jp\0tanagura.fukushima.jp\0erimo.hokkaido.jp\0otaru.hokkaido.jp\0kakuda.miyagi.jp\0kitahata.saga.jp\0" -"ms.gov.br\0morena.br\0" -"casino.hu\0pyatigorsk.ru\0" -"s3.dualstack.ap-northeast-1.amazonaws.com\0s3-website.dualstack.ap-northeast-3.amazonaws.com\0s3-website.ap-south-1.amazonaws.com\0betainabox.com\0" -"*.build.run\0" -"cc.il.us\0holdings\0" -"bulsan-sudtirol.it\0""123homepage.it\0priv.at\0service.gov.scot\0" -"tselinograd.su\0" -"for-more.biz\0" -"mielno.pl\0williamhill\0" -"h\xc3\xa1pmir.no\0rollag.no\0ollo\0" -"minami.fukuoka.jp\0miharu.fukushima.jp\0taishi.hyogo.jp\0iwaizumi.iwate.jp\0shinkamigoto.nagasaki.jp\0miyake.nara.jp\0satosho.okayama.jp\0" -"mt.gov.br\0taxi.br\0" -"perspecta.cloud\0" -"forum.hu\0" -"gallery\0" -"chanel\0" -"s3-website.ca-central-1.amazonaws.com\0appspaceusercontent.com\0stufftoread.com\0" -"trentino-altoadige.it\0westus2.azurestaticapps.net\0de.gt\0" -"bib.ve\0fastvps.site\0" -"loisirs.bj\0" -"web.bo\0nissedal.no\0nyan.to\0" -"fuchu.hiroshima.jp\0embetsu.hokkaido.jp\0mifune.kumamoto.jp\0tado.mie.jp\0shimoichi.nara.jp\0okinawa.okinawa.jp\0xii.jp\0" -"\xe4\xb8\xad\xe4\xbf\xa1\0" -"tsk.tr\0" -"jetzt\0" -"fh.se\0" -"supply\0" -"s3.us-west-1.amazonaws.com\0webview-assets.cloud9.ap-southeast-2.amazonaws.com\0codespot.com\0" -"web.co\0github.io\0" -"studio.eu-west-3.sagemaker.aws\0" -"emr.it\0trentino-s-tirol.it\0florence.it\0novara.it\0olbia-tempio.it\0" -"bialowieza.pl\0" -"web.do\0skodje.no\0" -"misawa.aomori.jp\0mitsuke.niigata.jp\0nakijin.okinawa.jp\0abeno.osaka.jp\0loginline.app\0" -"rio.br\0simplesite.com.br\0port.fr\0" -"spb.ru\0" -"ally\0" -"vfs.cloud9.eu-west-2.amazonaws.com\0from-in.com\0encoreapi.com\0" -"cn.in\0education\0" -"data\0" -"studio.ap-south-1.sagemaker.aws\0" -"cn.it\0vi.it\0nextdirect\0" -"asn.au\0date\0spb.su\0" -"simplesite.pl\0" -"vinhlong.vn\0" -"stavanger.no\0" -"iwakura.aichi.jp\0yusui.kagoshima.jp\0taiki.mie.jp\0hita.oita.jp\0yoshida.saitama.jp\0streamlit.app\0" -"de.ls\0" -"perso.ht\0tn.oxa.cloud\0de.md\0" -"hb.cldmail.ru\0" -"emrnotebooks-prod.eu-west-3.amazonaws.com\0s3-accesspoint.eu-south-2.amazonaws.com\0s3-external-1.amazonaws.com\0mydatto.com\0barsycenter.com\0" -"hostyhosting.io\0" -"k12.vi.us\0" -"friuli-vgiulia.it\0tos.it\0vb.it\0" -"sa.edu.au\0web.gu\0" -"fi.eu.org\0" -"tm.cy\0richardli\0" -"nowruz\0" -"prochowice.pl\0" -"nat.tn\0laichau.vn\0" -"luster.no\0v\xc3\xa5gs\xc3\xb8y.no\0" -"yamaguchi.jp\0matsumae.hokkaido.jp\0noto.ishikawa.jp\0kitagawa.miyazaki.jp\0minamiaiki.nagano.jp\0kashima.saga.jp\0yoshinogari.saga.jp\0gotsu.shimane.jp\0kita.tokyo.jp\0clerkstage.app\0" -"shop.ht\0web.id\0" -"pvt.ge\0shop.hu\0" -"tm.dz\0" -"s3-website.dualstack.af-south-1.amazonaws.com\0" -"uk.in\0agakhan\0web.in\0" -"sakura\0" -"community-pro.de\0" -"nflfan.org\0" -"webhop.biz\0" -"slupsk.pl\0" -"hjartdal.no\0k\xc3\xa1r\xc3\xa1\xc5\xa1johka.no\0" -"yokote.akita.jp\0sannohe.aomori.jp\0onojo.fukuoka.jp\0iwamizawa.hokkaido.jp\0uchinada.ishikawa.jp\0nishinoshima.shimane.jp\0" -"odessa.ua\0" -"sorocaba.br\0tmp.br\0tm.fr\0" -"de.trendhosting.cloud\0" -"uk.kg\0" -"independent-inquiry.uk\0" -"tt.im\0execute-api.ap-southeast-2.amazonaws.com\0execute-api.us-gov-west-1.amazonaws.com\0s3.dualstack.eu-south-2.amazonaws.com\0elasticbeanstalk.com\0dojin.com\0" -"univ.sn\0" -"abo.pa\0" -"sucks\0supplies\0" -"bi.it\0ud.it\0rackmaze.net\0" -"melbourne\0traeumtgerade.de\0" -"web.lk\0" -"bjerkreim.no\0r\xc3\xb8mskog.no\0sorum.no\0vestby.no\0" -"soni.nara.jp\0ginowan.okinawa.jp\0nakagusuku.okinawa.jp\0nasu.tochigi.jp\0ohtawara.tochigi.jp\0nyanta.jp\0" -"\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x90\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\xa5.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"oxa.cloud\0" -"tm.hu\0" -"delivery\0" -"lefrak\0" -"auth.eu-central-1.amazoncognito.com\0s3-accesspoint.dualstack.ap-southeast-1.amazonaws.com\0stackhero-network.com\0" -"sh.cn\0" -"athleta\0" -"notebook.af-south-1.sagemaker.aws\0" -"ar.it\0adobeaemcloud.net\0u.channelsdvr.net\0""32-b.it\0mymediapc.net\0" -"sa.au\0" -"web.nf\0autocode.dev\0*.stgstage.dev\0" -"amex\0" -"web.ni\0" -"\xd0\xb1\xd0\xb5\xd0\xbb\0" -"\xd0\xbe\xd0\xbd\xd0\xbb\xd0\xb0\xd0\xb9\xd0\xbd\0" -"cantho.vn\0" -"engerdal.no\0varoy.no\0" -"nagareyama.chiba.jp\0yoro.gifu.jp\0akashi.hyogo.jp\0kanzaki.saga.jp\0" -"vodka\0" -"microsoft\0" -"iwi.nz\0" -"glug.org.uk\0" -"tm.km\0emrappui-prod.ap-south-1.amazonaws.com\0s3-accesspoint.dualstack.ca-central-1.amazonaws.com\0writesthisblog.com\0orsites.com\0" -"uk0.bigv.io\0id.forgerock.io\0" -"gob.ar\0sa.cr\0" -"de.us\0golffan.us\0" -"sv.it\0" -"dnsupdater.de\0synology-diskstation.de\0" -"jp.eu.org\0" -"web.pk\0" -"basketball\0aus.basketball\0" -"gob.bo\0stjordalshalsen.no\0" -"!city.kitakyushu.jp\0seto.aichi.jp\0amami.kagoshima.jp\0" -"cn.ua\0" -"tm.mc\0" -"123paginaweb.pt\0" -"dagestan.ru\0" -"asn.lv\0" -"tm.mg\0" -"search\0" -"gob.cl\0prudential\0" -"emrstudio-prod.ap-east-1.amazonaws.com\0s3-object-lambda.ap-south-1.amazonaws.com\0me-south-1.elasticbeanstalk.com\0ryd.wafaicloud.com\0ladesk.com\0" -"vi.us\0" -"val-d-aosta.it\0so.it\0embaixada.st\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4\0" -"aquarelle\0dagestan.su\0" -"homeftp.org\0podzone.org\0" -"ybo.faith\0" -"priv.pl\0" -"aerodrome.aero\0gob.do\0tm.no\0\xc3\xb8rland.no\0ralingen.no\0" -"ad.jp\0yugawa.fukushima.jp\0sakawa.kochi.jp\0higashiyama.kyoto.jp\0tsuno.miyazaki.jp\0yamazoe.nara.jp\0yoshino.nara.jp\0ivory.ne.jp\0" -"gob.ec\0" -"cn.vu\0" -"\xd8\xa8\xd8\xa7\xd8\xb1\xd8\xaa\0" -"auth.ca-central-1.amazoncognito.com\0s3-fips.dualstack.ca-central-1.amazonaws.com\0s3-ap-southeast-2.amazonaws.com\0is-a-therapist.com\0freebox-os.com\0fentiger.mythic-beasts.com\0" -"gob.es\0gratis\0studio.us-gov-west-1.sagemaker.aws\0studio-fips.us-gov-west-1.sagemaker.aws\0" -"ham-radio-op.net\0" -"conf.au\0lebtimnetz.de\0" -"z.bg\0" -"web.tj\0" -"tm.pl\0" -"priv.no\0batsfjord.no\0tydal.no\0dnsupdate.info\0" -"gifu.jp\0asahi.chiba.jp\0mitake.gifu.jp\0niikappu.hokkaido.jp\0matsuura.nagasaki.jp\0naha.okinawa.jp\0" -"des.br\0web.tr\0" -"coupons\0" -"soundcast.me\0" -"muni.il\0" -"vfs.cloud9.eu-central-1.amazonaws.com\0familyds.com\0" -"s3-deprecated.cn-north-1.amazonaws.com.cn\0" -"qoto.io\0apps.lair.io\0" -"pictures\0" -"gob.gt\0sa.it\0trani-barletta-andria.it\0channelsdvr.net\0jelastic.saveincloud.net\0" -"schools.nsw.edu.au\0web.ve\0progressive\0" -"s.bg\0readmyblog.org\0in-dsl.org\0" -"econo.bj\0" -"legnica.pl\0gliwice.pl\0" -"gob.hn\0" -"hammarfeasta.no\0mosvik.no\0odda.no\0osteroy.no\0tm.ro\0" -"okazaki.aichi.jp\0gifu.gifu.jp\0mino.gifu.jp\0toyosato.shiga.jp\0" -"rep.br\0" -"discount\0" -"priv.me\0tm.se\0" -"ricoh\0" -"myiphost.com\0" -"ericsson\0cn-northwest-1.eb.amazonaws.com.cn\0" -"devices.resinstaging.io\0" -"balsan-sudtirol.it\0easypanel.host\0j.scaleforce.net\0ddns.net\0" -"l.bg\0" -"rexroth\0" -"r\xc3\xb8ros.no\0abogado\0" -"isumi.chiba.jp\0mobara.chiba.jp\0higashikagura.hokkaido.jp\0komatsu.ishikawa.jp\0joyo.kyoto.jp\0ohira.miyagi.jp\0yoita.niigata.jp\0hasuda.saitama.jp\0itigo.jp\0" -"tiaa\0" -"ms.leg.br\0" -"rentals\0" -"*.compute-1.amazonaws.com\0s3.ap-southeast-4.amazonaws.com\0s3.dualstack.us-east-2.amazonaws.com\0is-a-lawyer.com\0" -"perso.sn\0" -"makeup\0" -"web.za\0" -"ar.us\0" -"lig.it\0rc.it\0vibovalentia.it\0centralus.azurestaticapps.net\0" -"dyn.home-webserver.de\0" -"e.bg\0" -"gop.pk\0" -"perso.tn\0" -"norddal.no\0voagat.no\0" -"narita.chiba.jp\0etajima.hiroshima.jp\0minamimaki.nagano.jp\0morimachi.shizuoka.jp\0hokuto.yamanashi.jp\0staba.jp\0a.run.app\0" -"santoandre.br\0mt.leg.br\0" -"\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" -"execute-api.ap-south-1.amazonaws.com\0s3.dualstack.ap-southeast-3.amazonaws.com\0s3-ca-central-1.amazonaws.com\0" -"construction\0studio.cn-north-1.sagemaker.com.cn\0" -"ak.us\0" -"ferrara.it\0pavia.it\0" -"other.nf\0" -"gob.mx\0shop.th\0" -"gob.ni\0" -"mypep.link\0" -"boleslawiec.pl\0" -"haiphong.vn\0" -"honefoss.no\0hammerfest.no\0nittedal.no\0vard\xc3\xb8.no\0" -"ainan.ehime.jp\0kanmaki.nara.jp\0aguni.okinawa.jp\0kitanakagusuku.okinawa.jp\0higashisumiyoshi.osaka.jp\0tsuruoka.yamagata.jp\0" -"gitapp.si\0" -"s3-accesspoint.dualstack.us-east-2.amazonaws.com\0*.ocs.customer-oci.com\0ip.linodeusercontent.com\0xnbay.com\0" -"gob.pa\0tm.za\0" -"incheon.kr\0" -"\xe8\x87\xba\xe7\x81\xa3\0swiss\0studio.il-central-1.sagemaker.aws\0" -"cesenaforli.it\0pu.it\0hicam.net\0" -"gob.pe\0" -"living\0" -"\xd8\xa7\xd8\xa8\xd9\x88\xd8\xb8\xd8\xa8\xd9\x8a\0" -"gob.pk\0dclk\0" -"konsulat.gov.pl\0" -"airline.aero\0grimstad.no\0naroy.no\0shop.ro\0" -"toyoake.aichi.jp\0sakura.chiba.jp\0masaki.ehime.jp\0esan.hokkaido.jp\0shimokawa.hokkaido.jp\0urakawa.hokkaido.jp\0zao.miyagi.jp\0iki.nagasaki.jp\0suita.osaka.jp\0arakawa.saitama.jp\0kosei.shiga.jp\0kainan.tokushima.jp\0" -"\xe1\x83\x92\xe1\x83\x94\0" -"demo.datadetect.com\0" -"rep.kp\0" -"locker\0" -"associates\0" -"trentino-sued-tirol.it\0vall\xc3\xa9""edaoste.it\0pn.it\0" -"eero.online\0" -"azimuth.network\0" -"shop.pl\0swidnik.pl\0" -"moss.no\0trondheim.no\0fido\0" -"seki.gifu.jp\0chippubetsu.hokkaido.jp\0yawata.kyoto.jp\0nikko.tochigi.jp\0mugi.tokushima.jp\0shunan.yamaguchi.jp\0rdy.jp\0" -"ong.br\0" -"farmers\0" -"\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa\0" -"*.us-west-2.airflow.amazonaws.com\0s3-website.dualstack.us-west-1.amazonaws.com\0awsglobalaccelerator.com\0likescandy.com\0onfabrica.com\0" -"pg.in\0" -"notebook.us-east-1.sagemaker.aws\0" -"pg.it\0tempurl.host\0co.krd\0" -"*.triton.zone\0" -"gob.sv\0" -"microlight.aero\0oksnes.no\0v\xc3\xa6r\xc3\xb8y.no\0" -"mihara.hiroshima.jp\0marugame.kagawa.jp\0tokorozawa.saitama.jp\0hikone.shiga.jp\0hikimi.shimane.jp\0susono.shizuoka.jp\0mima.tokushima.jp\0murayama.yamagata.jp\0" -"\xe3\x82\xa2\xe3\x83\x9e\xe3\x82\xbe\xe3\x83\xb3\0" -"weatherchannel\0" -"execute-api.ap-northeast-2.amazonaws.com\0execute-api.us-west-1.amazonaws.com\0s3-accesspoint.dualstack.eu-central-1.amazonaws.com\0s3-eu-west-2.amazonaws.com\0" -"studio.us-east-2.sagemaker.aws\0" -"cal.it\0etisalat\0blog.gt\0" -"gob.ve\0" -"gotdns.org\0" -"kddi\0" -"charter.aero\0revista.bo\0sandoy.no\0tynset.no\0" -"kanagawa.jp\0chikusei.ibaraki.jp\0takatori.nara.jp\0yamagata.yamagata.jp\0" -"the.br\0" -"z.se\0conf.se\0" -"study\0" -"execute-api.sa-east-1.amazonaws.com\0webview-assets.aws-cloud9.sa-east-1.amazonaws.com\0" -"lib.as.us\0graphics\0" -"cesena-forl\xc3\xac.it\0matera.it\0savona.it\0" -"is.eu.org\0" -"football\0" -"nghean.vn\0" -"blog.bo\0froland.no\0l\xc3\xa6rdal.no\0vaksdal.no\0" -"\xe5\xb2\x90\xe9\x98\x9c.jp\0nakagawa.fukuoka.jp\0sarufutsu.hokkaido.jp\0takikawa.hokkaido.jp\0uchihara.ibaraki.jp\0muroto.kochi.jp\0yonezawa.yamagata.jp\0hayakawa.yamanashi.jp\0" -"blog.br\0" -"sex.hu\0s.se\0" -"analytics-gateway.us-west-2.amazonaws.com\0is-a-hunter.com\0" -"crd.co\0" -"int.ar\0gangwon.kr\0" -"k12.ny.us\0notebook.eu-north-1.sagemaker.aws\0" -"4.bg\0it.eu.org\0" -"mini\0" -"int.az\0" -"film\0" -"thaibinh.vn\0" -"pilot.aero\0int.bo\0mo-i-rana.no\0stathelle.no\0" -"tateyama.chiba.jp\0ogori.fukuoka.jp\0kembuchi.hokkaido.jp\0hanamaki.iwate.jp\0ichinoseki.iwate.jp\0tono.iwate.jp\0ebina.kanagawa.jp\0yasuda.kochi.jp\0kiwa.mie.jp\0kamitsue.oita.jp\0chillout.jp\0" -"from.hr\0" -"tips\0" -"mint\0it1.jenv-aruba.cloud\0" -"l.se\0" -"int.ci\0" -"no-ip.co.uk\0" -"s3.il-central-1.amazonaws.com\0s3-accesspoint.us-west-2.amazonaws.com\0postman-echo.com\0neko.am\0" -"int.co\0" -"cc.sd.us\0" -"mypsx.net\0" -"int.cv\0" -"rybnik.pl\0" -"loten.no\0" -"rikubetsu.hokkaido.jp\0kanoya.kagoshima.jp\0minami.kyoto.jp\0morotsuka.miyazaki.jp\0yamagata.nagano.jp\0nishiawakura.okayama.jp\0koza.wakayama.jp\0" -"e.se\0politie\0travelersinsurance\0" -"emrnotebooks-prod.eu-central-1.amazonaws.com\0dyndns-mail.com\0from-tn.com\0quicksytes.com\0" -"realtor\0" -"k12.ms.us\0k12.nc.us\0" -"emilia-romagna.it\0mt.it\0" -"istmein.de\0draydns.de\0" -"in.eu.org\0" -"council.aero\0\xc3\xa1lt\xc3\xa1.no\0hjelmeland.no\0sirdal.no\0" -"kaho.fukuoka.jp\0inawashiro.fukushima.jp\0sakahogi.gifu.jp\0hitachiomiya.ibaraki.jp\0tone.ibaraki.jp\0arita.saga.jp\0koganei.tokyo.jp\0tanabe.wakayama.jp\0" -"inf.br\0" -"yombo.me\0" -"beauty\0" -"dyndns-free.com\0" -"kitchen\0emrnotebooks-prod.cn-northwest-1.amazonaws.com.cn\0" -"bradesco\0" -"studio.eu-west-1.sagemaker.aws\0" -"aosta-valley.it\0brescia.it\0caltanissetta.it\0como.it\0parma.it\0homeftp.net\0" -"inf.cu\0fire\0" -"*.lclstage.dev\0" -"fi.cloudplatform.fi\0" -"sex.pl\0" -"orkanger.no\0sandnessjoen.no\0finnoy.no\0h\xc3\xa1mm\xc3\xa1rfeasta.no\0" -"ichinomiya.chiba.jp\0furudono.fukushima.jp\0hitachinaka.ibaraki.jp\0wazuka.kyoto.jp\0komono.mie.jp\0toba.mie.jp\0zombie.jp\0" -"\xec\x82\xbc\xec\x84\xb1\0" -"read\0" -"fhv.se\0" -"conf.lv\0" -"fish\0" -"myspreadshop.co.uk\0" -"lplfinancial\0" -"authgear-staging.com\0" -"int.in\0" -"int.is\0k12.me.us\0" -"pescara.it\0trust\0akamaized.net\0" -"naklo.pl\0" -"magazine.aero\0\xc3\xa5seral.no\0orsta.no\0os.hedmark.no\0porsgrunn.no\0" -"toyama.toyama.jp\0" -"edgestack.me\0vp4.me\0" -"eun.eg\0" -"emrnotebooks-prod.ap-south-1.amazonaws.com\0s3.dualstack.us-gov-west-1.amazonaws.com\0doesntexist.com\0from-ia.com\0unusualperson.com\0" -"int.la\0bnr.la\0" -"observer\0" -"ny.us\0cupcake.is\0" -"trentinosued-tirol.it\0carrara-massa.it\0lo.it\0moonscale.net\0in-dsl.net\0bar0.net\0" -"qld.gov.au\0mein-iserv.de\0" -"int.lk\0" -"indigena.bo\0ibestad.no\0lierne.no\0storfjord.no\0" -"shingu.fukuoka.jp\0katashina.gunma.jp\0isahaya.nagasaki.jp\0chuo.osaka.jp\0omihachiman.shiga.jp\0setagaya.tokyo.jp\0oe.yamagata.jp\0mongolian.jp\0" -"curitiba.br\0" -"builders\0" -"blog.vu\0" -"\xd8\xb3\xd9\x88\xd8\xaf\xd8\xa7\xd9\x86\0" -"independent-panel.uk\0" -"deal\0" -"ap-south-1.elasticbeanstalk.com\0" -"js.cn\0development.run\0" -"lib.ri.us\0wales\0studio.eu-south-1.sagemaker.aws\0" -"azurestaticapps.net\0pages.torproject.net\0" -"cloud.interhostsolutions.be\0" -"int.mv\0" -"int.mw\0is-a-linux-user.org\0" -"int.ni\0" -"\xce\xb5\xce\xbb\0" -"gs.ol.no\0kautokeino.no\0rendalen.no\0" -"\xe6\x96\xb0\xe6\xbd\x9f.jp\0\xe9\x9d\x99\xe5\xb2\xa1.jp\0kiyosato.hokkaido.jp\0urausu.hokkaido.jp\0nishihara.kumamoto.jp\0togura.nagano.jp\0ibara.okayama.jp\0miyashiro.saitama.jp\0kusatsu.shiga.jp\0kanuma.tochigi.jp\0crap.jp\0" -"eti.br\0ac.gov.br\0" -"sec.ps\0" -"\xce\xb5\xcf\x85\0" -"emrnotebooks-prod.ap-southeast-3.amazonaws.com\0instance.datadetect.com\0" -"jl.cn\0" -"hiphop\0" -"\xd9\x82\xd8\xb7\xd8\xb1\0" -"tennis\0" -"aostavalley.it\0" -"accenture\0institute\0vote\0kurgan.su\0" -"giving\0" -"blogspot.com.cy\0" -"kazimierz-dolny.pl\0""123website.nl\0" -"statefarm\0" -"namdinh.vn\0" -"student.aero\0voto\0" -"togane.chiba.jp\0mombetsu.hokkaido.jp\0tsukuba.ibaraki.jp\0higashiosaka.osaka.jp\0aisho.shiga.jp\0yasu.shiga.jp\0himi.toyama.jp\0egoism.jp\0" -"bargains\0" -"int.pt\0" -"blogspot.com.ee\0magnet.page\0" -"blogspot.com.eg\0" -"inf.mk\0" -"auth.ap-southeast-3.amazoncognito.com\0is-certified.com\0kilatiron.com\0xen.prgmr.com\0" -"berlin\0" -"career\0blogspot.com.ar\0" -"mt.us\0nd.us\0notebook.us-east-2.sagemaker.aws\0" -"arezzo.it\0s\xc3\xbc""dtirol.it\0turin.it\0reit\0se.net\0ru.net\0" -"\xd5\xb0\xd5\xa1\xd5\xb5\0blogspot.com.au\0" -"ltd.cy\0" -"gulen.no\0" -"utashinai.hokkaido.jp\0kakogawa.hyogo.jp\0kibichuo.okayama.jp\0yuza.yamagata.jp\0" -"media\0" -"blogspot.com.br\0" -"int.ru\0""123website.lu\0synology.me\0" -"blogspot.com.by\0" -"execute-api.eu-west-2.amazonaws.com\0uk.com\0from-ne.com\0paas.massivegrid.com\0" -"open\0" -"blogspot.com.co\0protonet.io\0" -"lawyer\0" -"host\0cloudaccess.host\0jele.host\0edu.krd\0" -"firewall-gateway.de\0" -"mozilla-iot.org\0" -"int.tj\0" -"mosj\xc3\xb8""en.no\0" -"aichi.jp\0hashikami.aomori.jp\0aizubange.fukushima.jp\0kakamigahara.gifu.jp\0minamiise.mie.jp\0kashihara.nara.jp\0kurotaki.nara.jp\0asakuchi.okayama.jp\0" -"lv.ua\0" -"geo.br\0" -"base.ec\0" -"int.tt\0" -"\xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\0" -"ltd.gi\0" -"alstom\0auth-fips.us-east-2.amazoncognito.com\0s3-fips.dualstack.us-east-1.amazonaws.com\0authgearapps.com\0" -"notebook.cn-northwest-1.sagemaker.com.cn\0" -"blogspot.com.es\0" -"sar.it\0" -"int.ve\0arkhangelsk.su\0" -"blogsite.xyz\0mmafan.biz\0" -"\xe6\x94\xbf\xe5\xba\x9c.hk\0ltd.hk\0" -"int.vn\0" -"agents.aero\0res.aero\0biev\xc3\xa1t.no\0r\xc3\xa1isa.no\0sogndal.no\0" -"okuma.fukushima.jp\0ikaruga.nara.jp\0masuda.shimane.jp\0yamanakako.yamanashi.jp\0" -"dupont\0rent\0" -"from.tv\0" -"s3-website.dualstack.ap-southeast-2.amazonaws.com\0analytics-gateway.ap-northeast-1.amazonaws.com\0webview-assets.aws-cloud9.eu-west-1.amazonaws.com\0us-west-2.elasticbeanstalk.com\0" -"\xe9\xa6\x99\xe6\xb8\xaf\0\xe5\x9c\xa8\xe7\xba\xbf\0" -"k12.in.us\0is-by.us\0" -"from-az.net\0" -"mangyshlak.su\0lcube-server.de\0" -"hepforge.org\0zapto.org\0" -"szkola.pl\0dell\0sdscloud.pl\0" -"beiarn.no\0grong.no\0lunner.no\0rad\xc3\xb8y.no\0" -"midori.chiba.jp\0kawaba.gunma.jp\0honbetsu.hokkaido.jp\0takayama.nagano.jp\0misaki.osaka.jp\0omaezaki.shizuoka.jp\0" -"inf.ua\0" -"osasco.br\0name.hr\0" -"keliweb.cloud\0" -"blog.kg\0" -"airtel\0" -"s3-accesspoint.af-south-1.amazonaws.com\0s3-object-lambda.eu-south-1.amazonaws.com\0is-a-designer.com\0static.observableusercontent.com\0" -"hi.cn\0" -"gallup\0\xe5\xa8\xb1\xe4\xb9\x90\0" -"poker\0" -"name.et\0friuliv-giulia.it\0chieti.it\0" -"tas.au\0" -"opencraft.hosting\0" -"energy\0" -"name.fj\0" -"ltd.lk\0" -"jelenia-gora.pl\0" -"dongnai.vn\0" -"wiki.bo\0floro.no\0g\xc3\xa1ivuotna.no\0saltdal.no\0mayfirst.info\0" -"date.hokkaido.jp\0otofuke.hokkaido.jp\0anamizu.ishikawa.jp\0tomiya.miyagi.jp\0okinoshima.shimane.jp\0katsuragi.wakayama.jp\0rs.webaccel.jp\0" -"wiki.br\0" -"lifeinsurance\0" -"monash\0" -"is-a-hard-worker.com\0dnsiskinky.com\0" -"hb.cn\0" -"dyndns.dappnode.io\0" -"la.us\0lib.oh.us\0" -"molise.it\0democrat\0rest\0jp.net\0" -"123website.be\0" -"dvrdns.org\0ltd.ng\0mayfirst.org\0" -"cipriani\0" -"for-some.biz\0" -"khanhhoa.vn\0" -"academia.bo\0gran.no\0\xc3\xa1k\xc5\x8boluokta.no\0vaga.no\0" -"bihoro.hokkaido.jp\0seika.kyoto.jp\0onagawa.miyagi.jp\0miyakonojo.miyazaki.jp\0tateyama.toyama.jp\0tokuyama.yamaguchi.jp\0matrix.jp\0" -"\xe9\xa3\x9f\xe5\x93\x81\0\xd0\xba\xd0\xbe\xd0\xbc.\xd1\x80\xd1\x83\xd1\x81\0" -"nodes.k8s.fr-par.scw.cloud\0" -"name.eg\0" -"123website.ch\0" -"allfinanz\0" -"*.devcdnaccesso.com\0emrappui-prod.ap-northeast-1.amazonaws.com\0s3-object-lambda.eu-north-1.amazonaws.com\0s3-accesspoint.dualstack.me-south-1.amazonaws.com\0balena-devices.com\0""4u.com\0" -"nyc.mn\0" -"physio\0mypi.co\0" -"in.na\0grondar.za\0\xe6\xb7\xa1\xe9\xa9\xac\xe9\x94\xa1\0" -"cc.mi.us\0lab.ms\0webspace.rocks\0" -"barletta-trani-andria.it\0blogspot.com.mt\0" -"wellbeingzone.eu\0" -"blogspot.com.ng\0" -"in.ni\0" -"name.az\0" -"dlugoleka.pl\0hosting-cluster.nl\0" -"flora.no\0hamar.no\0krager\xc3\xb8.no\0snillfjord.no\0tana.no\0" -"kasuga.fukuoka.jp\0umi.fukuoka.jp\0nakatsugawa.gifu.jp\0\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\0" -"myforum.community\0" -"copro.uk\0" -"final\0" -"emrappui-prod.eu-central-1.amazonaws.com\0s3.dualstack.us-gov-east-1.amazonaws.com\0vfs.cloud9.eu-west-1.amazonaws.com\0dreamhosters.com\0" -"gd.cn\0" -"milan.it\0endofinternet.net\0" -"deloitte\0" -"konskowola.pl\0" -"b\xc3\xa1hccavuotna.no\0" -"hisayama.fukuoka.jp\0muroran.hokkaido.jp\0goshiki.hyogo.jp\0sakai.ibaraki.jp\0kagami.kochi.jp\0oshima.tokyo.jp\0parallel.jp\0" -"fm.br\0al.gov.br\0vet.br\0blogspot.com.tr\0" -"*.eu-central-1.airflow.amazonaws.com\0s3-website-us-gov-west-1.amazonaws.com\0bplaced.com\0eu.com\0from-ak.com\0is-a-rockstar.com\0" -"olayangroup\0" -"gr.it\0a.ssl.fastly.net\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd9\x87\0pt.eu.org\0" -"sanofi\0technology\0" -"rennebu.no\0" -"gr.jp\0fuchu.toyama.jp\0kaneyama.yamagata.jp\0" -"ltd.ua\0" -"in.rs\0" -"router.management\0" -"dyndns.tv\0" -"appengine.flow.ch\0" -"ltd.uk\0" -"kr.com\0mysecuritycamera.com\0" -"law.za\0" -"goodyear\0" -"lib.md.us\0tires\0" -"trentino-sud-tirol.it\0barefoot\0boomla.net\0""7.azurestaticapps.net\0" -"in.th\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0" -"custom.metacentrum.cz\0" -"elblag.pl\0zachpomor.pl\0" -"forde.no\0moskenes.no\0m\xc3\xa1latvuopmi.no\0" -"kashiwa.chiba.jp\0narashino.chiba.jp\0yawatahama.ehime.jp\0namie.fukushima.jp\0hidaka.kochi.jp\0kameyama.mie.jp\0miyoshi.tokushima.jp\0wakasa.tottori.jp\0" -"in.ua\0" -"erotica.hu\0page\0voyage\0" -"*.firenet.ch\0" -"baby\0" -"independent-inquest.uk\0" -"xx.gl\0" -"execute-api.ap-southeast-1.amazonaws.com\0builtwithdark.com\0fastly-terrarium.com\0" -"xj.cn\0" -"in.us\0dyndns.ws\0" -"is-found.org\0" -"blogspot.com.uy\0" -"wiih.gov.pl\0wlocl.pl\0" -"leksvik.no\0unj\xc3\xa1rga.no\0" -"ako.hyogo.jp\0inabe.mie.jp\0chuo.tokyo.jp\0" -"log.br\0trd.br\0" -"domains\0" -"s3.dualstack.eu-central-2.amazonaws.com\0dyndns-pics.com\0dyndns-server.com\0" -"landrover\0" -"dst.mi.us\0" -"fm.it\0" -"turystyka.pl\0augustow.pl\0" -"insurance.aero\0" -"toho.fukuoka.jp\0kasamatsu.gifu.jp\0kitahiroshima.hokkaido.jp\0nanae.hokkaido.jp\0rifu.miyagi.jp\0izumiotsu.osaka.jp\0fujimino.saitama.jp\0kuki.saitama.jp\0vivian.jp\0" -"\xd0\xbc\xd1\x81\xd0\xba.\xd1\x80\xd1\x83\xd1\x81\0" -"en-root.fr\0ac.leg.br\0" -"\xe5\x98\x89\xe9\x87\x8c\0" -"s3-website.ap-northeast-1.amazonaws.com\0from-mo.com\0" -"crotone.it\0cloudjiffy.net\0now-dns.net\0" -"google\0" -"wang\0" -"name.vn\0" -"folkebibl.no\0badaddja.no\0" -"\xe5\x8c\x97\xe6\xb5\xb7\xe9\x81\x93.jp\0\xe4\xb8\x89\xe9\x87\x8d.jp\0otama.fukushima.jp\0tsukiyono.gunma.jp\0haboro.hokkaido.jp\0yakumo.hokkaido.jp\0" -"zt.ua\0" -"eng.br\0fbx-os.fr\0" -"we.bs\0" -"social\0" -"emrnotebooks-prod.ap-northeast-2.amazonaws.com\0s3-fips.ca-central-1.amazonaws.com\0webview-assets.aws-cloud9.eu-south-1.amazonaws.com\0blogdns.com\0from-il.com\0" -"mormon\0cn-north-1.eb.amazonaws.com.cn\0" -"hi.us\0" -"at-band-camp.net\0office-on-the.net\0" -"youtube\0" -"name.tj\0dscloud.biz\0" -"fm.no\0ask\xc3\xb8y.no\0bajddar.no\0heroy.more-og-romsdal.no\0surnadal.no\0sogne.no\0whoswho\0" -"\xe5\xb1\xb1\xe5\xbd\xa2.jp\0katsuragi.nara.jp\0nago.okinawa.jp\0hamura.tokyo.jp\0main.jp\0" -"kharkov.ua\0\xd1\x8f.\xd1\x80\xd1\x83\xd1\x81\0" -"emp.br\0name.tr\0" -"name.tt\0" -"*.hosting.myjino.ru\0" -"hotel.tz\0" -"tirol\0" -"s3.dualstack.me-central-1.amazonaws.com\0s3-accesspoint.dualstack.me-central-1.amazonaws.com\0s3-accesspoint.dualstack.sa-east-1.amazonaws.com\0from-dc.com\0servepics.com\0" -"kaufen\0" -"iris.arpa\0" -"basilicata.it\0emiliaromagna.it\0balsan-s\xc3\xbc""dtirol.it\0" -"dyndns1.de\0" -"ilawa.pl\0" -"travinh.vn\0" -"gs.hl.no\0\xc3\xa5lg\xc3\xa5rd.no\0fusa.no\0" -"tokyo.jp\0abiko.chiba.jp\0eiheiji.fukui.jp\0showa.fukushima.jp\0nachikatsuura.wakayama.jp\0deca.jp\0" -"fot.br\0" -"equipment\0" -"180r.com\0woltlab-demo.com\0" -"emrstudio-prod.cn-north-1.amazonaws.com.cn\0" -"ap.ngrok.io\0" -"flir\0neustar\0" -"lib.in.us\0" -"sicilia.it\0aquila.it\0viterbo.it\0band\0" -"app.os.fedoraproject.org\0" -"fedex\0" -"bank\0" -"wsa.gov.pl\0" -"name.pm\0" -"group.aero\0empresa.bo\0folldal.no\0" -"chikuzen.fukuoka.jp\0ami.ibaraki.jp\0sango.nara.jp\0onna.okinawa.jp\0nishi.osaka.jp\0ogi.saga.jp\0shirataka.yamagata.jp\0" -"name.qa\0" -"name.pr\0" -"pars\0" -"emrappui-prod.eu-west-3.amazonaws.com\0s3.ap-northeast-3.amazonaws.com\0s3-object-lambda.eu-central-1.amazonaws.com\0s3-accesspoint.dualstack.us-west-1.amazonaws.com\0is-a-anarchist.com\0is-a-cubicle-slave.com\0loseyourip.com\0" -"*.compute.amazonaws.com.cn\0" -"name.na\0ws.na\0" -"knightpoint.systems\0" -"vda.it\0cz.it\0does-it.net\0" -"\xd9\x83\xd9\x88\xd9\x85\0internet-dns.de\0" -"name.mv\0" -"name.ng\0read-books.org\0" -"name.my\0" -"kaszuby.pl\0olawa.pl\0" -"dienbien.vn\0" -"\xe7\xa5\x9e\xe5\xa5\x88\xe5\xb7\x9d.jp\0hachinohe.aomori.jp\0kure.hiroshima.jp\0yahaba.iwate.jp\0minamitane.kagoshima.jp\0gobo.wakayama.jp\0" -"arab\0freeboxos.fr\0free.hr\0" -"auth.us-east-1.amazoncognito.com\0s3-deprecated.us-east-1.amazonaws.com\0is-a-liberal.com\0" -"cs.in\0" -"au.ngrok.io\0upli.io\0" -"k12.ct.us\0graphox.us\0notebook-fips.us-west-2.sagemaker.aws\0" -"cs.it\0reggioemilia.it\0sassari.it\0treviso.it\0" -"hotel.lk\0" -"quangngai.vn\0" -"raholt.no\0" -"otsuki.kochi.jp\0osaki.miyagi.jp\0hanyu.saitama.jp\0netgamers.jp\0" -"localhost.daplie.me\0" -"name.mk\0" -"*.ap-southeast-1.airflow.amazonaws.com\0webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com\0" -"\xe7\xb6\xb2\xe7\xb5\xa1.cn\0" -"cc.gu.us\0tunes\0" -"cl.it\0" -"toolforge.org\0" -"\xe6\x8b\x9b\xe8\x81\x98\0" -"praxi\0" -"zakopane.pl\0" -"name.jo\0flatanger.no\0unjarga.no\0" -"obira.hokkaido.jp\0hiraya.nagano.jp\0omi.nagano.jp\0yasaka.nagano.jp\0kuju.oita.jp\0hizen.saga.jp\0yoshikawa.saitama.jp\0karasuyama.tochigi.jp\0pinoko.jp\0" -"shop.brendly.rs\0" -"*.eu-west-2.airflow.amazonaws.com\0s3-website.us-west-1.amazonaws.com\0teaches-yoga.com\0githubusercontent.com\0" -"up.in\0" -"reservd.dev.thingdust.io\0" -"ce.it\0akamaihd-staging.net\0bplaced.net\0" -"gub.uy\0" -"gsm.pl\0" -"hokkaido.jp\0shikokuchuo.ehime.jp\0soma.fukushima.jp\0morioka.iwate.jp\0kami.kochi.jp\0fuji.shizuoka.jp\0shibuya.tokyo.jp\0moo.jp\0penne.jp\0" -"hotel.hu\0" -"co.financial\0" -"*.eu-north-1.airflow.amazonaws.com\0s3-accesspoint.me-south-1.amazonaws.com\0webview-assets.aws-cloud9.af-south-1.amazonaws.com\0" -"vallee-d-aoste.it\0bn.it\0" -"\xe9\xa4\x90\xe5\x8e\x85\0" -"emb.kw\0" -"\xe7\xb6\xb2\xe7\xb5\xa1.hk\0" -"krasnik.pl\0" -"k\xc3\xa5""fjord.no\0leka.no\0v\xc3\xa5ler.\xc3\xb8stfold.no\0" -"mihara.kochi.jp\0shibata.niigata.jp\0fukaya.saitama.jp\0kumagaya.saitama.jp\0toshima.tokyo.jp\0" -"ab.ca\0" -"al.leg.br\0" -"coop.ht\0elementor.cloud\0" -"s3-accesspoint.sa-east-1.amazonaws.com\0vfs.cloud9.ap-northeast-1.amazonaws.com\0ap-southeast-2.elasticbeanstalk.com\0boutir.com\0dyndns-web.com\0" -"coop.in\0" -"browsersafetymark.io\0" -"ip6.arpa\0" -"coop.ar\0" -"zappos\0studio.af-south-1.sagemaker.aws\0we.tc\0" -"bg.it\0salerno.it\0tr.it\0" -"leitungsen.de\0storebase.store\0mein-vigor.de\0" -"booking\0" -"bu.no\0bryne.no\0frogn.no\0" -"minamiboso.chiba.jp\0ishikawa.fukushima.jp\0sekikawa.niigata.jp\0moriyama.shiga.jp\0meguro.tokyo.jp\0" -"coop.br\0sp.leg.br\0" -"suli.hu\0baidu\0" -"ass.km\0emrstudio-prod.eu-west-3.amazonaws.com\0s3-fips.us-east-1.amazonaws.com\0" -"canon\0" -"dunlop\0" -"\xd9\x85\xd8\xb5\xd8\xb1\0" -"lib.ga.us\0" -"ap.it\0" -"lifestyle\0azerbaijan.su\0" -"demon.nl\0" -"natural.bo\0flekkefjord.no\0h\xc3\xb8yanger.no\0nsupdate.info\0" -"toyooka.hyogo.jp\0zentsuji.kagawa.jp\0obama.nagasaki.jp\0nosegawa.nara.jp\0ujiie.tochigi.jp\0" -"vn.ua\0aaa\0" -"s3-website.dualstack.eu-west-1.amazonaws.com\0s3-fips.dualstack.us-west-2.amazonaws.com\0is-into-games.com\0" -"ai.in\0" -"abb\0" -"dc.us\0k12.az.us\0abc\0" -"genova.it\0iobb.net\0redirectme.net\0" -"drive\0komatsu\0" -"army\0" -"elk.pl\0" -"tr.no\0rana.no\0sauda.no\0vpnplus.to\0" -"kujukuri.chiba.jp\0godo.gifu.jp\0ikeda.gifu.jp\0meiwa.mie.jp\0hirakata.osaka.jp\0omachi.saga.jp\0kawanehon.shizuoka.jp\0koya.wakayama.jp\0fashionstore.jp\0babyblue.jp\0" -"jdf.br\0" -"auth.ap-south-1.amazoncognito.com\0s3-website-ap-northeast-1.amazonaws.com\0est-a-la-masion.com\0is-a-player.com\0meteorapp.com\0qbuser.com\0u2-local.xnbay.com\0" -"aco\0" -"arpa\0" -"cc.wv.us\0hsbc\0icbc\0" -"andria-barletta-trani.it\0cagliari.it\0market\0edgesuite-staging.net\0hu.net\0fr-1.paas.massivegrid.net\0" -"mobile\0iservschule.de\0logoip.de\0" -"pccw\0" -"assn.lk\0" -"walbrzych.pl\0" -"binhthuan.vn\0" -"idrett.no\0levanger.no\0ullensaker.no\0" -"yukuhashi.fukuoka.jp\0ena.gifu.jp\0tsukigata.hokkaido.jp\0utazu.kagawa.jp\0okaya.nagano.jp\0ueda.nagano.jp\0yuu.yamaguchi.jp\0sumomo.ne.jp\0" -"ads\0" -"aeg\0url.tw\0" -"digital\0" -"presse.km\0" -"\xe4\xbf\xa1\xe6\x81\xaf\0resindevice.io\0" -"k12.al.us\0" -"isernia.it\0tempio-olbia.it\0" -"12hp.de\0""4lima.de\0" -"pages.dev\0" -"x.bg\0endofinternet.org\0jpn.org\0" -"afl\0" -"st.no\0n\xc3\xa1vuotna.no\0malatvuopmi.no\0v\xc3\xa5g\xc3\xa5.no\0" -"\xe5\xa5\x88\xe8\x89\xaf.jp\0hirono.fukushima.jp\0kuriyama.hokkaido.jp\0aogaki.hyogo.jp\0kamikawa.saitama.jp\0nasushiobara.tochigi.jp\0matsushige.tokushima.jp\0nagato.yamaguchi.jp\0" -"jus.br\0" -"rogers\0" -"k8s.nl-ams.scw.cloud\0" -"lilly\0" -"presse.ml\0" -"auth.eu-west-1.amazoncognito.com\0s3-website.eu-central-2.amazonaws.com\0s3.me-central-1.amazonaws.com\0ro.im\0rag-cloud-ch.hosteur.com\0pagefrontapp.com\0" -"asda\0" -"center\0" -"studio-fips.us-gov-east-1.sagemaker.aws\0" -"trentin-s\xc3\xbc""dtirol.it\0ro.it\0""12hp.at\0""4lima.at\0" -"arte\0style\0" -"q.bg\0" -"\xe7\xbb\x84\xe7\xbb\x87.hk\0" -"bearalv\xc3\xa1hki.no\0br\xc3\xb8nn\xc3\xb8y.no\0" -"shiroi.chiba.jp\0nakanojo.gunma.jp\0nayoro.hokkaido.jp\0takasu.hokkaido.jp\0ogimi.okinawa.jp\0fujiidera.osaka.jp\0moriguchi.osaka.jp\0kitagata.saga.jp\0yoshimi.saitama.jp\0kodaira.tokyo.jp\0" -"qc.ca\0sebastopol.ua\0" -"psc.br\0cloudns.club\0" -"k12.ec\0" -"clubmed\0" -"lease\0" -"aig\0" -"12hp.ch\0""4lima.ch\0" -"weeklylottery.org.uk\0" -"veterinaire.km\0auth.eu-north-1.amazoncognito.com\0s3-website.dualstack.sa-east-1.amazonaws.com\0lon.wafaicloud.com\0skygearapp.com\0" -"qcx.io\0" -"clan.rip\0" -"bbva\0" -"cc.wa.us\0lib.wy.us\0" -"balsan.it\0casacam.net\0global.ssl.fastly.net\0*.kunden.ortsinfo.at\0ric.jelastic.vps-host.net\0" -"j.bg\0" -"realm.cz\0" -"engine.aero\0homebuilt.aero\0sf.no\0fetsund.no\0balsfjord.no\0hurdal.no\0" -"itayanagi.aomori.jp\0abashiri.hokkaido.jp\0rishiri.hokkaido.jp\0shinjo.nara.jp\0akaiwa.okayama.jp\0nanto.toyama.jp\0chowder.jp\0" -"*.elb.amazonaws.com\0dattorelay.com\0" -"shw.io\0" -"cc.co.us\0gives\0services\0notebook.us-west-2.sagemaker.aws\0" -"iglesiascarbonia.it\0ra.it\0dentist\0*.ex.ortsinfo.at\0jelastic.tsukaeru.net\0" -"c.bg\0" -"gon.pk\0reg.dk\0" -"poniatowa.pl\0gdynia.pl\0" -"air-traffic-control.aero\0tecnologia.bo\0\xc3\xa5krehamn.no\0b\xc3\xa1l\xc3\xa1t.no\0davvesiida.no\0divtasvuodna.no\0groks-this.info\0" -"shimane.jp\0kiyosu.aichi.jp\0tokoname.aichi.jp\0imabari.ehime.jp\0oki.fukuoka.jp\0shonai.fukuoka.jp\0higashikawa.hokkaido.jp\0numata.hokkaido.jp\0uozu.toyama.jp\0candypop.jp\0weblike.jp\0" -"asia\0pe.ca\0" -"boavista.br\0veterinaire.fr\0" -"jobs.tt\0" -"rich\0now.sh\0" -"k12.il\0" -"eu-west-3.elasticbeanstalk.com\0site.tb-hosting.com\0" -"toshiba\0" -"autos\0notebook.ap-south-2.sagemaker.aws\0" -"pz.it\0vicenza.it\0azurewebsites.net\0" -"dnshome.de\0""123webseite.de\0" -"review\0" -"\xe7\xbd\x91\xe7\xab\x99\0" -"ai.vn\0" -"skydiving.aero\0austevoll.no\0loabat.no\0steinkjer.no\0" -"niihama.ehime.jp\0himeji.hyogo.jp\0fujimi.nagano.jp\0sasebo.nagasaki.jp\0kokonoe.oita.jp\0tama.tokyo.jp\0uh-oh.jp\0" -"on.ca\0sm.ua\0" -"film.hu\0" -"coop.rw\0" -"anz\0\xe8\x81\x94\xe9\x80\x9a\0" -"aol\0" -"s3-website-eu-west-1.amazonaws.com\0s3-accesspoint.us-gov-west-1.amazonaws.com\0ditchyourip.com\0" -"og.ao\0apigee.io\0" -"cc.ca.us\0" -"iglesias-carbonia.it\0""123webseite.at\0siteleaf.net\0" -"east-kazakhstan.su\0" -"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0now-dns.org\0" -"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0" -"\xe4\xb8\xad\xe5\x9b\xbd\0" -"cooperativa.bo\0os\xc3\xb8yro.no\0romskog.no\0ikano\0" -"\xe9\xb3\xa5\xe5\x8f\x96.jp\0fujisato.akita.jp\0fukuchi.fukuoka.jp\0uonuma.niigata.jp\0kiyama.saga.jp\0sakura.tochigi.jp\0app\0" -"rv.ua\0nagoya\0" -"kids\0" -"coop.tt\0es-1.axarnet.cloud\0" -"\xe4\xb8\xad\xe5\x9c\x8b\0" -"emrstudio-prod.af-south-1.amazonaws.com\0emrnotebooks-prod.ap-southeast-2.amazonaws.com\0emrstudio-prod.ap-southeast-3.amazonaws.com\0webview-assets.cloud9.eu-south-1.amazonaws.com\0is-into-cars.com\0issmarterthanyou.com\0" -"nissan\0virgin\0" -"bar\0" -"cc.az.us\0bbc\0" -"terni.it\0akadns.net\0" -"coop.mv\0workers.dev\0" -"coop.mw\0mlbfan.org\0" -"nissay\0" -"money.bj\0upaas.kazteleport.kz\0" -"lomza.pl\0" -"dyroy.no\0orskog.no\0" -"ishikawa.jp\0fukushima.fukushima.jp\0kaga.ishikawa.jp\0takagi.nagano.jp\0kumenan.okayama.jp\0koka.shiga.jp\0mashiko.tochigi.jp\0hidaka.wakayama.jp\0" -"\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82\0" -"art\0bbt\0" -"daplie.me\0" -"bcg\0" -"emrnotebooks-prod.me-south-1.amazonaws.com\0*.ca-central-1.airflow.amazonaws.com\0s3-website-ap-southeast-2.amazonaws.com\0is-leet.com\0" -"bcn\0" -"chungbuk.kr\0" -"cc.as.us\0cc.tn.us\0" -"abruzzo.it\0puglia.it\0pe.it\0diet\0" -"taifun-dns.de\0dray-dns.de\0" -"pl.eu.org\0" -"sydney\0" -"marker.no\0stord.no\0" -"\xe5\xbe\xb3\xe5\xb3\xb6.jp\0odate.akita.jp\0shimofusa.chiba.jp\0buzen.fukuoka.jp\0yamagata.gifu.jp\0miyoshi.hiroshima.jp\0kadena.okinawa.jp\0sakata.yamagata.jp\0" -"rivne.ua\0otsuka\0" -"scrapping.cc\0" -"abbott\0" -"coop.py\0" -"barsy.co.uk\0" -"vfs.cloud9.ap-south-1.amazonaws.com\0ar.com\0""001www.com\0" -"c.la\0" -"pe.kr\0boehringer\0" -"cc.al.us\0notebook.eu-west-2.sagemaker.aws\0" -"friuli-venezia-giulia.it\0pordenone.it\0bet\0" -"official.academy\0" -"no-ip.biz\0" -"wskr.gov.pl\0" -"binhdinh.vn\0" -"b\xc3\xa1id\xc3\xa1r.no\0bindal.no\0horten.no\0stryn.no\0" -"shiriuchi.hokkaido.jp\0teshikaga.hokkaido.jp\0chikuhoku.nagano.jp\0yamatotakada.nara.jp\0takanezawa.tochigi.jp\0" -"nb.ca\0" -"cri.br\0" -"myphotos.cc\0" -"x.se\0" -"coop.km\0s3.eu-central-1.amazonaws.com\0" -"\xe7\xb5\x84\xe7\xb9\x94.\xe9\xa6\x99\xe6\xb8\xaf\0" -"axa\0" -"lib.tx.us\0aws\0" -"brindisi.it\0og.it\0" -"9.bg\0" -"mobi\0" -"witd.gov.pl\0" -"lamdong.vn\0" -"h\xc3\xa5.no\0masfjorden.no\0nesodden.no\0\xe6\xb8\xb8\xe6\x88\x8f\0" -"ibaraki.jp\0\xe9\x9d\x92\xe6\xa3\xae.jp\0honjyo.akita.jp\0tomisato.chiba.jp\0ashibetsu.hokkaido.jp\0tohma.hokkaido.jp\0miki.hyogo.jp\0otoyo.kochi.jp\0minami.tokushima.jp\0chips.jp\0" -"k12.tr\0" -"bid\0" -"sport.hu\0filegear-sg.me\0" -"auth.ap-southeast-2.amazoncognito.com\0emrstudio-prod.ap-south-1.amazonaws.com\0*.0emm.com\0" -"bio\0" -"moda\0" -"lib.az.us\0" -"genoa.it\0target\0" -"hlx.live\0" -"2.bg\0voting\0" -"k12.vi\0hitachi\0" -"biz\0" -"czest.pl\0" -"baria-vungtau.vn\0" -"alstahaug.no\0kristiansund.no\0larvik.no\0cahcesuolo.no\0valer.ostfold.no\0" -"shiraoi.hokkaido.jp\0shinonsen.hyogo.jp\0yamada.iwate.jp\0tochio.niigata.jp\0oyabe.toyama.jp\0" -"chernivtsi.ua\0ipiranga\0" -"my.id\0sport\0" -"md.ci\0" -"emrappui-prod.eu-west-1.amazonaws.com\0s3.dualstack.ap-northeast-3.amazonaws.com\0s3-website.eu-north-1.amazonaws.com\0analytics-gateway.ap-northeast-2.amazonaws.com\0vfs.cloud9.me-south-1.amazonaws.com\0" -"isa.us\0reviews\0" -"laquila.it\0bitbridge.net\0jls-sto2.elastx.net\0soc.srcf.net\0" -"versicherung\0" -"eco.bj\0" -"\xe5\xa4\xa7\xe6\x8b\xbf\0" -"moriyoshi.akita.jp\0ichikawa.chiba.jp\0toon.ehime.jp\0tomobe.ibaraki.jp\0miyama.mie.jp\0tateshina.nagano.jp\0kawaguchi.saitama.jp\0kuron.jp\0eek.jp\0" -"pl.ua\0" -"eco.br\0to.leg.br\0" -"careers\0" -"jogasz.hu\0c.se\0" -"presse.ci\0" -"s3.ap-northeast-1.amazonaws.com\0s3-eu-north-1.amazonaws.com\0vfs.cloud9.ap-southeast-1.amazonaws.com\0us-east-2.elasticbeanstalk.com\0rag-cloud.hosteur.com\0" -"s3-website.cn-north-1.amazonaws.com.cn\0" -"bms\0" -"pisa.it\0\xe7\xbb\x84\xe7\xbb\x87\xe6\x9c\xba\xe6\x9e\x84\0bounceme.net\0" -"cyou\0dyn.ddnss.de\0" -"bmw\0us.org\0" -"ecologia.bo\0fitjar.no\0flesberg.no\0ris\xc3\xb8r.no\0sor-aurdal.no\0" -"oamishirasato.chiba.jp\0sumita.iwate.jp\0kumiyama.kyoto.jp\0\xe6\xbe\xb3\xe9\x96\x80\0" -"ind.br\0" -"comsec\0ftpaccess.cc\0" -"bom\0analytics-gateway.us-east-2.amazonaws.com\0from-vt.com\0is-an-accountant.com\0barsyonline.com\0" -"boo\0" -"lib.sd.us\0" -"bot\0mydatto.net\0" -"box\0" -"wloclawek.pl\0" -"afjord.no\0berlevag.no\0" -"hekinan.aichi.jp\0miyama.fukuoka.jp\0midori.gunma.jp\0kawakami.nagano.jp\0shimizu.shizuoka.jp\0backdrop.jp\0" -"cab\0" -"clinique\0" -"dish\0" -"cal\0" -"cam\0" -"eurovision\0" -"cba\0" -"car\0" -"kerrylogistics\0" -"cat\0lt.it\0" -"mediatech.dev\0" -"cbn\0" -"mr.no\0" -"nishio.aichi.jp\0ujitawara.kyoto.jp\0sugito.saitama.jp\0noop.app\0" -"bmd.br\0" -"it1.eur.aruba.jenv-aruba.cloud\0" -"vladikavkaz.ru\0" -"fidelity\0kiwi\0\xd8\xb4\xd8\xa8\xd9\x83\xd8\xa9\0" -"cri.nz\0" -"emrnotebooks-prod.eu-north-1.amazonaws.com\0emrnotebooks-prod.us-gov-west-1.amazonaws.com\0emrnotebooks-prod.us-west-1.amazonaws.com\0webview-assets.cloud9.af-south-1.amazonaws.com\0" -"jx.cn\0" -"webthings.io\0" -"ntdll.top\0" -"ind.gt\0akamaihd.net\0vps-host.net\0" -"wa.edu.au\0karacol.su\0vladikavkaz.su\0mintere.site\0" -"mitsubishi\0" -"griw.gov.pl\0bytom.pl\0sosnowiec.pl\0" -"binhphuoc.vn\0" -"flight.aero\0hanggliding.aero\0plurinacional.bo\0bomlo.no\0karm\xc3\xb8y.no\0lindas.no\0" -"mutsuzawa.chiba.jp\0ono.fukushima.jp\0hofu.yamaguchi.jp\0deta.app\0" -"framer.media\0" -"vix.br\0" -"*.on-rancher.cloud\0" -"\xe6\xbe\xb3\xe9\x97\xa8\0" -"bostik\0" -"plc.co.im\0s3-website.eu-west-3.amazonaws.com\0is-a-bulls-fan.com\0is-not-certified.com\0" -"ind.in\0" -"ceo\0" -"cfa\0" -"kosher\0" -"trentinsued-tirol.it\0cfd\0" -"phone\0loginline.site\0" -"blackfriday\0buy\0" -"quangninh.vn\0" -"sola.no\0suldal.no\0v-info.info\0" -"sakuragawa.ibaraki.jp\0yamamoto.miyagi.jp\0goto.nagasaki.jp\0ishikawa.okinawa.jp\0fireweb.app\0web.app\0" -"food\0" -"ieee\0barsy.menu\0" -"americanfamily\0dubai\0" -"health.nz\0" -"webview-assets.cloud9.me-south-1.amazonaws.com\0wpenginepowered.com\0" -"weir\0" -"siracusa.it\0from-co.net\0" -"ind.kw\0verm\xc3\xb6gensberatung\0sweetpepper.org\0" -"audi\0" -"wzmiuw.gov.pl\0" -"profesional.bo\0romsa.no\0v\xc3\xa5gan.no\0" -"\xe7\x9f\xb3\xe5\xb7\x9d.jp\0hamatonbetsu.hokkaido.jp\0sumoto.kumamoto.jp\0shiroishi.saga.jp\0tendo.yamagata.jp\0nikita.jp\0" -"kharkiv.ua\0" -"esp.br\0dedibox.fr\0" -"homegoods\0investments\0" -"myds.me\0" -"s3-accesspoint.dualstack.ap-southeast-3.amazonaws.com\0s3.us-east-1.amazonaws.com\0forgeblocks.com\0onza.mythic-beasts.com\0" -"beer\0" -"cc.pa.us\0" -"massacarrara.it\0ford\0half.host\0" -"vic.au\0omniwe.site\0" -"consulting\0no.eu.org\0" -"bzh\0" -"ostrowiec.pl\0" -"blogspot.vn\0" -"gs.nl.no\0sauherad.no\0moto\0" -"komaki.aichi.jp\0kayabe.hokkaido.jp\0iwate.iwate.jp\0haebaru.okinawa.jp\0\xe7\xbd\x91\xe5\x9d\x80\0" -"mk.ua\0" -"kasserver.com\0s3-object-lambda.ap-northeast-3.amazonaws.com\0" -"boston\0town\0" -"mypets.ws\0stuff-4-sale.us\0" -"trentino.it\0" -"\xe6\x89\x8b\xe6\x9c\xba\0" -"tourism.tn\0yenbai.vn\0" -"spydeberg.no\0photo\0" -"anpachi.gifu.jp\0nishimera.miyazaki.jp\0sub.jp\0" -"lt.ua\0omega\0\xd0\xba\xd1\x80\xd1\x8b\xd0\xbc.\xd1\x80\xd1\x83\xd1\x81\0" -"srv.br\0iz.hr\0" -"uwu.ai\0" -"execute-api.us-east-2.amazonaws.com\0s3-accesspoint.ap-southeast-1.amazonaws.com\0s3-accesspoint.eu-west-1.amazonaws.com\0webview-assets.cloud9.ap-northeast-2.amazonaws.com\0servebeer.com\0yolasite.com\0" -"immobilien\0" -"urn.arpa\0" -"biz.bb\0" -"md.us\0toys\0" -"pesaro-urbino.it\0saarland\0biz.at\0mydissent.net\0*.hosting.ovh.net\0" -"cyon.site\0tula.su\0vologda.su\0blogspot.re\0" -"hosting\0" -"biz.az\0" -"health.vn\0" -"tranby.no\0sondre-land.no\0blogspot.ro\0" -"kunohe.iwate.jp\0ide.kyoto.jp\0ookuwa.nagano.jp\0" -"chirurgiens-dentistes-en-france.fr\0" -"blogspot.rs\0" -"ch.trendhosting.cloud\0jotelulu.cloud\0" -"media.hu\0blogspot.ru\0blogspot.se\0" -"blogspot.sg\0" -"blogspot.si\0" -"blogspot.sk\0" -"com\0medecin.km\0s3-accesspoint.dualstack.ap-east-1.amazonaws.com\0s3-website-sa-east-1.amazonaws.com\0africa.com\0pythonanywhere.com\0" -"hn.cn\0execute-api.cn-north-1.amazonaws.com.cn\0blogspot.sn\0" -"shiftcrypto.io\0" -"cpa\0" -"lombardy.it\0trentino-s\xc3\xbc""d-tirol.it\0is.it\0blogspot.td\0" -"dynamisches-dns.de\0" -"lighting\0mywire.org\0nz.eu.org\0" -"biz.cy\0" -"biz.dk\0" -"gniezno.pl\0" -"ind.tn\0" -"grue.no\0lyngdal.no\0os.hordaland.no\0vestnes.no\0no-ip.info\0" -"showa.gunma.jp\0otake.hiroshima.jp\0mukawa.hokkaido.jp\0yamagata.ibaraki.jp\0easypanel.app\0usercontent.jp\0" -"kv.ua\0" -"tickets\0game-server.cc\0" -"dad\0" -"translate.goog\0blogspot.tw\0blogspot.ug\0" -"emerck\0" -"verisign\0" -"blogspot.mr\0" -"cc.ne.us\0works\0" -"biz.et\0bulsan.it\0world\0yandexcloud.net\0" -"lasalle\0exnet.su\0" -"blogspot.mx\0" -"day\0blogspot.my\0" -"biz.fj\0" -"starostwo.gov.pl\0mazury.pl\0blogspot.nl\0" -"moareke.no\0salangen.no\0sarpsborg.no\0blogspot.no\0" -"kumamoto.jp\0niki.hokkaido.jp\0tamba.hyogo.jp\0nakanoto.ishikawa.jp\0sanuki.kagawa.jp\0ureshino.mie.jp\0fuefuki.yamanashi.jp\0" -"crs\0" -"plc.ly\0" -"biz.gl\0" -"emrappui-prod.eu-west-2.amazonaws.com\0ap-northeast-3.elasticbeanstalk.com\0" -"edugit.io\0" -"cc.mn.us\0press\0" -"trentinoaltoadige.it\0barlettatraniandria.it\0appudo.net\0" -"qld.au\0blogspot.pe\0" -"webhop.org\0" -"wuoz.gov.pl\0" -"\xe5\x95\x86\xe5\x9f\x8e\0" -"andoy.no\0fyresdal.no\0rennes\xc3\xb8y.no\0" -"kira.aichi.jp\0ichikawa.hyogo.jp\0kumamoto.kumamoto.jp\0hinohara.tokyo.jp\0mokuren.ne.jp\0" -"kh.ua\0\xe9\x9b\xbb\xe8\xa8\x8a\xe7\x9b\x88\xe7\xa7\x91\0blogspot.qa\0" -"cards\0dds\0" -"biz.id\0blogspot.pt\0" -"execute-api.ca-central-1.amazonaws.com\0emrstudio-prod.us-west-2.amazonaws.com\0s3.ap-southeast-2.amazonaws.com\0" -"biz.in\0" -"lib.ms.us\0lib.nc.us\0blogspot.is\0" -"blogspot.it\0dnsup.net\0ownip.net\0" -"dev\0" -"is-very-evil.org\0couchpotatofries.org\0dsmynas.org\0" -"aid.pl\0media.pl\0" -"recreation.aero\0frana.no\0her\xc3\xb8y.nordland.no\0sande.more-og-romsdal.no\0troandin.no\0eng.pro\0volvo\0" -"osaka.jp\0\xe6\xa0\x83\xe6\x9c\xa8.jp\0\xe5\xb1\xb1\xe5\x8f\xa3.jp\0yokoshibahikari.chiba.jp\0usui.fukuoka.jp\0daigo.ibaraki.jp\0kami.miyagi.jp\0takanabe.miyazaki.jp\0pecori.jp\0blogspot.jp\0daynight.jp\0" -"africa\0" -"marshalls\0" -"fr-par-1.baremetal.scw.cloud\0k8s.scw.cloud\0" -"biz.ki\0" -"is-into-anime.com\0damnserver.com\0" -"blogspot.kr\0" -"lib.nh.us\0" -"best\0" -"viking\0small-web.org\0" -"blogspot.li\0" -"tourism.pl\0pila.pl\0dhl\0" -"airtraffic.aero\0auto\0" -"seiyo.ehime.jp\0nishigo.fukushima.jp\0matsumoto.kagoshima.jp\0takamori.nagano.jp\0mibu.tochigi.jp\0" -"biz.ls\0" -"blogspot.lt\0blogspot.md\0us.reclaim.cloud\0" -"mine.nu\0blogspot.lu\0" -"dnsking.ch\0" -"rugby\0" -"blogspot.mk\0" -"mex.com\0*.dev-builder.code.com\0" -"\xe6\x95\x99\xe8\x82\xb2.\xe9\xa6\x99\xe6\xb8\xaf\0" -"cc.ky.us\0lib.ma.us\0condos\0" -"biz.mv\0" -"biz.mw\0wedding\0" -"biz.my\0biz.ni\0diy\0blogspot.fi\0" -"tourism.bj\0" -"caobang.vn\0" -"kopervik.no\0sandnessj\xc3\xb8""en.no\0asker.no\0balestrand.no\0hvaler.no\0stordal.no\0" -"okayama.jp\0gojome.akita.jp\0kamijima.ehime.jp\0samegawa.fukushima.jp\0shobara.hiroshima.jp\0itami.hyogo.jp\0futsu.nagasaki.jp\0zamami.okinawa.jp\0" -"sevastopol.ua\0" -"sp.gov.br\0biz.nr\0blogspot.fr\0" -"download\0" -"framer.wiki\0" -"plc.uk\0" -"school\0" -"dyn-o-saur.com\0from-ca.com\0" -"*.migration.run\0" -"blogspot.gr\0" -"grosseto.it\0\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4\0florist\0alwaysdata.net\0""3.azurestaticapps.net\0" -"kalmykia.su\0" -"\xd9\x81\xd9\x84\xd8\xb3\xd8\xb7\xd9\x8a\xd9\x86\0" -"fedorainfracloud.org\0" -"biz.pk\0blogspot.hk\0" -"biz.pl\0nowaruda.pl\0" -"thanhphohochiminh.vn\0" -"\xc3\xa5rdal.no\0n\xc3\xb8tter\xc3\xb8y.no\0" -"\xe9\x95\xb7\xe9\x87\x8e.jp\0kisarazu.chiba.jp\0echizen.fukui.jp\0kyowa.hokkaido.jp\0kawaminami.miyazaki.jp\0tsuru.yamanashi.jp\0pigboat.jp\0" -"no-ip.ca\0" -"ntr.br\0biz.pr\0blogspot.hr\0" -"uk.reclaim.cloud\0whm.nl-ams.scw.cloud\0" -"blogspot.hu\0blogspot.ie\0lohmus.me\0pdns.page\0" -"mattel\0" -"s3-accesspoint.ap-east-1.amazonaws.com\0s3-us-west-1.amazonaws.com\0" -"blogspot.in\0" -"blogspot.ba\0" -"\xe9\x9b\x86\xe5\x9b\xa2\0" -"il.us\0windows\0" -"fr.it\0torino.it\0" -"blogspot.be\0" -"misconfused.org\0blogspot.bg\0" -"blogspot.bj\0" -"mail.pl\0so.gov.pl\0" -"scientist.aero\0kyoto\0" -"katori.chiba.jp\0matsuno.ehime.jp\0shiso.hyogo.jp\0miho.ibaraki.jp\0nagiso.nagano.jp\0sakae.nagano.jp\0suwa.nagano.jp\0hasama.oita.jp\0hirara.okinawa.jp\0kuroiso.tochigi.jp\0dnp\0buyshop.jp\0" -"blogspot.ca\0ie.ua\0" -"cim.br\0" -"kalmykia.ru\0i234.me\0" -"blogspot.cf\0" -"dog\0" -"blogspot.ch\0wedeploy.sh\0" -"blogspot.cl\0" -"emrstudio-prod.eu-west-2.amazonaws.com\0s3-object-lambda.eu-west-2.amazonaws.com\0cloudcontrolled.com\0is-a-nurse.com\0" -"daejeon.kr\0" -"biz.ss\0" -"dot\0" -"webhosting.be\0blogspot.de\0" -"githubpreview.dev\0blogspot.cv\0" -"blogsite.org\0" -"biz.tj\0blogspot.cz\0" -"fam.pk\0blogspot.dk\0" -"\xe6\x94\xbf\xe5\xba\x9c\0" -"lea\xc5\x8bgaviika.no\0v\xc3\xa1rgg\xc3\xa1t.no\0" -"tsuruta.aomori.jp\0hashima.gifu.jp\0hiraizumi.iwate.jp\0izumisano.osaka.jp\0kimino.wakayama.jp\0nanbu.yamanashi.jp\0rulez.jp\0" -"biz.ua\0" -"biz.tr\0on-web.fr\0" -"biz.tt\0museum.tt\0" -"execute-api.eu-central-2.amazonaws.com\0s3-fips.dualstack.us-west-1.amazonaws.com\0webview-assets.cloud9.us-east-1.amazonaws.com\0dynalias.com\0" -"canva-apps.cn\0" -"bet.ar\0senasa.ar\0" -"trani-andria-barletta.it\0eat\0cdn.prod.atlassian-dev.net\0" -"broadway\0" -"*.cloud.metacentrum.cz\0" -"sklep.pl\0gda.pl\0" -"biz.vn\0" -"emergency.aero\0globo\0" -"handa.aichi.jp\0nakama.fukuoka.jp\0iitate.fukushima.jp\0shika.ishikawa.jp\0higashitsuno.kochi.jp\0kawatana.nagasaki.jp\0koryo.nara.jp\0" -"londrina.br\0prof.pr\0rj.leg.br\0medecin.fr\0" -"fairwinds\0" -"eu.int\0" -"name\0" -"biz.wf\0" -"financial\0\xd0\xba\xd0\xbe\xd0\xbc\0" -"*.ap-south-1.airflow.amazonaws.com\0s3-accesspoint.dualstack.il-central-1.amazonaws.com\0s3-deprecated.us-west-2.amazonaws.com\0nfshost.com\0myqnapcloud.com\0logoip.com\0" -"eco\0" -"claims\0" -"*.in.futurecms.at\0pcloud.host\0" -"dnsdojo.org\0mt.eu.org\0" -"co.technology\0barsy.mobi\0" -"ostroda.pl\0" -"longan.vn\0ninhbinh.vn\0" -"varggat.no\0" -"toyama.jp\0iyo.ehime.jp\0nishinoomote.kagoshima.jp\0semine.miyagi.jp\0kamiizumi.saitama.jp\0" -"edu\0game\0blogspot.ae\0" -"dtv\0" -"ravpage.co.il\0blogspot.al\0" -"s3-deprecated.eu-west-1.amazonaws.com\0s3-accesspoint.il-central-1.amazonaws.com\0s3-ap-southeast-1.amazonaws.com\0webview-assets.aws-cloud9.us-east-2.amazonaws.com\0discordsez.com\0gentlentapis.com\0blogspot.am\0" -"cq.cn\0" -"aramco\0" -"uri.arpa\0" -"trentinoalto-adige.it\0vall\xc3\xa9""e-aoste.it\0aoste.it\0enna.it\0" -"dyndns.biz\0" -"biz.zm\0" -"muos\xc3\xa1t.no\0" -"namikata.ehime.jp\0tagawa.fukuoka.jp\0kawagoe.mie.jp\0miasa.nagano.jp\0hikari.yamaguchi.jp\0gloomy.jp\0" -"dvr\0" -"emrstudio-prod.eu-south-1.amazonaws.com\0mrap.accesspoint.s3-global.amazonaws.com\0is-a-conservative.com\0eu-4.evennode.com\0" -"mobi.gp\0" -"k12.wa.us\0" -"lecce.it\0sg-1.paas.massivegrid.net\0vpndns.net\0" -"chimkent.su\0*.tst.site\0" -"bentley\0" -"pup.gov.pl\0sr.gov.pl\0lowicz.pl\0" -"l\xc3\xb8ten.no\0m\xc3\xa5lselv.no\0sveio.no\0tranoy.no\0" -"dazaifu.fukuoka.jp\0takasaki.gunma.jp\0obihiro.hokkaido.jp\0saroma.hokkaido.jp\0nakatane.kagoshima.jp\0kaisei.kanagawa.jp\0nakai.kanagawa.jp\0uki.kumamoto.jp\0uji.kyoto.jp\0komoro.nagano.jp\0naruto.tokushima.jp\0gehirn.ne.jp\0" -"ato.br\0" -"instances.spawn.cc\0" -"firm.ht\0" -"filegear-jp.me\0wedeploy.me\0" -"feedback\0adimo.co.uk\0" -"airkitapps-au.com\0auth.eu-west-2.amazoncognito.com\0s3-ap-northeast-3.amazonaws.com\0apps.fbsbx.com\0lynx.mythic-beasts.com\0ciscofreak.com\0" -"firm.in\0\xe5\x8f\xb0\xe6\xb9\xbe\0" -"k12.co.us\0k12.vt.us\0cc.ia.us\0" -"ascoli-piceno.it\0forl\xc3\xac""cesena.it\0vs.it\0hangout\0" -"*.frusky.de\0dd-dns.de\0" -"museum.mv\0deta.dev\0" -"museum.mw\0al.eu.org\0" -"museum.no\0trana.no\0vennesla.no\0" -"\xe9\x95\xb7\xe5\xb4\x8e.jp\0kimitsu.chiba.jp\0kawanabe.kagoshima.jp\0hamada.shimane.jp\0" -"dnipropetrovsk.ua\0" -"tushu\0" -"public-inquiry.uk\0" -"museum.om\0s3.ap-southeast-3.amazonaws.com\0s3-accesspoint.us-east-1.amazonaws.com\0webview-assets.cloud9.ca-central-1.amazonaws.com\0is-a-guru.com\0eu-3.evennode.com\0" -"tw.cn\0s3-website.cn-northwest-1.amazonaws.com.cn\0" -"firm.co\0musician.io\0" -"abr.it\0comcast\0jls-sto3.elastx.net\0" -"ath.cx\0be.ax\0" -"bestbuy\0" -"ote.bj\0" -"firm.dk\0" -"malopolska.pl\0ostrowwlkp.pl\0wroc.pl\0" -"binhduong.vn\0" -"association.aero\0certification.aero\0flakstad.no\0lavagis.no\0r\xc3\xa6lingen.no\0stange.no\0cloudns.info\0" -"oketo.hokkaido.jp\0awaji.hyogo.jp\0shimoji.okinawa.jp\0kishiwada.osaka.jp\0konan.shiga.jp\0fujinomiya.shizuoka.jp\0numazu.shizuoka.jp\0funagata.yamagata.jp\0" -"volyn.ua\0" -"winners\0" -"free\0""123sait.ru\0" -"watch\0eu.platform.sh\0" -"navy\0" -"\xe8\xb0\xb7\xe6\xad\x8c\0" -"s3-fips.us-west-2.amazonaws.com\0dyndns-office.com\0" -"*.stolos.io\0" -"\xe0\xb4\xad\xe0\xb4\xbe\xe0\xb4\xb0\xe0\xb4\xa4\xe0\xb4\x82\0" -"k12.ca.us\0" -"bz.it\0cosenza.it\0ve.it\0servebbs.net\0" -"moscow\0my.eu.org\0" -"lipsy\0" -"ug.gov.pl\0\xe7\xbd\x91\xe7\xbb\x9c\0" -"cc.hn\0" -"engineer.aero\0bolivia.bo\0habmer.no\0hole.no\0nedre-eiker.no\0voss.no\0" -"kitami.hokkaido.jp\0mashike.hokkaido.jp\0shiiba.miyazaki.jp\0bungoono.oita.jp\0oita.oita.jp\0nose.osaka.jp\0" -"chambagri.fr\0" -"flowers\0" -"filegear-au.me\0" -"pymnt.uk\0" -"hospital\0" -"s3-accesspoint.dualstack.us-east-1.amazonaws.com\0from-nm.com\0eu-2.evennode.com\0*.cns.joyent.com\0bloxcms.com\0" -"lib.il.us\0studio.ap-southeast-3.sagemaker.aws\0" -"bs.it\0cloudapp.net\0seidat.net\0" -"olecko.pl\0" -"ens.tn\0" -"gs.oslo.no\0lur\xc3\xb8y.no\0sortland.no\0t\xc3\xb8nsberg.no\0barsy.info\0" -"mutsu.aomori.jp\0sosa.chiba.jp\0kyotango.kyoto.jp\0kisofukushima.nagano.jp\0wake.okayama.jp\0" -"yokohama\0" -"123siteweb.fr\0" -"s3.pl-waw.scw.cloud\0" -"enterprisecloud.nu\0" -"pages.wiardweb.com\0" -"fan\0" -"lib.gu.us\0" -"bl.it\0njs.jelastic.vps-host.net\0" -"ddnss.org\0" -"\xe5\xa4\xa9\xe4\xb8\xbb\xe6\x95\x99\0be.gy\0" -"gbiz\0for-the.biz\0" -"tayninh.vn\0" -"rotorcraft.aero\0alta.no\0notteroy.no\0matta-varjjat.no\0" -"tottori.jp\0aizumisato.fukushima.jp\0ishikari.hokkaido.jp\0matsushima.miyagi.jp\0" -"sk.ca\0" -"rr.leg.br\0" -"country\0realty\0" -"eu-1.evennode.com\0" -"cc.na\0esq\0" -"\xd0\xb1\xd0\xb3\0paris\0" -"tp.it\0" -"nl.eu.org\0" -"babia-gora.pl\0" -"frosta.no\0gildesk\xc3\xa5l.no\0" -"saka.hiroshima.jp\0kanonji.kagawa.jp\0nankoku.kochi.jp\0shoo.okayama.jp\0shimotsuke.tochigi.jp\0nanbu.tottori.jp\0" -"cx.ua\0" -"rs.leg.br\0sc.leg.br\0avocat.fr\0" -"accountant\0" -"il-central-1.elasticbeanstalk.com\0jed.wafaicloud.com\0bounty-full.com\0alpha.bounty-full.com\0" -"sd.cn\0" -"wedeploy.io\0" -"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86.ir\0blockbuster\0\xe3\x82\xb9\xe3\x83\x88\xe3\x82\xa2\0" -"eus\0" -"an.it\0dontexist.net\0squares.net\0" -"firm.ve\0home-webserver.de\0" -"doesntexist.org\0" -"attorney\0today\0" -"\xe4\xbc\x81\xe4\xb8\x9a\0" -"lapy.pl\0sejny.pl\0stalowa-wola.pl\0" -"lillehammer.no\0www.ro\0" -"toyoura.hokkaido.jp\0tsubata.ishikawa.jp\0nagaokakyo.kyoto.jp\0imari.saga.jp\0parasite.jp\0" -"rovno.ua\0\xd1\x83\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" -"sjc.br\0" -"su.paba.se\0" -"legal\0" -"s3-accesspoint.ap-northeast-2.amazonaws.com\0doomdns.com\0onthewifi.com\0ownprovider.com\0" -"notebook.ap-east-1.sagemaker.aws\0notebook.eu-south-1.sagemaker.aws\0" -"ag.it\0bergamo.it\0medio-campidano.it\0sr.it\0webhop.net\0familyds.net\0" -"is-a-knight.org\0" -"ismaili\0" -"beep.pl\0nz.basketball\0" -"amusement.aero\0patria.bo\0s\xc3\xb8rreisa.no\0tvedestrand.no\0" -"oarai.ibaraki.jp\0bizen.okayama.jp\0bunkyo.tokyo.jp\0tottori.tottori.jp\0kurobe.toyama.jp\0bitter.jp\0" -"uzhhorod.ua\0" -"to.gov.br\0" -"adobeaemcloud.com\0auth-fips.us-gov-west-1.amazoncognito.com\0emrappui-prod.eu-north-1.amazonaws.com\0emrappui-prod.sa-east-1.amazonaws.com\0webview-assets.aws-cloud9.eu-north-1.amazonaws.com\0webview-assets.aws-cloud9.eu-west-3.amazonaws.com\0freeboxos.com\0qa2.com\0" -"\xe5\x85\xac\xe5\x8f\xb8.cn\0\xd0\xb5\xd1\x8e\0" -"flickr\0" -"rovigo.it\0fit\0dsmynas.net\0" -"oracle\0jelastic.dogado.eu\0" -"ng.eu.org\0" -"ekloges.cy\0" -"\xe5\x85\xac\xe5\x8f\xb8.hk\0" -"kr\xc3\xb8""dsherad.no\0sande.m\xc3\xb8re-og-romsdal.no\0firm.ro\0" -"chuo.chiba.jp\0uwajima.ehime.jp\0naka.hiroshima.jp\0abira.hokkaido.jp\0yamaga.kumamoto.jp\0tonaki.okinawa.jp\0fuchu.tokyo.jp\0asahi.yamagata.jp\0mods.jp\0" -"uzhgorod.ua\0cc.ua\0" -"app.br\0dev.br\0rn.leg.br\0" -"chrome\0" -"auth.ap-northeast-3.amazoncognito.com\0auth.ap-southeast-1.amazoncognito.com\0homelinux.com\0" -"k12.sc.us\0fresenius\0" -"heteml.net\0" -"v.bg\0" -"crafting.xyz\0" -"\xe5\xa4\xa7\xe5\x88\x86.jp\0tatebayashi.gunma.jp\0hadano.kanagawa.jp\0sayama.osaka.jp\0kawajima.saitama.jp\0tsurugashima.saitama.jp\0ohkura.yamagata.jp\0cutegirl.jp\0" -"ro.leg.br\0" -"mobi.tt\0" -"\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88\0" -"fly\0" -"mobi.tz\0" -"s3.ap-northeast-2.amazonaws.com\0" -"qh.cn\0" -"id.repl.co\0" -"\xd9\x83\xd8\xa7\xd8\xab\xd9\x88\xd9\x84\xd9\x8a\xd9\x83\0" -"rm.it\0*.ex.futurecms.at\0" -"firm.nf\0" -"o.bg\0firm.ng\0" -"gs.va.no\0lodingen.no\0vestv\xc3\xa5g\xc3\xb8y.no\0x0.to\0" -"tobishima.aichi.jp\0yabuki.fukushima.jp\0kunneppu.hokkaido.jp\0moriya.ibaraki.jp\0kotohira.kagawa.jp\0setouchi.okayama.jp\0encr.app\0" -"parts\0" -"\xd0\xbc\xd0\xba\xd0\xb4\0walmart\0" -"party\0" -"emrappui-prod.ap-northeast-3.amazonaws.com\0s3-accesspoint.dualstack.ap-northeast-1.amazonaws.com\0s3-website.ap-southeast-3.amazonaws.com\0s3-website.dualstack.ca-central-1.amazonaws.com\0af-south-1.elasticbeanstalk.com\0eu-central-1.elasticbeanstalk.com\0dyndns-at-home.com\0messwithdns.com\0" -"foo\0" -"app.gp\0" -"cc.ct.us\0studio.eu-west-2.sagemaker.aws\0" -"carraramassa.it\0rome.it\0dnsdojo.net\0lon-2.paas.massivegrid.net\0" -"oz.au\0" -"h.bg\0is-very-good.org\0" -"fox\0" -"gos.pk\0" -"dr\xc3\xb8""bak.no\0bergen.no\0gol.no\0lahppi.no\0" -"chuo.fukuoka.jp\0tamamura.gunma.jp\0atsuma.hokkaido.jp\0hyuga.miyazaki.jp\0hashimoto.wakayama.jp\0" -"df.leg.br\0" -"vapor.cloud\0" -"gal\0" -"pharmaciens.km\0freemyip.com\0" -"*.backyards.banzaicloud.io\0" -"gap\0" -"mobi.na\0" -"phx.enscaled.us\0" -"bulsan-suedtirol.it\0ragusa.it\0vanguard\0onavstack.net\0sells-it.net\0" -"fnwk.site\0" -"a.bg\0mobi.ng\0sling\0hobby-site.org\0edu.eu.org\0" -"gay\0" -"frl\0" -"osen.no\0\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\x9f\0" -"asaminami.hiroshima.jp\0takarazuka.hyogo.jp\0yamakita.kanagawa.jp\0uto.kumamoto.jp\0kyotamba.kyoto.jp\0nagi.okayama.jp\0hino.tokyo.jp\0nirasaki.yamanashi.jp\0ciao.jp\0opal.ne.jp\0" -"floripa.br\0bbs.tr\0" -"\xd0\xbc\xd0\xbe\xd0\xbd\0us-east-1.amazonaws.com\0emrnotebooks-prod.af-south-1.amazonaws.com\0emrnotebooks-prod.eu-west-2.amazonaws.com\0s3-1.amazonaws.com\0webview-assets.aws-cloud9.eu-central-1.amazonaws.com\0cloudflare-ipfs.com\0dyndns-at-work.com\0" -"res.in\0wien\0*.cn-northwest-1.airflow.amazonaws.com.cn\0" -"cc.va.us\0lib.wi.us\0pics\0" -"\xd1\x80\xd1\x84\0\xe6\x85\x88\xe5\x96\x84\0a.prod.fastly.net\0" -"skype\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xd8\xa9\0" -"\xe4\xb8\xaa\xe4\xba\xba.hk\0" -"gdn\0" -"soeda.fukuoka.jp\0shikabe.hokkaido.jp\0tosa.kochi.jp\0pupu.jp\0hasura.app\0" -"gea\0" -"ftr\0" -"rel.ht\0support\0" -"emrstudio-prod.us-gov-east-1.amazonaws.com\0s3-website.eu-west-2.amazonaws.com\0*.builder.code.com\0" -"fun\0" -"paas.beebyte.io\0" -"aetna\0cuisinella\0toyota\0" -"k12.pr.us\0" -"friuli-veneziagiulia.it\0valleeaoste.it\0barsy.net\0" -"syno-ds.de\0" -"zagan.pl\0" -"lenvik.no\0""123hjemmeside.no\0" -"\xe7\xa6\x8f\xe5\xb3\xb6.jp\0nagara.chiba.jp\0shimamaki.hokkaido.jp\0asahi.mie.jp\0tokigawa.saitama.jp\0musashimurayama.tokyo.jp\0tonkotsu.jp\0" -"nu.ca\0" -"brussels\0" -"ingatlan.hu\0mobi.ke\0jelastic.regruhosting.ru\0" -"dh.bytemark.co.uk\0" -"auth.af-south-1.amazoncognito.com\0emrappui-prod.us-east-2.amazonaws.com\0eu-west-1.elasticbeanstalk.com\0dnsalias.com\0is-a-libertarian.com\0" -"agric.za\0" -"sd.us\0k12.pa.us\0\xe5\x8f\xb0\xe7\x81\xa3\0" -"trentins\xc3\xbc""d-tirol.it\0pgafan.net\0" -"estate\0" -"platter-app.dev\0" -"leasing.aero\0" -"\xe5\xae\xae\xe5\xb4\x8e.jp\0choshi.chiba.jp\0ozu.ehime.jp\0wanouchi.gifu.jp\0hakusan.ishikawa.jp\0tonosho.kagawa.jp\0tomi.nagano.jp\0tenkawa.nara.jp\0gosen.niigata.jp\0" -"se.leg.br\0" -"storage\0" -"fyi\0wiki\0" -"gmail\0" -"execute-api.ap-southeast-3.amazonaws.com\0s3.us-east-2.amazonaws.com\0webview-assets.cloud9.ap-south-1.amazonaws.com\0" -"recipes\0notebook-fips.us-gov-west-1.sagemaker.aws\0" -"vald-aosta.it\0pc.it\0akamai-staging.net\0" -"eidsvoll.no\0" -"misato.miyagi.jp\0seiro.niigata.jp\0izumi.osaka.jp\0kyuragi.saga.jp\0" -"vinnytsia.ua\0okinawa\0" -"ppg.br\0" -"music\0travelers\0" -"s3-object-lambda.sa-east-1.amazonaws.com\0s3-website.us-east-2.amazonaws.com\0from-ks.com\0is-a-cpa.com\0eu.pythonanywhere.com\0" -"notebook.ap-southeast-2.sagemaker.aws\0" -"veneto.it\0carbonia-iglesias.it\0" -"gle\0wine\0dyn.cosidns.de\0obninsk.su\0" -"rel.pl\0" -"jan-mayen.no\0aremark.no\0rindal.no\0" -"koriyama.fukushima.jp\0mitoyo.kagawa.jp\0sakurai.nara.jp\0kawachinagano.osaka.jp\0taira.toyama.jp\0" -"mp.br\0" -"goldpoint\0hyatt\0" -"prime\0forgot.his.name\0" -"s3-accesspoint.ap-northeast-3.amazonaws.com\0webview-assets.cloud9.eu-north-1.amazonaws.com\0no.com\0from-wy.com\0" -"gmo\0" -"nu.it\0verona.it\0fra1-de.cloudjiffy.net\0" -"7.bg\0ping\0\xe5\x81\xa5\xe5\xba\xb7\0" -"gmx\0" -"pink\0secaas.hk\0" -"wif.gov.pl\0" -"hof.no\0" -"toyako.hokkaido.jp\0hirado.nagasaki.jp\0minobu.yamanashi.jp\0" -"donetsk.ua\0yoga\0v.ua\0" -"komvux.se\0o.se\0bike\0bashkiria.ru\0filegear-ie.me\0barsy.me\0dev.vu\0xs4all.space\0" -"*.usercontent.goog\0" -"s3-object-lambda.ap-northeast-2.amazonaws.com\0s3-accesspoint.eu-west-2.amazonaws.com\0from-nh.com\0" -"goo\0vaporcloud.io\0" -"gop\0" -"vall\xc3\xa9""eaoste.it\0got\0" -"bashkiria.su\0" -"gov\0" -"0.bg\0" -"caa.li\0" -"123hjemmeside.dk\0" -"pc.pl\0upow.gov.pl\0" -"quangbinh.vn\0" -"journal.aero\0services.aero\0ol.no\0b\xc3\xa6rum.no\0rahkkeravju.no\0" -"\xe7\x86\x8a\xe6\x9c\xac.jp\0tatsuno.hyogo.jp\0fussa.tokyo.jp\0misato.wakayama.jp\0hungry.jp\0punyu.jp\0" -"mb.ca\0" -"contractors\0official.ec\0*.diher.solutions\0" -"h.se\0hlx3.page\0" -"*.ap-southeast-2.airflow.amazonaws.com\0awsmppl.com\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xdb\x83\0docs\0" -"altoadige.it\0belluno.it\0homelinux.net\0website.yandexcloud.net\0" -"bing\0servebbs.org\0int.eu.org\0" -"zapto.xyz\0" -"*.dweb.link\0" -"ambulance.aero\0fuel.aero\0karlsoy.no\0r\xc3\xb8st.no\0skjerv\xc3\xb8y.no\0hbo\0barsy.pro\0" -"noda.chiba.jp\0hida.gifu.jp\0tomika.gifu.jp\0shinshinotsu.hokkaido.jp\0kasumigaura.ibaraki.jp\0" -"saogonca.br\0" -"a.se\0" -"\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\0" -"*.eu-west-1.airflow.amazonaws.com\0s3-ap-northeast-1.amazonaws.com\0*.nodebalancer.linode.com\0ddnslive.com\0servehttp.com\0" -"emrappui-prod.cn-northwest-1.amazonaws.com.cn\0" -"cc.ri.us\0*.advisor.ws\0" -"\xe6\x9c\xba\xe6\x9e\x84\0" -"azure\0furniture\0" -"targi.pl\0wolomin.pl\0" -"design.aero\0granvin.no\0lind\xc3\xa5s.no\0siellak.no\0valle.no\0barsy.ro\0" -"bibai.hokkaido.jp\0sannan.hyogo.jp\0zushi.kanagawa.jp\0ryokami.saitama.jp\0" -"aju.br\0barsy.pub\0" -"emrnotebooks-prod.us-east-1.amazonaws.com\0""3utilities.com\0" -"ravendb.run\0" -"k12.nj.us\0homes\0" -"sardinia.it\0mi.it\0" -"tube\0" -"bievat.no\0dovre.no\0kvafjord.no\0naamesjevuemie.no\0dvrcam.info\0" -"hazu.aichi.jp\0pippu.hokkaido.jp\0beppu.oita.jp\0shinjo.okayama.jp\0digick.jp\0websozai.jp\0snowflake.app\0" -"com.ac\0" -"com.af\0" -"com.ag\0" -"com.ai\0ravendb.community\0" -"barsy.uk\0" -"com.al\0" -"com.am\0amfam\0s3.dualstack.ap-southeast-2.amazonaws.com\0webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com\0ddns5.com\0sakuraweb.com\0" -"com.ba\0" -"com.ar\0com.bb\0" -"k12.mi.us\0barclays\0" -"val-daosta.it\0mb.it\0gets-it.net\0mircloud.host\0nordeste-idc.saveincloud.net\0" -"com.au\0" -"com.aw\0freeddns.org\0" -"com.bh\0" -"com.bi\0" -"com.az\0com.bj\0" -"jgora.pl\0" -"com.bm\0" -"com.bn\0" -"com.bo\0agdenes.no\0hob\xc3\xb8l.no\0meloy.no\0v\xc3\xa5ler.hedmark.no\0" -"yanagawa.fukuoka.jp\0nagawa.nagano.jp\0tatsuno.nagano.jp\0yoshida.shizuoka.jp\0user.aseinet.ne.jp\0ondigitalocean.app\0lovepop.jp\0" -"kirovograd.ua\0" -"com.br\0" -"com.bs\0" -"com.bt\0" -"abbvie\0college\0" -"com.by\0com.ci\0" -"com.bz\0" -"com.cm\0room\0from-wa.com\0wphostedmail.com\0" -"com.cn\0" -"com.co\0drud.io\0" -"\xe0\xa8\xad\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\xa4\0" -"com.cu\0com.de\0service.one\0" -"com.cv\0hiv\0" -"com.cw\0\xd9\x85\xd9\x84\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa7\0dontexist.org\0" -"com.cy\0" -"powiat.pl\0" -"com.dm\0" -"com.do\0balat.no\0sande.vestfold.no\0" -"nogata.fukuoka.jp\0shinyoshitomi.fukuoka.jp\0eniwa.hokkaido.jp\0okoppe.hokkaido.jp\0toyotomi.hokkaido.jp\0tsukumi.oita.jp\0kamiichi.toyama.jp\0" -"com.ec\0" -"madrid\0" -"com.ee\0utazas.hu\0" -"com.eg\0" -"swatch\0" -"com.dz\0" -"*.code.run\0" -"com.es\0k12.ks.us\0land-4-sale.us\0" -"com.et\0hkt\0uk.net\0" -"familyds.org\0" -"com.fj\0" -"com.fm\0" -"hadsel.no\0oystre-slidre.no\0" -"owariasahi.aichi.jp\0noshiro.akita.jp\0oga.akita.jp\0shirako.chiba.jp\0kumano.mie.jp\0koshigaya.saitama.jp\0akishima.tokyo.jp\0" -"cherkassy.ua\0" -"com.fr\0" -"deals\0" -"aip.ee\0com.ge\0" -"com.gh\0" -"com.gi\0" -"com.gl\0" -"s3-object-lambda.us-west-2.amazonaws.com\0radio.am\0appchizi.com\0" -"com.gn\0*.cn-north-1.airflow.amazonaws.com.cn\0" -"com.gp\0" -"com.gr\0chungnam.kr\0" -"lib.pr.us\0" -"com.gt\0valleedaoste.it\0dell-ogliastra.it\0" -"com.gu\0" -"yandex\0" -"com.gy\0" -"com.hk\0" -"\xed\x95\x9c\xea\xb5\xad\0" -"com.hn\0" -"toyone.aichi.jp\0kosaka.akita.jp\0hatsukaichi.hiroshima.jp\0kuromatsunai.hokkaido.jp\0kasama.ibaraki.jp\0bato.tochigi.jp\0lolipopmc.jp\0" -"campinagrande.br\0rj.gov.br\0radio.br\0com.hr\0" -"net.ac\0" -"com.ht\0" +"no.com\0api.gov.uk\0" +"sumita.iwate.jp\0" +"sorfold.no\0bradesco\0" +"glass\0inc\0" +"tv.im\0lib.ny.us\0mein-vigor.de\0" +"tv.in\0" +"ing\0" +"chicappa.jp\0" +"cloud.goog\0" +"ink\0s3.eu-south-1.amazonaws.com\0" +"tv.it\0kumejima.okinawa.jp\0" +"ktistory.com\0" +"amami.kagoshima.jp\0" +"ono.fukushima.jp\0anpachi.gifu.jp\0aid.pl\0" +"emrappui-prod.cn-north-1.amazonaws.com.cn\0" +"lib.mn.us\0" +"int\0ama.aichi.jp\0" +"k12.ar.us\0amsterdam\0" +"tr\xc3\xa6na.no\0" +"to.it\0awaji.hyogo.jp\0" +"\xd0\xbe\xd1\x80\xd0\xb3\0" +"pp.az\0akamaihd.net\0" +"studio\0tv.kg\0" +"danang.vn\0" +"ivanovo.su\0" +"fuso.aichi.jp\0minoh.osaka.jp\0hikawa.shimane.jp\0dedibox.fr\0" +"photography\0" +"takagi.nagano.jp\0nagasaki.nagasaki.jp\0" +"net.ac\0vaapste.no\0webview-assets.aws-cloud9.ca-central-1.amazonaws.com\0" "net.ae\0" "net.af\0" "net.ag\0" "net.ai\0" -"\xd8\xa7\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\0" +"hyuga.miyazaki.jp\0" "net.al\0" -"net.am\0com.im\0execute-api.us-west-2.amazonaws.com\0auth.sa-east-1.amazoncognito.com\0s3.dualstack.eu-central-1.amazonaws.com\0s3-object-lambda.us-gov-east-1.amazonaws.com\0customer.mythic-beasts.com\0" -"com.in\0" -"com.io\0dedyn.io\0mo-siemens.io\0" -"net.ba\0com.iq\0" -"net.ar\0net.bb\0" -"com.is\0framer.photos\0" -"laz.it\0hot\0freetls.fastly.net\0" -"net.au\0*.compute.estate\0" -"\xd8\xa7\xd9\x84\xd8\xa8\xd8\xad\xd8\xb1\xd9\x8a\xd9\x86\0" -"how\0" -"net.bh\0mi.th\0" -"net.az\0net.bj\0" -"ugim.gov.pl\0wkz.gov.pl\0glogow.pl\0" -"net.bm\0" +"net.am\0pb.ao\0" +"prvcy.page\0" +"net.ba\0myasustor.com\0" +"net.ar\0or.at\0net.bb\0simplesite.gr\0" +"onfabrica.com\0" +"ta.it\0\xd8\xa7\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\0" +"net.au\0\xd8\xa8\xd9\x8a\xd8\xaa\xd9\x83\0" +"or.bi\0and\xc3\xb8y.no\0" +"net.bh\0bando.ibaraki.jp\0scalebook.scw.cloud\0" +"*.elb.amazonaws.com\0" +"net.az\0net.bj\0kitaaiki.nagano.jp\0" +"lib.me.us\0" +"net.bm\0loten.no\0k12.ak.us\0qcx.io\0" "net.bn\0" -"catering.aero\0net.bo\0com.jo\0tingvoll.no\0verdal.no\0vagsoy.no\0" -"ichinomiya.aichi.jp\0urayasu.chiba.jp\0ashiya.fukuoka.jp\0kurogi.fukuoka.jp\0miyako.fukuoka.jp\0nakatombetsu.hokkaido.jp\0harima.hyogo.jp\0ono.hyogo.jp\0nakamura.kochi.jp\0motobu.okinawa.jp\0shiraoka.saitama.jp\0tabayama.yamanashi.jp\0" -"\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0" +"net.bo\0" "net.br\0" -"net.bs\0bananarepublic\0" -"net.bt\0marriott\0" -"com.kg\0" -"net.ci\0com.ki\0" -"net.bz\0" -"net.cm\0com.km\0s3-website.ap-northeast-2.amazonaws.com\0" -"net.cn\0" -"net.co\0gitlab.io\0" -"com.kp\0" -"com.la\0" -"com.lb\0" -"com.lc\0mi.us\0cc.oh.us\0" -"ascolipiceno.it\0ny-2.paas.massivegrid.net\0reserve-online.net\0" -"net.cu\0shopware.store\0" -"net.cw\0com.kw\0barsy.org\0" -"health\0" -"net.cy\0com.ky\0" -"com.kz\0" -"com.lk\0" -"net.dm\0ibm\0radio.fm\0" -"air-surveillance.aero\0show.aero\0net.do\0\xc3\xa5mli.no\0fjaler.no\0royken.no\0" -"tsuiki.fukuoka.jp\0kannami.shizuoka.jp\0mishima.shizuoka.jp\0kamitonda.wakayama.jp\0pepper.jp\0" -"com.lr\0" +"net.bs\0" +"net.bt\0" +"or.ci\0tv.na\0s3-accesspoint.dualstack.ap-southeast-2.amazonaws.com\0" +"fakefur.jp\0to.md\0" +"net.ci\0" +"net.bz\0campidanomedio.it\0hakusan.ishikawa.jp\0kadogawa.miyazaki.jp\0" +"healthcare\0" +"net.cm\0" +"net.cn\0homeunix.net\0" +"nt.au\0net.co\0" +"or.cr\0wodzislaw.pl\0jcb\0" +"s3-website.ap-northeast-2.amazonaws.com\0" +"ojiya.niigata.jp\0" +"net.cu\0s3-accesspoint-fips.dualstack.ca-central-1.amazonaws.com\0operaunite.com\0" +"net.cw\0lib.ks.us\0myactivedirectory.com\0" +"net.cy\0" +"asti.it\0" +"nt.ca\0" +"net.dm\0" +"net.do\0" +"sc.ke\0" +"takata.fukuoka.jp\0ist\0" "net.ec\0" -"diadem.cloud\0" -"ice\0myjino.ru\0" -"com.lv\0" -"net.eg\0com.mg\0game.tw\0" -"com.ly\0" -"net.dz\0" -"com.mk\0" -"com.ml\0" -"s3-object-lambda.us-gov-west-1.amazonaws.com\0webview-assets.aws-cloud9.us-west-1.amazonaws.com\0trycloudflare.com\0" -"playstation\0" -"com.mo\0basicserver.io\0" -"com.na\0honda\0" -"juniper\0" -"com.ms\0" -"net.et\0trentino-a-adige.it\0trentino-s\xc3\xbc""dtirol.it\0com.mt\0quest\0*.webpaas.ovh.net\0dev.static.land\0" -"com.mu\0icu\0" -"com.mv\0com.nf\0" -"com.mw\0com.ng\0barsy.bg\0" -"com.mx\0" -"com.my\0com.ni\0" +"s3.ap-south-1.amazonaws.com\0grozny.su\0" +"edgeapp.net\0" +"net.eg\0" +"net.dz\0abr.it\0" +"re.it\0kawajima.saitama.jp\0" +"aurland.no\0" +"okinawa.jp\0sc.kr\0" +"giehtavuoatna.no\0" +"tagawa.fukuoka.jp\0" +"guovdageaidnu.no\0" +"is-a-chef.org\0" +"net.et\0malopolska.pl\0itv\0" +"webhop.info\0" +"nm.cn\0kimitsu.chiba.jp\0chungnam.kr\0" +"nf.ca\0" +"tobishima.aichi.jp\0kami.kochi.jp\0" +"servebeer.com\0" "net.fj\0" -"\xe6\x95\x8e\xe8\x82\xb2.hk\0" -"net.fm\0" -"safety.aero\0kvinesdal.no\0\xc3\xb8ksnes.no\0rade.no\0" -"!city.nagoya.jp\0mihama.chiba.jp\0miyazu.kyoto.jp\0uenohara.yamanashi.jp\0framer.app\0" -"barsy.ca\0" -"com.nr\0" -"tatamotors\0\xd0\xbe\xd1\x80\xd0\xb3\0" +"net.fm\0s3-accesspoint.us-east-2.amazonaws.com\0" +"sc.ls\0" +"hakuba.nagano.jp\0embaixada.st\0" +"s3-ap-northeast-1.amazonaws.com\0" +"wi.us\0webview-assets.cloud9.us-west-2.amazonaws.com\0" +"azumino.nagano.jp\0" "net.ge\0" -"net.gg\0\xe7\xb6\xb2\xe8\xb7\xaf.tw\0" +"kasuya.fukuoka.jp\0" +"net.gg\0" +"serveexchange.com\0" +"re.kr\0fund\0" "net.gl\0" -"com.om\0s3-website.dualstack.eu-west-3.amazonaws.com\0publishproxy.com\0impertrix.com\0playstation-cloud.com\0" -"hl.cn\0net.gn\0" -"net.gp\0" -"com.pa\0nis.za\0" -"net.gr\0" -"cc.nj.us\0drud.us\0" -"net.gt\0trentinoa-adige.it\0fund\0select\0akamaized-staging.net\0" -"net.gu\0com.pe\0barsy.de\0" -"com.pf\0" -"\xe0\xba\xa5\xe0\xba\xb2\xe0\xba\xa7\0" -"com.ph\0" -"net.gy\0kapsi.fi\0" -"net.hk\0com.pk\0" -"com.pl\0tmall\0" -"ifm\0" -"net.hn\0" -"drammen.no\0orkdal.no\0sor-varanger.no\0" -"katsuura.chiba.jp\0onga.fukuoka.jp\0ota.gunma.jp\0sowa.ibaraki.jp\0kitakata.miyazaki.jp\0wada.nagano.jp\0kawagoe.saitama.jp\0mond.jp\0" -"com.qa\0khmelnytskyi.ua\0" -"far.br\0mat.br\0com.pr\0ba.leg.br\0" -"com.ps\0" -"net.ht\0net.id\0com.pt\0gent\0" -"marine.ru\0" -"zuerich\0hashbang.sh\0alp1.ae.flow.ch\0" -"com.py\0community\0" -"net.il\0" -"net.im\0emrstudio-prod.sa-east-1.amazonaws.com\0webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com\0cloudcontrolapp.com\0oncilla.mythic-beasts.com\0myvnc.com\0gotpantheon.com\0" -"he.cn\0net.in\0" -"net.iq\0" -"net.ir\0\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86.ir\0" -"net.is\0k12.ia.us\0cc.ms.us\0cc.nc.us\0" -"lazio.it\0contact\0shopselect.net\0" -"net.je\0com.re\0barsy.eu\0" -"bacninh.vn\0" -"net.jo\0j\xc3\xb8rpeland.no\0eigersund.no\0kvam.no\0nes.buskerud.no\0com.ro\0" -"\xe4\xbd\x90\xe8\xb3\x80.jp\0kuroishi.aomori.jp\0kamishihoro.hokkaido.jp\0shiogama.miyagi.jp\0hatoyama.saitama.jp\0komae.tokyo.jp\0kotoura.tottori.jp\0higashine.yamagata.jp\0" -"com.sa\0km.ua\0" -"bhz.br\0com.sb\0" -"plo.ps\0com.sc\0" -"com.sd\0" -"com.se\0com.ru\0co.place\0" -"\xd9\xbe\xd8\xa7\xd9\x83\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" -"net.kg\0com.sg\0kpmg\0x443.pw\0" -"com.sh\0" -"net.ki\0" -"\xd7\x90\xd7\xa7\xd7\x93\xd7\x9e\xd7\x99\xd7\x94.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0com.sl\0" -"s3-object-lambda.eu-central-2.amazonaws.com\0s3.us-west-2.amazonaws.com\0webview-assets.aws-cloud9.ap-south-1.amazonaws.com\0eu-north-1.elasticbeanstalk.com\0onrender.com\0myshopblocks.com\0" -"net.kn\0com.sn\0" -"com.so\0" +"servecounterstrike.com\0" +"net.gn\0omihachiman.shiga.jp\0" +"net.gp\0ikaruga.nara.jp\0" +"mo.cn\0net.gr\0" +"net.gt\0fujioka.gunma.jp\0soka.saitama.jp\0" +"net.gu\0translated.page\0grozny.ru\0lima.zone\0" +"oguchi.aichi.jp\0" +"execute-api.eu-central-2.amazonaws.com\0" +"net.gy\0from-nv.com\0" +"tv.sd\0gent\0" +"net.hk\0" +"otaru.hokkaido.jp\0rikuzentakata.iwate.jp\0" +"\xe7\xb5\x84\xe7\xb9\x94.hk\0kommunalforbund.se\0jambyl.su\0" +"net.hn\0vercel.app\0" +"zama.kanagawa.jp\0" +"or.id\0" +"net.ht\0net.id\0pi.it\0shimamaki.hokkaido.jp\0" +"emrstudio-prod.me-south-1.amazonaws.com\0" +"yawara.ibaraki.jp\0" +"rl.no\0from-id.com\0uber.space\0" +"boats\0" +"net.il\0umbria.it\0ferrara.it\0neustar\0" +"net.im\0ut.us\0" +"net.in\0kasamatsu.gifu.jp\0" +"net.iq\0lanxess\0" +"net.ir\0or.it\0" +"net.is\0" +"net.je\0spb.ru\0" +"tv.tr\0" +"courses\0" +"namaste.jp\0simplesite.pl\0" +"jio\0" +"or.jp\0misawa.aomori.jp\0" +"net.jo\0dvrcam.info\0read-books.org\0" +"tv.tz\0" +"kaita.hiroshima.jp\0ide.kyoto.jp\0" +"or.ke\0oy.lc\0" +"spb.su\0" +"net.kg\0eidsvoll.no\0" +"net.ki\0kpmg\0is-a-chef.com\0" +"gotemba.shizuoka.jp\0" +"resto.bj\0gifu.jp\0net.kn\0" +"or.kr\0" "net.la\0" -"net.lb\0" -"net.lc\0com.ss\0k12.id.us\0" -"com.st\0freesite.host\0" -"bridgestone\0woodside\0" -"nome.cv\0com.sv\0" -"net.kw\0samsung\0" -"gg.ax\0" -"net.ky\0com.sy\0" -"net.kz\0com.tj\0" +"lombardia.it\0net.lb\0" +"net.lc\0v\xc3\xa5g\xc3\xa5.no\0su.paba.se\0" +"net.kw\0" +"fr-par-1.baremetal.scw.cloud\0" +"net.ky\0ninja\0" +"seirou.niigata.jp\0net.kz\0" "net.lk\0" -"com.tm\0" -"com.tn\0" -"b\xc3\xb8.nordland.no\0vardo.no\0com.to\0latino\0" -"yame.fukuoka.jp\0kasahara.gifu.jp\0nakagawa.hokkaido.jp\0naoshima.kagawa.jp\0ise.mie.jp\0saku.nagano.jp\0" -"net.ma\0com.ua\0" -"net.lr\0com.tr\0" -"net.ls\0" -"com.tt\0" +"ogori.fukuoka.jp\0shinagawa.tokyo.jp\0" +"kicks-ass.org\0" +"tomisato.chiba.jp\0" +"mcpe.me\0" +"kagawa.jp\0kunitomi.miyazaki.jp\0" +"net.ma\0" +"fujisawa.iwate.jp\0net.lr\0" +"net.ls\0lib.hi.us\0" "net.me\0" -"net.lv\0" -"com.tw\0com.ug\0" +"net.lv\0zakopane.pl\0" +"abiko.chiba.jp\0miki.hyogo.jp\0" "net.ly\0" +"jll\0" "net.mk\0" -"net.ml\0" -"emrappui-prod.us-west-1.amazonaws.com\0s3-ap-south-1.amazonaws.com\0hk.com\0" +"net.ml\0s3-accesspoint.cn-northwest-1.amazonaws.com.cn\0" +"net.mo\0or.na\0bievat.no\0land-4-sale.us\0" +"firenze.it\0\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0" +"stange.no\0" +"net.ms\0or.mu\0" +"net.mt\0caravan\0" +"net.mu\0" +"net.mv\0net.nf\0" +"net.mw\0net.ng\0kvanangen.no\0" +"mo.it\0net.mx\0ny-2.paas.massivegrid.net\0" +"net.my\0net.ni\0" +"net.mz\0" +"tran\xc3\xb8y.no\0" +"taka.hyogo.jp\0" +"naples.it\0jmp\0" +"dell-ogliastra.it\0net.nr\0" +"sc.ug\0" +"takashima.shiga.jp\0" +"s3.il-central-1.amazonaws.com\0mytabit.com\0" +"sc.tz\0" +"emrstudio-prod.ap-northeast-3.amazonaws.com\0" +"jnj\0" +"net.nz\0" +"molde.no\0net.om\0studio.eu-west-3.sagemaker.aws\0" +"njs.jelastic.vps-host.net\0" +"sc.us\0" +"haibara.shizuoka.jp\0" +"net.pa\0" +"bifuka.hokkaido.jp\0grajewo.pl\0" +"delivery\0" +"nes.buskerud.no\0net.pe\0" +"wa.edu.au\0" +"net.ph\0swidnik.pl\0" +"nt.no\0" +"net.pk\0news\0webview-assets.aws-cloud9.eu-west-2.amazonaws.com\0" +"net.pl\0" +"aisho.shiga.jp\0mielno.pl\0net.pn\0" +"net.qa\0" +"net.pr\0jot\0" +"entertainment.aero\0net.ps\0" +"net.pt\0" +"or.pw\0independent-review.uk\0" +"encr.app\0" +"\xc3\xb8ystre-slidre.no\0pp.se\0joy\0pp.ru\0" +"\xe7\x9f\xb3\xe5\xb7\x9d.jp\0" +"net.py\0" +"dontexist.org\0" +"next\0sg-1.paas.massivegrid.net\0" +"avocat.pro\0browsersafetymark.io\0" +"hamburg\0mex.com\0filegear-jp.me\0jelastic.dogado.eu\0" +"lc.it\0" +"vall\xc3\xa9""e-aoste.it\0izumiotsu.osaka.jp\0" +"nis.za\0*.backyards.banzaicloud.io\0" +"trentino-s-tirol.it\0handcrafted.jp\0vip.jelastic.cloud\0mydissent.net\0" +"hb.cldmail.ru\0" +"sennan.osaka.jp\0" +"\xed\x95\x9c\xea\xb5\xad\0" +"hk.cn\0" +"s3-accesspoint.dualstack.us-east-1.amazonaws.com\0" +"ap-northeast-2.elasticbeanstalk.com\0" +"higashichichibu.saitama.jp\0" +"grong.no\0net.sa\0" +"net.sb\0" +"net.sc\0pp.ua\0" +"net.sd\0cn-northwest-1.eb.amazonaws.com.cn\0lolitapunk.jp\0" +"net.ru\0" +"kamikoani.akita.jp\0kozaki.chiba.jp\0*.svc.firenet.ch\0" +"net.rw\0net.sg\0" +"net.sh\0" +"sex.hu\0safe\0" +"konyvelo.hu\0" +"net.sl\0clubmed\0" +"filegear-gb.me\0" +"net.so\0" +"yanagawa.fukuoka.jp\0" +"africa.com\0" +"iwade.wakayama.jp\0" +"net.ss\0" +"obama.nagasaki.jp\0net.st\0" +"andoy.no\0" +"or.th\0" +"nissedal.no\0paroch.k12.ma.us\0" +"net.th\0" +"nt.ro\0net.sy\0" +"9guacu.br\0net.tj\0earth\0" +"marnardal.no\0" +"showa.gunma.jp\0" +"net.tm\0lpages.co\0tcp4.me\0" +"kanie.aichi.jp\0net.tn\0" +"catholic.edu.au\0net.to\0" +"est.pr\0*.bzz.dapps.earth\0" +"net.ua\0" +"kamimine.saga.jp\0net.tr\0icurus.jp\0" +"net.tt\0" +"or.ug\0" +"net.tw\0play\0" +"or.tz\0" +"mod.gi\0" +"takamatsu.kagawa.jp\0" +"net.uk\0" +"oirase.aomori.jp\0" +"blogdns.org\0" +"or.us\0" +"kraanghke.no\0net.vc\0" +"hitra.no\0net.ve\0graphics\0\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\x89\0" +"net.uy\0net.vi\0" +"net.uz\0" +"od.ua\0" +"obama.fukui.jp\0jcloud.kz\0" +"notebook.ap-northeast-2.sagemaker.aws\0" +"net.vn\0nobushi.jp\0" +"equipment.aero\0ok.us\0us.com\0" +"krasnik.pl\0" +"plc.ly\0s3-fips.dualstack.us-east-2.amazonaws.com\0" +"minami.kyoto.jp\0" +"net.vu\0" +"kfh\0" +"microlight.aero\0" +"ju.mp\0" +"tono.iwate.jp\0toba.mie.jp\0" +"blogsyte.com\0" +"higashiizu.shizuoka.jp\0" +"\xe7\xa6\x8f\xe4\xba\x95.jp\0" +"firestone\0" +"umaji.kochi.jp\0" +"net.ws\0" +"now-dns.top\0" +"supply\0" +"itoman.okinawa.jp\0emrnotebooks-prod.cn-northwest-1.amazonaws.com.cn\0" +"lib.ar.us\0publishproxy.com\0id.firewalledreplit.co\0" +"trentinosudtirol.it\0" +"nm.us\0guide\0" +"oamishirasato.chiba.jp\0nogi.tochigi.jp\0" +"s3-website.us-east-1.amazonaws.com\0" +"priv.instances.scw.cloud\0" +"is-a-caterer.com\0" +"se.net\0ru.net\0" +"net.ye\0murmansk.su\0" +"does-it.net\0" +"store\0s3.dualstack.ap-southeast-2.amazonaws.com\0" +"sale\0unicom\0" +"kia\0" +"jor.br\0" +"net.za\0" +"emr.it\0" +"overhalla.no\0mo.us\0" +"arvo.network\0" +"matsudo.chiba.jp\0warszawa.pl\0" +"kim\0jpn.com\0" +"molise.it\0tamba.hyogo.jp\0heavy.jp\0" +"net.zm\0dance\0" +"iglesiascarbonia.it\0yufu.oita.jp\0" +"sex.pl\0" +"execute-api.us-west-2.amazonaws.com\0" +"kamiichi.toyama.jp\0mediatech.dev\0" +"serveftp.com\0" +"center\0" +"noboribetsu.hokkaido.jp\0camau.vn\0" +"higashihiroshima.hiroshima.jp\0eu.platform.sh\0" +"narviika.no\0" +"ote.bj\0" +"bamble.no\0kustanai.ru\0" +"ibigawa.gifu.jp\0""6.azurestaticapps.net\0" +"ma.us\0s3-website.dualstack.eu-south-1.amazonaws.com\0" +"kl\xc3\xa6""bu.no\0rauma.no\0" +"land\0" +"manaus.br\0ma.leg.br\0" +"kvam.no\0" +"ks.ua\0" +"pharmaciens.km\0school.za\0kustanai.su\0xnbay.com\0" +"tarnobrzeg.pl\0" +"sar.it\0" +"alpha.bounty-full.com\0" +"mydrobo.com\0" +"emrnotebooks-prod.ap-northeast-1.amazonaws.com\0" +"kutchan.hokkaido.jp\0" +"lcube-server.de\0" +"kosai.shizuoka.jp\0" +"ks.us\0" +"sec.ps\0" +"sanuki.kagawa.jp\0gsj.bz\0" +"university\0" +"kamikawa.hyogo.jp\0catfood.jp\0" +"\xe0\xba\xa5\xe0\xba\xb2\xe0\xba\xa7\0" +"omi.niigata.jp\0uk.primetel.cloud\0" +"zara\0" +"bearalvahki.no\0bplaced.com\0" +"\xe5\x85\xac\xe7\x9b\x8a\0" +"ggee\0" +"trentino.it\0andriabarlettatrani.it\0forl\xc3\xac""cesena.it\0" +"theater\0" +"shichinohe.aomori.jp\0ayabe.kyoto.jp\0sandvikcoromant\0" +"plc.uk\0" +"hamura.tokyo.jp\0" +"\xe7\xae\x87\xe4\xba\xba.hk\0emrappui-prod.us-east-2.amazonaws.com\0is-a-painter.com\0" +"bmd.br\0soma.fukushima.jp\0" +"de.gt\0" +"\xe5\x95\x86\xe5\xba\x97\0" +"tachikawa.tokyo.jp\0tabitorder.co.il\0" +"habmer.no\0" +"sarl\0" +"homeunix.org\0" +"kahoku.ishikawa.jp\0" +"s3-object-lambda.eu-south-2.amazonaws.com\0spdns.org\0" +"tranoy.no\0notebook.us-gov-west-1.sagemaker.aws\0" +"mazowsze.pl\0" +"cyon.link\0" +"masaki.ehime.jp\0minato.tokyo.jp\0" +"nagasu.kumamoto.jp\0" +"is-an-artist.com\0twmail.org\0" +"tochio.niigata.jp\0" +"trentinos\xc3\xbc""dtirol.it\0" +"kamo.kyoto.jp\0kpn\0" +"\xd0\xba\xd0\xbe\xd0\xbc.\xd1\x80\xd1\x83\xd1\x81\0" +"pl.eu.org\0" +"is-a-chef.net\0" +"cn.in\0valleedaoste.it\0kawanishi.hyogo.jp\0" +"fuossko.no\0" +"tokai.aichi.jp\0" +"gs.vf.no\0" +"cn.it\0" +"cloud.nospamproxy.com\0" +"avocat.fr\0" +"ybo.trade\0" +"krd\0lat\0" +"cc.wy.us\0law\0" +"kred\0" +"medicina.bo\0" +"save\0" +"s3.nl-ams.scw.cloud\0" +"\xe6\x95\x99\xe8\x82\xb2.hk\0rindal.no\0" +"biz.bb\0tgory.pl\0" +"biz.at\0" +"blog\0" +"conf.au\0" +"\xd7\x99\xd7\xa9\xd7\x95\xd7\x91.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0bihar.in\0" +"oracle\0" +"biz.az\0" +"\xd1\x80\xd1\x83\xd1\x81\0" +"marketing\0" +"ofunato.iwate.jp\0ureshino.mie.jp\0" +"lotte\0webview-assets.cloud9.af-south-1.amazonaws.com\0de.ls\0" +"de.md\0" +"home.dyndns.org\0demo.datacenter.fi\0dscloud.mobi\0" +"baria-vungtau.vn\0" +"mosjoen.no\0" +"bi.it\0\xe0\xb8\x97\xe0\xb8\xab\xe0\xb8\xb2\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0k8s.fr-par.scw.cloud\0" +"lotto\0" +"tokamachi.niigata.jp\0gehirn.ne.jp\0bookonline.app\0" +"fidelity\0" +"inabe.mie.jp\0nerima.tokyo.jp\0" +"\xe7\xbd\x91\xe5\xba\x97\0" +"rebun.hokkaido.jp\0" +"takaharu.miyazaki.jp\0coolblog.jp\0" +"\xd9\x85\xd9\x84\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa7\0" +"laquila.it\0!city.kitakyushu.jp\0ayagawa.kagawa.jp\0" +"cc.vt.us\0" +"daito.osaka.jp\0vanguard\0" +"lds\0" +"ar.it\0" +"frogn.no\0saxo\0" +"biz.cy\0rollag.no\0aramco\0audible\0" +"fh.se\0biz.dk\0" +"udi.br\0" +"is-leet.com\0" +"v\xc3\xa5ler.hedmark.no\0" +"nishiarita.saga.jp\0" +"yusuhara.kochi.jp\0" +"george\0" +"independent-commission.uk\0" +"verm\xc3\xb6gensberatung\0" +"expert\0imdb\0" +"varoy.no\0" +"econo.bj\0biz.et\0murakami.niigata.jp\0" +"furano.hokkaido.jp\0" +"c66.me\0" +"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0" +"biz.fj\0koka.shiga.jp\0susono.shizuoka.jp\0" +"media.aero\0\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0svn-repos.de\0" +"niimi.okayama.jp\0" +"*.on-k3s.io\0" +"ad.jp\0kita.tokyo.jp\0" +"snillfjord.no\0hotels\0mel.cloudlets.com.au\0" +"kherson.ua\0" +"monster\0" +"plus\0" +"yawatahama.ehime.jp\0sayo.hyogo.jp\0" +"austrheim.no\0" +"cc.tx.us\0" +"kawanishi.nara.jp\0biz.gl\0" +"sanofi\0" +"istanbul\0" +"studio.me-south-1.sagemaker.aws\0resindevice.io\0" +"izumi.osaka.jp\0" +"blue\0" +"homelinux.com\0" +"aoki.nagano.jp\0" +"analytics-gateway.us-west-2.amazonaws.com\0" +"tara.saga.jp\0" +"bostik\0" +"ac.gov.br\0\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86.ir\0\xe9\x9d\x92\xe6\xa3\xae.jp\0" +"accesscam.org\0" +"biz.id\0" +"hotel.tz\0" +"s3-accesspoint-fips.dualstack.us-west-1.amazonaws.com\0" +"is-a-teacher.com\0" +"mizuho.tokyo.jp\0" +"loabat.no\0" +"biz.in\0kagamiishi.fukushima.jp\0" +"flight.aero\0s3-fips.dualstack.us-gov-east-1.amazonaws.com\0" +"from-va.com\0" +"sasayama.hyogo.jp\0" +"matta-varjjat.no\0" +"chieti.it\0*.sapporo.jp\0us.platform.sh\0" +"r\xc3\xb8""d\xc3\xb8y.no\0" +"shimoji.okinawa.jp\0" +"championship.aero\0sor-fron.no\0" +"ozu.ehime.jp\0" +"*.eu-central-1.airflow.amazonaws.com\0" +"16-b.it\0" +"bet.ar\0hisayama.fukuoka.jp\0development.run\0" +"daknong.vn\0nikita.jp\0" +"is-with-theband.com\0" +"ine.kyoto.jp\0kunitachi.tokyo.jp\0gangwon.kr\0" +"donna.no\0llc\0" +"emrappui-prod.af-south-1.amazonaws.com\0" +"aguni.okinawa.jp\0nishi.osaka.jp\0" +"biz.ki\0" +"\xd8\xa8\xd8\xa7\xd8\xb1\xd8\xaa\0" +"cn.ua\0" +"campidano-medio.it\0" +"de.us\0" +"kikugawa.shizuoka.jp\0" +"pizza\0" +"imperia.it\0shinshiro.aichi.jp\0makurazaki.kagoshima.jp\0llp\0" +"vard\xc3\xb8.no\0" +"business.in\0emrnotebooks-prod.cn-north-1.amazonaws.com.cn\0" +"flog.br\0bolzano.it\0memorial\0vercel.dev\0" +"union.aero\0kristiansund.no\0yalta.ua\0" +"nittedal.no\0vestre-slidre.no\0" +"jls-sto3.elastx.net\0" +"imamat\0" +"biz.ls\0analytics-gateway.ap-southeast-1.amazonaws.com\0" +"nakagawa.fukuoka.jp\0" +"wolterskluwer\0" +"s3-accesspoint.dualstack.eu-central-2.amazonaws.com\0" +"sells-for-less.com\0" +"gulen.no\0ezproxy.kuleuven.be\0" +"toyono.osaka.jp\0yaizu.shizuoka.jp\0global.ssl.fastly.net\0" +"cn.vu\0" +"musica.ar\0" +"namdalseid.no\0" +"kawaue.gifu.jp\0takinoue.hokkaido.jp\0biz.mv\0zgora.pl\0" +"qld.gov.au\0museum\0biz.mw\0skj\xc3\xa5k.no\0" +"ato.br\0vlog.br\0" +"cargo.aero\0biz.my\0biz.ni\0" +"sosa.chiba.jp\0" +"gs.of.no\0\xd1\x81\xd1\x80\xd0\xb1\0" +"us-gov-west-1.elasticbeanstalk.com\0" +"boston\0lol\0syncloud.it\0" +"musica.bo\0" +"abbvie\0s3-object-lambda.me-central-1.amazonaws.com\0" +"utazu.kagawa.jp\0biz.nr\0barclaycard\0jetzt\0" +"kerryhotels\0" +"reg.dk\0" +"is-into-anime.com\0" +"choshi.chiba.jp\0aikawa.kanagawa.jp\0" +"chitose.hokkaido.jp\0" +"sagamihara.kanagawa.jp\0lpl\0" +"cleaning\0immo\0is-a-llama.com\0" +"ikawa.akita.jp\0" +"ar.us\0base.ec\0" +"hotel.lk\0cc.pr.us\0mydobiss.com\0" +"kurume.fukuoka.jp\0" +"4lima.de\0" +"biz.pk\0" +"mar.it\0biz.pl\0ath.cx\0" +"unj\xc3\xa1rga.no\0" +"gonohe.aomori.jp\0" +"is-saved.org\0wixstudio.io\0" +"man\0" +"omotego.fukushima.jp\0biz.pr\0map\0" +"ak.us\0mba\0" +"taiki.mie.jp\0saga.saga.jp\0" +"gok.pk\0theatre\0wanggou\0" +"aomori.jp\0maison\0" +"couchpotatofries.org\0" +"kafjord.no\0" +"tmp.br\0" +"oirm.gov.pl\0" +"treviso.it\0s3-website.cn-north-1.amazonaws.com.cn\0" +"aejrie.no\0" +"shiranuka.hokkaido.jp\0shima.mie.jp\0""4lima.at\0" +"travinh.vn\0flt.cloud.muni.cz\0" +"iserv.dev\0" +"vega.no\0charity\0" +"soundcast.me\0" +"bplaced.net\0" +"ltd\0" +"hlx.page\0conf.se\0" +"kuleuven.cloud\0" +"t.bg\0auth.ap-northeast-3.amazoncognito.com\0" +"4lima.ch\0" +"cc.nv.us\0" +"review\0" +"biz.ss\0from-nj.com\0" +"en-root.fr\0" +"ggf.br\0med\0" +"m.bg\0" +"biz.tj\0edgecompute.app\0" +"execute-api.eu-west-3.amazonaws.com\0" +"tos.it\0" +"groks-the.info\0is-a-green.com\0" +"discover\0" +"no-ip.info\0" +"men\0" +"hotel.hu\0eidfjord.no\0biz.ua\0" +"biz.tr\0pharmacien.fr\0" +"biz.tt\0tempurl.host\0" +"f.bg\0" +"tosu.saga.jp\0gonna.jp\0" +"siracusa.it\0" +"is-into-games.com\0" +"cc.nh.us\0" +"aseral.no\0" +"is-very-nice.org\0" +"naroy.no\0no.eu.org\0" +"vagsoy.no\0" +"app.br\0" +"bargains\0whoswho\0pstmn.io\0" +"oops.jp\0" +"onavstack.net\0" +"mg.leg.br\0" +"legnica.pl\0biz.vn\0haiduong.vn\0" +"kerryproperties\0" +"inderoy.no\0" +"samukawa.kanagawa.jp\0" +"nose.osaka.jp\0biz.wf\0" +"kr\xc3\xa5""anghke.no\0" +"sayama.osaka.jp\0" +"coupons\0js.org\0" +"abkhazia.su\0" +"motosu.gifu.jp\0" +"blogdns.net\0" +"rokunohe.aomori.jp\0" +"construction\0hicam.net\0" +"its.me\0" +"g\xc3\xa1ls\xc3\xa1.no\0studio.eu-west-1.sagemaker.aws\0" +"happou.akita.jp\0" +"caa.aero\0booking\0" +"tsk.tr\0" +"airforce\0" +"hokuto.yamanashi.jp\0" +"emrstudio-prod.ap-southeast-2.amazonaws.com\0" +"mil\0topaz.ne.jp\0" +"aland.fi\0info\0" +"otari.nagano.jp\0" +"hida.gifu.jp\0" +"smushcdn.com\0" +"dnsking.ch\0" +"\xe5\x98\x89\xe9\x87\x8c\xe5\xa4\xa7\xe9\x85\x92\xe5\xba\x97\0dynalias.com\0mypep.link\0" +"mit\0" +"apps.fbsbx.com\0" +"nakagyo.kyoto.jp\0tainai.niigata.jp\0" +"maebashi.gunma.jp\0" +"emrappui-prod.ap-south-1.amazonaws.com\0" +"nikolaev.ua\0studio.us-east-1.sagemaker.aws\0" +"feste-ip.net\0" +"bizen.okayama.jp\0gialai.vn\0" +"etnedal.no\0lanbib.se\0" +"film.hu\0" +"\xe7\xbb\x84\xe7\xbb\x87\xe6\x9c\xba\xe6\x9e\x84\0" +"nico\0" +"tanagura.fukushima.jp\0" +"biz.zm\0tatamotors\0" +"\xd7\xa7\xd7\x95\xd7\x9d\0" +"al.gov.br\0" +"\xc3\xa5lg\xc3\xa5rd.no\0nesset.no\0" +"chikuzen.fukuoka.jp\0consulado.st\0" +"nesodden.no\0royken.no\0mydatto.com\0" +"como.it\0mlb\0\xe5\x85\xab\xe5\x8d\xa6\0app.gp\0" +"minamiechizen.fukui.jp\0auction\0mypsx.net\0" +"5.bg\0servep2p.com\0" +"yamanouchi.nagano.jp\0oshima.tokyo.jp\0\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82\0" +"k12.mt.us\0office\0endoftheinternet.org\0" +"bygland.no\0" +"scot\0" +"gs.hm.no\0" +"sasaguri.fukuoka.jp\0" +"takahata.yamagata.jp\0" +"aerodrome.aero\0jur.pro\0analytics-gateway.ap-northeast-2.amazonaws.com\0" +"mma\0nz.eu.org\0" +"lomo.jp\0" +"mls\0" +"parma.it\0kamijima.ehime.jp\0" +"ueda.nagano.jp\0kumenan.okayama.jp\0" +"glitch.me\0" +"myjino.ru\0" +"mantova.it\0okutama.tokyo.jp\0" +"etajima.hiroshima.jp\0tottori.tottori.jp\0usercontent.jp\0" +"barsy.club\0" +"\xe9\xab\x98\xe7\x9f\xa5.jp\0kiwa.mie.jp\0" +"fuel.aero\0varggat.no\0" +"the.br\0oharu.aichi.jp\0dupont\0" +"conf.lv\0" +"auth.ap-southeast-3.amazoncognito.com\0" +"ddns.net\0" +"rennes\xc3\xb8y.no\0" +"lavangen.no\0" +"definima.io\0" +"kviteseid.no\0" +"forlicesena.it\0yuu.yamaguchi.jp\0sunnyday.jp\0" +"ap-east-1.elasticbeanstalk.com\0" +"amusement.aero\0moe\0" +"yachiyo.chiba.jp\0" +"moi\0drayddns.com\0" +"homelinux.net\0" +"accountants\0emrappui-prod.eu-central-1.amazonaws.com\0s3-accesspoint.dualstack.eu-west-3.amazonaws.com\0" +"gift\0clerkstage.app\0privatelink.snowflake.app\0" +"diamonds\0mom\0" +"for-better.biz\0" +"\xe5\x95\x86\xe6\xa5\xad.tw\0" +"in-vpn.org\0" +"qld.au\0ilovecollege.info\0" +"santoandre.br\0" +"mov\0cloudycluster.net\0" +"komagane.nagano.jp\0" +"*.ca-central-1.airflow.amazonaws.com\0" +"tonosho.kagawa.jp\0" +"giske.no\0" +"cc.id.us\0" +"ishikawa.okinawa.jp\0kotoura.tottori.jp\0nab\0" +"tysvar.no\0" +"weatherchannel\0" +"echizen.fukui.jp\0rishirifuji.hokkaido.jp\0" +"satosho.okayama.jp\0bambina.jp\0" +"belluno.it\0" +"masfjorden.no\0unjarga.no\0" +"nowaruda.pl\0" +"wiki.bo\0" +"wajima.ishikawa.jp\0" +"certmgr.org\0" +"wiki.br\0quangninh.vn\0" +"nba\0" +"lombardy.it\0miyama.fukuoka.jp\0" +"s3-fips.us-gov-east-1.amazonaws.com\0" +"itoigawa.niigata.jp\0" +"berlevag.no\0*.compute.estate\0" +"inc.hk\0" +"aju.br\0omi.nagano.jp\0" +"atami.shizuoka.jp\0" +"nike\0" +"tsuruoka.yamagata.jp\0" +"ddnss.org\0" +"vxl.sh\0" +"hdfcbank\0s3-website.ap-southeast-2.amazonaws.com\0" +"yachimata.chiba.jp\0msd\0" +"etne.no\0lib.vt.us\0firewall-gateway.de\0" +"rsvp\0" +"ris\xc3\xb8r.no\0" +"kamioka.akita.jp\0" +"*.landing.myjino.ru\0" +"leg.br\0cricket\0" +"slattum.no\0s3.dualstack.ap-northeast-2.amazonaws.com\0yali.mythic-beasts.com\0" +"ritto.shiga.jp\0" +"dyn.cosidns.de\0" +"za.bz\0" +"kasukabe.saitama.jp\0kwpsp.gov.pl\0" +"nanae.hokkaido.jp\0" +"pomorskie.pl\0" +"joburg\0emrappui-prod.us-west-1.amazonaws.com\0analytics-gateway.eu-west-1.amazonaws.com\0" +"yokaichiba.chiba.jp\0" +"hemnes.no\0" +"shimamoto.osaka.jp\0hamamatsu.shizuoka.jp\0minami.tokushima.jp\0tabuse.yamaguchi.jp\0bbs.tr\0mtn\0" +"ferrari\0rogers\0" +"narashino.chiba.jp\0tokuyama.yamaguchi.jp\0" +"us-west-1.elasticbeanstalk.com\0" +"mtr\0" +"nec\0" +"xz.cn\0" +"t.se\0s3-website.me-central-1.amazonaws.com\0" +"cc.ga.us\0" +"s3.dualstack.eu-central-1.amazonaws.com\0iki.fi\0" +"iwate.iwate.jp\0kanmaki.nara.jp\0" +"spydeberg.no\0" +"kawachinagano.osaka.jp\0london\0" +"*.sys.qcx.io\0" +"utashinai.hokkaido.jp\0" +"airline.aero\0m.se\0s3-ap-northeast-2.amazonaws.com\0dontexist.com\0" +"sorocaba.br\0tempioolbia.it\0taishi.hyogo.jp\0nonoichi.ishikawa.jp\0taketa.oita.jp\0net\0barefoot\0\xe5\x85\xac\xe5\x8f\xb8\0in.net\0" +"control.aero\0godaddy\0new\0" +"mj\xc3\xb8ndalen.no\0" +"usa.oita.jp\0" +"bremanger.no\0cherkassy.ua\0" +"nfl\0" +"co.technology\0" +"lucania.it\0toda.saitama.jp\0" +"groundhandling.aero\0f.se\0auth.eu-south-1.amazoncognito.com\0emrnotebooks-prod.ap-northeast-3.amazonaws.com\0" +"fl\xc3\xa5.no\0hasura-app.io\0" +"sytes.net\0" +"lutsk.ua\0" +"aip.ee\0" +"tsu.mie.jp\0cloudaccess.net\0" +"*.dweb.link\0" +"emrnotebooks-prod.us-west-1.amazonaws.com\0s3-fips-us-gov-west-1.amazonaws.com\0" +"kotohira.kagawa.jp\0chirurgiens-dentistes.fr\0" +"ngo\0" +"shakotan.hokkaido.jp\0" +"lebesby.no\0meraker.no\0" +"jessheim.no\0k\xc3\xa1r\xc3\xa1\xc5\xa1johka.no\0" +"nhk\0sakuraweb.com\0" +"kuokgroup\0" +"dnsupdate.info\0" +"ochi.kochi.jp\0" +"taiki.hokkaido.jp\0" +"tatsuno.hyogo.jp\0doshi.yamanashi.jp\0" +"urayasu.chiba.jp\0" +"trader.aero\0s3-us-west-1.amazonaws.com\0dyndns-at-work.com\0" +"cri.br\0gdynia.pl\0" +"l\xc3\xb8ten.no\0k12.ga.us\0" +"tas.au\0tennis\0" +"bofa\0" +"inuyama.aichi.jp\0motoyama.kochi.jp\0" +"\xe9\xa6\x99\xe6\xa0\xbc\xe9\x87\x8c\xe6\x8b\x89\0" +"webhop.me\0" +"zakarpattia.ua\0studio.ap-southeast-3.sagemaker.aws\0dagestan.ru\0" +"miyazaki.jp\0" +"\xd1\x83\xd0\xba\xd1\x80\0\xe3\x82\xb9\xe3\x83\x88\xe3\x82\xa2\0" +"swiebodzin.pl\0" +"fukushima.hokkaido.jp\0yoka.hyogo.jp\0nishinoshima.shimane.jp\0stargard.pl\0pohl\0" +"is-into-cartoons.com\0" +"readymade.jp\0" +"ntdll.top\0" +"gausdal.no\0" +"masuda.shimane.jp\0*.developer.app\0" +"comsec\0" +"engine.aero\0dagestan.su\0" +"shimodate.ibaraki.jp\0saarland\0*.kunden.ortsinfo.at\0" +"r\xc3\xb8st.no\0applinzi.com\0" +"suwalki.pl\0" +"vefsn.no\0cloudns.asia\0" +"iwama.ibaraki.jp\0" +"jp.ngrok.io\0" +"is-certified.com\0" +"urown.cloud\0" +"s3-object-lambda.us-west-2.amazonaws.com\0" +"pioneer\0" +"knowsitall.info\0" +"pages.it.hs-heilbronn.de\0" +"matsusaka.mie.jp\0" +"ltd.co.im\0" +"olkusz.pl\0" +"s3-accesspoint.il-central-1.amazonaws.com\0dynamic-dns.info\0" +"leclerc\0" +"mytis.ru\0" +"doomdns.org\0" +"\xe6\x9d\xb1\xe4\xba\xac.jp\0tenkawa.nara.jp\0" +"salvador.br\0" +"mordovia.su\0" +"shitara.aichi.jp\0*.build.run\0" +"execute-api.ap-south-2.amazonaws.com\0" +"univ.bj\0" +"auth.me-south-1.amazoncognito.com\0" +"paragliding.aero\0tinn.no\0" +"nishikatsura.yamanashi.jp\0seat\0eating-organic.net\0" +"komatsu.ishikawa.jp\0" +"fukuoka.jp\0" +"vagan.no\0" +"dnsupdater.de\0" +"reggiocalabria.it\0" +"motegi.tochigi.jp\0\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4\0" +"\xe7\xbb\x84\xe7\xbb\x87.hk\0" +"fbx-os.fr\0" +"rana.no\0" +"emrstudio-prod.cn-northwest-1.amazonaws.com.cn\0" +"tm.cy\0" +"nasushiobara.tochigi.jp\0higashimurayama.tokyo.jp\0" +"in.ngrok.io\0" +"\xe6\x97\xb6\xe5\xb0\x9a\0" +"arezzo.it\0" +"\xe9\x9d\x99\xe5\xb2\xa1.jp\0" +"yonago.tottori.jp\0pigboat.jp\0" +"emrstudio-prod.ap-northeast-2.amazonaws.com\0" +"\xd0\xbe\xd0\xb1\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0now\0*.amplifyapp.com\0" +"nara.nara.jp\0" +"tm.dz\0\xe9\xb3\xa5\xe5\x8f\x96.jp\0" +"hjartdal.no\0" +"sa.au\0" +"clinique\0builtwithdark.com\0mordovia.ru\0" +"mt.eu.org\0" +"vevelstad.no\0" +"sh.cn\0nanporo.hokkaido.jp\0" +"misato.shimane.jp\0edgesuite-staging.net\0" +"bitbucket.io\0" +"liguria.it\0vi.it\0" +"flor\xc3\xb8.no\0" +"bond\0schokokeks.net\0" +"hagebostad.no\0nra\0seek\0" +"tm.fr\0cloudfront.net\0" +"ownprovider.com\0" +"app.os.fedoraproject.org\0" +"sucks\0" +"obi\0" +"sa.cr\0vb.it\0" +"yamagata.jp\0" +"firewall-gateway.com\0" +"wsa.gov.pl\0" +"uk.in\0oyodo.nara.jp\0" +"f\xc3\xb8rde.no\0\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xd8\xa9\0" +"otoineppu.hokkaido.jp\0" +"book\0nrw\0" +"kudamatsu.yamaguchi.jp\0" +"odawara.kanagawa.jp\0" +"trentin-suedtirol.it\0tachiarai.fukuoka.jp\0" +"jevnaker.no\0work\0" +"ostroda.pl\0" +"tt.im\0lib.ok.us\0" +"takikawa.hokkaido.jp\0social\0" +"tm.hu\0" +"ud.it\0gojome.akita.jp\0kagamino.okayama.jp\0bialowieza.pl\0" +"workinggroup.aero\0" +"ravpage.co.il\0s3-website.fr-par.scw.cloud\0" +"h\xc3\xb8ylandet.no\0" +"uk.kg\0" +"sakaki.nagano.jp\0" +"porn\0" +"mobara.chiba.jp\0akashi.hyogo.jp\0sakae.nagano.jp\0" +"lego\0" +"ntt\0" +"risor.no\0" +"ruhr\0" +"deloitte\0" +"cruises\0" +"is-a-photographer.com\0" +"cri.nz\0*.webpaas.ovh.net\0" +"juegos\0" +"valled-aosta.it\0sv.it\0weblike.jp\0" +"post\0framer.app\0" +"shibukawa.gunma.jp\0" +"n\xc3\xb8tter\xc3\xb8y.no\0\xd9\x83\xd8\xa7\xd8\xab\xd9\x88\xd9\x84\xd9\x8a\xd9\x83\0ravendb.community\0" +"mizusawa.iwate.jp\0" +"badaddja.no\0" +"shimada.shizuoka.jp\0" +"firmdale\0al.eu.org\0" +"kaneyama.yamagata.jp\0jozi.biz\0" +"tm.km\0execute-api.us-gov-east-1.amazonaws.com\0" +"energy\0" +"so.it\0pepper.jp\0" +"kv\xc3\xa6""fjord.no\0" +"gotpantheon.com\0" +"trieste.it\0\xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\0" +"yonabaru.okinawa.jp\0" +"shiksha\0" +"unusualperson.com\0" +"hareid.no\0" +"tm.mc\0jele.site\0" +"gotdns.org\0" +"tm.mg\0broadway\0" +"nic.in\0" +"ppg.br\0" +"sa.it\0" +"sakurai.nara.jp\0sakado.saitama.jp\0freeboxos.fr\0" +"desa.id\0" +"troitsk.su\0" +"inawashiro.fukushima.jp\0" +"economia.bo\0nannestad.no\0nyc\0" +"ama.shimane.jp\0ricoh\0" +"studio.cn-northwest-1.sagemaker.com.cn\0" +"skjervoy.no\0" +"is-a-hunter.com\0" +"nishi.fukuoka.jp\0" +"piacenza.it\0" +"tm.no\0" +"nombre.bo\0" +"onjuku.chiba.jp\0" +"s3-accesspoint.ap-east-1.amazonaws.com\0" +"s3-accesspoint.dualstack.ca-central-1.amazonaws.com\0webview-assets.aws-cloud9.eu-north-1.amazonaws.com\0lenug.su\0" +"science\0" +"rc.it\0ybo.faith\0" +"eun.eg\0" +"shiftcrypto.dev\0" +"engineer.aero\0" +"eti.br\0" +"cim.br\0" +"emrappui-prod.us-west-2.amazonaws.com\0my.eu.org\0*.frusky.de\0" +"kosuge.yamanashi.jp\0bc.platform.sh\0" +"nantan.kyoto.jp\0" +"tadaoka.osaka.jp\0tm.pl\0" +"homelinux.org\0" +"kitagawa.miyazaki.jp\0" +"pescara.it\0" +"vodka\0" +"sphinx.mythic-beasts.com\0" +"pu.it\0fashionstore.jp\0" +"honai.ehime.jp\0" +"firebaseapp.com\0" +"hu.com\0" +"karasuyama.tochigi.jp\0staba.jp\0" +"redstone\0" +"muko.kyoto.jp\0" +"webview-assets.cloud9.me-south-1.amazonaws.com\0" +"angiang.vn\0" +"pn.it\0cloudapps.digital\0" +"iwafune.tochigi.jp\0" +"pg.in\0" +"vi.us\0" +"tm.ro\0execute-api.us-east-1.amazonaws.com\0vladimir.su\0" +"pg.it\0" +"yachts\0" +"ibaraki.ibaraki.jp\0" +"tm.se\0one\0" +"ichinomiya.aichi.jp\0kita.osaka.jp\0" +"ong\0zero\0" +"mytabit.co.il\0" +"emrnotebooks-prod.ap-east-1.amazonaws.com\0" +"emrappui-prod.us-east-1.amazonaws.com\0geekgalaxy.com\0" +"onl\0" +"\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\0" +"tokushima.jp\0kayabe.hokkaido.jp\0supersale.jp\0" +"lib.id.us\0webview-assets.cloud9.ca-central-1.amazonaws.com\0" +"univ.sn\0" +"uy.com\0" +"dvag\0" +"independent-panel.uk\0" +"moka.tochigi.jp\0" +"ooo\0pleskns.com\0" +"from-ia.com\0" +"\xe3\x82\xb3\xe3\x83\xa0\0" +"recreation.aero\0" +"yokote.akita.jp\0sakegawa.yamagata.jp\0user.aseinet.ne.jp\0" +"s3.dualstack.ap-south-2.amazonaws.com\0" +"alto-adige.it\0amazon\0" +"wakasa.tottori.jp\0" +"iris.arpa\0\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xdb\x83\0vladimir.ru\0" +"groks-this.info\0nl.eu.org\0" +"olsztyn.pl\0" +"us-gov-east-1.elasticbeanstalk.com\0nyan.to\0" +"fhv.se\0" +"s3-object-lambda.eu-west-3.amazonaws.com\0webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com\0" +"repl.co\0" +"iizuna.nagano.jp\0" +"higashimatsuyama.saitama.jp\0" +"ac\0is-slick.com\0" +"ad\0osasco.br\0js.cn\0" +"ae\0\xe7\xbd\x91\xe7\xb5\xa1.hk\0" +"af\0ogimi.okinawa.jp\0" +"ag\0" +"mt.it\0" +"ai\0org\0filegear-de.me\0" +"yamagata.ibaraki.jp\0" +"pay\0s3-accesspoint.eu-south-1.amazonaws.com\0" +"al\0kouyama.kagoshima.jp\0" +"am\0jele.io\0" +"tanohata.iwate.jp\0" +"ao\0shw.io\0" +"aq\0ba\0*.eu-west-3.airflow.amazonaws.com\0" +"ar\0bb\0jl.cn\0" +"as\0cloudflare-ipfs.com\0" +"at\0recife.br\0kisosaki.mie.jp\0" +"au\0be\0" +"bf\0nic.tj\0" +"aw\0bg\0" +"ax\0bh\0" +"bi\0" +"az\0bj\0inami.toyama.jp\0" +"oji.nara.jp\0" +"bm\0divtasvuodna.no\0s3.ap-east-1.amazonaws.com\0" +"bn\0for-the.biz\0" +"bo\0" +"in-vpn.net\0" +"ca\0zapto.org\0" +"br\0" +"bs\0cc\0klabu.no\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa4\xae\xe0\xa5\x8d\0forsale\0" +"bt\0cd\0" +"bv\0cf\0direct.quickconnect.cn\0" +"bw\0cg\0nhs.uk\0s3-accesspoint-fips.us-east-2.amazonaws.com\0" +"ch\0" +"by\0ci\0" +"bz\0yamagata.yamagata.jp\0" +"s3-ap-east-1.amazonaws.com\0" +"cl\0ota.gunma.jp\0ninomiya.kanagawa.jp\0dunlop\0" +"cm\0is-an-actor.com\0" +"cn\0heguri.nara.jp\0" +"co\0athleta\0swiss\0" +"aizubange.fukushima.jp\0gyeongnam.kr\0s3.dualstack.cn-north-1.amazonaws.com.cn\0" +"parachuting.aero\0s3-accesspoint.eu-central-2.amazonaws.com\0" +"cr\0lo.it\0isla.pr\0" +"flatanger.no\0tm.za\0n4t.co\0""123kotisivu.fi\0" +"fujiidera.osaka.jp\0" +"cu\0de\0dnsalias.com\0" +"cv\0ott\0*.dapps.earth\0wpmudev.host\0" +"cw\0*.compute.amazonaws.com\0" +"cx\0" +"cy\0" +"cz\0dj\0joboji.iwate.jp\0matsubushi.saitama.jp\0" +"dk\0acct.pro\0" +"goto.nagasaki.jp\0" +"dm\0hol.no\0is-a-musician.com\0" +"mishima.fukushima.jp\0" +"do\0grimstad.no\0auth.us-east-2.amazoncognito.com\0" +"sexy\0*.azurecontainer.io\0" +"chofu.tokyo.jp\0" +"ec\0" +"ee\0condos\0" +"hirosaki.aomori.jp\0binhdinh.vn\0pet\0" +"eg\0lib.fl.us\0" +"internet.in\0kawanabe.kagoshima.jp\0mihara.kochi.jp\0" +"claims\0shopping\0" +"dz\0gouv.fr\0!city.yokohama.jp\0ovh\0" +"tsukiyono.gunma.jp\0" +"dattorelay.com\0" +"augustow.pl\0" +"es\0ng.eu.org\0" +"eng.br\0et\0shunan.yamaguchi.jp\0vinhphuc.vn\0" +"eu\0evje-og-hornnes.no\0eu.com\0is-uberleet.com\0" +"caserta.it\0" +"hi.cn\0" +"fi\0" +"fj\0meiwa.mie.jp\0" +"fm\0studio.us-gov-east-1.sagemaker.aws\0" +"fo\0lelux.site\0loginline.site\0" +"snowflake.app\0" +"ga\0" +"emp.br\0fr\0gb\0" +"*.customer-oci.com\0" +"gd\0" +"ge\0mykolaiv.ua\0" +"hb.cn\0gf\0phd\0" +"gg\0" +"gh\0wazuka.kyoto.jp\0myfast.host\0nodes.k8s.nl-ams.scw.cloud\0" +"gi\0\xc3\xa1laheadju.no\0" +"gl\0gouv.ht\0" +"gm\0halsa.no\0l\xc3\xa6rdal.no\0nic.za\0" +"gn\0final\0" +"barsycenter.com\0" +"gp\0edgekey-staging.net\0" +"gq\0lib.dc.us\0" +"gr\0" +"gs\0flekkefjord.no\0" +"gt\0nakama.fukuoka.jp\0" +"gu\0" +"pid\0" +"gw\0" +"pussycat.jp\0" +"gy\0auth-fips.us-west-2.amazoncognito.com\0" +"trentino-sudtirol.it\0" +"hk\0" +"hm\0from-sc.com\0" +"hn\0watari.miyagi.jp\0" +"emrnotebooks-prod.eu-north-1.amazonaws.com\0" +"pin\0" +"gd.cn\0hr\0komoro.nagano.jp\0" +"cafe\0viajes\0" +"fm.br\0ht\0id\0" +"hu\0ie\0" +"higashi.fukuoka.jp\0" +"alaheadju.no\0" +"execute-api.ap-southeast-2.amazonaws.com\0" +"il\0" +"im\0lib.ca.us\0" +"in\0" +"io\0" +"gouv.ci\0iq\0" +"ir\0toyota.aichi.jp\0\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0*.code.run\0" +"is\0" +"it\0" +"je\0singles\0" +"omasvuotna.no\0" +"meiwa.gunma.jp\0ina.ibaraki.jp\0" +"cupcake.is\0" +"tosashimizu.kochi.jp\0" +"webview-assets.cloud9.ap-south-1.amazonaws.com\0" +"toei.aichi.jp\0okoppe.hokkaido.jp\0noda.iwate.jp\0" +"dnipropetrovsk.ua\0ny.us\0" +"nodes.k8s.fr-par.scw.cloud\0" +"jo\0study\0" +"jp\0yasugi.shimane.jp\0" +"br\xc3\xb8nn\xc3\xb8y.no\0" +"s3-object-lambda.ap-southeast-1.amazonaws.com\0" +"ke\0lillesand.no\0" +"kg\0" +"ki\0" +"notebook.ap-southeast-4.sagemaker.aws\0homeunix.com\0" +"km\0quicksytes.com\0" +"kn\0" +"servepics.com\0" +"kp\0" +"la\0" +"\xd7\x90\xd7\xa7\xd7\x93\xd7\x9e\xd7\x99\xd7\x94.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0kr\0lb\0gotdns.ch\0" +"lc\0sochi.su\0" +"kw\0media\0reservd.com\0" +"shiroi.chiba.jp\0" +"ky\0li\0" +"otaki.saitama.jp\0kz\0" +"!www.ck\0lk\0loppa.no\0stj\xc3\xb8rdal.no\0" +"plo.ps\0" +"ma\0" +"goiania.br\0lr\0" +"ls\0mc\0from-il.com\0" +"\xe6\xb2\x96\xe7\xb8\x84.jp\0sarufutsu.hokkaido.jp\0lt\0md\0west1-us.cloudjiffy.net\0" +"lu\0me\0pnc\0" +"lv\0omg.lol\0" +"mg\0mt.us\0nd.us\0s3-accesspoint.dualstack.eu-central-1.amazonaws.com\0" +"agano.niigata.jp\0mh\0" +"ly\0" +"shinonsen.hyogo.jp\0" +"mk\0" +"gr.it\0ml\0uh-oh.jp\0" +"galsa.no\0sirdal.no\0" +"mn\0" +"mo\0" +"kamiamakusa.kumamoto.jp\0mp\0""123homepage.it\0" +"mq\0na\0in.na\0lv.ua\0analytics-gateway.ap-southeast-2.amazonaws.com\0" +"mr\0" +"ms\0nc\0" +"yoshida.saitama.jp\0mt\0weather\0" +"mu\0ne\0mus.mi.us\0*.ap-southeast-1.airflow.amazonaws.com\0s3-website.dualstack.ca-central-1.amazonaws.com\0" +"mv\0nf\0" +"mw\0ng\0" +"gr.jp\0honjo.saitama.jp\0mx\0githubpreview.dev\0" +"my\0ni\0in.ni\0" +"mz\0" +"group.aero\0krodsherad.no\0investments\0s3-external-1.amazonaws.com\0folionetwork.site\0" +"nl\0" +"onga.fukuoka.jp\0" +"no\0" +"lib.ak.us\0" +"minato.osaka.jp\0nr\0" +"kimobetsu.hokkaido.jp\0" +"nu\0auth.eu-west-1.amazoncognito.com\0s3.dualstack.eu-north-1.amazonaws.com\0" +"kasai.hyogo.jp\0" +"gjemnes.no\0webview-assets.cloud9.us-east-2.amazonaws.com\0" +"\xe7\xb6\xb2\xe7\xbb\x9c.hk\0freemyip.com\0" +"tomigusuku.okinawa.jp\0nz\0call\0lgbt\0blackbaudcdn.net\0" +"sigdal.no\0" +"om\0lpusercontent.com\0" +"uji.kyoto.jp\0""2.azurestaticapps.net\0" +"pa\0" +"v\xc3\xa6r\xc3\xb8y.no\0pymnt.uk\0" +"pe\0" +"fm.it\0pf\0" +"ph\0" +"pk\0" +"pl\0chirurgiens-dentistes-en-france.fr\0" +"design.aero\0pm\0" +"pn\0camp\0" +"qa\0servemp3.com\0" +"vald-aosta.it\0pr\0" +"ps\0webthings.io\0" +"pt\0" +"lancaster\0akamaiedge.net\0goupile.fr\0" +"pw\0miniserver.com\0" +"py\0" +"\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86\0vapor.cloud\0" +"trentinoaadige.it\0podhale.pl\0" +"org.ac\0tingvoll.no\0la.us\0" +"org.ae\0shacknet.nu\0" +"org.af\0keliweb.cloud\0" +"org.ag\0pro\0" +"org.ai\0emb.kw\0" +"re\0" +"org.al\0" +"org.am\0pru\0" +"kazo.saitama.jp\0\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4\0" +"org.ba\0" +"org.ar\0org.bb\0ragusa.it\0" +"s\xc3\xb8r-fron.no\0" +"kochi.jp\0" +"org.au\0ro\0" +"gujo.gifu.jp\0\xeb\x8b\xb7\xec\xbb\xb4\0" +"sa\0" +"org.bh\0sb\0verse.jp\0" +"org.bi\0fuoisku.no\0rs\0in.rs\0sc\0" +"org.az\0org.bj\0sd\0" +"ru\0se\0" +"org.bm\0rw\0sg\0ae.org\0jdevcloud.com\0" +"org.bn\0coop.ht\0sh\0" +"org.bo\0si\0notebook.ap-east-1.sagemaker.aws\0" +"mamurogawa.yamagata.jp\0sj\0" +"sk\0youtube\0" +"org.br\0otaki.chiba.jp\0usuki.oita.jp\0sl\0" +"org.bs\0osen.no\0sm\0" +"org.bt\0sn\0" +"so\0game-host.org\0rackmaze.com\0reservd.dev.thingdust.io\0" +"org.bw\0dynns.com\0" +"coop.in\0sr\0her.jp\0" +"org.ci\0ss\0tc\0" +"org.bz\0kiyama.saga.jp\0st\0td\0pub\0" +"su\0dvrdns.org\0" +"coop.ar\0sv\0tf\0" +"tg\0*.sch.uk\0readthedocs.io\0direct.quickconnect.to\0" +"org.cn\0sx\0th\0in.th\0" +"ab.ca\0org.co\0sy\0" +"\xe5\xb2\x90\xe9\x98\x9c.jp\0fujinomiya.shizuoka.jp\0sz\0tj\0" +"tk\0execute-api.eu-west-2.amazonaws.com\0s3-accesspoint.dualstack.us-west-2.amazonaws.com\0" +"cz.it\0yakage.okayama.jp\0tl\0" +"tm\0" +"ulsan.kr\0tn\0" +"research.aero\0org.cu\0to\0" +"org.cv\0watarai.mie.jp\0" +"org.cw\0fm.no\0ua\0in.ua\0caa.li\0" +"tr\0" +"org.cy\0care\0chrome\0" +"cs.in\0tt\0" +"for-our.info\0" +"coop.br\0tv\0" +"association.aero\0org.dm\0tw\0ug\0" +"minokamo.gifu.jp\0aya.miyazaki.jp\0" +"org.do\0" +"brescia.it\0cs.it\0tz\0" +"uk\0" +"org.ec\0realty\0" +"org.ee\0casa\0" +"towada.aomori.jp\0" +"org.eg\0va\0cars\0" +"us\0in.us\0vc\0case\0bukhara.su\0" +"org.dz\0sejny.pl\0" +"ve\0pwc\0s3-accesspoint.ca-central-1.amazonaws.com\0appchizi.com\0" +"cash\0homedepot\0" +"\xc3\xa5s.no\0vg\0s3-ca-central-1.amazonaws.com\0" +"cl.it\0dlugoleka.pl\0" +"uy\0vi\0furniture\0" +"uz\0" +"sakura.chiba.jp\0" +"org.es\0" +"org.et\0toshima.tokyo.jp\0vn\0" +"barueri.br\0yamamoto.miyagi.jp\0fastvps.host\0" +"org.fj\0" +"\xc3\xa5l.no\0vu\0" +"ce.it\0elk.pl\0wf\0" +"org.fm\0engineering\0s3-website-ap-southeast-1.amazonaws.com\0" +"debian.net\0" +"is-an-anarchist.com\0" +"minamiuonuma.niigata.jp\0" +"lund.no\0" +"studio.me-central-1.sagemaker.aws\0" +"moriyoshi.akita.jp\0fedex\0trust\0" +"org.ge\0" +"org.gg\0java\0" +"org.gh\0" +"org.gi\0ws\0" +"bn.it\0auspost\0meinforum.net\0" +"org.gl\0cloudaccess.host\0" +"divttasvuotna.no\0" +"org.gn\0" +"org.gp\0" +"chernovtsy.ua\0staples\0" +"org.gr\0aso.kumamoto.jp\0democrat\0" +"hi.us\0" +"org.gt\0" +"org.gu\0cc.wi.us\0" +"emrstudio-prod.sa-east-1.amazonaws.com\0" +"bg.it\0mukawa.hokkaido.jp\0settsu.osaka.jp\0" +"org.gy\0" +"gob.ar\0" +"org.hk\0ye\0" +"niteroi.br\0" +"sund.no\0edu.eu.org\0" +"org.hn\0" +"ibaraki.jp\0khanhhoa.vn\0" +"warabi.saitama.jp\0" +"charter.aero\0baidu\0" +"org.ht\0" +"org.hu\0ciscofreak.com\0" +"ap.it\0" +"gob.bo\0" +"gmbh\0" +"amli.no\0\xe7\xb6\xb2\xe8\xb7\xaf.tw\0" +"bulsan-suedtirol.it\0longan.vn\0yt\0nordeste-idc.saveincloud.net\0" +"org.il\0kaminokawa.tochigi.jp\0gouv.sn\0" +"org.im\0" +"bhz.br\0ai.in\0org.in\0anan.tokushima.jp\0" +"uk.com\0stage.nodeart.io\0" +"guam.gu\0org.iq\0" +"eco.bj\0org.ir\0iizuka.fukuoka.jp\0pa.leg.br\0" +"org.is\0zm\0" +"gob.cl\0" +"org.je\0s3-website.us-west-2.amazonaws.com\0diskstation.me\0" +"nagano.jp\0" +"nakadomari.aomori.jp\0" +"komforb.se\0notebook.us-gov-east-1.sagemaker.aws\0" +"eco.br\0" +"rovigo.it\0mashiko.tochigi.jp\0\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xa0\xe0\xa4\xa8\0" +"zw\0" +"nakatane.kagoshima.jp\0" +"org.jo\0cc.ut.us\0oncilla.mythic-beasts.com\0" +"taxi.br\0kuji.iwate.jp\0oe.yamagata.jp\0" +"\xe5\xbe\xae\xe5\x8d\x9a\0" +"public-inquiry.uk\0in-dsl.de\0" +"diskstation.eu\0" +"gob.do\0org.kg\0bu.no\0" +"sunagawa.hokkaido.jp\0" +"org.ki\0" +"aoste.it\0wakuya.miyagi.jp\0" +"gob.ec\0" +"umi.fukuoka.jp\0govt.nz\0" +"org.km\0" +"sayama.saitama.jp\0org.kn\0" +"likes-pie.com\0" +"org.kp\0" +"org.la\0" +"org.lb\0hospital\0pb.leg.br\0" +"org.lc\0j.scaleforce.com.cy\0" +"poker\0" +"tsumagoi.gunma.jp\0canon\0" +"org.kw\0k12.wy.us\0" +"org.ky\0" +"bibai.hokkaido.jp\0org.kz\0" +"gob.es\0org.lk\0gs.rl.no\0" +"collegefan.org\0" +"shingu.hyogo.jp\0nakagusuku.okinawa.jp\0" +"fnwk.site\0from-mt.com\0from-nd.com\0" +"matsuura.nagasaki.jp\0on-web.fr\0" +"org.ma\0" +"kokubunji.tokyo.jp\0org.lr\0no-ip.biz\0" +"org.ls\0sula.no\0dyndns-web.com\0" +"org.me\0shaw\0" +"org.lv\0olayangroup\0" +"org.mg\0sogne.no\0troms\xc3\xb8.no\0" +"org.ly\0fedje.no\0" +"org.mk\0" +"varese.it\0hakone.kanagawa.jp\0minowa.nagano.jp\0org.ml\0" +"fauske.no\0" +"kamiizumi.saitama.jp\0org.mn\0" +"org.mo\0" +"basilicata.it\0biei.hokkaido.jp\0" +"org.na\0wpenginepowered.com\0" +"miyagi.jp\0" +"org.ms\0s3-accesspoint.dualstack.eu-west-2.amazonaws.com\0" +"trd.br\0org.mt\0" +"org.mu\0" +"org.mv\0serveblog.net\0" +"org.mw\0org.ng\0" +"kyotango.kyoto.jp\0org.mx\0" +"org.my\0org.ni\0" +"org.mz\0prof.pr\0" +"gob.gt\0aomori.aomori.jp\0" +"r\xc3\xb8yken.no\0business\0" +"eek.jp\0" +"katsuragi.nara.jp\0org.nr\0wroclaw.pl\0" +"chuo.chiba.jp\0goshiki.hyogo.jp\0" +"gob.hn\0iwakuni.yamaguchi.jp\0" +"org.nz\0" +"prod\0" +"org.om\0" +"prof\0" +"ralingen.no\0" +"veneto.it\0takayama.gunma.jp\0aga.niigata.jp\0" +"org.pa\0wales\0" +"xbox\0" +"freebox-os.com\0" +"us.reclaim.cloud\0" +"org.pe\0\xe3\x82\xa2\xe3\x83\x9e\xe3\x82\xbe\xe3\x83\xb3\0" +"org.pf\0" +"org.ph\0" +"org.pk\0" +"org.pl\0" +"malvik.no\0" +"org.pn\0" +"tas.edu.au\0dc.us\0" +"barlettatraniandria.it\0kawara.fukuoka.jp\0katano.osaka.jp\0mibu.tochigi.jp\0" +"m\xc3\xa1tta-v\xc3\xa1rjjat.no\0org.qa\0cc.sc.us\0" +"org.pr\0gdansk.pl\0" +"org.ps\0" +"org.pt\0jotelulu.cloud\0" +"s3.dualstack.cn-northwest-1.amazonaws.com.cn\0" +"*.cloudera.site\0" +"kakamigahara.gifu.jp\0" +"org.py\0" +"gouv.km\0int.eu.org\0" +"backdrop.jp\0" +"a.prod.fastly.net\0" +"express.aero\0frana.no\0statefarm\0notebook.eu-west-2.sagemaker.aws\0" +"nosegawa.nara.jp\0uk.reclaim.cloud\0" +"\xe6\xb7\xa1\xe9\xa9\xac\xe9\x94\xa1\0" +"higashimatsushima.miyagi.jp\0" +"pagefrontapp.com\0" +"mihama.fukui.jp\0hamatama.saga.jp\0" +"togane.chiba.jp\0school\0" +"dyndns-pics.com\0" +"tvedestrand.no\0" +"dynathome.net\0" +"cipriani\0mytuleap.com\0paris.eu.org\0googlecode.com\0" +"org.ro\0" +"noheji.aomori.jp\0katsuyama.fukui.jp\0" +"org.sa\0githubusercontent.com\0barsy.site\0" +"org.sb\0" +"org.rs\0org.sc\0" +"firm.ht\0kushimoto.wakayama.jp\0org.sd\0" +"askvoll.no\0org.se\0org.ru\0" +"miyoshi.saitama.jp\0" +"org.rw\0org.sg\0s3-fips.dualstack.ca-central-1.amazonaws.com\0" +"org.sh\0" +"meldal.no\0" +"sera.hiroshima.jp\0gouv.ml\0s3-accesspoint.dualstack.cn-north-1.amazonaws.com.cn\0" +"gs.nt.no\0" +"ohda.shimane.jp\0org.sl\0red\0" +"ferrero\0" +"firm.in\0suzuka.mie.jp\0org.sn\0" +"org.so\0shia\0" +"nakamura.kochi.jp\0" +"royrvik.no\0drive\0" +"yamada.fukuoka.jp\0matsushima.miyagi.jp\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4\0" +"org.ss\0analytics-gateway.us-east-2.amazonaws.com\0user.party.eus\0" +"org.st\0" +"fr\xc3\xb8ya.no\0holtalen.no\0" +"org.sv\0ren\0" +"nagiso.nagano.jp\0" +"veterinaire.km\0org.sy\0cbre\0" +"org.sz\0org.tj\0" +"studio.ap-south-1.sagemaker.aws\0" +"org.tm\0webview-assets.cloud9.eu-north-1.amazonaws.com\0" +"org.tn\0" +"org.to\0gratis\0" +"gob.mx\0" +"gob.ni\0coop.rw\0org.ua\0" +"fukuroi.shizuoka.jp\0ohkura.yamagata.jp\0org.tr\0" +"kushiro.hokkaido.jp\0org.tt\0" +"gop.pk\0org.tw\0org.ug\0writesthisblog.com\0" +"org.uk\0" +"termez.su\0gitapp.si\0" +"firm.co\0" +"sassari.it\0" +"author.aero\0veg\xc3\xa5rshei.no\0org.vc\0auth.eu-north-1.amazoncognito.com\0" +"lovesick.jp\0" +"org.ve\0" +"minamiboso.chiba.jp\0target\0" +"gob.pa\0org.uy\0org.vi\0" +"cesena-forl\xc3\xac.it\0org.uz\0" +"firm.dk\0stuff-4-sale.org\0" +"gallup\0" +"gob.pe\0twmail.cc\0" +"coop.tt\0ai.vn\0org.vn\0" +"arq.br\0" +"dyndns1.de\0" +"unnan.shimane.jp\0" +"gob.pk\0cc.or.us\0mo-siemens.io\0" +"org.vu\0emrstudio-prod.eu-west-1.amazonaws.com\0hostedpi.com\0" +"y.bg\0" +"res.in\0beppu.oita.jp\0" +"\xc3\xa5krehamn.no\0" +"veterinaire.fr\0" +"001www.com\0" +"rel.ht\0sodegaura.chiba.jp\0coop.mv\0boyfriend.jp\0" +"tksat.bo\0coop.mw\0cc.ok.us\0" +"uchinada.ishikawa.jp\0" +"org.ws\0" +"monza-brianza.it\0ril\0" +"kasserver.com\0*.ocp.customer-oci.com\0" +"rio\0" +"rip\0" +"r.bg\0" +"autos\0" +"minamisanriku.miyagi.jp\0" +"snasa.no\0" +"dyndns-server.com\0" +"org.ye\0" +"nagawa.nagano.jp\0geek.nz\0" +"k.bg\0" +"ena.gifu.jp\0ravendb.cloud\0jeez.jp\0" +"apigee.io\0" +"cc.nm.us\0" +"campinas.br\0" +"telebit.io\0" +"org.za\0" +"lom.it\0pi.leg.br\0" +"b\xc3\xa5tsfjord.no\0" +"yusui.kagoshima.jp\0org.yt\0" +"d.bg\0" +"hyundai\0mypi.co\0" +"vestnes.no\0" +"trentin-sued-tirol.it\0" +"wios.gov.pl\0" +"org.zm\0" +"tajiri.osaka.jp\0gob.sv\0shop\0" +"jab.br\0tako.chiba.jp\0takasaki.gunma.jp\0" +"gaivuotna.no\0" +"takatori.nara.jp\0" +"coop.py\0" +"shimokitayama.nara.jp\0" +"show\0studio.us-west-1.sagemaker.aws\0go.dyndns.org\0" +"\xd0\xbc\xd0\xbe\xd1\x81\xd0\xba\xd0\xb2\xd0\xb0\0" +"org.zw\0" +"cc.mo.us\0" +"davvenj\xc3\xa1rga.no\0" +"frosta.no\0khmelnitskiy.ua\0" +"geo.br\0neyagawa.osaka.jp\0pulawy.pl\0" +"morena.br\0kainan.wakayama.jp\0shinjo.yamagata.jp\0" +"dazaifu.fukuoka.jp\0mragowo.pl\0agakhan\0" +"noip.us\0*.s5y.io\0" +"ukiha.fukuoka.jp\0privatizehealthinsurance.net\0" +"gob.ve\0" +"paas.hosted-by-previder.com\0" +"noor.jp\0" +"urakawa.hokkaido.jp\0" +"cc.ma.us\0*.digitaloceanspaces.com\0" +"gosen.niigata.jp\0" +"coop.km\0execute-api.ap-south-1.amazonaws.com\0" +"kuriyama.hokkaido.jp\0" +"web.bo\0" +"raisa.no\0" +"tempio-olbia.it\0eniwa.hokkaido.jp\0fool.jp\0" +"tromsa.no\0" +"friuli-ve-giulia.it\0" +"friuli-v-giulia.it\0" +"nsw.au\0from-or.com\0" +"togitsu.nagasaki.jp\0matsubara.osaka.jp\0" +"web.co\0" +"lom.no\0k12.oh.us\0" +"hachioji.tokyo.jp\0" +"s3-website.dualstack.af-south-1.amazonaws.com\0lon.wafaicloud.com\0" +"cc.ks.us\0is-a-landscaper.com\0" +"realestate.pl\0" +"modalen.no\0" +"sanda.hyogo.jp\0quangnam.vn\0" +"rel.pl\0" +"schoolbus.jp\0" +"web.do\0k12.mo.us\0tires\0" +"haebaru.okinawa.jp\0" +"bas.it\0" +"chonan.chiba.jp\0" +"firm.ve\0" +"3.bg\0\xd1\x83\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0s3-accesspoint-fips.dualstack.us-east-2.amazonaws.com\0" +"lidl\0sap\0" +"sas\0" +"daemon.panel.gg\0" +"sbi\0mircloud.us\0" +"atm.pl\0" +"gratangen.no\0" +"air-traffic-control.aero\0k12.ma.us\0" +"tawaramoto.nara.jp\0" +"act.edu.au\0gs.oslo.no\0" +"scb\0" +"sbs\0" +"autocode.dev\0" +"discourse.group\0" +"abudhabi\0" +"telebit.app\0" +"life\0" +"asahi.nagano.jp\0pe.leg.br\0" +"\xe5\x85\xac\xe5\x8f\xb8.cn\0aogashima.tokyo.jp\0" +"k12.md.us\0" +"sp.gov.br\0" +"sola.no\0gitlab.io\0" +"trentins\xc3\xbc""dtirol.it\0nanbu.tottori.jp\0" +"asuke.aichi.jp\0" +"mihama.aichi.jp\0" +"filegear.me\0" +"monzaebrianza.it\0" +"works.aero\0" +"rome.it\0" +"web.gu\0\xe5\x85\xac\xe5\x8f\xb8.hk\0" +"sydney\0" +"littlestar.jp\0" +"giving\0" +"miyama.mie.jp\0mymediapc.net\0" +"hachinohe.aomori.jp\0observer\0" +"kaluga.su\0" +"gniezno.pl\0pisz.pl\0functions.fnc.fr-par.scw.cloud\0" +"itau\0myspreadshop.com.au\0" +"domains\0" +"web.id\0yotsukaido.chiba.jp\0cloudns.biz\0dynv6.net\0" +"bjarkoy.no\0" +"caobang.vn\0" +"gives\0wpmucdn.com\0" +"run\0mimoza.jp\0za.net\0" +"friuli-venezia-giulia.it\0higashiyamato.tokyo.jp\0web.in\0blush.jp\0" +"emrstudio-prod.us-west-2.amazonaws.com\0" +"salud.bo\0" +"akamaized.net\0" +"firm.ro\0sew\0" +"sex\0" +"pokrovsk.su\0static.observableusercontent.com\0" +"issmarterthanyou.com\0" +"kanra.gunma.jp\0" +"tanabe.wakayama.jp\0" +"s3-website.eu-west-3.amazonaws.com\0" +"sfr\0" +"jewelry\0" +"dev.br\0" +"rwe\0webview-assets.cloud9.ap-northeast-1.amazonaws.com\0ditchyourip.com\0" +"nishiaizu.fukushima.jp\0" +"nord-aurdal.no\0trana.no\0" +"takaishi.osaka.jp\0so.gov.pl\0" +"leirfjord.no\0" +"askim.no\0*.us-east-2.airflow.amazonaws.com\0mircloud.ru\0*.vps.myjino.ru\0" +"uryu.hokkaido.jp\0isehara.kanagawa.jp\0" +"inami.wakayama.jp\0" +"\xe5\x85\xb5\xe5\xba\xab.jp\0" +"lib.wa.us\0vologda.su\0" +"nanyo.yamagata.jp\0" +"mycloud.by\0" +"yamaxun\0" +"trentino-sud-tirol.it\0" +"hanam.vn\0" +"like\0" +"lel.br\0" +"fot.br\0" +"web.lk\0nsupdate.info\0" +"shijonawate.osaka.jp\0yoshimi.saitama.jp\0" +"silk\0" +"fredrikstad.no\0noip.me\0" +"christmas\0" +"minamidaito.okinawa.jp\0" +"noticias.bo\0" +"b\xc3\xb8.telemark.no\0" +"emrnotebooks-prod.us-east-1.amazonaws.com\0s3-fips-us-gov-east-1.amazonaws.com\0" +"firm.nf\0ketrzyn.pl\0" +"harstad.no\0firm.ng\0" +"y.se\0" +"lowicz.pl\0realtor\0" +"kofu.yamanashi.jp\0" +"karacol.su\0" +"shirakawa.fukushima.jp\0" +"sina\0" +"shiriuchi.hokkaido.jp\0" +"praxi\0" +"bunkyo.tokyo.jp\0web.nf\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8b\xe0\xa4\xa4\0" +"lib.ut.us\0" +"tirol\0" +"web.ni\0servehalflife.com\0" +"\xe5\x9f\xbc\xe7\x8e\x89.jp\0" +"r.se\0hs.zone\0" +"ginowan.okinawa.jp\0" +"sklep.pl\0" +"limo\0meteorapp.com\0" +"rackmaze.net\0" +"ski\0" +"k.se\0firewalledreplit.co\0" +"link\0webview-assets.cloud9.us-west-1.amazonaws.com\0" +"ap-southeast-2.elasticbeanstalk.com\0lima-city.de\0" +"auth.il-central-1.amazoncognito.com\0" +"sky\0" +"xj.cn\0ikusaka.nagano.jp\0rulez.jp\0" +"erotika.hu\0d.se\0" +"horokanai.hokkaido.jp\0" +"reggio-calabria.it\0kui.hiroshima.jp\0" +"web.pk\0" +"davvenjarga.no\0" +"demon.nl\0" +"withyoutube.com\0" +"k12.gu.us\0" +"srv.br\0" +"nishikawa.yamagata.jp\0pr.leg.br\0" +"friuli-vegiulia.it\0jobs.tt\0" +"toyako.hokkaido.jp\0" +"lilly\0" +"lima-city.at\0" +"shikokuchuo.ehime.jp\0" +"s3-accesspoint.dualstack.me-central-1.amazonaws.com\0from-vt.com\0" +"agr.br\0" +"microsoft\0channelsdvr.net\0" +"s\xc3\xb8rreisa.no\0we.bs\0" +"fashion\0xx.gl\0" +"tysfjord.no\0" +"koryo.nara.jp\0" +"lease\0" +"misaki.osaka.jp\0" +"\xe7\xa5\x9e\xe5\xa5\x88\xe5\xb7\x9d.jp\0centralus.azurestaticapps.net\0" +"tama.tokyo.jp\0notebook.cn-north-1.sagemaker.com.cn\0lima-city.ch\0" +"crap.jp\0" +"hepforge.org\0" +"k8s.scw.cloud\0" +"ikano\0" +"nara.jp\0" +"emiliaromagna.it\0" +"voagat.no\0spa\0" +"cutegirl.jp\0" +"cc.de.us\0" +"steinkjer.no\0soy\0" +"site\0" +"toolforge.org\0" +"web.tj\0" +"jolster.no\0" +"politica.bo\0plesk.page\0" +"tab\0" +"cloudfunctions.net\0" +"*.0emm.com\0" +"itabashi.tokyo.jp\0web.tr\0" +"3utilities.com\0" +"sr.gov.pl\0easypanel.host\0" +"vfs.cloud9.eu-south-1.amazonaws.com\0" +"tajimi.gifu.jp\0" +"trentin-s\xc3\xbc""d-tirol.it\0sub.jp\0" +"eu.ngrok.io\0" +"\xd8\xb4\xd8\xa8\xd9\x83\xd8\xa9\0net.eu.org\0googleapis.com\0" +"com.ac\0" +"hirara.okinawa.jp\0tax\0" +"web.ve\0s3-accesspoint.eu-south-2.amazonaws.com\0" +"com.af\0forl\xc3\xac-cesena.it\0" +"com.ag\0" +"shonai.fukuoka.jp\0srl\0familyds.net\0" +"com.ai\0" +"kitagata.saga.jp\0" +"emrnotebooks-prod.eu-west-1.amazonaws.com\0" +"com.al\0" +"com.am\0\xe3\x82\xbb\xe3\x83\xbc\xe3\x83\xab\0s3-accesspoint.eu-west-1.amazonaws.com\0notebook.il-central-1.sagemaker.aws\0" +"com.ba\0" +"com.ar\0com.bb\0busan.kr\0" +"oygarden.no\0notebook.ap-south-2.sagemaker.aws\0" +"com.au\0live\0tci\0trading\0mine.nu\0" +"mihama.mie.jp\0" +"com.aw\0" +"com.bh\0" +"com.bi\0s3-website.il-central-1.amazonaws.com\0" +"com.az\0com.bj\0clerk.app\0" +"com.bm\0" +"com.bn\0" +"com.bo\0stc\0" +"\xe7\xb5\x84\xe7\xbb\x87.hk\0" +"com.br\0" +"com.bs\0synology-diskstation.de\0" +"com.bt\0" +"uonuma.niigata.jp\0pya.jp\0" +"skanland.no\0cc.ar.us\0tdk\0" +"kuzumaki.iwate.jp\0gold\0" +"com.by\0com.ci\0rissa.no\0" +"com.bz\0golf\0whm.nl-ams.scw.cloud\0" +"dattolocal.com\0" +"mashike.hokkaido.jp\0jaguar\0typedream.app\0" +"broker.aero\0com.cm\0tunes\0webview-assets.cloud9.sa-east-1.amazonaws.com\0" +"com.cn\0elementor.cloud\0" +"com.co\0zhytomyr.ua\0cust.disrec.thingdust.io\0" +"kumiyama.kyoto.jp\0" +"tana.no\0s3-me-south-1.amazonaws.com\0" +"koto.shiga.jp\0" +"com.cu\0cc.ak.us\0com.de\0" +"com.cv\0jpmorgan\0" +"com.cw\0" +"tel\0" +"com.cy\0" +"barsy.shop\0" +"vfs.cloud9.eu-west-3.amazonaws.com\0" +"com.dm\0lib.pa.us\0" +"komae.tokyo.jp\0yuza.yamagata.jp\0" +"com.do\0scrysec.com\0" +"verona.it\0saito.miyazaki.jp\0" +"hurum.no\0web.za\0" +"com.ec\0emrnotebooks-prod.us-gov-east-1.amazonaws.com\0" +"com.ee\0" +"shinjuku.tokyo.jp\0" +"com.eg\0here-for-more.info\0" +"carrara-massa.it\0pup.gov.pl\0" +"com.dz\0ryugasaki.ibaraki.jp\0" +"sweetpepper.org\0" +"vfs.cloud9.ca-central-1.amazonaws.com\0" +"crotone.it\0" +"com.es\0" +"com.et\0ug.gov.pl\0" +"ws.na\0" +"fyresdal.no\0" +"com.fj\0up.in\0" +"goog\0" +"nakijin.okinawa.jp\0kashima.saga.jp\0" +"com.fm\0" +"vaksdal.no\0" +"thd\0" +"com.fr\0" +"pro.az\0" +"com.ge\0zt.ua\0" +"oi.kanagawa.jp\0" +"orkanger.no\0" +"com.gh\0" +"com.gi\0execute-api.us-gov-west-1.amazonaws.com\0" +"jeep\0" +"pro.br\0com.gl\0fujikawa.yamanashi.jp\0*.beget.app\0" +"com.gn\0\xe9\xa6\x99\xe5\xb7\x9d.jp\0" +"com.gp\0" +"vp4.me\0" +"com.gr\0akadns.net\0" +"emerck\0" +"com.gt\0\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0" +"com.gu\0" +"k12.as.us\0rentals\0" +"com.gy\0" +"isumi.chiba.jp\0" +"com.hk\0" +"tr.it\0" +"karasjok.no\0" +"com.hn\0" +"porsanger.no\0" +"com.hr\0" +"show.aero\0pro.cy\0studio.eu-central-1.sagemaker.aws\0" +"com.ht\0" +"windows\0execute-api.ap-southeast-1.amazonaws.com\0" +"qc.ca\0" +"playstation\0" +"higashikagawa.kagawa.jp\0suwa.nagano.jp\0ogi.saga.jp\0" +"pro.ec\0com.im\0" +"com.in\0" +"com.io\0dubai\0" +"wsse.gov.pl\0" +"com.iq\0hapmir.no\0" +"kuroiso.tochigi.jp\0" +"com.is\0homesecuritypc.com\0dev.vu\0" +"tjx\0" +"vallee-aoste.it\0" +"in-the-band.net\0" +"s3-object-lambda.ap-southeast-2.amazonaws.com\0" +"com.jo\0volda.no\0" +"pe.ca\0kv\xc3\xa6nangen.no\0" +"pro.fj\0" +"nsw.edu.au\0notebook.ap-southeast-3.sagemaker.aws\0" +"com.kg\0" +"kazuno.akita.jp\0akamai-staging.net\0" +"com.ki\0from-in.com\0" +"ullensaker.no\0" +"og.ao\0com.km\0lib.mi.us\0" +"vet.br\0deno-staging.dev\0" +"execute-api.me-central-1.amazonaws.com\0" +"com.kp\0" +"on.ca\0com.la\0" +"com.lb\0" +"com.lc\0" +"onagawa.miyagi.jp\0" +"com.kw\0" +"niihama.ehime.jp\0saiki.oita.jp\0" +"com.ky\0" +"omitama.ibaraki.jp\0com.kz\0" +"com.lk\0cloudns.eu\0ro.im\0" +"s3-accesspoint.ap-southeast-3.amazonaws.com\0" +"hino.tokyo.jp\0" +"komvux.se\0" +"jeonbuk.kr\0" +"motorcycles\0" +"ro.it\0com.lr\0" +"utsira.no\0" +"com.lv\0" +"com.mg\0tr.no\0" +"com.ly\0fjell.no\0med.pro\0" +"fuji.shizuoka.jp\0discount\0" +"com.mk\0" +"abruzzo.it\0com.ml\0floppy.jp\0" +"pro.ht\0" +"com.mo\0" +"com.na\0" +"com.ms\0" +"com.mt\0" +"com.mu\0we.tc\0" +"com.mv\0com.nf\0" +"homebuilt.aero\0com.mw\0com.ng\0" +"pro.in\0com.mx\0" +"com.my\0com.ni\0lviv.ua\0" +"sjc.br\0miharu.fukushima.jp\0*.stg.dev\0" +"top\0" +"ra.it\0" +"stavanger.no\0sebastopol.ua\0" +"higashiagatsuma.gunma.jp\0nankoku.kochi.jp\0" +"toyota.yamaguchi.jp\0com.nr\0" +"st.no\0" +"\xe9\x95\xb7\xe5\xb4\x8e.jp\0u.channelsdvr.net\0" +"b\xc3\xa1jddar.no\0" +"nb.ca\0withgoogle.com\0h\xc3\xa4kkinen.fi\0" +"kaneyama.fukushima.jp\0" +"pz.it\0" +"federation.aero\0hurdal.no\0k\xc3\xa5""fjord.no\0com.om\0careers\0is-lost.org\0" +"shingo.aomori.jp\0" +"*.linodeobjects.com\0panel.gg\0" +"jele.cloud\0" +"com.pa\0vn.ua\0" +"esp.br\0kariwa.niigata.jp\0" +"intuit\0cloudns.in\0linkyard-cloud.ch\0" +"com.pe\0" +"toki.gifu.jp\0shimonita.gunma.jp\0com.pf\0" +"tokke.no\0" +"com.ph\0" +"hornindal.no\0" +"to.gov.br\0carboniaiglesias.it\0" +"com.pk\0" +"com.pl\0" +"snoasa.no\0za.org\0" +"boavista.br\0wegrow.pl\0tn.oxa.cloud\0" +"sf.no\0" +"assn.lk\0stat.no\0com.qa\0" +"com.pr\0" +"com.ps\0s3-1.amazonaws.com\0" +"com.pt\0" +"style\0" +"tomi.nagano.jp\0" +"com.py\0cloudns.cc\0" +"washtenaw.mi.us\0" +"md.ci\0notebook.eu-south-1.sagemaker.aws\0" +"law.pro\0cards\0ubs\0vfs.cloud9.sa-east-1.amazonaws.com\0lug.org.uk\0" +"beagleboard.io\0" +"fermo.it\0trv\0" +"bayern\0" +"com.re\0" +"pe.it\0" +"iwata.shizuoka.jp\0pecori.jp\0" +"d\xc3\xb8nna.no\0" +"\xe5\xba\x83\xe5\xb3\xb6.jp\0" +"pro.na\0" +"lib.ia.us\0\xe5\xa4\xa9\xe4\xb8\xbb\xe6\x95\x99\0is-a-designer.com\0" +"com.ro\0" +"kikonai.hokkaido.jp\0fukaya.saitama.jp\0pro.mv\0" +"com.sa\0" +"com.sb\0" +"com.sc\0" +"com.sd\0" +"malselv.no\0pub.sa\0com.se\0com.ru\0" +"kuju.oita.jp\0" +"com.sg\0" +"caltanissetta.it\0tamano.okayama.jp\0com.sh\0" +"s3.af-south-1.amazonaws.com\0notebook-fips.us-gov-west-1.sagemaker.aws\0" +"asahi.toyama.jp\0*.hosting.ovh.net\0" +"nagareyama.chiba.jp\0com.sl\0" +"mutual.ar\0com.sn\0" +"com.so\0tec.mi.us\0" +"trentino-aadige.it\0" +"og.it\0" +"com.ss\0lighting\0azerbaijan.su\0" +"susaki.kochi.jp\0pe.kr\0com.st\0" +"tui\0" +"com.sv\0" +"pro.om\0studio.us-gov-west-1.sagemaker.aws\0" +"komaki.aichi.jp\0" +"granvin.no\0com.sy\0" +"ookuwa.nagano.jp\0com.tj\0" +"\xe5\x95\x86\xe6\xa0\x87\0" +"com.tm\0" +"my.id\0com.tn\0" +"com.to\0" +"skin\0" +"com.ua\0" +"com.tr\0" +"b\xc3\xa1l\xc3\xa1t.no\0s3-object-lambda.eu-central-1.amazonaws.com\0s3-object-lambda.me-south-1.amazonaws.com\0from-oh.com\0" +"sukagawa.fukushima.jp\0com.tt\0" +"\xe5\xb1\xb1\xe6\xa2\xa8.jp\0cern\0" +"com.tw\0com.ug\0" +"aknoluokta.no\0us.ngrok.io\0" +"jx.cn\0andria-trani-barletta.it\0" +"notodden.no\0" +"pro.pr\0" +"orsta.no\0" +"tvs\0" +"shiogama.miyagi.jp\0limanowa.pl\0" +"oumu.hokkaido.jp\0kouzushima.tokyo.jp\0" +"gloppen.no\0sm.ua\0com.vc\0dyn53.io\0" +"com.ve\0streamlitapp.com\0" +"osaka.jp\0" +"com.uy\0com.vi\0" +"com.uz\0" +"biev\xc3\xa1t.no\0" +"kapsi.fi\0myds.me\0" +"com.vn\0mydatto.net\0" +"kariya.aichi.jp\0gets-it.net\0" +"h\xc3\xa5.no\0rade.no\0sk\xc3\xa1nit.no\0rv.ua\0" +"balashov.su\0" +"trani-barletta-andria.it\0fudai.iwate.jp\0" +"com.vu\0mypets.ws\0" +"vda.it\0\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0" +"*.nom.br\0" +"elementor.cool\0" +"tj\xc3\xb8me.no\0" +"v\xc3\xa5gs\xc3\xb8y.no\0com.ws\0" +"repair\0" +"aquarelle\0tuva.su\0" +"lt.it\0myamaze.net\0" +"miyawaka.fukuoka.jp\0" +"auth.us-east-1.amazoncognito.com\0" +"livorno.it\0torun.pl\0" +"ekloges.cy\0com.ye\0" +"\xe5\xb3\xb6\xe6\xa0\xb9.jp\0foundation\0" +"\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88\0" +"hyllestad.no\0" +"taiji.wakayama.jp\0" +"winners\0" +"pro.tt\0" +"trycloudflare.com\0" +"hongo.hiroshima.jp\0" +"austevoll.no\0" +"studio.ap-northeast-3.sagemaker.aws\0" +"africa.bj\0it1.eur.aruba.jenv-aruba.cloud\0" +"s3.ap-northeast-3.amazonaws.com\0" +"*.user.localcert.dev\0" +"stokke.no\0com.zm\0" +"hn.cn\0izumozaki.niigata.jp\0" +"obninsk.su\0" +"messerli.app\0" +"sorreisa.no\0q-a.eu.org\0" +"riopreto.br\0hiphop\0" +"site.tb-hosting.com\0" +"kaisei.kanagawa.jp\0higashiomi.shiga.jp\0comcast\0penne.jp\0" +"mr.no\0alibaba\0" +"pro.vn\0" +"catania.it\0\xe5\xb2\xa9\xe6\x89\x8b.jp\0kitakata.fukushima.jp\0" +"google\0" +"adobeioruntime.net\0" +"kitanakagusuku.okinawa.jp\0" +"balestrand.no\0is-very-bad.org\0s3.teckids.org\0" +"yamakita.kanagawa.jp\0test.tj\0" +"\xc3\xb8ksnes.no\0in-brb.de\0*.nodebalancer.linode.com\0" +"friulive-giulia.it\0yashio.saitama.jp\0" +"pl.ua\0" +"takasago.hyogo.jp\0" +"\xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\0" +"bsb.br\0appengine.flow.ch\0" +"cloudns.us\0" +"iz.hr\0" +"chikusei.ibaraki.jp\0" +"from-ct.com\0" +"nabari.mie.jp\0" +"*.eu-north-1.airflow.amazonaws.com\0" +"1kapp.com\0" +"ebetsu.hokkaido.jp\0noto.ishikawa.jp\0" +"vps.mcdir.ru\0lib.de.us\0" +"\xe5\xae\xb6\xe9\x9b\xbb\0s3.eu-south-2.amazonaws.com\0cloudcontrolapp.com\0" +"ballangen.no\0sellfy.store\0" +"thanhphohochiminh.vn\0cat.ax\0" +"uno\0" +"palermo.it\0" +"iservschule.de\0shopitsite.com\0" +"buzz\0" +"\xe4\xb8\xaa\xe4\xba\xba.hk\0" +"cooperativa.bo\0" +"ms.leg.br\0" +"\xd0\xb0\xd0\xba.\xd1\x81\xd1\x80\xd0\xb1\0emrappui-prod.eu-west-3.amazonaws.com\0" +"yokosuka.kanagawa.jp\0szkola.pl\0uol\0smartlabeling.scw.cloud\0" +"ghost.io\0" +"is.it\0" +"gitpage.si\0" +"bss.design\0" +"laakesvuemie.no\0police.uk\0test.ru\0" +"lenvik.no\0emrstudio-prod.ap-east-1.amazonaws.com\0" +"jele.club\0" +"dnepropetrovsk.ua\0" +"koga.fukuoka.jp\0" +"gs.jan-mayen.no\0" +"fujimi.nagano.jp\0" +"v\xc3\xa5ler.\xc3\xb8stfold.no\0simplesite.com\0" +"anan.nagano.jp\0" +"cci.fr\0" +"v-info.info\0" +"ups\0" +"egoism.jp\0" +"dyndns-office.com\0" +"mt.leg.br\0" +"insurance.aero\0webview-assets.cloud9.ap-northeast-3.amazonaws.com\0" +"otsuchi.iwate.jp\0" +"dynamisches-dns.de\0" +"tsubetsu.hokkaido.jp\0" +"s\xc3\xb8rum.no\0" +"rexroth\0" +"app.render.com\0" +"hair\0" +"supplies\0tr.eu.org\0mayfirst.org\0" +"sowa.ibaraki.jp\0" +"hasuda.saitama.jp\0" +"ichikawa.hyogo.jp\0" +"fam.pk\0" +"res.aero\0\xd1\x81\xd0\xbf\xd0\xb1.\xd1\x80\xd1\x83\xd1\x81\0" +"mk.ua\0" +"xii.jp\0" +"kindle\0" +"kitakami.iwate.jp\0*.lcl.dev\0" +"boomla.net\0" +"mil.ac\0alsace\0" +"kawahara.tottori.jp\0" +"mil.ae\0" +"jampa.br\0tenei.fukushima.jp\0lezajsk.pl\0" +"vfs.cloud9.ap-east-1.amazonaws.com\0" +"kyowa.akita.jp\0" +"s3.ap-south-2.amazonaws.com\0" +"honjyo.akita.jp\0nakatombetsu.hokkaido.jp\0kitayama.wakayama.jp\0ostrowiec.pl\0j.scaleforce.net\0" +"lt.ua\0" +"mil.al\0andria-barletta-trani.it\0uwajima.ehime.jp\0" +"sport\0" +"vana\0" +"takahagi.ibaraki.jp\0" +"mil.ba\0" +"mil.ar\0vall\xc3\xa9""e-d-aoste.it\0" +"chiyoda.tokyo.jp\0" +"ann-arbor.mi.us\0" +"\xe0\xb8\xa8\xe0\xb8\xb6\xe0\xb8\x81\xe0\xb8\xa9\xe0\xb8\xb2.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"mil.az\0pavia.it\0" +"\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4\0" +"md.us\0s3-website.dualstack.eu-west-1.amazonaws.com\0" +"cq.cn\0kawakami.nara.jp\0tochigi.tochigi.jp\0digick.jp\0" +"mil.bo\0" +"nagaoka.niigata.jp\0" +"mil.br\0fr.it\0yatsuka.shimane.jp\0definima.net\0" +"vet\0" +"kv.ua\0" +"mil.by\0skedsmokorset.no\0zhitomir.ua\0url.tw\0" +"heteml.net\0" +"s3.me-central-1.amazonaws.com\0" +"mil.cl\0eu.int\0perugia.it\0" +"mil.cn\0" +"mil.co\0odesa.ua\0phone\0" +"ichinohe.iwate.jp\0higashiosaka.osaka.jp\0slupsk.pl\0" +"lur\xc3\xb8y.no\0familyds.org\0" +"mil.cy\0" +"cam.it\0shimonoseki.yamaguchi.jp\0" +"midtre-gauldal.no\0" +"bozen-sudtirol.it\0ryuoh.shiga.jp\0" +"ichinomiya.chiba.jp\0" +"mil.do\0" +"be.ax\0" +"industries\0" +"powiat.pl\0" +"mil.ec\0kh.ua\0" +"chips.jp\0oxa.cloud\0" +"mil.eg\0skanit.no\0" +"katsuura.chiba.jp\0" +"s3-website.dualstack.us-east-1.amazonaws.com\0" +"miyoshi.hiroshima.jp\0" +"miyoshi.aichi.jp\0" +"no-ip.ca\0" +"inazawa.aichi.jp\0" +"cloudns.pw\0" +"nz.basketball\0" +"sumy.ua\0" +"himeshima.oita.jp\0" +"dnsdojo.org\0" +"h\xc3\xa1""bmer.no\0vig\0" +"mil.fj\0" +"pictet\0" +"vin\0" +"shinshinotsu.hokkaido.jp\0starachowice.pl\0vip\0" +"is-a-anarchist.com\0" +"kep.tr\0" +"mil.ge\0" +"higashiyama.kyoto.jp\0" +"mil.gh\0" +"kinghost.net\0" +"toshiba\0vfs.cloud9.ap-northeast-1.amazonaws.com\0servehumour.com\0" +"thruhere.net\0" +"shinjo.nara.jp\0" +"hekinan.aichi.jp\0futsu.nagasaki.jp\0" +"r\xc3\xa5""de.no\0" +"mil.gt\0" +"blockbuster\0" +"r\xc3\xa6lingen.no\0" +"shizuoka.jp\0rs.webaccel.jp\0" +"s3.dualstack.us-east-1.amazonaws.com\0" +"zlg.br\0" +"okawa.kochi.jp\0inagi.tokyo.jp\0phutho.vn\0" +"omega\0""180r.com\0" +"mil.hn\0" +"sande.m\xc3\xb8re-og-romsdal.no\0clothing\0" +"gyokuto.kumamoto.jp\0namegawa.saitama.jp\0fukumitsu.toyama.jp\0" +"valleaosta.it\0" +"roros.no\0studio.ap-southeast-1.sagemaker.aws\0" +"mil.id\0eiheiji.fukui.jp\0" +"nanto.toyama.jp\0" +"voyage\0" +"aarp\0" +"ie.ua\0" +"cc.hn\0" +"azure-mobile.net\0" +"il.us\0" +"mil.in\0gorizia.it\0ens.tn\0" +"mil.iq\0vestby.no\0globo\0" +"bz.it\0" +"alesund.no\0barsyonline.co.uk\0" +"kure.hiroshima.jp\0" +"sk\xc3\xa5nland.no\0emrnotebooks-prod.eu-west-3.amazonaws.com\0" +"herad.no\0bo.telemark.no\0organic\0photo\0" +"togo.aichi.jp\0" +"nohost.me\0" +"servebbs.net\0" +"mil.jo\0stord.no\0" +"bs.it\0fukuchiyama.kyoto.jp\0peewee.jp\0" +"notebook-fips.us-east-2.sagemaker.aws\0be.gy\0" +"winb.gov.pl\0" +"mil.kg\0ybo.review\0" +"cdn77-ssl.net\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.\xe9\xa6\x99\xe6\xb8\xaf\0orange\0" +"kisarazu.chiba.jp\0" +"kawazu.shizuoka.jp\0wif.gov.pl\0" +"mil.km\0haus\0" +"bl.it\0mie.jp\0" +"kitagawa.kochi.jp\0" +"studio.eu-west-2.sagemaker.aws\0" +"mil.kr\0" +"maringa.br\0shiraoka.saitama.jp\0" +"outsystemscloud.com\0" +"\xe5\xa5\x88\xe8\x89\xaf.jp\0" +"ecologia.bo\0movimiento.bo\0gs.tm.no\0bharti\0sa.com\0" +"otaki.nagano.jp\0mil.kz\0" +"myddns.rocks\0" +"takamori.nagano.jp\0" +"s3-sa-east-1.amazonaws.com\0" +"bio.br\0" +"storfjord.no\0s3-object-lambda.ap-south-2.amazonaws.com\0" +"mil.lv\0buyshouses.net\0redirectme.net\0" +"szex.hu\0mil.mg\0batsfjord.no\0auth.us-west-2.amazoncognito.com\0" +"kanazawa.ishikawa.jp\0" +"an.it\0" +"dyn.ddnss.de\0ashgabad.su\0" +"cdn-edges.net\0" +"genting\0" +"tagajo.miyagi.jp\0" +"luster.no\0cc.vi.us\0" +"mil.mv\0" +"mil.ng\0fedorapeople.org\0" +"ag.it\0" +"mil.my\0mil.ni\0" +"mil.mz\0" +"annaka.gunma.jp\0" +"cc.na\0halden.no\0hitachi\0" +"mil.no\0" +"shioya.tochigi.jp\0myspreadshop.nl\0" +"from-mo.com\0" +"hungry.jp\0" +"myspreadshop.no\0" +"r\xc3\xa5holt.no\0" +"koza.wakayama.jp\0" +"oshu.iwate.jp\0" +"saogonca.br\0niiza.saitama.jp\0mil.nz\0principe.st\0" +"higashi.okinawa.jp\0" +"mandal.no\0" +"mil.pe\0net-freaks.com\0" +"s3-eu-north-1.amazonaws.com\0syno-ds.de\0" +"yamagata.gifu.jp\0mil.ph\0" +"mil.pl\0" +"barclays\0" +"is-very-good.org\0" +"ishikawa.jp\0tsuno.kochi.jp\0myspreadshop.pl\0" +"city.hu\0\xc3\xb8stre-toten.no\0mil.qa\0\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0emrappui-prod.us-gov-west-1.amazonaws.com\0" +"select\0" +"jeju.kr\0" +"in-dsl.org\0" +"mil.py\0jpn.org\0" +"campinagrande.br\0" +"k12.ec\0vestvagoy.no\0*.ap-southeast-2.airflow.amazonaws.com\0" +"chernihiv.ua\0uk.eu.org\0" +"venezia.it\0gsm.pl\0\xe0\xb4\xad\xe0\xb4\xbe\xe0\xb4\xb0\xe0\xb4\xa4\xe0\xb4\x82\0leczna.pl\0" +"jc.neen.it\0" +"studio.ap-east-1.sagemaker.aws\0" +"fujikawa.shizuoka.jp\0binhduong.vn\0" +"wed\0" +"k12.wi.us\0kyoto\0" +"nakaniikawa.toyama.jp\0myspreadshop.it\0" +"loab\xc3\xa1t.no\0" +"usui.fukuoka.jp\0" +"my-gateway.de\0" +"pippu.hokkaido.jp\0" +"able\0*.triton.zone\0opensocial.site\0" +"is-a-doctor.com\0" +"notebook.ap-northeast-3.sagemaker.aws\0" +"tone.ibaraki.jp\0chat\0" +"notebook.ap-southeast-1.sagemaker.aws\0cx.ua\0" +"education\0" +"press\0mil.ru\0" +"sampa.br\0higashine.yamagata.jp\0" +"mil.rw\0" +"mil.sh\0" +"enscaled.sg\0" +"restaurant.bj\0cuiaba.br\0" +"s3-website.dualstack.ap-south-1.amazonaws.com\0s3.eu-central-1.amazonaws.com\0is-a-bulls-fan.com\0" +"westeurope.azurestaticapps.net\0" +"gentlentapis.com\0" +"from-ny.net\0" +"bydgoszcz.pl\0" +"gleeze.com\0" +"s3-website.eu-west-2.amazonaws.com\0" +"mil.st\0" +"s3.dualstack.us-gov-west-1.amazonaws.com\0" +"zpisdn.gov.pl\0" +"mil.sy\0" +"cieszyn.pl\0mil.tj\0" +"l\xc3\xa1hppi.no\0co.events\0" +"mil.tm\0" +"kvinnherad.no\0mil.to\0notebook.af-south-1.sagemaker.aws\0" +"rj.gov.br\0" +"gub.uy\0" +"mil.tr\0" +"aktyubinsk.su\0" +"\xe6\xbb\x8b\xe8\xb3\x80.jp\0kasama.ibaraki.jp\0lamdong.vn\0" +"s3-accesspoint.dualstack.ap-southeast-4.amazonaws.com\0" +"mil.tw\0" +"selfip.info\0" +"mil.tz\0" +"sakura.tochigi.jp\0" +"revista.bo\0mo-i-rana.no\0cc.ua\0us.org\0" +"afjord.no\0luroy.no\0" +"rishiri.hokkaido.jp\0" +"mil.vc\0" +"k12.il\0" +"mil.ve\0" +"\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0" +"*.tst.site\0" +"achi.nagano.jp\0" +"navuotna.no\0mil.uy\0eu-west-2.elasticbeanstalk.com\0" +"minamata.kumamoto.jp\0" +"yamanakako.yamanashi.jp\0targi.pl\0" +"k12.tx.us\0emrnotebooks-prod.us-east-2.amazonaws.com\0secaas.hk\0" +"goip.de\0virtualserver.io\0" +"rec.br\0win\0de.trendhosting.cloud\0" +"nakai.kanagawa.jp\0ondigitalocean.app\0" +"sauda.no\0" +"webview-assets.aws-cloud9.eu-south-1.amazonaws.com\0*.awdev.ca\0" +"ownip.net\0" +"country\0" +"laocai.vn\0eurovision\0it1.jenv-aruba.cloud\0" +"norddal.no\0s3-accesspoint.af-south-1.amazonaws.com\0" +"hitachinaka.ibaraki.jp\0" +"rec.co\0" +"akamai.net\0" +"abashiri.hokkaido.jp\0" +"s3-deprecated.us-east-1.amazonaws.com\0dyndns-remote.com\0" +"from-az.net\0" +"accountant\0" +"koobin.events\0" +"ikeda.hokkaido.jp\0worse-than.tv\0" +"republican\0" +"nhlfan.net\0" +"mel\xc3\xb8y.no\0mil.ye\0ufcfan.org\0" +"kobierzyce.pl\0" +"eu.encoway.cloud\0" +"gon.pk\0*.on-rio.io\0" +"kunigami.okinawa.jp\0nirasaki.yamanashi.jp\0" +"vestre-toten.no\0""123sait.ru\0" +"a.run.app\0" +"mil.za\0" +"ishikawa.fukushima.jp\0" +"kashiba.nara.jp\0" +"scientist.aero\0wme\0" +"yoshinogari.saga.jp\0hoabinh.vn\0" +"yahaba.iwate.jp\0" +"mil.zm\0" +"genoa.it\0nagatoro.saitama.jp\0" +"messwithdns.com\0" +"hosting-cluster.nl\0" +"official.academy\0" +"surgery\0" +"ayase.kanagawa.jp\0azurestaticapps.net\0" +"eng.pro\0club.tw\0mil.zw\0" +"aaa.pro\0studio.ca-central-1.sagemaker.aws\0myspreadshop.se\0" +"karatsu.saga.jp\0" +"bozen-suedtirol.it\0yatomi.aichi.jp\0" +"w.bg\0" +"dyndns.biz\0" +"sunndal.no\0dnsfor.me\0" +"cc.ny.us\0" +"\xe5\xb1\xb1\xe5\xbd\xa2.jp\0" +"nh-serv.co.uk\0" +"*.usercontent.goog\0" +"aetna\0" +"p.bg\0" +"itayanagi.aomori.jp\0sncf\0yandexcloud.net\0" +"s3-fips.us-east-1.amazonaws.com\0" +"slask.pl\0" +"nakamichi.yamanashi.jp\0" +"raffleentry.org.uk\0" +"kashihara.nara.jp\0" +"sevastopol.ua\0wow\0virtualuser.de\0" +"i.bg\0schule\0" +"kami.miyagi.jp\0" +"macerata.it\0" +"mokuren.ne.jp\0" +"anani.br\0uozu.toyama.jp\0wkz.gov.pl\0" +"airport.aero\0" +"rugby\0" +"holdings\0" +"shiki.saitama.jp\0" +"b.bg\0" +"iwi.nz\0" +"webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com\0" +"cc.mt.us\0cc.nd.us\0" +"skjak.no\0webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com\0" +"suifu.ibaraki.jp\0mincom.tn\0" +"mckinsey\0" +"b.br\0sabae.fukui.jp\0" +"kitaura.miyazaki.jp\0" +"is-a-cubicle-slave.com\0" +"wakasa.fukui.jp\0" +"pramerica\0myftp.org\0" +"vlaanderen\0" +"playstation-cloud.com\0" +"tsukigata.hokkaido.jp\0" +"jelastic.saveincloud.net\0" +"kani.gifu.jp\0hidaka.kochi.jp\0" +"namikata.ehime.jp\0" +"mihama.chiba.jp\0" +"cust.testing.thingdust.io\0" +"s3-accesspoint.eu-west-2.amazonaws.com\0" +"oiso.kanagawa.jp\0" +"emrnotebooks-prod.eu-south-1.amazonaws.com\0eu-south-1.elasticbeanstalk.com\0" +"wtc\0" +"h\xc3\xb8yanger.no\0webview-assets.cloud9.ap-southeast-2.amazonaws.com\0" +"wtf\0s3-website.nl-ams.scw.cloud\0" +"k12.tr\0" +"int.ar\0kadena.okinawa.jp\0" +"dyn-vpn.de\0" +"stordal.no\0cust.retrosnub.co.uk\0" +"kuromatsunai.hokkaido.jp\0" +"\xc3\xa5rdal.no\0lipsy\0" +"shiso.hyogo.jp\0" +"sa.gov.au\0" +"int.az\0rec.nf\0computer\0dnsdojo.net\0" +"empresa.bo\0finance\0" +"tabayama.yamanashi.jp\0" +"bozen-s\xc3\xbc""dtirol.it\0s3-object-lambda.cn-north-1.amazonaws.com.cn\0" +"int.bo\0" +"berlev\xc3\xa5g.no\0vaporcloud.io\0" +"tomioka.gunma.jp\0" +"works\0loseyourip.com\0" +"world\0" +"k12.nv.us\0k12.vi\0emrstudio-prod.ap-northeast-1.amazonaws.com\0" +"int.ci\0" +"toyo.kochi.jp\0vpndns.net\0" +"cc.la.us\0s3.ap-northeast-1.amazonaws.com\0studio.sa-east-1.sagemaker.aws\0" +"\xe0\xb8\x98\xe0\xb8\xb8\xe0\xb8\xa3\xe0\xb8\x81\xe0\xb8\xb4\xe0\xb8\x88.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"virgin\0watson.jp\0halfmoon.jp\0" +"int.co\0" +"nago.okinawa.jp\0" +"nikko.tochigi.jp\0static-access.net\0" +"8.bg\0storebase.store\0" +"suita.osaka.jp\0" +"k12.ne.us\0fantasyleague.cc\0" +"int.cv\0" +"andebu.no\0" +"ranzan.saitama.jp\0bona.jp\0" +"\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0dattoweb.com\0" +"inf.br\0namie.fukushima.jp\0katsuragi.wakayama.jp\0" +"bokn.no\0" +"1.bg\0" +"k12.nh.us\0jelastic.team\0" +"tarui.gifu.jp\0" +"rr.gov.br\0" +"volvo\0tech.orange\0" +"abira.hokkaido.jp\0ikeda.nagano.jp\0" +"dyndns-ip.com\0" +"*.bd\0massa-carrara.it\0hagiang.vn\0" +"novara.it\0\xe5\x92\x8c\xe6\xad\x8c\xe5\xb1\xb1.jp\0" +"inf.cu\0college\0" +"aizuwakamatsu.fukushima.jp\0" +"benevento.it\0semine.miyagi.jp\0" +"komatsu\0" +"vardo.no\0is-a-rockstar.com\0" +"capoo.jp\0" +"emrappui-prod.eu-west-1.amazonaws.com\0" +"firewall-gateway.net\0" +"myspreadshop.es\0" +"oshima.yamaguchi.jp\0" +"lib.ee\0siiites.com\0" +"chikuhoku.nagano.jp\0netgamers.jp\0" +"holy.jp\0" +"*.ck\0asnes.no\0h\xc3\xa6gebostad.no\0rec.ro\0damnserver.com\0myspreadshop.fi\0" +"taranto.it\0ninohe.iwate.jp\0" +"webview-assets.aws-cloud9.ap-south-1.amazonaws.com\0" +"rs.gov.br\0sc.gov.br\0xin\0perma.jp\0" +"in-vpn.de\0loginto.me\0" +"savona.it\0*.stgstage.dev\0" +"wmcloud.org\0ybo.science\0" +"s3.eu-west-1.amazonaws.com\0" +"myspreadshop.fr\0" +"k12.la.us\0" +"frei.no\0" +"b\xc3\xa1hccavuotna.no\0cc.in.us\0" +"hashima.gifu.jp\0" +"s3-eu-west-1.amazonaws.com\0" +"dongthap.vn\0a.ssl.fastly.net\0" +"gs.fm.no\0" +"kasugai.aichi.jp\0" +"ocelot.mythic-beasts.com\0" +"s3.dualstack.us-gov-east-1.amazonaws.com\0" +"yao.osaka.jp\0przeworsk.pl\0\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x90\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\xa5.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"api.stdlib.com\0" +"mein-iserv.de\0" +"*.er\0" +"stranda.no\0" +"homeftp.org\0" +"int.in\0kontum.vn\0" +"myspreadshop.ie\0" +"i.ng\0" +"*.fk\0int.is\0" +"florist\0" +"\xc3\xb8rland.no\0" +"det.br\0" +"rec.ve\0airbus\0" +"cc.hi.us\0nalchik.ru\0" +"legal\0myspreadshop.at\0" +"riik.ee\0aurskog-h\xc3\xb8land.no\0framer.website\0cloud.interhostsolutions.be\0myspreadshop.be\0" +"kasahara.gifu.jp\0" +"muosat.no\0\xeb\x8b\xb7\xeb\x84\xb7\0boldlygoingnowhere.org\0homelink.one\0" +"tateyama.chiba.jp\0taketomi.okinawa.jp\0daynight.jp\0" +"airkitapps.com\0" +"kawakami.nagano.jp\0" +"meloy.no\0s3-accesspoint.ap-southeast-2.amazonaws.com\0" +"trani-andria-barletta.it\0seiro.niigata.jp\0" +"safety\0s3.dualstack.ap-southeast-4.amazonaws.com\0nalchik.su\0myspreadshop.ca\0" +"limited\0static.land\0" +"grocery\0" +"int.la\0" +"def.br\0setouchi.okayama.jp\0i.ph\0curv.dev\0myspreadshop.ch\0" +"hdfc\0" +"qld.edu.au\0" +"kamoenai.hokkaido.jp\0ooshika.nagano.jp\0" +"mymailer.com.tw\0" +"loan\0" +"int.lk\0stockholm\0" +"dni.us\0" +"intl.tn\0ric.jelastic.vps-host.net\0" +"heroy.more-og-romsdal.no\0lib.va.us\0myspreadshop.de\0" +"trentinosuedtirol.it\0" +"puglia.it\0mikawa.yamagata.jp\0" +"w.se\0" +"hyogo.jp\0" +"myspreadshop.dk\0" +"rn.gov.br\0" +"agematsu.nagano.jp\0in-dsl.net\0" +"adygeya.su\0" +"udine.it\0" +"office-on-the.net\0" +"csx.cc\0" +"p.se\0bridgestone\0" +"fuchu.hiroshima.jp\0" +"infiniti\0" +"laspezia.it\0" +"*.jm\0commbank\0" +"int.mv\0""7.azurestaticapps.net\0" +"int.mw\0inder\xc3\xb8y.no\0" +"int.ni\0" +"azure\0barsy.online\0novecore.site\0" +"s3-accesspoint.dualstack.ap-northeast-1.amazonaws.com\0" +"i.se\0azimuth.network\0" +"*.kh\0hotmail\0" +"honbetsu.hokkaido.jp\0" +"estate\0" +"netbank\0servebbs.org\0" +"ro.gov.br\0kitashiobara.fukushima.jp\0" +"inf.mk\0" +"cloudcontrolled.com\0" +"yahiko.niigata.jp\0" +"k12.il.us\0cafjs.com\0" +"b.se\0" +"chungbuk.kr\0" +"gs.bu.no\0amfam\0" +"karuizawa.nagano.jp\0opole.pl\0" +"wlocl.pl\0" +"*.diher.solutions\0" +"ichikawa.chiba.jp\0shimotsuma.ibaraki.jp\0" +"nagano.nagano.jp\0" +"rar.ve\0adygeya.ru\0" +"hatsukaichi.hiroshima.jp\0kawai.nara.jp\0saitama.saitama.jp\0" +"dyr\xc3\xb8y.no\0" +"kouhoku.saga.jp\0" +"takko.aomori.jp\0" +"paris\0security\0emrnotebooks-prod.ap-south-1.amazonaws.com\0" +"tome.miyagi.jp\0" +"int.pt\0gmail\0" +"*.mm\0est-a-la-masion.com\0" +"nishiawakura.okayama.jp\0" +"notebook.eu-west-3.sagemaker.aws\0" +"friulivegiulia.it\0" +"square7.de\0" +"monza.it\0ogawa.ibaraki.jp\0gda.pl\0" +"s3.us-west-1.amazonaws.com\0amscompute.com\0" +"brasilia.me\0" +"shobara.hiroshima.jp\0" +"kochi.kochi.jp\0*.np\0" +"is-a-financialadvisor.com\0" +"engineer\0" +"shirako.chiba.jp\0shibuya.tokyo.jp\0ac.leg.br\0" +"\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\0" +"konan.aichi.jp\0" +"df.gov.br\0" +"ibestad.no\0barsy.me\0" +"sohu\0from-wa.com\0stuff-4-sale.us\0" +"int.ru\0" +"oguni.kumamoto.jp\0" +"kvitsoy.no\0cc.dc.us\0" +"sanok.pl\0swatch\0" +"naka.ibaraki.jp\0" +"pixolino.com\0" +"indigena.bo\0agency\0" +"*.pg\0" +"fastvps-server.com\0" +"int.tj\0sakura.ne.jp\0" +"webview-assets.aws-cloud9.sa-east-1.amazonaws.com\0" +"square7.ch\0mongolian.jp\0lon-2.paas.massivegrid.net\0" +"int.tt\0" +"frenchkiss.jp\0" +"levanger.no\0blogdns.com\0" +"tushu\0execute-api.ap-east-1.amazonaws.com\0" +"myoko.niigata.jp\0" +"citi\0kurgan.su\0" +"tw.cn\0cdn.prod.atlassian-dev.net\0" +"crew.aero\0" +"soc.srcf.net\0" +"s3-website.af-south-1.amazonaws.com\0" +"modena.it\0nakano.nagano.jp\0" +"int.ve\0" +"kunisaki.oita.jp\0flickr\0" +"eidskog.no\0toyota\0" +"b\xc3\xb8.nordland.no\0" +"sakyo.kyoto.jp\0" +"adv.br\0\xe0\xb8\xad\xe0\xb8\x87\xe0\xb8\x84\xe0\xb9\x8c\xe0\xb8\x81\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"city\0inf.ua\0" +"int.vn\0" +"xxx\0" +"skien.no\0" +"okinawa.okinawa.jp\0" +"s3.dualstack.ca-central-1.amazonaws.com\0" +"handa.aichi.jp\0" +"zone\0" +"omuta.fukuoka.jp\0" +"vix.br\0bandai.fukushima.jp\0" +"lifeinsurance\0kilatiron.com\0" +"cloud.jelastic.open.tim.it\0" +"nsn.us\0" +"prato.it\0s\xc3\xbc""dtirol.it\0netflix\0" +"fujisawa.kanagawa.jp\0hinohara.tokyo.jp\0" +"giize.com\0" +"ostroleka.pl\0xyz\0myfritz.net\0" +"kazimierz-dolny.pl\0" +"song\0" +"cnt.br\0" +"e12.ve\0" +"sk.ca\0" +"nextdirect\0" +"barsy.ro\0" +"valleeaoste.it\0vs.it\0" +"rovno.ua\0" +"studio.ap-northeast-2.sagemaker.aws\0" +"minamiizu.shizuoka.jp\0hyatt\0emrappui-prod.cn-northwest-1.amazonaws.com.cn\0" +"vic.au\0independent-inquiry.uk\0" +"arida.wakayama.jp\0thanhhoa.vn\0" +"sony\0" +"airtraffic.aero\0wpdevcloud.com\0" +"zapto.xyz\0" +"time.no\0" +"kolobrzeg.pl\0" +"morioka.iwate.jp\0" +"yonaguni.okinawa.jp\0" +"mrap.accesspoint.s3-global.amazonaws.com\0" +"sd.cn\0" +"graphox.us\0uwu.ai\0" +"svalbard.no\0sondre-land.no\0" +"ve.it\0izumizaki.fukushima.jp\0" +"nichinan.miyazaki.jp\0okuizumo.shimane.jp\0cn-north-1.eb.amazonaws.com.cn\0" +"misato.miyagi.jp\0" +"sor-odal.no\0" +"nagato.yamaguchi.jp\0" +"trentino-sued-tirol.it\0dongnai.vn\0" +"rhcloud.com\0" +"se.gov.br\0contact\0on-the-web.tv\0" +"sandnessj\xc3\xb8""en.no\0emrappui-prod.ap-northeast-1.amazonaws.com\0barsy.uk\0" +"kitaakita.akita.jp\0" +"elverum.no\0" +"deals\0" +"matrix.jp\0" +"lib.nv.us\0s3-accesspoint.us-west-1.amazonaws.com\0nov.ru\0" +"parts\0" +"taa.it\0akagi.shimane.jp\0" +"voting\0" +"gokase.miyazaki.jp\0watch\0siteleaf.net\0" +"flakstad.no\0party\0" +"saltdal.no\0radio.am\0" +"vercelli.it\0" +"cpa.pro\0lib.mo.us\0" +"kill.jp\0" +"\xe6\x9b\xb8\xe7\xb1\x8d\0nov.su\0" +"valer.hedmark.no\0notebook.ap-northeast-1.sagemaker.aws\0" +"tp.it\0kin.okinawa.jp\0" +"emrappui-prod.eu-west-2.amazonaws.com\0" +"guge\0" +"lib.mt.us\0lib.nd.us\0" +"tondabayashi.osaka.jp\0" +"salangen.no\0edgestack.me\0gentapps.com\0" +"qh.cn\0!city.sapporo.jp\0" +"certification.aero\0you\0iamallama.com\0nflfan.org\0" +"radio.br\0*.compute.amazonaws.com.cn\0" +"oz.au\0alt.za\0flowers\0" +"pug.it\0itakura.gunma.jp\0direct\0" +"bmoattachments.org\0" +"\xe7\xa6\x8f\xe5\xb2\xa1.jp\0" +"kanagawa.jp\0" +"sonla.vn\0" +"lib.nm.us\0" +"casacam.net\0" +"siellak.no\0" +"sr.it\0" +"\xc3\xa5lesund.no\0" +"mishima.shizuoka.jp\0" +"filegear-sg.me\0""123webseite.de\0" +"seiyo.ehime.jp\0" +"kurate.fukuoka.jp\0" +"kristiansand.no\0" +"oyabe.toyama.jp\0" +"skedsmo.no\0" +"amagasaki.hyogo.jp\0iwaizumi.iwate.jp\0" +"accenture\0*.user.fm\0" +"today\0" +"oum.gov.pl\0" +"sande.vestfold.no\0" +"kyuragi.saga.jp\0" +"guitars\0" +"shinyoshitomi.fukuoka.jp\0misato.wakayama.jp\0" +"florence.it\0" +"alvdal.no\0" +"sld.do\0rendalen.no\0" +"marriott\0hu.net\0" +"loginline.services\0" +"s\xc3\xa1lat.no\0homes\0" +"marshalls\0" +"sa.gov.pl\0" +"love\0dyn.home-webserver.de\0" +"shikabe.hokkaido.jp\0cranky.jp\0""123webseite.at\0" +"nu.ca\0" +"tokoname.aichi.jp\0" +"getmyip.com\0pagespeedmobilizer.com\0" +"rm.it\0" +"radio.fm\0" +"markets\0" +"mywire.org\0" +"boleslawiec.pl\0" +"lib.ky.us\0" +"iwamizawa.hokkaido.jp\0" +"air-surveillance.aero\0" +"ham-radio-op.net\0" +"adv.mz\0" +"takanezawa.tochigi.jp\0" +"dyroy.no\0upli.io\0" +"nagara.chiba.jp\0" +"notebook-fips.us-gov-east-1.sagemaker.aws\0" +"help\0" +"ostre-toten.no\0ap.ngrok.io\0" +"i234.me\0" +"yun\0" +"in-addr.arpa\0pimienta.org\0karelia.su\0" +"music\0" +"bjugn.no\0farsund.no\0farmers\0" +"yoichi.hokkaido.jp\0voorloper.cloud\0" +"notebook.me-south-1.sagemaker.aws\0" +"mp.br\0" +"frogans\0" +"catering.aero\0" +"konskowola.pl\0edgekey.net\0" +"dyndns-home.com\0" +"sos.pl\0" +"balena-devices.com\0" +"toyama.toyama.jp\0" +"emrnotebooks-prod.ap-northeast-2.amazonaws.com\0" +"enna.it\0" +"pol.dz\0al.leg.br\0" +"au.ngrok.io\0" +"higashiyodogawa.osaka.jp\0" +"horten.no\0" +"hidaka.saitama.jp\0" +"alwaysdata.net\0" +"marumori.miyagi.jp\0realm.cz\0sopot.pl\0" +"agdenes.no\0institute\0systems\0" +"mizumaki.fukuoka.jp\0" +"bajddar.no\0" +"homeftp.net\0" +"mb.ca\0" +"yasuoka.nagano.jp\0" +"sugito.saitama.jp\0" +"takatsuki.osaka.jp\0himi.toyama.jp\0" +"zaporizhzhe.ua\0" +"idrett.no\0" +"download\0" +"is-a-guru.com\0" +"tamaki.mie.jp\0taishi.osaka.jp\0kounosu.saitama.jp\0" +"\xe5\x8c\x97\xe6\xb5\xb7\xe9\x81\x93.jp\0" +"vaga.no\0emrstudio-prod.eu-south-1.amazonaws.com\0" +"pc.it\0" +"teaches-yoga.com\0" +"rieti.it\0okayama.okayama.jp\0sp.leg.br\0" +"alipay\0" +"emrnotebooks-prod.ca-central-1.amazonaws.com\0from-ks.com\0" +"kaho.fukuoka.jp\0zip\0" +"nore-og-uvdal.no\0s\xc3\xb8r-odal.no\0" +"gamagori.aichi.jp\0" +"emrappui-prod.eu-south-1.amazonaws.com\0studio.ap-southeast-2.sagemaker.aws\0x0.to\0" +"tottori.jp\0" +"far.br\0" +"takaoka.toyama.jp\0" +"barsy.bg\0" +"shisui.chiba.jp\0" +"here\0" +"pol.ht\0" +"nu.it\0" +"h\xc3\xb8nefoss.no\0" +"toyotsu.fukuoka.jp\0" +"sling\0" +"barsy.ca\0webview-assets.cloud9.eu-central-1.amazonaws.com\0" +"izumisano.osaka.jp\0" +"health-carereform.com\0" +"froland.no\0" +"guru\0viking\0" +"sannan.hyogo.jp\0" +"\xd0\xbe\xd0\xb4.\xd1\x81\xd1\x80\xd0\xb1\0" +"yaita.tochigi.jp\0tayninh.vn\0hra.health\0" +"tattoo\0" +"nozawaonsen.nagano.jp\0endofinternet.net\0krakow.pl\0" +"aero\0" +"midsund.no\0sn\xc3\xa5sa.no\0barsy.de\0" +"spot\0workers.dev\0" +"ro.eu.org\0" +"tsurugi.ishikawa.jp\0ny-1.paas.massivegrid.net\0" +"blogspot.co.at\0" +"webview-assets.aws-cloud9.us-east-2.amazonaws.com\0" +"skype\0" +"onrender.com\0" +"gushikami.okinawa.jp\0wedeploy.sh\0" +"yura.wakayama.jp\0murayama.yamagata.jp\0" +"s3-website-ap-northeast-1.amazonaws.com\0" +"calabria.it\0" +"floro.no\0" +"s3-website-ap-southeast-2.amazonaws.com\0notebook-fips.us-east-1.sagemaker.aws\0qualifioapp.com\0" +"\xc3\xa5seral.no\0sld.pa\0" +"vipsinaapp.com\0" +"koya.wakayama.jp\0" +"sic.it\0" +"ivgu.no\0" +"mi.it\0" +"execute-api.ap-northeast-3.amazonaws.com\0barsy.eu\0" +"hobby-site.com\0" +"ol.no\0" +"suzuki\0l-o-g-i-n.de\0" +"sd.us\0notebook.us-west-1.sagemaker.aws\0" +"oseto.nagasaki.jp\0konin.pl\0" +"prime\0" +"mb.it\0" +"sicily.it\0yamada.iwate.jp\0" +"flora.no\0" +"kobayashi.miyazaki.jp\0pc.pl\0" +"sm\xc3\xb8la.no\0" +"bitbridge.net\0" +"bauhaus\0" +"hakata.fukuoka.jp\0" +"jele.host\0" +"akamaihd-staging.net\0" +"emrappui-prod.us-gov-east-1.amazonaws.com\0" +"sano.tochigi.jp\0hayakawa.yamanashi.jp\0\xe7\xa7\xbb\xe5\x8a\xa8\0" +"os.hedmark.no\0si.eu.org\0" +"sch.ae\0bible\0" +"melbourne\0s3-website-us-west-1.amazonaws.com\0camdvr.org\0" +"naha.okinawa.jp\0" +"honda\0" +"auth.af-south-1.amazoncognito.com\0ap-northeast-3.elasticbeanstalk.com\0" +"\xd8\xb9\xd8\xb1\xd8\xa8\0" +"uchiko.ehime.jp\0" +"sagae.yamagata.jp\0akamaized-staging.net\0" +"hl.cn\0sakata.yamagata.jp\0" +"tonsberg.no\0" +"funahashi.toyama.jp\0" +"rawa-maz.pl\0" +"skierv\xc3\xa1.no\0bar.pro\0" "barsy.in\0" -"net.mo\0barsy.io\0" +"barsy.io\0" +"uk0.bigv.io\0" +"sadist.jp\0dev.static.land\0" +"\xe4\xbd\x9b\xe5\xb1\xb1\0in-butter.de\0""123minsida.se\0" +"honjo.akita.jp\0" +"ladesk.com\0" +"he.cn\0" +"cnpy.gdn\0" +"discordsays.com\0git-repos.de\0" +"gallery\0" +"gg.ax\0" +"*.cn-northwest-1.airflow.amazonaws.com.cn\0" +"bronnoy.no\0" +"s3-us-east-2.amazonaws.com\0" +"\xe0\xa4\x95\xe0\xa5\x89\xe0\xa4\xae\0" +"samsung\0s3-accesspoint.sa-east-1.amazonaws.com\0" +"blogspot.co.id\0" +"nedre-eiker.no\0" +"nagi.okayama.jp\0" +"blogspot.co.il\0" +"mitsuke.niigata.jp\0" +"\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xaa\xe0\xaf\x82\xe0\xae\xb0\xe0\xaf\x8d\0s3-website.ca-central-1.amazonaws.com\0s3.eu-west-3.amazonaws.com\0" +"koga.ibaraki.jp\0" +"\xd2\x9b\xd0\xb0\xd0\xb7\0sk.eu.org\0" +"impertrix.com\0" +"drobak.no\0somna.no\0myiphost.com\0" +"yabu.hyogo.jp\0tsuno.miyazaki.jp\0" +"realestate\0mayfirst.info\0" +"fage\0s3-eu-west-3.amazonaws.com\0" +"ichikai.tochigi.jp\0" +"nishitosa.kochi.jp\0glogow.pl\0" +"\xe7\x82\xb9\xe7\x9c\x8b\0" +"kujukuri.chiba.jp\0sites.static.land\0" +"vicenza.it\0" +"s3-website-eu-west-1.amazonaws.com\0" +"fi.cr\0" +"mol.it\0" +"sado.niigata.jp\0maif\0" +"sukumo.kochi.jp\0pol.tr\0" +"ed.ao\0\xc3\xa5mli.no\0myhome-server.de\0" +"sakuho.nagano.jp\0" +"wiw.gov.pl\0ngrok-free.dev\0" +"m\xc3\xa1latvuopmi.no\0wedeploy.me\0" +"bosch\0" +"cog.mi.us\0" +"aparecida.br\0" +"futuremailing.at\0" +"s3-website-sa-east-1.amazonaws.com\0eero-stage.online\0" +"oshino.yamanashi.jp\0wielun.pl\0*.banzai.cloud\0" +"tas.gov.au\0nes.akershus.no\0lib.as.us\0msk.ru\0" +"perso.ht\0machida.tokyo.jp\0" +"shinichi.hiroshima.jp\0fail\0" +"mediatech.by\0" +"reggioemilia.it\0hokuryu.hokkaido.jp\0" +"nanmoku.gunma.jp\0" +"s3-accesspoint.dualstack.ap-southeast-1.amazonaws.com\0is-a-celticsfan.org\0awsmppl.com\0" +"saigawa.fukuoka.jp\0" +"ed.ci\0" +"friuli-veneziagiulia.it\0" +"is-a-nurse.com\0" +"tateyama.toyama.jp\0" +"ru.eu.org\0se.eu.org\0msk.su\0srht.site\0" +"sch.id\0piw.gov.pl\0mi.th\0" +"co.ae\0" +"co.ag\0from-al.com\0" +"ed.cr\0" +"cymru\0talk\0" +"mino.gifu.jp\0hs.kr\0" +"lesja.no\0lugansk.ua\0" +"co.am\0" +"co.ao\0" +"vs.mythic-beasts.com\0" +"co.bb\0sch.ir\0" +"co.at\0" +"il-central-1.elasticbeanstalk.com\0" +"omachi.nagano.jp\0" +"agrar.hu\0" +"co.bi\0" +"co.bj\0" +"okinoshima.shimane.jp\0co.bn\0" +"sch.jo\0mi.us\0" +"yomitan.okinawa.jp\0ashikaga.tochigi.jp\0" +"co.ca\0" +"taiwa.miyagi.jp\0" +"co.bw\0\xd0\xbc\xd1\x81\xd0\xba.\xd1\x80\xd1\x83\xd1\x81\0" +"aisai.aichi.jp\0kawaiishop.jp\0" +"co.ci\0" +"co.cl\0" +"co.cm\0" +"ponpes.id\0" +"ba.gov.br\0trentin-sud-tirol.it\0" +"co.cr\0onomichi.hiroshima.jp\0" +"cesenaforl\xc3\xac.it\0" +"furubira.hokkaido.jp\0tsuwano.shimane.jp\0" +"co.cz\0experts-comptables.fr\0" +"sch.lk\0co.dk\0" +"chuo.osaka.jp\0" +"webspace.rocks\0" +"fi.it\0tsugaru.aomori.jp\0" +"my-wan.de\0" +"shinanomachi.nagano.jp\0" +"griw.gov.pl\0" +"hl.no\0km.ua\0" +"funagata.yamagata.jp\0" +"er.in\0" +"sch.ly\0" +"naruto.tokushima.jp\0" +"execute-api.eu-central-1.amazonaws.com\0" +"\xe3\x81\xbf\xe3\x82\x93\xe3\x81\xaa\0" +"fans\0" +"epson\0" +"valle-d-aosta.it\0" +"leangaviika.no\0" +"yamada.toyama.jp\0" +"chintai\0" +"trentinsued-tirol.it\0" +"sch.ng\0archi\0" +"bj.cn\0" +"bc.ca\0homesense\0" +"for-some.biz\0" +"namsos.no\0*.ap-northeast-1.airflow.amazonaws.com\0" +"emrstudio-prod.ca-central-1.amazonaws.com\0" +"amot.no\0" +"localhost.daplie.me\0lugs.org.uk\0" +"uchihara.ibaraki.jp\0iliadboxos.it\0" +"s\xc3\xb8ndre-land.no\0emrnotebooks-prod.ap-southeast-1.amazonaws.com\0" +"backan.vn\0" +"co.gg\0" +"seidat.net\0" +"luhansk.ua\0from-ms.com\0from-nc.com\0" +"co.gl\0hanyu.saitama.jp\0channel\0" +"uni5.net\0" +"kragero.no\0" +"ed.jp\0" +"co.gy\0" +"ginan.gifu.jp\0" +"from-ca.com\0" +"blogspot.co.uk\0" +"sch.qa\0ngrok.pizza\0" +"yamaguchi.jp\0emrstudio-prod.cn-north-1.amazonaws.com.cn\0" +"sor-aurdal.no\0watches\0" +"co.id\0*.magentosite.cloud\0" +"co.hu\0" +"per.la\0farm\0" +"aivencloud.com\0" +"co.il\0obuse.nagano.jp\0" +"co.im\0" +"co.in\0iruma.saitama.jp\0boo.jp\0torproject.net\0" +"unicloud.pl\0" +"co.ir\0edogawa.tokyo.jp\0" +"s3-object-lambda.eu-west-2.amazonaws.com\0webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com\0" +"co.it\0" +"co.je\0\xe9\x80\x9a\xe8\xb2\xa9\0dyndns.ddnss.de\0" +"uk.net\0" +"khakassia.su\0" +"kasaoka.okayama.jp\0" +"minamiaiki.nagano.jp\0" +"saves-the-whales.com\0own.pm\0" +"better-than.tv\0pupu.jp\0" +"sakai.fukui.jp\0fast\0jp.net\0" +"studio.us-west-2.sagemaker.aws\0" +"co.jp\0naie.hokkaido.jp\0" +"sch.sa\0" +"ch.it\0yamanashi.jp\0" +"2ix.at\0" +"co.ke\0" +"walbrzych.pl\0" +"ask\xc3\xb8y.no\0hlx3.page\0s3-accesspoint.eu-west-3.amazonaws.com\0" +"ca.in\0" +"gose.nara.jp\0per.nf\0" +"osteroy.no\0" +"ogawa.nagano.jp\0" +"reviews\0sch.so\0" +"am.gov.br\0ca.it\0irish\0" +"co.kr\0" +"co.lc\0sch.ss\0amica\0wedeploy.io\0" +"vic.gov.au\0" +"sch.tf\0" +"dovre.no\0mer\xc3\xa5ker.no\0reservd.disrec.thingdust.io\0" +"valle-daosta.it\0""2ix.ch\0" +"gs.tr.no\0kirkenes.no\0eu-central-1.elasticbeanstalk.com\0" +"educator.aero\0bloomberg\0" +"med.br\0candypop.jp\0" +"democracia.bo\0is-a-blogger.com\0" +"accident-prevention.aero\0co.ma\0" +"co.ls\0" +"co.me\0""2ix.de\0" +"co.mg\0gu.us\0taxi\0" +"coupon\0" +"balsan-suedtirol.it\0" +"ngrok.io\0" +"co.na\0" +"casino\0barsyonline.com\0" +"co.mu\0*.stg-builder.code.com\0" +"beskidy.pl\0" +"co.mw\0gs.st.no\0shop.brendly.rs\0from-ky.com\0blogspot.co.ke\0" +"yaotsu.gifu.jp\0" +"co.ni\0alpha-myqnapcloud.com\0" +"al.it\0co.mz\0*.cryptonomic.net\0" +"s3.ap-northeast-2.amazonaws.com\0" +"co.nl\0" +"ed.pw\0" +"med.ec\0co.no\0" +"nakano.tokyo.jp\0zarow.pl\0" +"med.ee\0" +"ogaki.gifu.jp\0" +"verdal.no\0" +"asago.hyogo.jp\0" +"fuchu.tokyo.jp\0sch.wf\0" +"jondal.no\0" +"co.nz\0" +"extraspace\0servebbs.com\0" +"ca.na\0co.om\0jed.wafaicloud.com\0" +"parti.se\0" +"to.leg.br\0" +"gs.sf.no\0balsfjord.no\0" +"hanoi.vn\0" +"exchange.aero\0recht.pro\0" +"tkmaxx\0" +"hoylandet.no\0" +"kinokawa.wakayama.jp\0" +"cloudsite.builders\0" +"co.pl\0" +"per.sg\0" +"aosta.it\0co.pn\0" +"*.moonscale.io\0" +"yamatotakada.nara.jp\0bialystok.pl\0" +"civilaviation.aero\0" +"independent-inquest.uk\0" +"prudential\0" +"club\0s3-deprecated.cn-north-1.amazonaws.com.cn\0freebox-os.fr\0" +"sandnes.no\0co.pw\0" +"s3-deprecated.us-west-2.amazonaws.com\0" +"laichau.vn\0" +"bplaced.de\0" +"quest\0" +"obu.aichi.jp\0" +"ap.gov.br\0" +"global.prod.fastly.net\0" +"chuo.fukuoka.jp\0" +"eu.org\0" +"contractors\0" +"brand.se\0" +"blogspot.co.nz\0" +"sch.zm\0" +"trentinostirol.it\0perso.sn\0" +"co.ro\0" +"med.ht\0sakura.tv\0" +"shari.hokkaido.jp\0" +"co.rs\0express\0" +"al.no\0" +"tamamura.gunma.jp\0" +"co.rw\0", + +"fukui.fukui.jp\0ap.gov.pl\0" +"perso.tn\0" +"execute-api.ap-southeast-3.amazonaws.com\0" +"fujishiro.ibaraki.jp\0" +"cv.ua\0fh-muenster.io\0\xd1\x8f.\xd1\x80\xd1\x83\xd1\x81\0" +"reggio-emilia.it\0co.st\0" +"kuroishi.aomori.jp\0" +"co.th\0" +"co.sz\0co.tj\0" +"\xe0\xb8\x84\xe0\xb8\xad\xe0\xb8\xa1\0" +"kota.aichi.jp\0" +"co.tm\0" +"toho.fukuoka.jp\0" +"hatinh.vn\0" +"emrstudio-prod.eu-north-1.amazonaws.com\0pointto.us\0workisboring.com\0co.ua\0ch.tc\0" +"toyonaka.osaka.jp\0krellian.net\0" +"k12.vi.us\0erni\0" +"co.tt\0" +"lefrak\0hosp.uk\0minisite.ms\0" +"ashoro.hokkaido.jp\0" +"moss.no\0co.ug\0" +"internet-dns.de\0" +"co.tz\0" +"co.uk\0" +"*.awsapprunner.com\0dyn-ip24.de\0hotelwithflight.com\0" +"tsuruga.fukui.jp\0imakane.hokkaido.jp\0uda.nara.jp\0" +"pharmacy\0" +"kinko.kagoshima.jp\0" +"co.us\0" +"geisei.kochi.jp\0" +"valer.ostfold.no\0co.ve\0s3-fips.us-west-2.amazonaws.com\0" +"kartuzy.pl\0swidnica.pl\0" +"co.vi\0auth-fips.us-gov-west-1.amazoncognito.com\0" +"\xe7\xbd\x91\xe7\xbb\x9c.cn\0co.uz\0" +"s3.dualstack.ap-southeast-1.amazonaws.com\0" +"ee.eu.org\0" +"akamaiorigin.net\0" +"richardli\0" +"kushima.miyazaki.jp\0" +"nobeoka.miyazaki.jp\0thainguyen.vn\0" +"med.ly\0" +"turin.it\0pfizer\0" +"tickets.io\0" +"melhus.no\0" +"canva-apps.cn\0" +"\xd8\xa8\xd8\xa7\xd8\xb2\xd8\xa7\xd8\xb1\0" +"ca.us\0nokia\0mozilla-iot.org\0" +"vall\xc3\xa9""eaoste.it\0olayan\0supabase.in\0" +"az.us\0endofinternet.org\0cloud-fr1.unispace.io\0" +"gol.no\0panasonic\0" +"ericsson\0" +"krokstadelva.no\0" +"jdf.br\0" +"customer.speedpartner.de\0" +"onza.mythic-beasts.com\0" +"med.om\0americanfamily\0" +"kyoto.jp\0toride.ibaraki.jp\0" +"r\xc3\xa1hkker\xc3\xa1vju.no\0as.us\0" +"rgr.jp\0" +"med.pa\0gos.pk\0\xd1\x81\xd0\xb0\xd0\xbc\xd0\xb0\xd1\x80\xd0\xb0.\xd1\x80\xd1\x83\xd1\x81\0" +"teshikaga.hokkaido.jp\0" +"co.za\0vfs.cloud9.ap-southeast-2.amazonaws.com\0" +"s3-website.cn-northwest-1.amazonaws.com.cn\0" +"\xd1\x81\xd0\xbe\xd1\x87\xd0\xb8.\xd1\x80\xd1\x83\xd1\x81\0" +"med.pl\0" +"skydiving.aero\0al.us\0emrnotebooks-prod.us-west-2.amazonaws.com\0" +"qsl.br\0fujieda.shizuoka.jp\0tmall\0" +"gs.mr.no\0finn\xc3\xb8y.no\0s3.ap-southeast-4.amazonaws.com\0" +"shoo.okayama.jp\0" +"langevag.no\0co.zm\0shiftedit.io\0" +"mmafan.biz\0" +"gjerdrum.no\0kongsvinger.no\0auth.ap-northeast-1.amazoncognito.com\0" +"fujitsu\0" +"tozawa.yamagata.jp\0" +"oystre-slidre.no\0yombo.me\0" +"art.br\0samsclub\0" +"\xe7\xbd\x91\xe7\xbb\x9c.hk\0co.zw\0" +"valdaosta.it\0" +"kosaka.akita.jp\0" +"ciencia.bo\0" +"natura\0" +"moriguchi.osaka.jp\0" +"kannami.shizuoka.jp\0" +"s3-us-west-2.amazonaws.com\0" +"from-md.com\0dray-dns.de\0" +"dynu.net\0" +"minamimaki.nagano.jp\0" +"services.aero\0" +"med.sa\0" +"asaka.saitama.jp\0" +"u.bg\0affinitylottery.org.uk\0" +"med.sd\0hoplix.shop\0" +"art.do\0is-a-linux-user.org\0blogspot.co.za\0" +"tecnologia.bo\0" +"viterbo.it\0beep.pl\0" +"askoy.no\0pvt.k12.ma.us\0" +"sth.ac.at\0" +"lierne.no\0cust.prod.thingdust.io\0" +"frosinone.it\0" +"n.bg\0" +"art.dz\0" +"mazeplay.com\0" +"us-east-1.elasticbeanstalk.com\0" +"wada.nagano.jp\0kikirara.jp\0" +"lebtimnetz.de\0supabase.co\0" +"tsukui.kanagawa.jp\0" +"conn.uk\0" +"off.ai\0" +"inatsuki.fukuoka.jp\0" +"g.bg\0" +"dynalias.net\0" +"vic.edu.au\0" +"ancona.it\0" +"g\xc3\xa1ivuotna.no\0solund.no\0" +"accident-investigation.aero\0\xe7\xb5\x84\xe7\xb9\x94.\xe9\xa6\x99\xe6\xb8\xaf\0lamborghini\0" +"online\0" +"matera.it\0" +"magnet.page\0" +"malatvuopmi.no\0" +"actor\0akamaiedge-staging.net\0whm.fr-par.scw.cloud\0" +"sobetsu.hokkaido.jp\0wiih.gov.pl\0" +"hirono.fukushima.jp\0*.webhare.dev\0" +"uri.arpa\0" +"activetrail.biz\0" +"shinkamigoto.nagasaki.jp\0" +"from-tn.com\0" +"mosvik.no\0" +"nemuro.hokkaido.jp\0matsuzaki.shizuoka.jp\0" +"okuma.fukushima.jp\0" +"foggia.it\0" +"chiryu.aichi.jp\0" +"club.aero\0tysnes.no\0from-fl.com\0" +"art.ht\0" +"cloud.fedoraproject.org\0" +"cc.md.us\0" +"akaiwa.okayama.jp\0" +"nishinoomote.kagoshima.jp\0" +"s3.dualstack.us-west-1.amazonaws.com\0" +"shiraoi.hokkaido.jp\0custom.metacentrum.cz\0" +"bod\xc3\xb8.no\0" +"maniwa.okayama.jp\0" +"\xd8\xa7\xd8\xb1\xd8\xa7\xd9\x85\xd9\x83\xd9\x88\0" +"loginline.io\0" +"soja.okayama.jp\0tsurugashima.saitama.jp\0" +"me-south-1.elasticbeanstalk.com\0" +"seranishi.hiroshima.jp\0swinoujscie.pl\0" +"ikoma.nara.jp\0platform0.app\0" +"east-kazakhstan.su\0" +"tokorozawa.saitama.jp\0" +"lunner.no\0is-a-nascarfan.com\0" +"k12.ny.us\0" +"higashikurume.tokyo.jp\0citadel\0sharp\0" +"s3-website.dualstack.eu-central-1.amazonaws.com\0" +"solutions\0" +"ogawara.miyagi.jp\0kumatori.osaka.jp\0" +"*.alces.network\0vfs.cloud9.eu-west-2.amazonaws.com\0" +"kiwi.nz\0crafting.xyz\0" +"vibo-valentia.it\0" +"cyon.site\0" +"\xe8\xb4\xad\xe7\x89\xa9\0logoip.com\0" +"piedmont.it\0" +"dyn-berlin.de\0" +"6.bg\0" +"delhi.in\0bacninh.vn\0" +"k12.ms.us\0k12.nc.us\0" +"auth.ap-southeast-1.amazoncognito.com\0" +"ind.br\0clan.rip\0" +"bentley\0" +"origins\0studio.ap-northeast-1.sagemaker.aws\0spacekit.io\0" +"deca.jp\0" +"trentinos\xc3\xbc""d-tirol.it\0futtsu.chiba.jp\0" +"skiptvet.no\0" +"sandcats.io\0" +"ebino.miyazaki.jp\0miyota.nagano.jp\0" +"*.hosting.myjino.ru\0" +"pomorze.pl\0" +"k12.me.us\0emrstudio-prod.me-central-1.amazonaws.com\0" +"shirataka.yamagata.jp\0" +"sauherad.no\0hopto.me\0" +"theshop.jp\0" +"execute-api.af-south-1.amazonaws.com\0s3-accesspoint.us-gov-east-1.amazonaws.com\0is-a-personaltrainer.com\0" +"crown\0star\0" +"agents.aero\0" +"yamatokoriyama.nara.jp\0" +"kodaira.tokyo.jp\0" +"s3-accesspoint.us-west-2.amazonaws.com\0" +"r\xc3\xa1isa.no\0" +"is-a-socialist.com\0" +"x.mythic-beasts.com\0" +"kakuda.miyagi.jp\0urawa.saitama.jp\0" +"roma.it\0shibata.niigata.jp\0" +"shinjo.okayama.jp\0oia.gov.pl\0" +"is-not-certified.com\0" +"cc.il.us\0" +"aus.basketball\0" +"cn.eu.org\0" +"flights\0" +"art.pl\0" +"recipes\0" +"academy\0" +"blogspot.vn\0" +"katsushika.tokyo.jp\0homesklep.pl\0" +"pythonanywhere.com\0" +"ltda\0" +"polkowice.pl\0ngrok-free.app\0" +"ohira.miyagi.jp\0" +"gangaviika.no\0" +"kaufen\0" +"moareke.no\0" +"ind.gt\0sumida.tokyo.jp\0" +"is-an-accountant.com\0" +"hjelmeland.no\0" +"shibecha.hokkaido.jp\0*.lclstage.dev\0" +"ilawa.pl\0" +"osaki.miyagi.jp\0" +"nom.ad\0isa.kagoshima.jp\0" +"kurotaki.nara.jp\0" +"nom.ag\0" +"takamori.kumamoto.jp\0" +"demo.jelastic.com\0" +"lig.it\0rikubetsu.hokkaido.jp\0hanno.saitama.jp\0" +"s3-website.ap-northeast-3.amazonaws.com\0" +"tokyo.jp\0" +"ipiranga\0" +"art.sn\0" +"emergency.aero\0*.transurl.be\0" +"not.br\0ind.in\0" +"qbuser.com\0" +"mysecuritycamera.net\0" +"ringebu.no\0selje.no\0" +"bar2.net\0" +"finnoy.no\0odessa.ua\0" +"is-a-soxfan.org\0" +"kitahiroshima.hokkaido.jp\0" +"k12.in.us\0loans\0" +"yk.ca\0blogspot.re\0mintere.site\0" +"auth.sa-east-1.amazoncognito.com\0" +"wakayama.jp\0naka.hiroshima.jp\0" +"blogspot.ro\0" +"\xe6\x94\xbf\xe5\xba\x9c.\xe9\xa6\x99\xe6\xb8\xaf\0s3.dualstack.me-south-1.amazonaws.com\0is-by.us\0" +"u.se\0emrappui-prod.me-central-1.amazonaws.com\0blogspot.rs\0" +"conference.aero\0nom.co\0blogspot.ru\0blogspot.se\0" +"oizumi.gunma.jp\0ryokami.saitama.jp\0" +"*.ap-south-1.airflow.amazonaws.com\0blogspot.sg\0" +"analytics-gateway.eu-central-1.amazonaws.com\0blogspot.si\0" +"ohi.fukui.jp\0" +"trogstad.no\0blogspot.sk\0*.quipelements.com\0" +"blogspot.sn\0" +"jobs\0iopsys.se\0" +"miasa.nagano.jp\0yazu.tottori.jp\0rehab\0" +"n.se\0" +"hikimi.shimane.jp\0" +"ind.kw\0fairwinds\0s3.dualstack.eu-south-1.amazonaws.com\0cy.eu.org\0" +"blogspot.td\0" +"isa.us\0" +"olawa.pl\0""3.azurestaticapps.net\0" +"kutno.pl\0church\0" +"asahikawa.hokkaido.jp\0" +"is-a-knight.org\0" +"g.se\0" +"bloxcms.com\0" +"racing\0s3-website.dualstack.eu-west-3.amazonaws.com\0" +"inashiki.ibaraki.jp\0uw.gov.pl\0doctor\0" +"blogspot.tw\0blogspot.ug\0" +"fnd.br\0shika.ishikawa.jp\0" +"nom.es\0cloud66.zone\0*.transurl.eu\0" +"ogose.saitama.jp\0koge.tottori.jp\0" +"knightpoint.systems\0*.paywhirl.com\0" +"yurihonjo.akita.jp\0" +"fishing\0" +"blogspot.mr\0" +"cz.eu.org\0" +"pisa.it\0!city.kobe.jp\0wassamu.hokkaido.jp\0zp.gov.pl\0" +"nom.fr\0blogspot.mx\0" +"arendal.no\0blogspot.my\0" +"blogspot.nl\0" +"wa.au\0" +"pistoia.it\0yamanobe.yamagata.jp\0gb.net\0" +"blogspot.no\0" +"abeno.osaka.jp\0" +"forli-cesena.it\0chuo.tokyo.jp\0" +"visa\0" +"community-pro.net\0" +"webview-assets.aws-cloud9.us-west-1.amazonaws.com\0" +"ikeda.fukui.jp\0" +"natural.bo\0living\0dk.eu.org\0" +"blogspot.pe\0" +"daisen.akita.jp\0" +"daiwa.hiroshima.jp\0" +"us.ax\0" +"game-server.cc\0freeddns.org\0" +"armenia.su\0" +"leksvik.no\0blogspot.qa\0" +"toga.toyama.jp\0" +"blogspot.pt\0" +"itcouldbewor.se\0" +"tosa.kochi.jp\0" +"s3-website.eu-south-2.amazonaws.com\0" +"americanexpress\0" +"higashikagura.hokkaido.jp\0moriya.ibaraki.jp\0" +"riobranco.br\0podlasie.pl\0design\0" +"s3-object-lambda.eu-central-2.amazonaws.com\0" +"nishio.aichi.jp\0freetls.fastly.net\0" +"s3-website.dualstack.ap-northeast-2.amazonaws.com\0" +"nomi.ishikawa.jp\0konan.shiga.jp\0" +"blogspot.is\0" +"blogspot.it\0" +"tamatsukuri.ibaraki.jp\0chizu.tottori.jp\0under.jp\0" +"jan-mayen.no\0b\xc3\xa5""d\xc3\xa5""ddj\xc3\xa5.no\0\xe5\x80\x8b\xe4\xba\xba.\xe9\xa6\x99\xe6\xb8\xaf\0" +"bolzano-altoadige.it\0" +"viva\0s3-accesspoint.dualstack.af-south-1.amazonaws.com\0" +"garden\0" +"\xd8\xa7\xd8\xa8\xd9\x88\xd8\xb8\xd8\xa8\xd9\x8a\0" +"blogspot.jp\0" +"blogsite.xyz\0" +"nom.km\0" +"napoli.it\0rj.leg.br\0" +"vivo\0" +"lib.ri.us\0bestbuy\0" +"hisamitsu\0emrnotebooks-prod.us-gov-west-1.amazonaws.com\0" +"zgorzelec.pl\0" +"team\0" +"yaese.okinawa.jp\0blogspot.kr\0" +"de.eu.org\0" +"zagan.pl\0" +"tarumizu.kagoshima.jp\0" +"fukushima.fukushima.jp\0" +"blogspot.li\0" +"ind.tn\0" +"kagoshima.jp\0wanouchi.gifu.jp\0barsy.support\0" +"nom.mg\0travelersinsurance\0" +"kira.aichi.jp\0oschr.gov.pl\0" +"bato.tochigi.jp\0" +"translate.goog\0" +"soni.nara.jp\0" +"\xe5\xb9\xbf\xe4\xb8\x9c\0blogspot.lt\0blogspot.md\0" +"nord-odal.no\0blogspot.lu\0" +"nom.nc\0" +"adm.br\0nachikatsuura.wakayama.jp\0" +"nog.community\0blogspot.mk\0" +"tech\0" +"co.place\0" +"cosenza.it\0itami.hyogo.jp\0" +"nom.ni\0property\0" +"*.transurl.nl\0" +"rakkestad.no\0" +"elasticbeanstalk.com\0from-wy.com\0" +"myftp.biz\0" +"k12.ct.us\0" +"teramo.it\0ina.nagano.jp\0" +"blogspot.fi\0" +"fin.ci\0" +"nanao.ishikawa.jp\0" +"pila.pl\0" +"blogspot.fr\0" +"exposed\0punyu.jp\0" +"nom.pa\0" +"shibata.miyagi.jp\0" +"hikari.yamaguchi.jp\0lawyer\0" +"nom.pe\0" +"selbu.no\0" +"moriyama.shiga.jp\0szczytno.pl\0grainger\0" +"\xe6\x96\xb0\xe9\x97\xbb\0" +"us.in\0nom.pl\0blogspot.gr\0" +"shop.ht\0kawasaki.miyagi.jp\0" +"fin.ec\0shop.hu\0" +"psi.br\0hino.tottori.jp\0" +"vc.it\0zao.miyagi.jp\0" +"execute-api.sa-east-1.amazonaws.com\0" +"blogspot.hk\0" +"tank.jp\0" +"ibaraki.osaka.jp\0akishima.tokyo.jp\0" +"gallo\0" +"soc.dz\0ichikawamisato.yamanashi.jp\0" +"genkai.saga.jp\0blogspot.hr\0" +"hemne.no\0" +"tateshina.nagano.jp\0" +"blogspot.hu\0blogspot.ie\0" +"ce.gov.br\0cool\0meet\0" +"hammarfeasta.no\0" +"ujitawara.kyoto.jp\0" +"coop\0sener\0" +"nom.re\0zp.ua\0rag-cloud.hosteur.com\0us.kg\0" +"lib.oh.us\0" +"r2.dev\0blogspot.in\0" +"blogspot.ba\0" +"fukuchi.fukuoka.jp\0" +"medecin.km\0siljan.no\0forumz.info\0" +"angry.jp\0" +"nom.ro\0blogspot.be\0" +"blogspot.bg\0weeklylottery.org.uk\0" +"otsuki.yamanashi.jp\0storipress.app\0" +"forgeblocks.com\0" +"blogspot.bj\0" +"abc.br\0" +"seljord.no\0" +"chuo.yamanashi.jp\0" +"blogspot.ca\0" +"tn.it\0\xe7\xa7\x8b\xe7\x94\xb0.jp\0ashibetsu.hokkaido.jp\0" +"myspreadshop.co.uk\0" +"tel.tr\0blogspot.cf\0" +"torsken.no\0" +"blogspot.ch\0" +"h\xc3\xa1pmir.no\0" +"owani.aomori.jp\0" +"k12.az.us\0" +"balsan-sudtirol.it\0blogspot.cl\0" +"s3-ap-south-1.amazonaws.com\0" +"barsy.net\0" +"obihiro.hokkaido.jp\0" +"s3-fips.dualstack.us-east-1.amazonaws.com\0" +"hammerfest.no\0nom.tm\0ca.eu.org\0dnsiskinky.com\0wellbeingzone.eu\0" +"us.na\0blogspot.de\0" +"owariasahi.aichi.jp\0greater.jp\0blogspot.cv\0" +"yamatsuri.fukushima.jp\0" +"kizu.kyoto.jp\0blogspot.cz\0" +"\xe6\x94\xbf\xe5\x8a\xa1\0blogspot.dk\0yolasite.com\0" +"localzone.xyz\0""32-b.it\0" +"kids.us\0exchange\0simple-url.com\0" +"sp.it\0mitake.gifu.jp\0" +"\xc3\xa5""fjord.no\0" +"koto.tokyo.jp\0" +"hacca.jp\0" +"lib.md.us\0" +"messina.it\0kamikawa.saitama.jp\0" +"k12.al.us\0" +"tendo.yamagata.jp\0karpacz.pl\0" +"lab.ms\0" +"\xd8\xa7\xd9\x84\xd8\xb9\xd9\x84\xd9\x8a\xd8\xa7\xd9\x86\0" +"fla.no\0nom.ve\0video\0nyaa.am\0" +"mus.br\0si.it\0sumoto.kumamoto.jp\0yasaka.nagano.jp\0hidaka.wakayama.jp\0" +"kr.com\0" +"hatoyama.saitama.jp\0" +"tranibarlettaandria.it\0" +"basketball\0locker\0selfip.net\0" +"schools.nsw.edu.au\0" +"nid.io\0" +"makeup\0" +"doomdns.com\0" +"neat-url.com\0" +"okagaki.fukuoka.jp\0mail-box.ne.jp\0" +"omigawa.chiba.jp\0" +"prd.fr\0" +"katowice.pl\0" +"ns.ca\0" +"s3.dualstack.ap-northeast-1.amazonaws.com\0" +"hiji.oita.jp\0johana.toyama.jp\0" +"servegame.com\0" +"kitakata.miyazaki.jp\0" +"yuki.ibaraki.jp\0kudoyama.wakayama.jp\0" +"soc.lk\0wv.us\0" +"joinville.br\0\xe5\xae\xae\xe5\xb4\x8e.jp\0minamiise.mie.jp\0" +"nl.ca\0" +"yono.saitama.jp\0" +"dating\0dynalias.org\0" +"meme\0d.gv.vc\0from-pr.com\0" +"jaworzno.pl\0main.jp\0" +"lindesnes.no\0nl.ci\0" +"norton\0webhop.biz\0" +"from-wi.com\0" +"pesaro-urbino.it\0\xe4\xb8\x96\xe7\x95\x8c\0" +"s3-website.ap-south-2.amazonaws.com\0" +"\xc3\xb8rskog.no\0" +"blogspot.ae\0" +"um.gov.pl\0" +"nom.za\0" +"s3-object-lambda.ap-northeast-3.amazonaws.com\0" +"etc.br\0" +"zombie.jp\0blogspot.al\0" +"mosj\xc3\xb8""en.no\0blogspot.am\0" +"analytics-gateway.ap-south-1.amazonaws.com\0""1337.pictures\0" +"emrstudio-prod.af-south-1.amazonaws.com\0" +"pv.it\0edu.krd\0" +"games\0cd.eu.org\0" +"v\xc3\xa1rgg\xc3\xa1t.no\0cust.dev.thingdust.io\0" +"uz.ua\0menu\0" +"lib.in.us\0" +"!city.nagoya.jp\0" +"wa.us\0" +"higashiizumo.shimane.jp\0forte.id\0" +"kawaguchi.saitama.jp\0clickrising.net\0" +"po.it\0" +"s3-object-lambda.af-south-1.amazonaws.com\0dyndns.info\0logoip.de\0" +"diadem.cloud\0" +"e164.arpa\0" +"kiyokawa.kanagawa.jp\0kanzaki.saga.jp\0" +"kumakogen.ehime.jp\0rr.leg.br\0" +"sdn.gov.pl\0" +"prd.km\0" +"ascoli-piceno.it\0wnext.app\0" +"video.hu\0ngo.lk\0" +"lier.no\0" +"baidar.no\0shangrila\0" +"akdn\0" +"lodingen.no\0" +"mugi.tokushima.jp\0" +"hashimoto.wakayama.jp\0skr.jp\0" +"lardal.no\0stryn.no\0" +"surf\0" +"pa.it\0schmidt\0" +"boxfuse.io\0from-dc.com\0" +"emilia-romagna.it\0udono.mie.jp\0" +"emrappui-prod.me-south-1.amazonaws.com\0" +"*.ocs.customer-oci.com\0" +"muroran.hokkaido.jp\0mimata.miyazaki.jp\0" +"lincoln\0" +"prd.mg\0" +"us.gov.pl\0" +"s3-object-lambda.eu-south-1.amazonaws.com\0" +"rs.leg.br\0sc.leg.br\0" +"ngo.ng\0" +"choyo.kumamoto.jp\0nakagawa.nagano.jp\0" +"vgs.no\0fhsk.se\0s3.dualstack.il-central-1.amazonaws.com\0" +"witd.gov.pl\0" +"mysecuritycamera.org\0" +"tomika.gifu.jp\0" +"emrstudio-prod.eu-west-3.amazonaws.com\0" +"funabashi.chiba.jp\0health\0" +"horse\0id.repl.co\0" +"shimokawa.hokkaido.jp\0" +"s3-object-lambda.us-west-1.amazonaws.com\0" +"okazaki.aichi.jp\0" +"folkebibl.no\0" +"durban\0" +"law.za\0" +"\xe4\xb8\x89\xe9\x87\x8d.jp\0toya.hokkaido.jp\0" +"tn.us\0" +"wskr.gov.pl\0dnsalias.net\0" +"wafflecell.com\0" +"myvnc.com\0" +"arts.co\0" +"ngo.ph\0" +"safety.aero\0progressive\0" +"trentinsud-tirol.it\0miyazu.kyoto.jp\0qpon\0ch.trendhosting.cloud\0" +"fin.tn\0" +"zappos\0" +"izu.shizuoka.jp\0" +"arte.bo\0teva\0" +"jus.br\0koshigaya.saitama.jp\0" +"barsy.pro\0" +"arakawa.tokyo.jp\0" +"lib.ga.us\0" +"shizukuishi.iwate.jp\0nagahama.shiga.jp\0" +"nexus\0leadpages.co\0" +"ne.jp\0" +"verran.no\0" +"mn.it\0hatogaya.saitama.jp\0takatsuki.shiga.jp\0" +"gotdns.com\0u2-local.xnbay.com\0" +"ne.ke\0" +"sb.ua\0" +"miyoshi.tokushima.jp\0" +"android\0" +"larvik.no\0" +"suli.hu\0framer.media\0" +"saobernardo.br\0\xe6\x96\xb0\xe6\xbd\x9f.jp\0tenri.nara.jp\0ne.kr\0" +"her\xc3\xb8y.nordland.no\0" +"inzai.chiba.jp\0motobu.okinawa.jp\0" +"kawaba.gunma.jp\0" +"barsy.pub\0" +"pmn.it\0iwanai.hokkaido.jp\0" +"wa.gov.au\0" +"doesntexist.com\0" +"chikushino.fukuoka.jp\0" +"iglesias-carbonia.it\0futaba.fukushima.jp\0mima.tokushima.jp\0" +"bulsan-s\xc3\xbc""dtirol.it\0" +"luxe\0" +"fukudomi.saga.jp\0shop.th\0rn.leg.br\0" +"iijima.nagano.jp\0" +"li.it\0tohnosho.chiba.jp\0" +"jprs\0" +"nl.no\0" +"kamifurano.hokkaido.jp\0" +"hof.no\0" +"cheap.jp\0" +"oslo.no\0lerdal.no\0" +"kr.it\0" +"lublin.pl\0" +"chtr.k12.ma.us\0ox.rs\0" +"jcloud-ver-jpc.ik-server.com\0" +"small-web.org\0" +"higashinaruse.akita.jp\0bytom.pl\0" +"gz.cn\0bacgiang.vn\0" +"webview-assets.aws-cloud9.ap-east-1.amazonaws.com\0" +"go.gov.br\0" +"ro.leg.br\0medecin.fr\0" +"ishikari.hokkaido.jp\0" +"trentino-s\xc3\xbc""d-tirol.it\0" +"akita.jp\0hiroo.hokkaido.jp\0" +"shop.ro\0" +"carrd.co\0" +"gs.cn\0" +"reise\0" +"s3-accesspoint.dualstack.il-central-1.amazonaws.com\0" +"haboro.hokkaido.jp\0global\0" +"ap-northeast-1.elasticbeanstalk.com\0x443.pw\0" +"matsuno.ehime.jp\0" +"toscana.it\0" +"\xc3\xb8vre-eiker.no\0" +"s3.dualstack.af-south-1.amazonaws.com\0" +"rifu.miyagi.jp\0" +"fastlylb.net\0fireweb.app\0" +"kameyama.mie.jp\0" +"ne.pw\0ravendb.me\0" +"trentinsuedtirol.it\0" +"inagawa.hyogo.jp\0" +"post.in\0shop.pl\0" +"kirovograd.ua\0" +"s3-accesspoint-fips.us-west-2.amazonaws.com\0" +"toyoake.aichi.jp\0" +"haugesund.no\0" +"s3-accesspoint.me-central-1.amazonaws.com\0" +"daigo.ibaraki.jp\0" +"io.in\0sakai.ibaraki.jp\0ivory.ne.jp\0" +"pa.us\0" +"from.hr\0*.elb.amazonaws.com.cn\0" +"\xe7\xbe\xa4\xe9\xa6\xac.jp\0s3.isk01.sakurastorage.jp\0" +"nt.edu.au\0" +"df.leg.br\0" +"ngo.za\0locus\0" +"aostavalley.it\0" +"ismaili\0" +"izumi.kagoshima.jp\0kanan.osaka.jp\0" +"iida.nagano.jp\0" +"ddnsfree.com\0" +"iiyama.nagano.jp\0" +"software\0" +"ako.hyogo.jp\0" +"arts.ve\0altervista.org\0" +"macapa.br\0" +"baclieu.vn\0" +"mlbfan.org\0io.kg\0" +"miyake.nara.jp\0" +"kiyosu.aichi.jp\0" +"navigation.aero\0bnpparibas\0mitsubishi\0" +"moseushi.hokkaido.jp\0aero.tt\0\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0" +"test-iserv.de\0" +"mifune.kumamoto.jp\0" +"helsinki\0" +"64-b.it\0" +"scrapper-site.net\0" +"vinnytsia.ua\0" +"setagaya.tokyo.jp\0" +"lavagis.no\0ne.ug\0" +"opencraft.hosting\0" +"aero.mv\0ne.tz\0" +"taipei\0" +"samegawa.fukushima.jp\0" +"s3-accesspoint.ap-southeast-4.amazonaws.com\0" +"lib.az.us\0" +"otobe.hokkaido.jp\0toyoura.hokkaido.jp\0uenohara.yamanashi.jp\0" +"karm\xc3\xb8y.no\0ne.us\0analytics\0" +"hokkaido.jp\0" +"ouda.nara.jp\0nanbu.yamanashi.jp\0" +"games.hu\0" +"loginline.dev\0" +"mn.us\0" +"even\xc3\xa1\xc5\xa1\xc5\xa1i.no\0" +"dsmynas.org\0" +"sinaapp.com\0" +"toyotomi.hokkaido.jp\0yamaga.kumamoto.jp\0" +"promo\0" +"langev\xc3\xa5g.no\0" +"balsan-s\xc3\xbc""dtirol.it\0" +"dy.fi\0" +"ge.it\0service.gov.scot\0" +"from-me.org\0" +"makinohara.shizuoka.jp\0" +"arts.ro\0quebec\0technology\0hk.com\0" +"casino.hu\0" +"\xe4\xb8\xad\xe4\xbf\xa1\0" +"krasnodar.su\0" +"nat.tn\0" +"kr.ua\0" +"hopto.org\0" +"ebina.kanagawa.jp\0" +"trainer.aero\0ky.us\0shopware.store\0" +"ent.platform.sh\0" +"chosei.chiba.jp\0unzen.nagasaki.jp\0" +"travelers\0backplaneapp.io\0" +"fg.it\0saka.hiroshima.jp\0uto.kumamoto.jp\0" +"barsy.org\0" +"merseine.nu\0" +"saijo.ehime.jp\0tanabe.kyoto.jp\0haugiang.vn\0" +"ryd.wafaicloud.com\0" +"*.telebit.xyz\0" +"notebook.eu-south-2.sagemaker.aws\0vfs.cloud9.eu-central-1.amazonaws.com\0wellbeingzone.co.uk\0" +"salerno.it\0ostrowwlkp.pl\0" +"likescandy.com\0" +"lundbeck\0" +"binhthuan.vn\0" +"klepp.no\0" +"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0se.leg.br\0" +"ac.ae\0chernivtsi.ua\0" +"her\xc3\xb8y.m\xc3\xb8re-og-romsdal.no\0" +"aioi.hyogo.jp\0tsunan.niigata.jp\0arts.nf\0" +"ueno.gunma.jp\0cloudapp.net\0" +"ch.eu.org\0" +"dr.in\0yorii.saitama.jp\0" +"ollo\0" +"ac.at\0" +"ac.be\0vfs.cloud9.af-south-1.amazonaws.com\0" +"shell\0" +"corsica\0" +"\xe5\xa4\xa7\xe5\x88\x86.jp\0" +"shimabara.nagasaki.jp\0" +"uruma.okinawa.jp\0naklo.pl\0" +"ac.ci\0chimkent.su\0" +"reserve-online.net\0" +"aerobatic.aero\0naustdal.no\0" +"ac.cn\0" +"moskenes.no\0" +"ac.cr\0ct.it\0" +"*.kawasaki.jp\0seihi.nagasaki.jp\0" +"stavern.no\0" +"s3-object-lambda.us-east-1.amazonaws.com\0" +"ac.cy\0ally\0" +"industria.bo\0patria.bo\0" +"trondheim.no\0" +"friuliveneziagiulia.it\0" +"kaszuby.pl\0" +"edu.ac\0" +"loisirs.bj\0kishiwada.osaka.jp\0" +"edu.af\0io.vn\0" +"data\0""123hjemmeside.no\0" +"odate.akita.jp\0upper.jp\0" +"emrappui-prod.ap-southeast-2.amazonaws.com\0br.com\0" +"date\0" +"edu.al\0" +"edu.ba\0gjerstad.no\0potager.org\0" +"edu.ar\0edu.bb\0" +"dr.na\0" +"dentist\0" +"edu.au\0www.ro\0" +"ia.us\0s3-accesspoint.eu-central-1.amazonaws.com\0" +"edu.bh\0terni.it\0" +"edu.bi\0drammen.no\0" +"edu.az\0edu.bj\0ac.fj\0" +"bo.it\0kamisunagawa.hokkaido.jp\0" +"edu.bm\0" +"edu.bn\0" +"edu.bo\0oya.to\0" +"s3.dualstack.us-west-2.amazonaws.com\0" +"edu.br\0" +"edu.bs\0" +"edu.bt\0ikeda.osaka.jp\0" +"\xe6\x95\x99\xe8\x82\xb2.\xe9\xa6\x99\xe6\xb8\xaf\0" +"vads\xc3\xb8.no\0" +"zachpomor.pl\0" +"edu.ci\0" +"edu.bz\0" +"cbg.ru\0" +"misasa.tottori.jp\0" +"edu.cn\0ac.gn\0" +"edu.co\0lasalle\0" +"trapani.it\0ogata.akita.jp\0bentre.vn\0" +"verbania.it\0kashiwazaki.niigata.jp\0" +"studio.af-south-1.sagemaker.aws\0" +"beta.tailscale.net\0" +"edu.cu\0" +"edu.cv\0" +"edu.cw\0\xd0\xb1\xd0\xb5\xd0\xbb\0studio.us-east-2.sagemaker.aws\0" +"aq.it\0ba.it\0" +"philips\0s3.sa-east-1.amazonaws.com\0" +"edu.dm\0kongsberg.no\0campaign.gov.uk\0" +"saotome.st\0" +"edu.do\0notteroy.no\0" +"habikino.osaka.jp\0" +"joyo.kyoto.jp\0fly.dev\0pcloud.host\0" +"edu.ec\0stjordal.no\0vfs.cloud9.eu-west-1.amazonaws.com\0" +"ac.id\0" +"edu.ee\0*.vultrobjects.com\0" +"naoshima.kagawa.jp\0" +"edu.eg\0" +"vanylven.no\0drr.ac\0" +"edu.dz\0" +"authgearapps.com\0" +"ac.il\0" +"ac.im\0l\xc3\xb8""dingen.no\0" +"ac.in\0" +"at.eu.org\0" +"6g.in\0" +"ac.ir\0minamiminowa.nagano.jp\0" +"edu.es\0selfip.org\0myqnapcloud.com\0" +"edu.et\0map.fastlylb.net\0" +"ltd.cy\0edu.fm\0" +"ac.jp\0wuoz.gov.pl\0" +"eid.no\0pages.wiardweb.com\0" +"starostwo.gov.pl\0" +"edu.gd\0" +"edu.ge\0ac.ke\0" +"canva-apps.com\0" +"edu.gh\0hanamigawa.chiba.jp\0" +"trading.aero\0edu.gi\0emrappui-prod.ap-northeast-3.amazonaws.com\0" +"auth.us-west-1.amazoncognito.com\0" +"edu.gl\0ohtawara.tochigi.jp\0" +"enterprises\0" +"edu.gn\0gmina.pl\0" +"s3.us-east-1.amazonaws.com\0myspreadshop.com\0" +"edu.gp\0" +"trade\0" +"edu.gr\0ac.kr\0" +"feira.br\0edu.gt\0" +"edu.gu\0shouji\0" +"onflashdrive.app\0" +"vacations\0schulserver.de\0" +"edu.gy\0photos\0" +"edu.hk\0ac.lk\0" +"lecce.it\0wloclawek.pl\0from.tv\0" +"edu.hn\0" +"kashiwara.osaka.jp\0tjmaxx\0" +"ac.ma\0" +"ac.ls\0n\xc3\xa5\xc3\xa5mesjevuemie.no\0" +"edu.ht\0dr.tr\0" +"ac.me\0s3-website.eu-central-2.amazonaws.com\0" +"museum.tt\0" +"amex\0free.hr\0" +"troandin.no\0stada\0ooguy.com\0" +"is-found.org\0" +"ltd.gi\0karmoy.no\0s3-fips.dualstack.us-west-2.amazonaws.com\0" +"edu.in\0" +"auth.eu-west-3.amazoncognito.com\0" +"edu.iq\0" +"edu.is\0" +"edu.it\0" +"ac.mu\0s3-accesspoint-fips.us-west-1.amazonaws.com\0" +"ac.mw\0" +"mitaka.tokyo.jp\0stalowa-wola.pl\0" +"ac.ni\0s3-eu-central-1.amazonaws.com\0" +"ac.mz\0" +"notebook.us-east-1.sagemaker.aws\0" +"eu-west-3.elasticbeanstalk.com\0" +"kurashiki.okayama.jp\0velvet.jp\0" +"edu.jo\0ltd.hk\0" +"est-le-patron.com\0" +"notogawa.shiga.jp\0" +"123hjemmeside.dk\0" +"webview-assets.cloud9.ap-northeast-2.amazonaws.com\0" +"edu.kg\0" +"edu.ki\0" +"ac.nz\0faith\0" +"kasumigaura.ibaraki.jp\0otoyo.kochi.jp\0" +"edu.km\0fetsund.no\0" +"furukawa.miyagi.jp\0bungotakada.oita.jp\0edu.kn\0" +"edu.kp\0" +"edu.la\0lind\xc3\xa5s.no\0ac.pa\0ct.us\0" +"edu.lb\0" +"edu.lc\0cc.sd.us\0" +"opoczno.pl\0\xe1\x83\x92\xe1\x83\x94\0" +"edu.kw\0" +"edu.ky\0" +"edu.kz\0lebork.pl\0online.th\0" +"edu.lk\0" +"ogawa.saitama.jp\0" +"s3-website.ap-southeast-3.amazonaws.com\0" +"edu.lr\0ac.pr\0" +"edu.ls\0*.ap-northeast-2.airflow.amazonaws.com\0" +"shinto.gunma.jp\0" +"edu.me\0nordreisa.no\0" +"edu.lv\0" +"edu.mg\0nordre-land.no\0" +"gyeonggi.kr\0" +"edu.ly\0s3-accesspoint.dualstack.ap-east-1.amazonaws.com\0" +"sdscloud.pl\0" +"edu.mk\0" +"edu.ml\0author\0" +"fastvps.site\0\xd0\xbc\xd0\xb8\xd1\x80.\xd1\x80\xd1\x83\xd1\x81\0" +"edu.mn\0eastus2.azurestaticapps.net\0" +"edu.mo\0gs.ol.no\0" +"training\0" +"edu.ms\0voss.no\0" +"edu.mt\0green\0" +"edu.mv\0" +"edu.mw\0edu.ng\0u2.xnbay.com\0" +"edu.mx\0" +"edu.my\0edu.ni\0" +"edu.mz\0" +"arakawa.saitama.jp\0adobeaemcloud.net\0" +"productions\0" +"*.yokohama.jp\0atl.jelastic.vps-host.net\0" +"ltd.lk\0notebook.eu-north-1.sagemaker.aws\0" +"log.br\0" +"dnsalias.org\0" +"edu.nr\0" +"ac.rs\0degree\0" +"ac.se\0ac.ru\0pagexl.com\0myshopify.com\0" +"ac.rw\0rocky.page\0" +"kahoku.yamagata.jp\0" +"edu.om\0place\0" +"es-1.axarnet.cloud\0" +"fylkesbibl.no\0" +"ariake.saga.jp\0" +"edu.pa\0*.platformsh.site\0" +"caxias.br\0" +"s\xc3\xb8gne.no\0" +"semboku.akita.jp\0" +"edu.pe\0" +"edu.pf\0pages.torproject.net\0" +"sakaiminato.tottori.jp\0edu.ph\0ac.th\0" +"ac.sz\0ac.tj\0kuron.jp\0" +"edu.pk\0ltd.ng\0" +"iheya.okinawa.jp\0wajiki.tokushima.jp\0edu.pl\0" +"edu.pn\0phuyen.vn\0now-dns.net\0ts.net\0" +"edu.qa\0" +"edu.pr\0" +"edu.ps\0" +"edu.pt\0" +"mihara.hiroshima.jp\0" +"ac.ug\0services\0" +"edu.py\0" +"ac.tz\0" +"ac.uk\0" +"other.nf\0" +"hiranai.aomori.jp\0" +"s3-website.us-gov-west-1.amazonaws.com\0" +"webcam\0*.eu-west-2.airflow.amazonaws.com\0" +"raindrop.jp\0" +"ubank\0" +"cagliari.it\0museum.mv\0" +"museum.mw\0" +"nayoro.hokkaido.jp\0" +"yokohama\0" +"z.bg\0fi.cloudplatform.fi\0" +"ac.vn\0" +"museum.no\0edu.sa\0" +"hachirogata.akita.jp\0edu.sb\0" +"edu.rs\0edu.sc\0" +"edu.sd\0" +"tokyo\0edu.ru\0" +"tobetsu.hokkaido.jp\0" +"belau.pw\0edu.sg\0" +"s.bg\0" +"edu.sl\0" +"edu.sn\0" +"museum.om\0edu.so\0s3-website.me-south-1.amazonaws.com\0" +"yamazoe.nara.jp\0" +"edu.ss\0" +"mobi.gp\0\xe4\xba\xac\xe9\x83\xbd.jp\0edu.st\0" +"bir.ru\0" +"edu.sv\0" +"naamesjevuemie.no\0" +"l.bg\0edu.sy\0emrstudio-prod.us-gov-east-1.amazonaws.com\0" +"edu.tj\0" +"rodoy.no\0edu.tm\0" +"shonai.yamagata.jp\0" +"edu.to\0from-ma.com\0" +"edu.ua\0" +"muroto.kochi.jp\0edu.tr\0sblo.jp\0" +"allstate\0" +"name.hr\0saitama.jp\0edu.tt\0fr-par-2.baremetal.scw.cloud\0" +"minakami.gunma.jp\0saku.nagano.jp\0" +"e.bg\0edu.tw\0" +"karumai.iwate.jp\0weber\0" +"m\xc3\xa5lselv.no\0skygearapp.com\0" +"crimea.ua\0" +"takahashi.okayama.jp\0" +"s3-website.dualstack.ap-northeast-1.amazonaws.com\0" +"bykle.no\0" +"usr.cloud.muni.cz\0" +"ac.za\0" +"creditcard\0" +"edu.vc\0" +"edu.ve\0" +"name.et\0hannan.osaka.jp\0unazuki.toyama.jp\0" +"kvalsund.no\0tysv\xc3\xa6r.no\0barsy.co.uk\0" +"edu.uy\0" +"radom.pl\0" +"name.fj\0chijiwa.nagasaki.jp\0" +"ac.zm\0" +"maibara.shiga.jp\0edu.vn\0from-co.net\0" +"emrnotebooks-prod.eu-west-2.amazonaws.com\0" +"*.statics.cloud\0" +"council.aero\0tiaa\0" +"takazaki.miyazaki.jp\0" +"emrappui-prod.ap-southeast-3.amazonaws.com\0" +"adachi.tokyo.jp\0verisign\0half.host\0" +"gen.mi.us\0edu.vu\0ltd.ua\0" +"ac.zw\0" +"gliding.aero\0cc.mi.us\0" +"flier.jp\0" +"emrstudio-prod.eu-central-1.amazonaws.com\0" +"ternopil.ua\0ltd.uk\0au.eu.org\0be.eu.org\0" +"\xe6\x95\x8e\xe8\x82\xb2.hk\0kvafjord.no\0" +"aizumisato.fukushima.jp\0tomiya.miyagi.jp\0" +"edu.ws\0execute-api.ap-northeast-1.amazonaws.com\0emrstudio-prod.us-east-2.amazonaws.com\0" +"meguro.tokyo.jp\0" +"os.hordaland.no\0no-ip.co.uk\0" +"kawanishi.yamagata.jp\0" +"publ.pt\0" +"cooking\0" +"gunma.jp\0ipifony.net\0" +"folldal.no\0" +"indie.porn\0" +"website\0" +"edu.ye\0" +"odo.br\0" +"name.eg\0s3-website.us-gov-east-1.amazonaws.com\0" +"smart\0" +"sakai.osaka.jp\0" +"\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0" +"house\0" +"edu.za\0dclk\0" +"taishin.fukushima.jp\0" +"blogspot.com.cy\0" +"bergen.no\0" +"nuoro.it\0yasuda.kochi.jp\0broker\0" +"yakumo.shimane.jp\0" +"fst.br\0shimoichi.nara.jp\0stripper.jp\0" +"sokndal.no\0" +"name.az\0" +"edu.zm\0" +"chiba.jp\0ba.leg.br\0" +"blogspot.com.ee\0" +"blogspot.com.eg\0" +"skoczow.pl\0" +"id.forgerock.io\0" +"oto.fukuoka.jp\0" +"co.network\0adimo.co.uk\0" +"czest.pl\0" +"passenger-association.aero\0" +"asakawa.fukushima.jp\0" +"4.bg\0" +"minobu.yamanashi.jp\0pinoko.jp\0" +"blogspot.com.ar\0" +"tienda\0" +"gs.hl.no\0bg.eu.org\0blogspot.com.au\0" +"oke.gov.pl\0thaibinh.vn\0" +"theworkpc.com\0" +"quangngai.vn\0" +"midori.chiba.jp\0" +"raholt.no\0framer.wiki\0" +"s3-website.pl-waw.scw.cloud\0" +"exnet.su\0" +"fido\0" +"map.fastly.net\0blogspot.com.br\0" +"koshimizu.hokkaido.jp\0hinode.tokyo.jp\0" +"yoita.niigata.jp\0primetel.cloud\0dsmynas.net\0" +"blogspot.com.by\0" +"fvg.it\0" +"samnanger.no\0blogspot.com.co\0" +"trentinosued-tirol.it\0ainan.ehime.jp\0" +"okinawa\0" +"belem.br\0catanzaro.it\0\xd9\x81\xd9\x84\xd8\xb3\xd8\xb7\xd9\x8a\xd9\x86\0" +"deatnu.no\0" +"asso.fr\0" +"\xe8\x87\xba\xe7\x81\xa3\0" +"barletta-trani-andria.it\0nakanoto.ishikawa.jp\0" +"0e.vc\0" +"ic.gov.pl\0babyblue.jp\0" +"bel.tr\0\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4\0" +"oppeg\xc3\xa5rd.no\0" +"dyn-o-saur.com\0" +"asso.gp\0" +"\xce\xb5\xce\xbb\0from-pa.com\0" +"shimane.jp\0higashitsuno.kochi.jp\0" +"rdv.to\0" +"blogspot.com.es\0" +"cya.gg\0" +"nowruz\0b.ssl.fastly.net\0" +"vestv\xc3\xa5g\xc3\xb8y.no\0" +"\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb8\0lovepop.jp\0" +"\xce\xb5\xcf\x85\0partners\0" +"ozora.hokkaido.jp\0ota.tokyo.jp\0" +"modum.no\0notebook.us-east-2.sagemaker.aws\0github.io\0" +"higashiyoshino.nara.jp\0" +"vfs.cloud9.us-west-2.amazonaws.com\0stackhero-network.com\0" +"asso.ht\0noda.chiba.jp\0" +"audnedaln.no\0" +"vindafjord.no\0" +"lib.wy.us\0" +"fuchu.toyama.jp\0" +"kddi\0" +"sor-varanger.no\0" +"aizumi.tokushima.jp\0" +"padua.it\0chigasaki.kanagawa.jp\0" +"gamvik.no\0" +"iwakura.aichi.jp\0" +"s3-accesspoint.dualstack.ap-southeast-3.amazonaws.com\0" +"takahama.aichi.jp\0" +"hr.eu.org\0" +"cc.gu.us\0\xd0\xba\xd1\x80\xd1\x8b\xd0\xbc.\xd1\x80\xd1\x83\xd1\x81\0" +"takayama.nagano.jp\0wake.okayama.jp\0" +"muos\xc3\xa1t.no\0" +"numazu.shizuoka.jp\0" +"jls-sto2.elastx.net\0" +"baseball\0" +"is-a-conservative.com\0" +"asso.ci\0" +"am.leg.br\0" +"pesarourbino.it\0" +"xy.ax\0" +"s3.dualstack.sa-east-1.amazonaws.com\0ap-south-1.elasticbeanstalk.com\0" +"loginline.app\0" +"kikuchi.kumamoto.jp\0tatsuno.nagano.jp\0" +"tec.br\0" +"z.se\0barsy.menu\0" +"minami-alps.yamanashi.jp\0lapy.pl\0" +"misato.akita.jp\0" +"lillehammer.no\0t\xc3\xb8nsberg.no\0httpbin.org\0" +"yatsushiro.kumamoto.jp\0schwarz\0" +"s.se\0film\0" +"vpnplus.to\0" +"capital\0" +"asso.dz\0" +"nesoddtangen.no\0ap-southeast-3.elasticbeanstalk.com\0" +"bar1.net\0" +"zaporizhzhia.ua\0" +"us-west-2.elasticbeanstalk.com\0" +"marugame.kagawa.jp\0" +"tobe.ehime.jp\0kosher\0" +"l.se\0mini\0is-a-hard-worker.com\0" +"olbia-tempio.it\0" +"hoyanger.no\0hughes\0" +"esan.hokkaido.jp\0" +"mock.pstmn.io\0" +"mint\0" +"e.se\0" +"parliament.nz\0" +"gran.no\0svelvik.no\0" +"date.fukushima.jp\0" +"dnsup.net\0" +"egersund.no\0" +"shintomi.miyazaki.jp\0" +"\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\0" +"skjerv\xc3\xb8y.no\0lib.tx.us\0" +"name.vn\0" +"s3-object-lambda.ap-northeast-2.amazonaws.com\0" +"chihayaakasaka.osaka.jp\0" +"tips\0" +"okawa.fukuoka.jp\0moonscale.net\0" +"futurehosting.at\0" +"kainan.tokushima.jp\0" +"media.hu\0flesberg.no\0" +"shiftcrypto.io\0" +"blogspot.com.mt\0" +"ip6.arpa\0" +"blogspot.com.ng\0" +"aca.pro\0" +"emrnotebooks-prod.ap-southeast-3.amazonaws.com\0lohmus.me\0" +"oppdal.no\0" +"hob\xc3\xb8l.no\0" +"latina.it\0" +"seki.gifu.jp\0name.tj\0" +"ap.leg.br\0" +"magazine.aero\0schulplattform.de\0" +"kunimi.fukushima.jp\0shiroishi.miyagi.jp\0fujikawaguchiko.yamanashi.jp\0" +"plumbing\0" +"es.gov.br\0kozagawa.wakayama.jp\0" +"mangyshlak.su\0sakuratan.com\0" +"name.tr\0" +"wmflabs.org\0" +"name.tt\0" +"s3-fips.us-east-2.amazonaws.com\0" +"mobi.tt\0" +"sandnessjoen.no\0gjovik.no\0" +"olecko.pl\0girlfriend.jp\0lubartow.pl\0" +"mircloud.host\0" +"emrstudio-prod.eu-west-2.amazonaws.com\0" +"suedtirol.it\0mobi.tz\0" +"webview-assets.cloud9.ap-east-1.amazonaws.com\0vfs.cloud9.ap-northeast-3.amazonaws.com\0freeddns.us\0" +"fire\0" +"vegarshei.no\0daplie.me\0members.linode.com\0" +"gjesdal.no\0" +"sells-it.net\0" +"lib.sd.us\0" +"horonobe.hokkaido.jp\0" +"otama.fukushima.jp\0" +"asahi.ibaraki.jp\0misaki.okayama.jp\0kakegawa.shizuoka.jp\0dental\0blogspot.com.tr\0gov.scot\0" +"info.gu\0cc.co.us\0asso.eu.org\0" +"higashiura.aichi.jp\0" +"hzc.io\0" +"trentinos-tirol.it\0" +"chikuma.nagano.jp\0" +"sa-east-1.elasticbeanstalk.com\0eurodir.ru\0" +"chikuho.fukuoka.jp\0fish\0" +"statebank\0" +"hitachiomiya.ibaraki.jp\0" +"strand.no\0" +"webview-assets.aws-cloud9.eu-central-1.amazonaws.com\0" +"pvh.br\0" +"presse.km\0airkitapps-au.com\0" +"info.ht\0" +"info.hu\0" +"stj\xc3\xb8rdalshalsen.no\0" +"email\0" +"black\0webview-assets.aws-cloud9.us-east-1.amazonaws.com\0" +"report\0" +"info.in\0yokoshibahikari.chiba.jp\0yakumo.hokkaido.jp\0kiho.mie.jp\0" +"softbank\0servesarcasm.com\0" +"cc.ca.us\0" +"info.et\0chikugo.fukuoka.jp\0nishigo.fukushima.jp\0" +"read\0" +"name.pm\0" +"kaas.gg\0" +"info.fj\0urbinopesaro.it\0kalisz.pl\0" +"name.qa\0" +"name.pr\0" +"platterp.us\0" +"otake.hiroshima.jp\0" +"cc.az.us\0" +"dep.no\0encoreapi.com\0" +"presse.ml\0" +"evenassi.no\0s3-accesspoint.ap-northeast-2.amazonaws.com\0" +"n\xc3\xa1vuotna.no\0brussels\0" +"yamato.kanagawa.jp\0" +"\xe5\xb1\xb1\xe5\x8f\xa3.jp\0mods.jp\0" +"monash\0" +"name.na\0kautokeino.no\0" +"kamisu.ibaraki.jp\0uzs.gov.pl\0" +"jogasz.hu\0mobi.na\0cc.as.us\0us.eu.org\0" +"selfip.biz\0" +"auth-fips.us-east-1.amazoncognito.com\0emrnotebooks-prod.af-south-1.amazonaws.com\0dyndns-mail.com\0" +"ise.mie.jp\0name.mv\0" +"name.ng\0s3-accesspoint.dualstack.me-south-1.amazonaws.com\0from-ar.com\0" +"fuefuki.yamanashi.jp\0" +"a\xc3\xa9roport.ci\0name.my\0mobi.ng\0kyiv.ua\0" +"k12.co.us\0" +"keisen.fukuoka.jp\0info.cx\0" +"act.au\0auth.ap-south-1.amazoncognito.com\0webview-assets.aws-cloud9.eu-west-1.amazonaws.com\0golffan.us\0" +"media.pl\0deal\0" +"cc.al.us\0" +"valle-aosta.it\0vv.it\0" +"bieszczady.pl\0langson.vn\0" +"dopaas.com\0" +"ma.gov.br\0" +"rivne.ua\0emrnotebooks-prod.me-central-1.amazonaws.com\0" +"2-d.jp\0" +"info.ec\0\xc3\xa1k\xc5\x8boluokta.no\0" +"aosta-valley.it\0satte.saitama.jp\0" +"sn.cn\0trentino-suedtirol.it\0" +"s\xc3\xb8r-varanger.no\0" +"dev-myqnapcloud.com\0" +"blogspot.com.uy\0diskstation.org\0" +"123website.nl\0" +"rotorcraft.aero\0dyndns.org\0" +"s3-website.dualstack.ap-southeast-1.amazonaws.com\0" +"l\xc3\xb8renskog.no\0" +"info.bb\0" +"k12.ca.us\0" +"info.at\0" +"info.au\0" +"\xe0\xa8\xad\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\xa4\0" +"karaganda.su\0" +"info.az\0info.bj\0" +"aurskog-holand.no\0s3-ap-southeast-2.amazonaws.com\0" +"mup.gov.pl\0" +"alstahaug.no\0" +"info.bo\0\xd5\xb0\xd5\xa1\xd5\xb5\0\xd9\x82\xd8\xb7\xd8\xb1\0from-wv.com\0" +"g12.br\0erimo.hokkaido.jp\0" +"bomlo.no\0asso.re\0" +"market\0" +"name.mk\0" +"va.it\0prochowice.pl\0" +"h\xc3\xa1mm\xc3\xa1rfeasta.no\0" +"kijo.miyazaki.jp\0shimane.shimane.jp\0pruszkow.pl\0" +"kumano.hiroshima.jp\0okaya.nagano.jp\0" +"info.co\0" +"hiraizumi.iwate.jp\0goodyear\0" +"fie.ee\0\xc3\xb8rsta.no\0" +"123website.lu\0" +"streamlit.app\0" +"kr\xc3\xb8""dsherad.no\0" +"name.jo\0s3.me-south-1.amazonaws.com\0" +"takanabe.miyazaki.jp\0anquan\0" +"chippubetsu.hokkaido.jp\0kilo.jp\0" +"idv.hk\0synology.me\0" +"tuscany.it\0" +"mobi.ke\0" +"ts.it\0" +"arao.kumamoto.jp\0mail.pl\0" +"lib.ms.us\0lib.nc.us\0" +"community\0rocks\0service.gov.uk\0" +"studio.cn-north-1.sagemaker.com.cn\0" +"dyndns-blog.com\0" +"football\0" +"vote\0" +"pro.typeform.com\0" +"lib.nh.us\0arkhangelsk.su\0" +"now-dns.org\0" +"slg.br\0\xe4\xba\x9a\xe9\xa9\xac\xe9\x80\x8a\0" +"ogano.saitama.jp\0" +"voto\0" +"te.it\0" +"asso.nc\0" +"s3-object-lambda.cn-northwest-1.amazonaws.com.cn\0" +"takasu.hokkaido.jp\0hiratsuka.kanagawa.jp\0" +"pri.ee\0" +"ichinoseki.iwate.jp\0" +"lib.ma.us\0s3-website.dualstack.us-west-2.amazonaws.com\0dyndns-wiki.com\0" +"reit\0" +"il.eu.org\0" +"naturbruksgymn.se\0myfirewall.org\0" +"dojin.com\0" +"higashishirakawa.gifu.jp\0hita.oita.jp\0arai.shizuoka.jp\0" +"izunokuni.shizuoka.jp\0host\0" +"kiev.ua\0" +"kasuga.hyogo.jp\0ravendb.run\0" +"va.no\0" +"mediocampidano.it\0" +"tec.ve\0prequalifyme.today\0" +"isa-geek.org\0ddnsgeek.com\0" +"honefoss.no\0framercanvas.com\0" +"ribeirao.br\0open\0" +"frontier\0" +"reliance\0" +"\xe5\x9c\xa8\xe7\xba\xbf\0tuleap-partners.com\0" +"nishimera.miyazaki.jp\0stcgroup\0" +"homedns.org\0" +"jls-sto1.elastx.net\0" +"s\xc3\xa1l\xc3\xa1t.no\0" +"s3.dualstack.ap-southeast-3.amazonaws.com\0" +"hu.eu.org\0ie.eu.org\0" +"money.bj\0ono.fukui.jp\0mito.ibaraki.jp\0oow.gov.pl\0" +"consulting\0" +"takahama.fukui.jp\0" +"storage\0" +"kvits\xc3\xb8y.no\0" +"nx.cn\0" +"tadotsu.kagawa.jp\0" +"ri.it\0furudono.fukushima.jp\0matsumae.hokkaido.jp\0" +"profesional.bo\0kommune.no\0leikanger.no\0" +"gwangju.kr\0hashbang.sh\0" +"freesite.host\0" +"us-4.evennode.com\0" +"\xe5\xa8\xb1\xe4\xb9\x90\0" +"execute-api.us-west-1.amazonaws.com\0" +"toyooka.hyogo.jp\0cloudns.club\0" +"appspacehosted.com\0" +"tsushima.aichi.jp\0ugim.gov.pl\0" +"aeroclub.aero\0" +"omura.nagasaki.jp\0kirara.st\0" +"appspaceusercontent.com\0" +"dell\0ngrok.app\0" +"bolivia.bo\0clinic\0\xec\x82\xbc\xec\x84\xb1\0" +"hobol.no\0" +"poa.br\0" +"bo.nordland.no\0" +"snaase.no\0s3-accesspoint.dualstack.us-gov-east-1.amazonaws.com\0" +"rent\0" +"val-daosta.it\0" +"asso.km\0" +"kiyosato.hokkaido.jp\0" +"altoadige.it\0" +"dgca.aero\0mortgage\0" +"pt.it\0" +"selfip.com\0" +"oga.akita.jp\0kusu.oita.jp\0" +"s3.ap-southeast-2.amazonaws.com\0dyndns-free.com\0""123website.be\0" +"esashi.hokkaido.jp\0czeladz.pl\0" +"fosnes.no\0" +"itigo.jp\0" +"jcloud.ik-server.com\0" +"tsukumi.oita.jp\0" +"asso.mc\0is-a-geek.com\0" +"hiho.jp\0" +"stream\0" +"info.ve\0" +"circle\0co.com\0virtual-user.de\0" +"deta.app\0""123website.ch\0" +"s3.dualstack.eu-west-3.amazonaws.com\0" +"koori.fukushima.jp\0kembuchi.hokkaido.jp\0info.vn\0" +"ulvik.no\0us-3.evennode.com\0" +"yamanashi.yamanashi.jp\0" +"va.us\0" +"ln.cn\0" +"consultant.aero\0money\0istmein.de\0" +"s3.cn-northwest-1.amazonaws.com.cn\0" +"rodeo\0" +"nerdpol.ovh\0" +"xs4all.space\0" +"hirado.nagasaki.jp\0" +"beats\0" +"tomari.hokkaido.jp\0" +"delta\0blogsite.org\0" +"ven.it\0genova.it\0chita.aichi.jp\0" +"is-a-liberal.com\0" +"nichinan.tottori.jp\0" +"balsan.it\0" +"vinnica.ua\0" +"tychy.pl\0" +"hidaka.hokkaido.jp\0mormon\0" +"drud.io\0" +"info.tn\0fem.jp\0" +"abo.pa\0lib.il.us\0apartments\0s3.dualstack.us-east-2.amazonaws.com\0" +"info.tr\0binhphuoc.vn\0" +"sakuragawa.ibaraki.jp\0kagoshima.kagoshima.jp\0info.tt\0" +"qc.com\0" +"rest\0" +"idv.tw\0" +"info.tz\0" +"te.ua\0traeumtgerade.de\0" +"lib.gu.us\0scrapping.cc\0" +"calvinklein\0" +"vikna.no\0s3-object-lambda.us-east-2.amazonaws.com\0" +"ishigaki.okinawa.jp\0" +"yokoze.saitama.jp\0" +"dyndns-at-home.com\0" +"trentinosud-tirol.it\0saga.jp\0" +"desi\0webview-assets.cloud9.eu-west-2.amazonaws.com\0bryansk.su\0" +"mango\0" +"\xe7\x86\x8a\xe6\x9c\xac.jp\0lomza.pl\0" +"it.ao\0" +"aki.kochi.jp\0ube.yamaguchi.jp\0" +"barsy.mobi\0" +"k8s.nl-ams.scw.cloud\0" +"info.ro\0us-2.evennode.com\0" +"hadsel.no\0masoy.no\0nordkapp.no\0" +"ms.it\0kaizuka.osaka.jp\0" +"info.sd\0" +"nodes.k8s.pl-waw.scw.cloud\0" +"\xe9\xa6\x99\xe6\xb8\xaf\0gr.eu.org\0ybo.party\0" +"*.cns.joyent.com\0" +"mitane.akita.jp\0hitachi.ibaraki.jp\0" +"ullensvang.no\0" +"fet.no\0" +"bearalv\xc3\xa1hki.no\0" +"yandex\0" +"ski.no\0xfinity\0s3-accesspoint.dualstack.eu-south-2.amazonaws.com\0" +"awsglobalaccelerator.com\0" +"me.in\0daejeon.kr\0chu.jp\0" +"seg.br\0warmia.pl\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0" +"info.pk\0" +"ome.tokyo.jp\0info.pl\0" +"s3-accesspoint.ap-northeast-3.amazonaws.com\0from-ak.com\0" +"lu.it\0me.it\0" +"presse.ci\0emrstudio-prod.ap-south-1.amazonaws.com\0" +"ms.kr\0" +"vossevangen.no\0servegame.org\0" +"kuchinotsu.nagasaki.jp\0info.pr\0" +"nakagawa.hokkaido.jp\0suzu.ishikawa.jp\0daklak.vn\0orx.biz\0" +"\xc3\xa5mot.no\0radio\0" +"fnc.fr-par.scw.cloud\0" +"cf-ipfs.com\0" +"eu.meteorapp.com\0" +"suldal.no\0isa-geek.com\0" +"nishikata.tochigi.jp\0" +"me.ke\0" +"piemonte.it\0tuyenquang.vn\0" +"info.na\0" +"ri.us\0" +"info.mv\0info.nf\0" +"is-a-republican.com\0" +"info.ni\0stjordalshalsen.no\0" +"kwp.gov.pl\0" +"romsa.no\0" +"iki.nagasaki.jp\0" +"s3-website.us-west-1.amazonaws.com\0us-1.evennode.com\0paas.massivegrid.com\0" +"cherkasy.ua\0" +"info.nr\0" +"\xd9\x85\xd9\x88\xd8\xb1\xd9\x8a\xd8\xaa\xd8\xa7\xd9\x86\xd9\x8a\xd8\xa7\0" +"lg.jp\0" +"kanna.gunma.jp\0" +"software.aero\0kozow.com\0site.transip.me\0" +"securitytactics.com\0" +"enf.br\0trentino-alto-adige.it\0" +"apps.lair.io\0" +"info.la\0randaberg.no\0baby\0tools\0wphostedmail.com\0" +"gx.cn\0vao.it\0dscloud.biz\0" +"plc.co.im\0\xe9\xa3\x9f\xe5\x93\x81\0" +"*.us-east-1.airflow.amazonaws.com\0" +"s3-website.dualstack.sa-east-1.amazonaws.com\0vladikavkaz.ru\0" +"webhosting.be\0is-a-geek.org\0" +"websozai.jp\0" +"atsuma.hokkaido.jp\0tsushima.nagasaki.jp\0" +"kppsp.gov.pl\0" +"ha.cn\0" +"emrappui-prod.ap-northeast-2.amazonaws.com\0s3-accesspoint.dualstack.ap-south-2.amazonaws.com\0serveirc.com\0" +"nikaho.akita.jp\0" +"info.ls\0ftpaccess.cc\0" +"mjondalen.no\0s3.us-east-2.amazonaws.com\0vladikavkaz.su\0" +"shimogo.fukushima.jp\0" +"gs.svalbard.no\0rag-cloud-ch.hosteur.com\0" +"kadoma.osaka.jp\0" +"postman-echo.com\0" +"urbino-pesaro.it\0" +"gc.ca\0andasuolo.no\0" +"page\0" +"harima.hyogo.jp\0" +"osoyro.no\0est-mon-blogueur.com\0" +"j\xc3\xb8lster.no\0" +"togura.nagano.jp\0" +"discordsez.com\0impertrixcdn.com\0" +"hichiso.gifu.jp\0but.jp\0" +"\xe5\x98\x89\xe9\x87\x8c\0" +"government.aero\0" +"tokigawa.saitama.jp\0" +"mints.ne.jp\0eu.ax\0" +"hamar.no\0" +"info.ke\0s3-fips.dualstack.us-west-1.amazonaws.com\0" +"*.sendai.jp\0homeip.net\0" +"info.ki\0" +"akkeshi.hokkaido.jp\0bitter.jp\0" +"im.it\0ito.shizuoka.jp\0" +"kropyvnytskyi.ua\0" +"fujimino.saitama.jp\0" +"cisco\0" +"oh.us\0" +"munakata.fukuoka.jp\0pgafan.net\0" +"\xc3\xa1lt\xc3\xa1.no\0s3.us-gov-west-1.amazonaws.com\0is-a-bookkeeper.com\0" +"moo.jp\0" +"davvesiida.no\0" +"gujarat.in\0" +"mg.gov.br\0dellogliastra.it\0oishida.yamagata.jp\0" +"dielddanuorri.no\0drud.us\0" +"upow.gov.pl\0" +"ora.gunma.jp\0" +"padova.it\0dabur\0" +"s3-website.sa-east-1.amazonaws.com\0" +"port.fr\0" +"supabase.net\0" +"notebook.me-central-1.sagemaker.aws\0" +"kunneppu.hokkaido.jp\0sanagochi.tokushima.jp\0nc.tr\0" +"s3-website-us-east-1.amazonaws.com\0" +"nj.us\0" +"s3-website.ap-northeast-1.amazonaws.com\0s3-website.ap-southeast-4.amazonaws.com\0" +"guardian\0" +"hasura.app\0" +"me.so\0s3-fips.us-west-1.amazonaws.com\0" +"rzeszow.pl\0dienbien.vn\0" +"vennesla.no\0" +"anamizu.ishikawa.jp\0" +"tananger.no\0me.ss\0me.tc\0" +"ms.us\0nc.us\0s3-fips.ca-central-1.amazonaws.com\0" +"nanjo.okinawa.jp\0" +"*.us-west-2.airflow.amazonaws.com\0" +"kasuga.fukuoka.jp\0" +"is-a-candidate.org\0" +"niikappu.hokkaido.jp\0" +"mc.eu.org\0" +"higashi.fukushima.jp\0" +"berg.no\0" +"me.tz\0" +"me.uk\0wang\0" +"is-gone.com\0" +"takayama.gifu.jp\0ibara.okayama.jp\0" +"dnshome.de\0" +"\xe6\xa0\x83\xe6\x9c\xa8.jp\0" +"me.us\0" +"sasebo.nagasaki.jp\0" +"on-aptible.com\0" +"kumano.mie.jp\0iwatsuki.saitama.jp\0ngrok.dev\0" +"s3-accesspoint.us-east-1.amazonaws.com\0" +"hanawa.fukushima.jp\0" +"namsskogan.no\0" +"is-an-actress.com\0" +"s3.cn-north-1.amazonaws.com.cn\0" +"lg.ua\0" +"matsukawa.nagano.jp\0" +"4.azurestaticapps.net\0" +"umb.it\0" +"cahcesuolo.no\0aaa\0lt.eu.org\0" +"me.vu\0" +"s3-accesspoint.dualstack.ap-northeast-3.amazonaws.com\0" +"trentins\xc3\xbc""d-tirol.it\0vps-host.net\0" +"vfs.cloud9.ap-southeast-1.amazonaws.com\0" +"onthewifi.com\0" +"isshiki.aichi.jp\0yamashina.kyoto.jp\0" +"ru.com\0" +"yamato.fukushima.jp\0band\0" +"friulivenezia-giulia.it\0fe.it\0abb\0" +"abc\0s3.ap-southeast-3.amazonaws.com\0" +"shichikashuku.miyagi.jp\0" +"s3-website.dualstack.us-west-1.amazonaws.com\0forgot.his.name\0" +"bedzin.pl\0" +"tr\xc3\xb8gstad.no\0bank\0" +"isahaya.nagasaki.jp\0" +"volyn.ua\0" +"tourism.tn\0flir\0" +"management\0" +"pordenone.it\0ninhthuan.vn\0cocotte.jp\0" +"barsy.info\0" +"en.it\0takino.hyogo.jp\0" +"s3-object-lambda.us-gov-east-1.amazonaws.com\0" +"duckdns.org\0" +"sardinia.it\0otofuke.hokkaido.jp\0" +"ha.no\0pgfog.com\0" +"dh.bytemark.co.uk\0" +"jelenia-gora.pl\0" +"ce.leg.br\0" +"mobile\0" +"aco\0" +"takarazuka.hyogo.jp\0omaezaki.shizuoka.jp\0" +"amakusa.kumamoto.jp\0" +"cologne\0" +"mombetsu.hokkaido.jp\0" +"\xd9\x83\xd9\x88\xd9\x85\0" +"meland.no\0appspot.com\0" +"spjelkavik.no\0" +"sakae.chiba.jp\0minamioguni.kumamoto.jp\0arab\0""123siteweb.fr\0" +"airkitapps.eu\0" +"akita.akita.jp\0" +"lorenskog.no\0" +"kuki.saitama.jp\0flynnhosting.net\0" +"ads\0pars\0g\xc3\xbcnstigbestellen.de\0paas.beebyte.io\0" +"boy.jp\0jellybean.jp\0" +"ah.cn\0" +"aeg\0" +"click\0network\0" +"kagami.kochi.jp\0morotsuka.miyazaki.jp\0" +"hirogawa.wakayama.jp\0" +"netlify.app\0" +"router.management\0" +"ichihara.chiba.jp\0" +"miyakonojo.miyazaki.jp\0" +"kiengiang.vn\0" +"cr.it\0" +"gov.ac\0" +"appudo.net\0" +"gov.ae\0webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com\0" +"gov.af\0\xda\x80\xd8\xa7\xd8\xb1\xd8\xaa\0afl\0" +"eigersund.no\0if.ua\0bingo\0s3-accesspoint.dualstack.eu-north-1.amazonaws.com\0" +"tur.ar\0katashina.gunma.jp\0" +"gov.al\0" +"erotica.hu\0" +"soo.kagoshima.jp\0\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0poznan.pl\0" +"webview-assets.cloud9.eu-west-3.amazonaws.com\0woltlab-demo.com\0" +"gov.ba\0" +"gov.ar\0gov.bb\0" +"gov.as\0rad\xc3\xb8y.no\0" +"nakasatsunai.hokkaido.jp\0ami.ibaraki.jp\0osakasayama.osaka.jp\0store.nf\0" +"gov.au\0" +"gov.bf\0" +"gov.bh\0tur.br\0" +"emrstudio-prod.ap-southeast-3.amazonaws.com\0" +"gov.az\0" +"cc.wv.us\0" +"gov.bm\0tula.su\0" +"gov.bn\0bt.it\0" +"from-ne.com\0herokuapp.com\0" +"cesena-forli.it\0omiya.saitama.jp\0chowder.jp\0" +"kvinesdal.no\0" +"gov.br\0" +"gov.bs\0" +"gov.bt\0gov.cd\0isesaki.gunma.jp\0\xe6\x8b\x9b\xe8\x81\x98\0" +"remotewd.com\0" +"kisofukushima.nagano.jp\0" +"ashiya.fukuoka.jp\0" +"gov.by\0s3-object-lambda.us-gov-west-1.amazonaws.com\0studio.il-central-1.sagemaker.aws\0" +"gov.bz\0" +"gov.cl\0" +"gov.cm\0" +"gov.cn\0" +"gov.co\0" +"aig\0gripe\0notebook.us-west-2.sagemaker.aws\0thingdustdata.com\0" +"bolt.hu\0" +"atsugi.kanagawa.jp\0" +"gov.cu\0isa-hockeynut.com\0" +"kunohe.iwate.jp\0mielec.pl\0banamex\0" +"associates\0" +"gov.cx\0nyuzen.toyama.jp\0" +"gov.cy\0reserve-online.com\0" +"av.it\0akune.kagoshima.jp\0" +"info.zm\0" +"gov.dm\0" +"shingu.wakayama.jp\0wien.funkfeuer.at\0" +"gov.do\0hemsedal.no\0" +"shibetsu.hokkaido.jp\0" +"gov.ec\0" +"miasta.pl\0" +"gov.ee\0s\xc3\xb8r-aurdal.no\0cc.wa.us\0" +"wolomin.pl\0" +"gov.eg\0ringerike.no\0auth.ca-central-1.amazoncognito.com\0" +"ao.it\0" +"repbody.aero\0*.dev-builder.code.com\0" +"gov.dz\0nasu.tochigi.jp\0" +"friuli-vgiulia.it\0" +"bryne.no\0" +"isa-geek.net\0" +"gov.et\0kumagaya.saitama.jp\0" +"vfs.cloud9.eu-north-1.amazonaws.com\0b-data.io\0" +"gov.fj\0" +"ecn.br\0" +"coffee\0" +"bib.br\0\xe6\x84\x9b\xe7\x9f\xa5.jp\0" +"s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com\0s3-accesspoint.dualstack.us-east-2.amazonaws.com\0" +"deno.dev\0" +"ong.br\0" +"gov.gd\0kihoku.ehime.jp\0" +"gov.ge\0app.lmpm.com\0townnews-staging.com\0" +"grp.lk\0" +"gov.gh\0" +"gov.gi\0" +"yasu.shiga.jp\0" +"*.builder.code.com\0" +"fl.us\0" +"gov.gn\0miho.ibaraki.jp\0" +"gov.gr\0wix.run\0" +"gov.gu\0dst.mi.us\0" +"yoshino.nara.jp\0" +"app.banzaicloud.io\0" +"seven\0" +"gov.gy\0" +"isen.kagoshima.jp\0" +"gov.hk\0r\xc3\xb8ros.no\0" +"5g.in\0oyama.tochigi.jp\0" +"chillout.jp\0" +"ehime.jp\0tourism.pl\0" +"leka.no\0" +"serveminecraft.net\0" +"gov.ie\0" +"midori.gunma.jp\0blog.gt\0" +"k12.wa.us\0emrstudio-prod.us-west-1.amazonaws.com\0" +"kuwana.mie.jp\0*.gateway.dev\0" +"s3-accesspoint.eu-north-1.amazonaws.com\0s3.eu-west-2.amazonaws.com\0" +"build\0walmart\0" +"cc.tn.us\0mk.eu.org\0" +"gov.il\0" +"12hp.de\0" +"gov.in\0" +"xihuan\0" +"gov.iq\0surnadal.no\0is-very-sweet.org\0" +"gov.ir\0" +"gov.is\0dp.ua\0store.ve\0isteingeek.de\0" +"gov.it\0anz\0" +"journal.aero\0k12.vt.us\0feedback\0" +"aol\0" +"s3-eu-west-2.amazonaws.com\0" +"minamiashigara.kanagawa.jp\0orangecloud.tn\0" +"storj.farm\0" +"kyonan.chiba.jp\0" +"kerrylogistics\0" +"yoshioka.gunma.jp\0fujiyoshida.yamanashi.jp\0" +"\xd9\x85\xd8\xb5\xd8\xb1\0" +"gov.jo\0" +"tourism.bj\0" +"ah.no\0" +"kamaishi.iwate.jp\0reisen\0support\0" +"citic\0staging.onred.one\0" +"pilot.aero\0gov.kg\0" +"elblag.pl\0" +"gov.ki\0" +"kamitsue.oita.jp\0app\0" +"fresenius\0" +"12hp.at\0" +"gov.km\0vfs.cloud9.us-west-1.amazonaws.com\0" +"gov.kn\0" +"aa.no\0cr.ua\0dyndns.dappnode.io\0" +"gov.kp\0ca.reclaim.cloud\0" +"blog.bo\0gov.la\0" +"gov.lb\0" +"gov.lc\0" +"blog.br\0" +"tjome.no\0codespot.com\0" +"hitachiota.ibaraki.jp\0" +"gov.kw\0" +"kamagaya.chiba.jp\0gov.kz\0" +"gov.lk\0" +"minami.fukuoka.jp\0miyada.nagano.jp\0bar\0" +"ck.ua\0bbc\0" +"army\0" +"12hp.ch\0" +"gov.ma\0attorney\0from-mn.com\0" +"torino.it\0kamisato.saitama.jp\0gov.lr\0" +"gov.ls\0politie\0" +"gov.lt\0" +"gov.me\0arna.no\0\xe4\xbf\xa1\xe6\x81\xaf\0fr.eu.org\0" +"gov.lv\0" +"gov.mg\0" +"gov.ly\0eu-west-1.elasticbeanstalk.com\0" +"gov.mk\0ruovat.no\0*.advisor.ws\0lu.eu.org\0me.eu.org\0" +"gov.ml\0deta.dev\0" +"rost.no\0" +"gov.mn\0art\0bbt\0base.shop\0" +"gov.mo\0""2038.io\0" +"beiarn.no\0bcg\0" +"nishiokoppe.hokkaido.jp\0kanuma.tochigi.jp\0gov.mr\0" +"gov.ms\0" +"futbol\0solar\0is-a-geek.net\0" +"gov.mu\0rsc.cdn77.org\0" +"gov.mv\0koeln\0" +"arpa\0gov.mw\0gov.ng\0" +"bcn\0cloudjiffy.net\0" +"gov.my\0skaun.no\0s3.dualstack.ap-northeast-3.amazonaws.com\0" +"gov.mz\0" +"audio\0" +"*.ex.ortsinfo.at\0gov.nl\0" +"store.ro\0" +"matsushige.tokushima.jp\0" +"gov.nr\0" +"monzaedellabrianza.it\0" +"notaires.km\0\xe9\xa4\x90\xe5\x8e\x85\0servequake.com\0" +"sekikawa.niigata.jp\0" +"avoues.fr\0av.tr\0" +"s3-accesspoint-fips.us-gov-east-1.amazonaws.com\0" +"hsbc\0icbc\0lv.eu.org\0" +"thuathienhue.vn\0" +"gov.om\0vm.bytemark.co.uk\0" +"togakushi.nagano.jp\0" +"brumunddal.no\0bjerkreim.no\0" +"myphotos.cc\0" +"store.st\0" +"m\xc4\x81ori.nz\0" +"hofu.yamaguchi.jp\0gov.ph\0" +"asn.au\0" +"gs.nl.no\0gov.pk\0" +"gov.pl\0" +"gov.pn\0bet\0" +"s3.dualstack.eu-south-2.amazonaws.com\0""4u.com\0" +"gov.qa\0pccw\0" +"gov.pr\0*.in.futurecms.at\0" +"oster\xc3\xb8y.no\0gov.ps\0nagoya\0" +"sakawa.kochi.jp\0gov.pt\0" +"evenes.no\0" +"vall\xc3\xa9""edaoste.it\0turek.pl\0" +"gov.py\0try-snowplow.com\0" +"hosting\0pdns.page\0" +"ardal.no\0" +"pub.instances.scw.cloud\0" +"\xc3\xb8ygarden.no\0k12.sc.us\0" +"go.leg.br\0" +"us-east-2.elasticbeanstalk.com\0codeberg.page\0utwente.io\0" +"bulsan.it\0" +"asda\0eu-4.evennode.com\0" +"\xe5\xb2\xa1\xe5\xb1\xb1.jp\0" +"arte\0axa\0" +"aws\0studio-fips.us-gov-west-1.sagemaker.aws\0" +"gov.sa\0s3.dualstack.eu-west-1.amazonaws.com\0" +"friuliv-giulia.it\0oarai.ibaraki.jp\0gov.sb\0" +"trysil.no\0gov.rs\0gov.sc\0" +"gov.sd\0allfinanz\0" +"tjeldsund.no\0cc.pa.us\0gov.ru\0" +"gov.rw\0gov.sg\0" +"gov.sh\0" +"emrnotebooks-prod.ap-southeast-2.amazonaws.com\0s3.us-west-2.amazonaws.com\0" +"gov.sl\0" +"x.bg\0\xd0\xb1\xd0\xb8\xd0\xb7.\xd1\x80\xd1\x83\xd1\x81\0" +"bid\0upaas.kazteleport.kz\0" +"orkdal.no\0gov.so\0taobao\0" +"journalist.aero\0radoy.no\0\xd9\x87\xd9\x85\xd8\xb1\xd8\xa7\xd9\x87\0" +"gov.ss\0fastly-edge.com\0" +"maori.nz\0" +"2000.hu\0" +"bbva\0" +"shizuoka.shizuoka.jp\0is.gov.pl\0sosnowiec.pl\0gov.sx\0" +"gov.sy\0bio\0" +"gov.tj\0" +"q.bg\0s3-website-us-gov-west-1.amazonaws.com\0" +"gov.tl\0" +"gov.tm\0s3.dualstack.ap-east-1.amazonaws.com\0" +"gov.tn\0" +"gov.to\0" +"shikama.miyagi.jp\0" +"gov.ua\0" +"yanaizu.fukushima.jp\0gov.tr\0" +"biz\0marche.it\0gov.tt\0" +"auth.ap-northeast-2.amazoncognito.com\0vfs.cloud9.ap-northeast-2.amazonaws.com\0" +"gov.tw\0" +"bip.sh\0" +"j.bg\0" +"itako.ibaraki.jp\0" +"gov.uk\0" +"aibetsu.hokkaido.jp\0*.firenet.ch\0" +"ovre-eiker.no\0" +"nagasaki.jp\0" +"nyanta.jp\0" +"s3.amazonaws.com\0webview-assets.aws-cloud9.me-south-1.amazonaws.com\0" +"umig.gov.pl\0" +"gov.vc\0" +"chino.nagano.jp\0*.northflank.app\0" +"gov.ve\0execute-api.il-central-1.amazonaws.com\0s3-object-lambda.eu-north-1.amazonaws.com\0s3-website.eu-south-1.amazonaws.com\0" +"c.bg\0stathelle.no\0eu-3.evennode.com\0" +"holt\xc3\xa5len.no\0k12.pr.us\0sekd1.beebyteapp.io\0j.layershift.co.uk\0" +"akiruno.tokyo.jp\0s3.fr-par.scw.cloud\0" +"kharkov.ua\0cc.ne.us\0orsites.com\0" +"gov.vn\0mattel\0" +"khmelnytskyi.ua\0" +"toray\0temp-dns.com\0" +"asia\0sand\xc3\xb8y.no\0k12.pa.us\0" +"cc.mn.us\0kr.eu.org\0app.os.stg.fedoraproject.org\0" +"tsuru.yamanashi.jp\0" +"\xe4\xb8\xad\xe5\x9b\xbd\0" +"mazury.pl\0" +"emrnotebooks-prod.me-south-1.amazonaws.com\0" +"vallee-d-aoste.it\0hakodate.hokkaido.jp\0izumo.shimane.jp\0" +"gov.ws\0" +"saroma.hokkaido.jp\0" +"nord-fron.no\0\xe5\x85\xac\xe5\x8f\xb8.\xe9\xa6\x99\xe6\xb8\xaf\0" +"blog.vu\0" +"kashiwa.chiba.jp\0" +"capetown\0" +"\xe4\xb8\xad\xe5\x9c\x8b\0" +"bms\0" +"matsue.shimane.jp\0" +"bmw\0" +"gov.ye\0" +"osaka\0" +"simplesite.com.br\0" +"chambagri.fr\0" +"jgora.pl\0" +"bib.ve\0gov.za\0demo.datadetect.com\0fuettertdasnetz.de\0" +"ravenna.it\0" +"sa.edu.au\0*.otap.co\0nfshost.com\0" +"hiroshima.jp\0" +"cc.ky.us\0" +"bom\0eu-2.evennode.com\0" +"\xd9\xbe\xd8\xa7\xd9\x83\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0rich\0" +"boo\0latrobe\0freeboxos.com\0" +"square7.net\0" +"\xe0\xb9\x80\xe0\xb8\x99\xe0\xb9\x87\xe0\xb8\x95.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"gov.zm\0" +"bot\0" +"sko.gov.pl\0box\0" +"budejju.no\0" +"gov.zw\0" +"kawakita.ishikawa.jp\0" +"kokonoe.oita.jp\0asn.lv\0" +"9.bg\0" +"kosei.shiga.jp\0cab\0" +"onred.one\0" +"hobby-site.org\0x0.com\0" +"from-la.net\0" +"nishiizu.shizuoka.jp\0" +"gaular.no\0" +"huissier-justice.fr\0minano.saitama.jp\0cal\0nyc.mn\0" +"tozsde.hu\0cam\0" +"yenbai.vn\0" +"2.bg\0gj\xc3\xb8vik.no\0" +"mond.jp\0" +"aremark.no\0cba\0taifun-dns.de\0" +"biratori.hokkaido.jp\0car\0" +"cat\0kawamata.fukushima.jp\0" +"grondar.za\0" +"kids\0" +"ashiya.hyogo.jp\0gobo.wakayama.jp\0" +"hole.no\0" +"webhop.org\0" +"hasama.oita.jp\0opal.ne.jp\0" +"execute-api.eu-south-2.amazonaws.com\0" +"ogliastra.it\0shiroishi.saga.jp\0cbn\0" +"k12.nj.us\0s3-accesspoint.ap-south-1.amazonaws.com\0" +"salon\0" +"\xe7\xbd\x91\xe7\xab\x99\0" +"sardegna.it\0" +"marker.no\0properties\0" +"store.bb\0kawai.iwate.jp\0tokushima.tokushima.jp\0" +"sogndal.no\0" +"t3l3p0rt.net\0" +"stufftoread.com\0" +"shintoku.hokkaido.jp\0" +"emrappui-prod.ca-central-1.amazonaws.com\0" +"k12.mi.us\0eu-1.evennode.com\0" +"carraramassa.it\0tohma.hokkaido.jp\0" +"camera\0" +"lolipop.io\0" +"gen.in\0" +"imb.br\0diet\0" +"j\xc3\xb8rpeland.no\0" +"cuneo.it\0hioki.kagoshima.jp\0*.sensiosite.cloud\0" +"\xd7\x9e\xd7\x9e\xd7\xa9\xd7\x9c.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0\xe8\x81\x94\xe9\x80\x9a\0" +"deporte.bo\0" +"myspreadshop.net\0" +"auth.ap-southeast-2.amazoncognito.com\0is-a-cpa.com\0" +"is-a-libertarian.com\0" +"porsgrunn.no\0" +"c.la\0" +"architectes.bj\0red.sv\0gov.nc.tr\0" +"k12.ks.us\0" +"bahccavuotna.no\0\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4\xe0\xb1\x8d\0" +"londrina.br\0ynh.fr\0" +"ceo\0store.dk\0blogspot.com\0js.wpenginepowered.com\0" +"cfa\0beta.bounty-full.com\0" +"takehara.hiroshima.jp\0shikaoi.hokkaido.jp\0" +"ryukyu\0" +"cfd\0" +"buy\0miami\0" +"cc.ia.us\0" +"gorlice.pl\0" +"s3-accesspoint.us-gov-west-1.amazonaws.com\0" +"*.owo.codes\0" +"chichibu.saitama.jp\0" +"urn.arpa\0""123miweb.es\0basicserver.io\0" +"buzen.fukuoka.jp\0wakkanai.hokkaido.jp\0" +"instance.datadetect.com\0" +"doesntexist.org\0" +"foz.br\0ogasawara.tokyo.jp\0" +"tynset.no\0" +"*.eu-west-1.airflow.amazonaws.com\0" +"teo.br\0kusatsu.shiga.jp\0" +"!city.sendai.jp\0" +"gen.ng\0" +"merckmsd\0" +"akrehamn.no\0lib.wi.us\0" +"hiraya.nagano.jp\0" +"namdinh.vn\0" +"vfs.cloud9.us-east-2.amazonaws.com\0" +"ono.hyogo.jp\0" +"os\xc3\xb8yro.no\0" +"copro.uk\0" +"blog.kg\0" +"yn.cn\0gen.nz\0" +"tolga.no\0x.se\0" +"\xe5\xa4\xa7\xe9\x98\xaa.jp\0" +"mobi\0" +"sarpsborg.no\0" +"nakatsugawa.gifu.jp\0bzh\0" +"\xe6\xb8\xb8\xe6\x88\x8f\0ras.ru\0" +"k12.ia.us\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.cn\0verm\xc3\xb6gensberater\0" +"lifestyle\0" +"*.kobe.jp\0" +"s3-deprecated.us-east-2.amazonaws.com\0from-mi.com\0" +"\xe5\xa4\xa7\xe6\x8b\xbf\0s3-website.ap-south-1.amazonaws.com\0" +"tsuiki.fukuoka.jp\0aridagawa.wakayama.jp\0""5.azurestaticapps.net\0" +"analytics-gateway.us-east-1.amazonaws.com\0" +"jeonnam.kr\0" +"imizu.toyama.jp\0" +"k12.id.us\0moda\0" +"bergamo.it\0yabuki.fukushima.jp\0" +"\xc3\xa5snes.no\0" +"oita.jp\0" +"karasjohka.no\0" +"quangbinh.vn\0" +"uppo.gov.pl\0" +"yahoo\0" +"c.se\0" +"toyokawa.aichi.jp\0komono.mie.jp\0" +"ballooning.aero\0ap-southeast-1.elasticbeanstalk.com\0is-very-evil.org\0" +"bar0.net\0" +"freedesktop.org\0" +"kamo.niigata.jp\0" +"\xe9\xa3\x9e\xe5\x88\xa9\xe6\xb5\xa6\0user.srcf.net\0" +"student.aero\0*.on-acorn.io\0" +"noticeable.news\0" +"iobb.net\0" +"cloudns.info\0" +"nissan\0" +"uk.oxa.cloud\0" +"penza.su\0" +"cyou\0" +"\xe5\x8d\x83\xe8\x91\x89.jp\0" +"nissay\0" +"sandoy.no\0ing.pa\0" +"pubtls.org\0" +"toyosato.shiga.jp\0" +"notebook.eu-central-1.sagemaker.aws\0" +"ustka.pl\0" +"poniatowa.pl\0" +"spdns.eu\0" +"*.kitakyushu.jp\0*.ex.futurecms.at\0" +"minamifurano.hokkaido.jp\0gen.tr\0" +"auth-fips.us-east-2.amazoncognito.com\0us-east-1.amazonaws.com\0" +"bounceme.net\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.hk\0" +"coach\0" +"com\0bodo.no\0" +"yuasa.wakayama.jp\0" +"from-ga.com\0" +"notaires.fr\0" +"cpa\0" +"onojo.fukuoka.jp\0" +"cc.ct.us\0" +"trentino-s\xc3\xbc""dtirol.it\0\xe7\xa6\x8f\xe5\xb3\xb6.jp\0financial\0" +"news.hu\0emrappui-prod.eu-north-1.amazonaws.com\0" +"campania.it\0zushi.kanagawa.jp\0" +"brindisi.it\0secret.jp\0" +"ascolipiceno.it\0lon-1.paas.massivegrid.net\0" +"sellsyourhome.org\0" +"katori.chiba.jp\0" +"\xe9\xb9\xbf\xe5\x85\x90\xe5\xb3\xb6.jp\0dad\0" +"\xe6\xbe\xb3\xe9\x96\x80\0" +"dish\0" +"bungoono.oita.jp\0" +"\xd0\xba\xd0\xb0\xd1\x82\xd0\xbe\xd0\xbb\xd0\xb8\xd0\xba\0" +"waw.pl\0" +"xen.prgmr.com\0" +"mutsu.aomori.jp\0imabari.ehime.jp\0shirakawa.gifu.jp\0" +"day\0" +"coz.br\0co.education\0" +"k12.fl.us\0" +"my-router.de\0" +"buyshop.jp\0noop.app\0" +"avianca\0weibo\0" +"tatebayashi.gunma.jp\0" +"crs\0" +"andriatranibarletta.it\0toyohashi.aichi.jp\0" +"betainabox.com\0" +"medio-campidano.it\0vibovalentia.it\0" +"natal.br\0himeji.hyogo.jp\0" +"kibichuo.okayama.jp\0" +"commune.am\0r\xc3\xb8mskog.no\0game.tw\0discourse.team\0" +"hizen.saga.jp\0" +"lib.pr.us\0s3-accesspoint.dualstack.eu-south-1.amazonaws.com\0s3.us-gov-east-1.amazonaws.com\0" +"lodi.it\0gotsu.shimane.jp\0" +"pvt.ge\0eu.pythonanywhere.com\0" +"tj.cn\0higashikawa.hokkaido.jp\0tagami.niigata.jp\0komatsushima.tokushima.jp\0klodzko.pl\0" +"tc.br\0ouchi.saga.jp\0" +"webview-assets.aws-cloud9.af-south-1.amazonaws.com\0es.eu.org\0" +"nesseby.no\0gifts\0kiwi\0" +"schaeffler\0" +"dds\0myshopblocks.com\0" +"hanggliding.aero\0spdns.de\0" +"kakogawa.hyogo.jp\0" +"friulivgiulia.it\0vt.it\0" +"laz.it\0massacarrara.it\0" +"hvaler.no\0" +"iyo.ehime.jp\0nowtv\0" +"dev\0" +"fukusaki.hyogo.jp\0sanjo.niigata.jp\0" +"koriyama.fukushima.jp\0s3-accesspoint.dualstack.cn-northwest-1.amazonaws.com.cn\0" +"\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0" +"taku.saga.jp\0ina.saitama.jp\0" +"cng.br\0airtel\0" +"tydal.no\0de.com\0" +"mcdir.me\0" +"toyone.aichi.jp\0" +"nagaokakyo.kyoto.jp\0narusawa.yamanashi.jp\0lamer\0" +"ivano-frankivsk.ua\0\xd0\xbe\xd0\xbd\xd0\xbb\xd0\xb0\xd0\xb9\xd0\xbd\0" +"bjark\xc3\xb8y.no\0" +"rankoshi.hokkaido.jp\0food\0" +"sortland.no\0" +"\xe6\xbe\xb3\xe9\x97\xa8\0" +"roan.no\0" +"tonami.toyama.jp\0" +"ieee\0cloudns.pro\0" +"audi\0" +"kumamoto.kumamoto.jp\0*.cloud.metacentrum.cz\0" +"asahi.chiba.jp\0" +"steigen.no\0" +"val-d-aosta.it\0nghean.vn\0dhl\0" +"slz.br\0now.sh\0" +"transporte.bo\0lea\xc5\x8bgaviika.no\0" +"is-an-engineer.com\0" +"s3-accesspoint.dualstack.ap-south-1.amazonaws.com\0" +"miura.kanagawa.jp\0" +"\xe5\xbe\xb3\xe5\xb3\xb6.jp\0" +"bielawa.pl\0" +"daa.jp\0" +"ip.linodeusercontent.com\0" +"\xe9\x9b\xbb\xe8\xa8\x8a\xe7\x9b\x88\xe7\xa7\x91\0" +"\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\0beer\0" +"grosseto.it\0" +"hangout\0lplfinancial\0" +"tunk.org\0" +"kumamoto.jp\0" +"lib.ne.us\0studio.eu-north-1.sagemaker.aws\0home-webserver.de\0" +"fukagawa.hokkaido.jp\0" +"diy\0" +"v\xc3\xa5gan.no\0" +"ford\0" +"alstom\0dynserv.org\0" +"weir\0" +"lib.nj.us\0*.r.appspot.com\0" +"shiojiri.nagano.jp\0imari.saga.jp\0user.webaccel.jp\0" +"morimachi.shizuoka.jp\0" +"omniwe.site\0" +"ss.it\0hs.run\0" +"skodje.no\0" +"total\0" +"vinhlong.vn\0fra1-de.cloudjiffy.net\0" +"vf.no\0north-kazakhstan.su\0" +"production.aero\0" +"datsun\0" +"\xe6\x89\x8b\xe6\x9c\xba\0" +"idf.il\0" +"moto\0emrappui-prod.sa-east-1.amazonaws.com\0" +"\xe5\xae\xae\xe5\x9f\x8e.jp\0forex\0" +"reservd.testing.thingdust.io\0" +"seto.aichi.jp\0travel\0" +"*.futurecms.at\0" +"tonkotsu.jp\0" +"digital\0" +"odda.no\0" +"trentinoaltoadige.it\0yugawara.kanagawa.jp\0" +"mysecuritycamera.com\0" +"senasa.ar\0narita.chiba.jp\0" +"froya.no\0s3-website.ap-southeast-1.amazonaws.com\0" +"fitness\0" +"yonezawa.yamagata.jp\0" +"katagami.akita.jp\0" +"lib.la.us\0" +"tatar\0" +"fr-1.paas.massivegrid.net\0" +"execute-api.eu-north-1.amazonaws.com\0" +"hirono.iwate.jp\0" +"rn.it\0run.app\0" +"navoi.su\0" +"kamishihoro.hokkaido.jp\0town\0" +"of.by\0" +"ichiba.tokushima.jp\0" +"reklam.hu\0wy.us\0" +"dnp\0parallel.jp\0" +"forum.hu\0" +"ujiie.tochigi.jp\0" +"consulting.aero\0is-into-cars.com\0" +"rg.it\0\xe7\xbd\x91\xe5\x9d\x80\0platter-app.dev\0" +"otsuki.kochi.jp\0storage.yandexcloud.net\0" +"dog\0" +"arita.saga.jp\0" +"insurance\0" +"*.cn-north-1.airflow.amazonaws.com.cn\0" +"col.ng\0" +"thick.jp\0" +"gildeskal.no\0" +"is-a-lawyer.com\0webredirect.org\0" +"brother\0" +"s3.dualstack.eu-central-2.amazonaws.com\0" +"agrigento.it\0moroyama.saitama.jp\0" +"latino\0" +"pa.gov.br\0dot\0" +"webview-assets.cloud9.eu-south-1.amazonaws.com\0webview-assets.cloud9.us-east-1.amazonaws.com\0" +"ozu.kumamoto.jp\0asakuchi.okayama.jp\0" +"chase\0" +"daegu.kr\0*.rss.my.id\0" +"murata.miyagi.jp\0credit\0" +"fi.eu.org\0" +"easypanel.app\0" +"b\xc3\xa1hcavuotna.no\0beauty\0toys\0" +"shishikui.tokushima.jp\0" +"mcdir.ru\0" +"s3-accesspoint.dualstack.ap-northeast-2.amazonaws.com\0" +"ginoza.okinawa.jp\0urasoe.okinawa.jp\0" +"kmpsp.gov.pl\0" +"vt.us\0" +"s3-accesspoint.me-south-1.amazonaws.com\0" +"campobasso.it\0pr.it\0" +"vik.no\0cable-modem.org\0byen.site\0" +"matsuda.kanagawa.jp\0mc.ax\0" +"pictures\0" +"hirakata.osaka.jp\0restaurant\0" +"pb.gov.br\0kawaminami.miyazaki.jp\0eat\0" +"cruise\0" +"\xe5\x95\x86\xe5\x9f\x8e\0" +"nakagawa.tokushima.jp\0kamitonda.wakayama.jp\0cistron.nl\0" +"*.on-rancher.cloud\0" +"fhs.no\0*.oci.customer-oci.com\0" +"\xe7\xbb\x84\xe7\xb9\x94.hk\0lyngdal.no\0ua.rs\0" +"tomobe.ibaraki.jp\0" +"lacaixa\0" +"hayashima.okayama.jp\0de.cool\0" +"boehringer\0" +"smile\0togliatti.su\0" +"iveland.no\0" +"ot.it\0pd.it\0" +"filegear-au.me\0" +"cantho.vn\0" +"eco\0" +"sicilia.it\0" +"oyer.no\0" +"muni.il\0" +"nishihara.kumamoto.jp\0tsubame.niigata.jp\0" +"webview-assets.aws-cloud9.us-west-2.amazonaws.com\0" +"namegata.ibaraki.jp\0" +"gamo.shiga.jp\0" +"hermes\0" +"izena.okinawa.jp\0" +"modelling.aero\0tx.us\0cn.com\0" +"ushiku.ibaraki.jp\0shimizu.shizuoka.jp\0" +"edu\0" +"dtv\0myeffect.net\0" +"sandvik\0of.je\0" +"curitiba.br\0aichi.jp\0numata.hokkaido.jp\0eastasia.azurestaticapps.net\0" +"execute-api.eu-west-1.amazonaws.com\0s3-accesspoint.dualstack.us-west-1.amazonaws.com\0" +"floripa.br\0ninhbinh.vn\0" +"ringsaker.no\0s3.dualstack.me-central-1.amazonaws.com\0is-a-techie.com\0" +"bulsan-sudtirol.it\0szczecin.pl\0girly.jp\0" +"chanel\0" +"capitalone\0" +"lima-city.rocks\0" +"kiyose.tokyo.jp\0tiengiang.vn\0" +"*.uberspace.de\0" +"no.it\0" +"cesenaforli.it\0health.nz\0" +"logistics.aero\0s3-website.eu-north-1.amazonaws.com\0" +"hadano.kanagawa.jp\0webhop.net\0" +"aver\xc3\xb8y.no\0" +"lukow.pl\0" +"vision\0" +"rahkkeravju.no\0temasek\0" +"kurogi.fukuoka.jp\0chiyoda.gunma.jp\0embetsu.hokkaido.jp\0gyeongbuk.kr\0" +"hikone.shiga.jp\0oguni.yamagata.jp\0" +"gucci\0fldrv.com\0" +"mitsue.nara.jp\0dvr\0" +"oyamazaki.kyoto.jp\0" +"press.cy\0s3-website.dualstack.ap-northeast-3.amazonaws.com\0" +"s3-accesspoint.cn-north-1.amazonaws.com.cn\0" +"cloudns.org\0" +"kawanehon.shizuoka.jp\0" +"oppegard.no\0emrappui-prod.ap-southeast-1.amazonaws.com\0s3-accesspoint.dualstack.us-gov-west-1.amazonaws.com\0" +"na.it\0best\0" +"from-de.com\0" +"shoparena.pl\0edu.scot\0" +"jorpeland.no\0songdalen.no\0barrell-of-knowledge.info\0" +"milan.it\0nogata.fukuoka.jp\0" +"rimini.it\0" +"shoes\0" +"auto\0" +"broke-it.net\0" +"compare\0hlx.live\0" +"omachi.saga.jp\0" +"jp.eu.org\0" +"editorx.io\0" +"oki.fukuoka.jp\0" +"insure\0" +"id.au\0" +"mc.it\0" +"of.no\0" +"knx-server.net\0" +"minamitane.kagoshima.jp\0" +"ventures\0s3-object-lambda.ap-south-1.amazonaws.com\0" +"minamiyamashiro.kyoto.jp\0" +"sorum.no\0" +"aeroport.fr\0" +"g\xc3\xbcnstigliefern.de\0" +"mx.na\0from-ri.com\0" +"gv.ao\0" +"krym.ua\0cleverapps.io\0" +"gv.at\0trento.it\0" +"aircraft.aero\0" +"le.it\0shikatsu.aichi.jp\0hanamaki.iwate.jp\0" +"dyndns-work.com\0" +"auth-fips.us-west-1.amazoncognito.com\0" +"forum\0" +"bozen.it\0kaminoyama.yamagata.jp\0" +"ddnslive.com\0" +"lexus\0na4u.ru\0" +"nango.fukushima.jp\0" +"ambulance.aero\0" +"for-more.biz\0" +"physio\0" +"instances.spawn.cc\0" +"s3-fips.dualstack.us-gov-west-1.amazonaws.com\0phx.enscaled.us\0" +"babymilk.jp\0" +"point2this.com\0" +"go.ci\0" +"hamada.shimane.jp\0health.vn\0" +"lib.co.us\0readmyblog.org\0" +"aogaki.hyogo.jp\0" +"pr.us\0" +"berlin\0" +"qoto.io\0" +"trafficplex.cloud\0" +"co.business\0" +"go.cr\0" +"company\0events\0s3-accesspoint-fips.us-gov-west-1.amazonaws.com\0" +"\xd0\xba\xd0\xbe\xd0\xbc\0" +"s3-object-lambda.il-central-1.amazonaws.com\0" +"builders\0" +"lib.ct.us\0" +"s\xc3\xb8rfold.no\0" +"hokuto.hokkaido.jp\0onion\0" +"s3-accesspoint-fips.dualstack.us-gov-east-1.amazonaws.com\0" +"kg.kr\0" +"mikasa.hokkaido.jp\0" +"sci.eg\0jp.kg\0" +"quangtri.vn\0ciao.jp\0" +"sandefjord.no\0" +"milano.it\0es.leg.br\0" +"s3-website.eu-central-1.amazonaws.com\0s3-accesspoint.dualstack.eu-west-1.amazonaws.com\0" +"boutique\0" +"boutir.com\0" +"es.ax\0" +"niki.hokkaido.jp\0ando.nara.jp\0" +"bardu.no\0" +"pi.gov.br\0bologna.it\0yawata.kyoto.jp\0" +"fj.cn\0" +"moscow\0" +"space-to-rent.com\0" +"no-ip.org\0" +"\xe6\x94\xbf\xe5\xba\x9c\0serveftp.net\0" +"s3.eu-central-2.amazonaws.com\0servehttp.com\0" +"zuerich\0" +"n\xc3\xa6r\xc3\xb8y.no\0scholarships\0" +"iwanuma.miyagi.jp\0immobilien\0jp.md\0" +"dyndns.tv\0khplay.nl\0" +"ingatlan.hu\0nv.us\0" +"kanonji.kagawa.jp\0" +"s3-website.eu-west-1.amazonaws.com\0" +"id.ir\0auto.pl\0" +"neko.am\0" +"lyngen.no\0filegear-ie.me\0dynvpn.de\0" +"fed.us\0glug.org.uk\0" +"miyako.fukuoka.jp\0oketo.hokkaido.jp\0fan\0versus.jp\0" +"alessandria.it\0" +"sa.ngrok.io\0" +"yokkaichi.mie.jp\0" +"auth.eu-west-2.amazoncognito.com\0est-a-la-maison.com\0" +"natori.miyagi.jp\0" +"rennebu.no\0nh.us\0" +"siena.it\0" +"go.id\0" +"s3-us-gov-west-1.amazonaws.com\0" +"nishihara.okinawa.jp\0" +"hamaroy.no\0*.sa-east-1.airflow.amazonaws.com\0notebook.eu-west-1.sagemaker.aws\0" +"k8s.pl-waw.scw.cloud\0" +"trentinsudtirol.it\0execute-api.cn-northwest-1.amazonaws.com.cn\0" +"faststacks.net\0" +"\xd0\xb1\xd0\xb3\0" +"\xe9\x95\xb7\xe9\x87\x8e.jp\0kaga.ishikawa.jp\0kawagoe.mie.jp\0\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" +"esq\0dyndns.ws\0" +"dedyn.io\0" +"go.it\0" +"tselinograd.su\0" +"sel.no\0sells-for-u.com\0" +"agro.bj\0" +"fusa.no\0" +"sumoto.hyogo.jp\0id.lv\0parasite.jp\0" +"agro.bo\0" +"id.ly\0name\0aure.no\0family\0" +"go.jp\0" +"br\xc3\xb8nn\xc3\xb8ysund.no\0" +"shirahama.wakayama.jp\0" +"go.ke\0tuxfamily.org\0" +"koshu.yamanashi.jp\0" +"lib.al.us\0is-a-democrat.com\0" +"forsand.no\0game\0" +"trentino-stirol.it\0kanegasaki.iwate.jp\0" +"go.kr\0seoul.kr\0\xe9\x9b\x86\xe5\x9b\xa2\0" +"eus\0" +"edgesuite.net\0" +"cremona.it\0" +"musashimurayama.tokyo.jp\0" +"sakahogi.gifu.jp\0undo.jp\0" +"utazas.hu\0" +"dr\xc3\xb8""bak.no\0s\xc3\xb8mna.no\0" +"kusatsu.gunma.jp\0" +"madrid\0" +"hm.no\0g\xc3\xa1\xc5\x8bgaviika.no\0redumbrella\0is-a-patsfan.org\0" +"showa.yamanashi.jp\0rybnik.pl\0\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0" +"*.nagoya.jp\0\xe5\x8f\xb0\xe6\xb9\xbe\0web.app\0" +"cal.it\0fukushima.jp\0" +"priv.hu\0" +"muika.niigata.jp\0" +"nesna.no\0" +"fc.it\0" +"marine.ru\0" +"gru.br\0lolipopmc.jp\0" +"nahari.kochi.jp\0niyodogawa.kochi.jp\0tamayu.shimane.jp\0" +"drangedal.no\0holmestrand.no\0" +"pe.gov.br\0" +"execute-api.us-east-2.amazonaws.com\0" +"tahara.aichi.jp\0kepno.pl\0" +"averoy.no\0s3.dualstack.eu-west-2.amazonaws.com\0" +"qa2.com\0" +"ino.kochi.jp\0" +"\xc4\x8d\xc3\xa1hcesuolo.no\0" +"from-sd.com\0" +"wakayama.wakayama.jp\0" +"*.devcdnaccesso.com\0" +"sveio.no\0herokussl.com\0" +"am.br\0" +"ddns5.com\0" +"iide.yamagata.jp\0\xd0\xb5\xd1\x8e\0""123paginaweb.pt\0" +"es.kr\0" +"pantheonsite.io\0" +"e4.cz\0" +"hattfjelldal.no\0" +"\xe4\xbd\x90\xe8\xb3\x80.jp\0" +"press.se\0" +"fit\0podzone.net\0gloomy.jp\0" +"tomakomai.hokkaido.jp\0*.migration.run\0" +"fedorainfracloud.org\0" +"ishinomaki.miyagi.jp\0" +"hostyhosting.io\0" +"nl-ams-1.baremetal.scw.cloud\0" +"s3.dualstack.ap-south-1.amazonaws.com\0notebook.ca-central-1.sagemaker.aws\0" +"grue.no\0" +"torahime.shiga.jp\0" +"haram.no\0" +"\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa\0" +"dattolocal.net\0alp1.ae.flow.ch\0o0o0.jp\0" +"go.pw\0service.one\0devices.resinstaging.io\0" +"versicherung\0" +"forde.no\0mcpre.ru\0" +"monzabrianza.it\0" +"edugit.io\0" +"abbott\0" +"kitchen\0" +"creditunion\0" +"rennesoy.no\0" +"sannohe.aomori.jp\0nakanojo.gunma.jp\0" +"eaton.mi.us\0eero.online\0customer.mythic-beasts.com\0" +"priv.at\0" +"s3-object-lambda.sa-east-1.amazonaws.com\0" +"miyazaki.miyazaki.jp\0" +"lakas.hu\0" +"gs.va.no\0" +"porsangu.no\0s3.ca-central-1.amazonaws.com\0" +"ci.it\0azurewebsites.net\0" +"obira.hokkaido.jp\0" +"bindal.no\0tours\0community-pro.de\0" +"id.us\0fly\0" +"nishiwaki.hyogo.jp\0" +"tsuga.tochigi.jp\0turystyka.pl\0" +"free\0" +"palmas.br\0br.it\0cb.it\0pa.gov.pl\0" +"gifu.gifu.jp\0" +"id.vn\0servers.run\0" +"narvik.no\0" +"kimino.wakayama.jp\0go.th\0" +"orland.no\0tickets\0execute-api.ap-northeast-2.amazonaws.com\0emrstudio-prod.us-east-1.amazonaws.com\0bnr.la\0" +"yamato.kumamoto.jp\0go.tj\0" +"s3-accesspoint-fips.us-east-1.amazonaws.com\0" +"mutsuzawa.chiba.jp\0kakinoki.shimane.jp\0" +"nome.cv\0" +"is.eu.org\0" +"psse.gov.pl\0" +"navy\0" +"gv.vc\0" +"maizuru.kyoto.jp\0" +"go.ug\0" +"asaminami.hiroshima.jp\0" +"*.dev.adobeaemcloud.com\0" +"at.it\0go.tz\0" +"\xe6\x84\x9b\xe5\xaa\x9b.jp\0kamakura.kanagawa.jp\0landrover\0" +"webview-assets.aws-cloud9.eu-west-3.amazonaws.com\0" +"shingu.fukuoka.jp\0hirata.fukushima.jp\0" +"press.ma\0foo\0" +"am.in\0" +"rio.br\0taki.mie.jp\0" +"matsuyama.ehime.jp\0williamhill\0" +"b\xc3\xa6rum.no\0" +"fox\0" +"poivron.org\0" +"authgear-staging.com\0" +"venice.it\0" +"bahcavuotna.no\0s3-website-us-west-2.amazonaws.com\0" +"perspecta.cloud\0onporter.run\0" +"it.eu.org\0" +"incheon.kr\0" +"framer.photos\0" +"sumomo.ne.jp\0" +"!city.kawasaki.jp\0saikai.nagasaki.jp\0" +"dealer\0" +"gal\0" +"ga.us\0vfs.cloud9.ap-south-1.amazonaws.com\0" +"gap\0" +"cc.va.us\0" +"kawagoe.saitama.jp\0" +"grane.no\0donetsk.ua\0af-south-1.elasticbeanstalk.com\0" +"pr.gov.br\0" +"codes\0" +"gay\0" +"fujisato.akita.jp\0squares.net\0at.md\0" +"frl\0" +"execute-api.me-south-1.amazonaws.com\0" +"avocats.bj\0avellino.it\0" +"beardu.no\0s3-accesspoint.ap-south-2.amazonaws.com\0cechire.com\0" +"lecco.it\0tsuruta.aomori.jp\0\xe4\xbc\x81\xe4\xb8\x9a\0" +"shimoda.shizuoka.jp\0gbiz\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd9\x87\0" +"misato.saitama.jp\0" +"juniper\0\xe7\xbd\x91\xe7\xbb\x9c\0pages.dev\0" +"from-ut.com\0" +"execute-api.eu-south-1.amazonaws.com\0" +"\xd1\x80\xd1\x84\0" +"protection\0" +"tashkent.su\0wixsite.com\0" +"\xe8\xb0\xb7\xe6\xad\x8c\0" +"linkyard.cloud\0" +"bashkiria.ru\0" +"kashima.ibaraki.jp\0kitamoto.saitama.jp\0" +"space\0tele.amune.org\0" +"mat.br\0traniandriabarletta.it\0gdn\0co.financial\0" +"gea\0in.eu.org\0" +"olbiatempio.it\0asahi.mie.jp\0ftr\0" +"dn.ua\0" +"ikata.ehime.jp\0miyako.iwate.jp\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0" +"bashkiria.su\0" +"kharkiv.ua\0notebook-fips.us-west-2.sagemaker.aws\0studio.eu-south-1.sagemaker.aws\0" +"hasami.nagasaki.jp\0kitadaito.okinawa.jp\0goldpoint\0" +"fun\0" +"k12.va.us\0" +"yuzawa.niigata.jp\0" +"s3-object-lambda.ap-southeast-4.amazonaws.com\0jelastic.regruhosting.ru\0" +"pors\xc3\xa1\xc5\x8bgu.no\0" +"\xd7\xa6\xd7\x94\xd7\x9c.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0assabu.hokkaido.jp\0" +"musician.io\0" +"lucca.it\0" +"notebook.sa-east-1.sagemaker.aws\0" +"maintenance.aero\0" +"k12.ut.us\0" +"wroc.pl\0" +"eu-north-1.elasticbeanstalk.com\0" +"monza-e-della-brianza.it\0" +"lahppi.no\0is-an-entertainer.com\0" +"malbork.pl\0" +"gr.com\0" +"rep.br\0numata.gunma.jp\0" +"s3-website.us-east-2.amazonaws.com\0" +"smola.no\0" +"s3-accesspoint.ap-southeast-1.amazonaws.com\0" +"shimotsuke.tochigi.jp\0" +"hockey\0georgia.su\0" +"bd.se\0" +"k12.tn.us\0""611.to\0" +"kanoya.kagoshima.jp\0" +"hokksund.no\0cc.ri.us\0" +"s3.eu-north-1.amazonaws.com\0" +"ikeda.gifu.jp\0" +"suginami.tokyo.jp\0shopselect.net\0s3.pl-waw.scw.cloud\0" +"fyi\0" +"rzgw.gov.pl\0" +"vegas\0" +"\xd0\xbc\xd0\xba\xd0\xb4\0" +"memset.net\0" +"b\xc3\xb8mlo.no\0villas\0" +"carbonia-iglesias.it\0" +"keymachine.de\0" +"sande.more-og-romsdal.no\0sykkylven.no\0" +"vfs.cloud9.us-east-1.amazonaws.com\0" +"agro.pl\0" +"academia.bo\0" +"joso.ibaraki.jp\0" +"contagem.br\0miyashiro.saitama.jp\0" +"stor-elvdal.no\0" +"fr\xc3\xa6na.no\0" +"uchinomi.kagawa.jp\0" +"balat.no\0" +"taira.toyama.jp\0" +"s3-ap-northeast-3.amazonaws.com\0misconfused.org\0at.vg\0" +"adobeio-static.net\0" +"my-vigor.de\0" +"fukui.jp\0" +"*.compute-1.amazonaws.com\0" +"bluebite.io\0" +"gle\0" +"\xe5\xaf\x8c\xe5\xb1\xb1.jp\0haiphong.vn\0" +"kamogawa.chiba.jp\0mashiki.kumamoto.jp\0kamikitayama.nara.jp\0" +"no-ip.net\0" +"studio-fips.us-gov-east-1.sagemaker.aws\0" +"career\0" +"aukra.no\0" +"naganohara.gunma.jp\0" +"s3-website.ap-east-1.amazonaws.com\0pyatigorsk.ru\0" +"notebook.eu-central-2.sagemaker.aws\0" +"holiday\0" +"mihama.wakayama.jp\0" +"s3-object-lambda.ap-northeast-1.amazonaws.com\0" +"is-a-student.com\0kalmykia.su\0" +"la-spezia.it\0" +"s3-object-lambda.ap-east-1.amazonaws.com\0from-nm.com\0hk.org\0" +"gmo\0" +"ebiz.tw\0" +"tra.kp\0" +"\xd0\xbc\xd0\xbe\xd0\xbd\0" +"kopervik.no\0" +"toyama.jp\0kiryu.gunma.jp\0minamiawaji.hyogo.jp\0gmx\0" +"adobeaemcloud.com\0myfast.space\0" +"v.bg\0" +"priv.pl\0" +"haga.tochigi.jp\0cheap\0group\0" +"cc.oh.us\0yodobashi\0" +"international\0" +"lindas.no\0" +"mitou.yamaguchi.jp\0" +"hungyen.vn\0whitesnow.jp\0" +"o.bg\0" +"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x81\xd1\x80\xd0\xb1\0goo\0s3-object-lambda.eu-west-1.amazonaws.com\0" +"gop\0" +"vadso.no\0" +"co.krd\0" +"homegoods\0" +"got\0" +"emrnotebooks-prod.eu-central-1.amazonaws.com\0" +"gov\0kawatana.nagasaki.jp\0hachijo.tokyo.jp\0s3.isk02.sakurastorage.jp\0" +"ui.nabu.casa\0" +"repl.run\0" +"h.bg\0kalmykia.ru\0" +"yame.fukuoka.jp\0" +"rdy.jp\0" +"cc.nj.us\0" +"kamikawa.hokkaido.jp\0rep.kp\0execute-api.cn-north-1.amazonaws.com.cn\0" +"priv.no\0" +"alta.no\0" +"date.hokkaido.jp\0" +"a.bg\0fitjar.no\0movie\0c.cdn77.org\0" +"nikon\0" +"matsumoto.nagano.jp\0instantcloud.cn\0" +"toon.ehime.jp\0" +"cc.ms.us\0cc.nc.us\0" +"shirosato.ibaraki.jp\0po.gov.pl\0" +"barcelona\0" +"g.vbrplsbx.io\0" +"yukuhashi.fukuoka.jp\0kameoka.kyoto.jp\0kyotamba.kyoto.jp\0" +"s3-object-lambda.ca-central-1.amazonaws.com\0" +"tromso.no\0" +"aquila.it\0" +"birkenes.no\0" +"isernia.it\0tamakawa.fukushima.jp\0kitahata.saga.jp\0" +"hbo\0" +"trentinoalto-adige.it\0" +"agric.za\0secure\0" +"higashisumiyoshi.osaka.jp\0travel.pl\0" +"yoro.gifu.jp\0" +"chernigov.ua\0k12.or.us\0" +"musashino.tokyo.jp\0" +"notebook.ap-south-1.sagemaker.aws\0" +"notebook.cn-northwest-1.sagemaker.com.cn\0" +"priv.me\0cc.me.us\0dreamhosters.com\0" +"okegawa.saitama.jp\0lubin.pl\0\xe6\x85\x88\xe5\x96\x84\0" +"chikujo.fukuoka.jp\0nome.pt\0" +"orskog.no\0" +"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86.ir\0" +"hasvik.no\0s3-accesspoint.ap-northeast-1.amazonaws.com\0" +"osakikamijima.hiroshima.jp\0" +"ass.km\0" +"saloon.jp\0" +"tranby.no\0" +"nakayama.yamagata.jp\0" +"ntr.br\0sondrio.it\0tsuyama.okayama.jp\0" +"eidsberg.no\0edeka\0" +"sport.hu\0serveftp.org\0" +"ecommerce-shop.pl\0" +"hirokawa.fukuoka.jp\0" +"akamaiorigin-staging.net\0" +"\xe5\x8f\xb0\xe7\x81\xa3\0" +"nisshin.aichi.jp\0" +"k12.ok.us\0" +"biella.it\0" +"pics\0tlon.network\0" +"tarama.okinawa.jp\0fujimi.saitama.jp\0" +"bounty-full.com\0" +"lazio.it\0\xd8\xb3\xd9\x88\xd8\xaf\xd8\xa7\xd9\x86\0" +"otsuka\0podzone.org\0" +"yashiro.hyogo.jp\0kurobe.toyama.jp\0" +"kiso.nagano.jp\0" +"7.bg\0" +"akabira.hokkaido.jp\0psp.gov.pl\0" +"k12.mn.us\0s3-website.dualstack.ap-southeast-2.amazonaws.com\0" +"*.stolos.io\0" +"wien\0deci.jp\0" +"cloud\0" +"directory\0ddnss.de\0" +"kamigori.hyogo.jp\0seika.kyoto.jp\0" +"s3-website.dualstack.cn-north-1.amazonaws.com.cn\0" +"nagai.yamagata.jp\0noho.st\0" +"0.bg\0s3-ap-southeast-1.amazonaws.com\0" +"kita.kyoto.jp\0travel.tt\0senseering.net\0" +"k12.nm.us\0" +"hamatonbetsu.hokkaido.jp\0" +"s3-accesspoint.dualstack.sa-east-1.amazonaws.com\0" +"assur.bj\0asahi.yamagata.jp\0" +"r\xc3\xb8yrvik.no\0s3-deprecated.eu-west-1.amazonaws.com\0" +"draydns.de\0" +"algard.no\0caracal.mythic-beasts.com\0" +"wedding\0forgot.her.name\0" +"git-pages.rit.edu\0" +"emrstudio-prod.us-gov-west-1.amazonaws.com\0dnsdojo.com\0" +"it.com\0" +"xerox\0" +"fortal.br\0jelastic.tsukaeru.net\0" +"synology-ds.de\0" +"sakura\0" +"tokai.ibaraki.jp\0taito.tokyo.jp\0" +"pueblo.bo\0" +"namerikawa.toyama.jp\0" +"poltava.ua\0dd-dns.de\0" +"trentinoa-adige.it\0otsu.shiga.jp\0" +"satsumasendai.kagoshima.jp\0" +"s3-object-lambda.ap-southeast-3.amazonaws.com\0s3-accesspoint-fips.dualstack.us-west-2.amazonaws.com\0" +"hiv\0" +"execute-api.ap-southeast-4.amazonaws.com\0paas.datacenter.fi\0" +"rygge.no\0" +"babia-gora.pl\0" +"\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\x9f\0" +"shimosuwa.nagano.jp\0" +"engerdal.no\0" +"k12.ky.us\0\xe5\x81\xa5\xe5\xba\xb7\0" +"ssl.origin.cdn77-secure.org\0" +"royal-commission.uk\0" +"heroy.nordland.no\0from-nh.com\0" +"diskussionsbereich.de\0" +"pr.gov.pl\0r.cdn77.net\0" +"is-a-therapist.com\0" +"tokashiki.okinawa.jp\0yoshida.shizuoka.jp\0westus2.azurestaticapps.net\0" +"konsulat.gov.pl\0" +"m\xc3\xa5s\xc3\xb8y.no\0" +"hashikami.aomori.jp\0hkt\0" +"dscloud.me\0" +"sue.fukuoka.jp\0tsubata.ishikawa.jp\0" +"skierva.no\0notebook.ap-southeast-2.sagemaker.aws\0" +"oita.oita.jp\0dontexist.net\0" +"wiki\0" +"des.br\0" +"blackfriday\0" +"ar.com\0fentiger.mythic-beasts.com\0dsmynas.com\0" +"onna.okinawa.jp\0" +"nysa.pl\0" +"s3-accesspoint-fips.ca-central-1.amazonaws.com\0" +"aarborte.no\0" +"matsumoto.kagoshima.jp\0tonaki.okinawa.jp\0" +"barrel-of-knowledge.info\0" +"cs.keliweb.cloud\0" +"zj.cn\0zentsuji.kagawa.jp\0" +"equipment\0" +"fjaler.no\0lynx.mythic-beasts.com\0" +"emrnotebooks-prod.sa-east-1.amazonaws.com\0" +"okayama.jp\0" +"\xe6\x94\xbf\xe5\xba\x9c.hk\0b\xc3\xa1id\xc3\xa1r.no\0" +"adult\0flop.jp\0" +"krager\xc3\xb8.no\0official.ec\0" +"trentin-sudtirol.it\0jinsekikogen.hiroshima.jp\0" +"bike\0" +"yugawa.fukushima.jp\0" +"tado.mie.jp\0" +"romskog.no\0valle.no\0wine\0za.com\0" +"iwate.jp\0\xd8\xa7\xd9\x84\xd8\xa8\xd8\xad\xd8\xb1\xd9\x8a\xd9\x86\0" +"hazu.aichi.jp\0" +"koganei.tokyo.jp\0kicks-ass.net\0hippy.jp\0" +"valledaosta.it\0" +"school.na\0" +"yoshikawa.saitama.jp\0hot\0" +"lib.vi.us\0s3-fips.us-gov-west-1.amazonaws.com\0" +"santamaria.br\0showa.fukushima.jp\0" +"how\0ping\0" +"o.se\0cuisinella\0" +"shiwa.iwate.jp\0" +"cc.fl.us\0catholic\0pink\0" +"1.azurestaticapps.net\0" +"cloud66.ws\0" +"flap.id\0" +"pt.eu.org\0" +"lib.tn.us\0" +"oristano.it\0" +"karlsoy.no\0" +"h.se\0v.ua\0" +"school.nz\0" +"apple\0" +"trentino-a-adige.it\0" +"mw.gov.pl\0" +"hara.nagano.jp\0" +"ddns.me\0" +"pinb.gov.pl\0" +"bing\0s3.ap-southeast-1.amazonaws.com\0in-berlin.de\0" +"uki.kumamoto.jp\0joetsu.niigata.jp\0" +"plurinacional.bo\0a.se\0docs\0" +"bari.it\0" +"bronnoysund.no\0" +"ohira.tochigi.jp\0" +"yoga\0" +"abogado\0" +"ibm\0emrappui-prod.ap-east-1.amazonaws.com\0" +"yokawa.hyogo.jp\0" +"trentino-altoadige.it\0" +"ice\0" +"shimizu.hokkaido.jp\0" +"*.database.run\0" +"\xe8\x8c\xa8\xe5\x9f\x8e.jp\0" +"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x80\xd1\x83\xd1\x81\0" +"london.cloudapps.digital\0" +"ibxos.it\0" +"ms.gov.br\0anjo.aichi.jp\0hagi.yamaguchi.jp\0" +"asker.no\0icu\0my-firewall.org\0" +"nishinomiya.hyogo.jp\0website.yandexcloud.net\0" +"mo\xc3\xa5reke.no\0" +"sekigahara.gifu.jp\0" +"barum.no\0homesecuritymac.com\0" +"\xe7\xb5\x84\xe7\xb9\x94.tw\0" +"kyotanabe.kyoto.jp\0\xe6\x9c\xba\xe6\x9e\x84\0at-band-camp.net\0" +"oksnes.no\0" +"leasing.aero\0" +"zamami.okinawa.jp\0" +"kitagata.gifu.jp\0mizunami.gifu.jp\0manno.kagawa.jp\0mitoyo.kagawa.jp\0" +"lib.sc.us\0crd.co\0" +"tsuchiura.ibaraki.jp\0" +"fukuyama.hiroshima.jp\0" +"gs.ah.no\0" +"is-a-bruinsfan.org\0" +"mycd.eu\0" +"mt.gov.br\0gliwice.pl\0" +"woodside\0from-tx.com\0" +"yamagata.nagano.jp\0" +"leitungsen.de\0" +"soeda.fukuoka.jp\0" +"tv.bb\0" +"niigata.niigata.jp\0" +"gs.aa.no\0ifm\0" +"luxury\0" +"utsunomiya.tochigi.jp\0" +"fastly-terrarium.com\0" +"sn\xc3\xa5""ase.no\0webview-assets.cloud9.eu-west-1.amazonaws.com\0ddnsking.com\0" +"tv.bo\0" +"tv.br\0hakui.ishikawa.jp\0" +"maceio.br\0" +"trentin-s\xc3\xbc""dtirol.it\0tsukuba.ibaraki.jp\0" +"*.spectrum.myjino.ru\0" +"uzhhorod.ua\0ca-central-1.elasticbeanstalk.com\0myforum.community\0" +"adult.ht\0" +"soccer\0" +"vfs.cloud9.me-south-1.amazonaws.com\0" +"kitami.hokkaido.jp\0walter\0" +"obanazawa.yamagata.jp\0" +"platter-app.com\0" +"niigata.jp\0iwaki.fukushima.jp\0" +"tube\0" +"urausu.hokkaido.jp\0" +"lk3.ru\0" +"press.aero\0" +"nishiazai.shiga.jp\0abu.yamaguchi.jp\0" +"leirvik.no\0" +"greta.fr\0" +"emrstudio-prod.ap-southeast-1.amazonaws.com\0from-ok.com\0" +"potenza.it\0" +"mochizuki.nagano.jp\0nieruchomosci.pl\0search\0" +"webview-assets.cloud9.ap-southeast-1.amazonaws.com\0" +"kai.yamanashi.jp\0" +"uzhgorod.ua\0" +"sx.cn\0iitate.fukushima.jp\0yachiyo.ibaraki.jp\0suzaka.nagano.jp\0" +"vang.no\0" +"africa\0catering\0protonet.io\0" +"bci.dnstrace.pro\0" +"wzmiuw.gov.pl\0" +"from-hi.com\0" +"shiiba.miyazaki.jp\0" }; static const quint16 tldChunkCount = 2; -static const quint32 tldChunks[] = {65528, 127122}; +static const quint32 tldChunks[] = {65516, 127046}; QT_END_NAMESPACE From ebdc28670dc0b1c0a10d0e860922ba0c21f86b54 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 19 Dec 2023 14:22:37 +0100 Subject: [PATCH 33/58] Http2: fix potential overflow in assemble_hpack_block() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function is given a vector of Http2::Frame's and flattens it into a vector. While each Frame can contain a maximum of 16GiB of data (24-bit size field), one "only" needs 257 of them to overflow the quint32 variable's range. So make sure any overflow does not go undetected. Keep the limited uint32_t range for now, as we don't know whether all consumers of the result can deal with more than 4GiB of data. Since all these frames must be in memory, this cannot overflow in practice on 32-bit machines. Manual conflict resolutions: - qAddOverflow -> add_overflow (the former doesn't exist in Qt 5). Change-Id: Iafaa7d1c870cba9100e75065db11d95934f86213 Reviewed-by: Mårten Nordheim (cherry picked from commit 1e6bb61af3ae29755f93b92f157df026f934ae61) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit af8a9874c32c6b1af8998be9487170b6269dbe1f) (cherry picked from commit 2e50fbc30a61d69cc2caf6fbd8aca29aa6b8db86) (cherry picked from commit 3e1088416fd7bad353bbaa450d80a44ecf68adb7) (cherry picked from commit 76e6d922b9315b9fefade96a6852dc187cdafc94) Reviewed-by: Qt CI Bot --- src/network/access/qhttp2protocolhandler.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index 3409224f206..d1b5dfda2e2 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -46,6 +46,8 @@ #include #include + +#include #include #include #include @@ -124,8 +126,10 @@ std::vector assemble_hpack_block(const std::vector &frames) std::vector hpackBlock; quint32 total = 0; - for (const auto &frame : frames) - total += frame.hpackBlockSize(); + for (const auto &frame : frames) { + if (add_overflow(total, frame.hpackBlockSize(), &total)) + return hpackBlock; + } if (!total) return hpackBlock; From 3a7246b58f92900a01af02437d5e21cbd3bd60ad Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 30 Jan 2024 16:56:47 +0100 Subject: [PATCH 34/58] Update bundled libpng to version 1.6.41 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ChangeLog][Third-Party Code] libpng was updated to version 1.6.41 Change-Id: I3285bfa11f61c571ffda1b365011a5c6a798ca68 Reviewed-by: Kai Köhne (cherry picked from commit 528032c02771ddc35d054ff8d414b382904b607e) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 03bf71b7ff505b683edd484892f429a21b52d201) (cherry picked from commit 48b36d89c4b03e31d481c77b9383bd4517517c3b) (cherry picked from commit dce60a765e3724cae4d4d1dfaebfcc84f167289c) Reviewed-by: Eirik Aavitsland (cherry picked from commit 2f1cd87411b2471559b810941da71bfd22da2a9c) --- src/3rdparty/libpng/ANNOUNCE | 50 +++-- src/3rdparty/libpng/CHANGES | 32 ++++ src/3rdparty/libpng/LICENSE | 4 +- src/3rdparty/libpng/README | 2 +- src/3rdparty/libpng/libpng-manual.txt | 6 +- src/3rdparty/libpng/png.c | 73 ++----- src/3rdparty/libpng/png.h | 52 ++--- src/3rdparty/libpng/pngconf.h | 4 +- src/3rdparty/libpng/pngerror.c | 34 ++-- src/3rdparty/libpng/pngget.c | 245 ++++++++++++------------ src/3rdparty/libpng/pnglibconf.h | 9 +- src/3rdparty/libpng/pngpread.c | 8 +- src/3rdparty/libpng/pngpriv.h | 110 +++++++++-- src/3rdparty/libpng/pngread.c | 8 +- src/3rdparty/libpng/pngrtran.c | 6 +- src/3rdparty/libpng/pngrutil.c | 19 +- src/3rdparty/libpng/pngset.c | 22 ++- src/3rdparty/libpng/pngtrans.c | 14 +- src/3rdparty/libpng/pngwrite.c | 19 +- src/3rdparty/libpng/pngwutil.c | 10 +- src/3rdparty/libpng/qt_attribution.json | 8 +- 21 files changed, 428 insertions(+), 307 deletions(-) diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE index 404cbb0de9a..800446b059b 100644 --- a/src/3rdparty/libpng/ANNOUNCE +++ b/src/3rdparty/libpng/ANNOUNCE @@ -1,5 +1,5 @@ -libpng 1.6.40 - June 21, 2023 -============================= +libpng 1.6.41 - January 24, 2024 +================================ This is a public release of libpng, intended for use in production code. @@ -9,13 +9,13 @@ Files available for download Source files with LF line endings (for Unix/Linux): - * libpng-1.6.40.tar.xz (LZMA-compressed, recommended) - * libpng-1.6.40.tar.gz + * libpng-1.6.41.tar.xz (LZMA-compressed, recommended) + * libpng-1.6.41.tar.gz (deflate-compressed) Source files with CRLF line endings (for Windows): - * lpng1640.7z (LZMA-compressed, recommended) - * lpng1640.zip + * lpng1641.7z (LZMA-compressed, recommended) + * lpng1641.zip (deflate-compressed) Other information: @@ -25,15 +25,39 @@ Other information: * TRADEMARK.md -Changes from version 1.6.39 to version 1.6.40 +Changes from version 1.6.40 to version 1.6.41 --------------------------------------------- - * Fixed the eXIf chunk multiplicity checks. - * Fixed a memory leak in pCAL processing. - * Corrected the validity report about tRNS inside png_get_valid(). - * Fixed various build issues on *BSD, Mac and Windows. - * Updated the configurations and the scripts for continuous integration. - * Cleaned up the code, the build scripts, and the documentation. + * Added SIMD-optimized code for the Loongarch LSX hardware. + (Contributed by GuXiWei, JinBo and ZhangLixia) + * Fixed the run-time discovery of MIPS MSA hardware. + (Contributed by Sui Jingfeng) + * Fixed an off-by-one error in the function `png_do_check_palette_indexes`, + which failed to recognize errors that might have existed in the first + column of a broken palette-encoded image. This was a benign regression + accidentally introduced in libpng-1.6.33. No pixel was harmed. + (Contributed by Adam Richter; reviewed by John Bowler) + * Fixed, improved and modernized the contrib/pngminus programs, i.e., + png2pnm.c and pnm2png.c + * Removed old and peculiar portability hacks that were meant to silence + warnings issued by gcc version 7.1 alone. + (Contributed by John Bowler) + * Fixed and modernized the CMake file, and raised the minimum required + CMake version from 3.1 to 3.6. + (Contributed by Clinton Ingram, Timothy Lyanguzov, Tyler Kropp, et al.) + * Allowed the configure script to disable the building of auxiliary tools + and tests, thus catching up with the CMake file. + (Contributed by Carlo Bramini) + * Fixed a build issue on Mac. + (Contributed by Zixu Wang) + * Moved the Autoconf macro files to scripts/autoconf. + * Moved the CMake files (except for the main CMakeLists.txt) to + scripts/cmake and moved the list of their contributing authors to + scripts/cmake/AUTHORS.md + * Updated the CI configurations and scripts. + * Relicensed the CI scripts to the MIT License. + * Improved the test coverage. + (Contributed by John Bowler) Send comments/corrections/commendations to png-mng-implement at lists.sf.net. diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES index 2d8c585c0e7..2d9a57e439e 100644 --- a/src/3rdparty/libpng/CHANGES +++ b/src/3rdparty/libpng/CHANGES @@ -6129,6 +6129,38 @@ Version 1.6.40 [June 21, 2023] Updated the configurations and the scripts for continuous integration. Cleaned up the code, the build scripts, and the documentation. +Version 1.6.41 [January 24, 2024] + Added SIMD-optimized code for the Loongarch LSX hardware. + (Contributed by GuXiWei, JinBo and ZhangLixia) + Fixed the run-time discovery of MIPS MSA hardware. + (Contributed by Sui Jingfeng) + Fixed an off-by-one error in the function `png_do_check_palette_indexes`, + which failed to recognize errors that might have existed in the first + column of a broken palette-encoded image. This was a benign regression + accidentally introduced in libpng-1.6.33. No pixel was harmed. + (Contributed by Adam Richter; reviewed by John Bowler) + Fixed, improved and modernized the contrib/pngminus programs, i.e., + png2pnm.c and pnm2png.c + Removed old and peculiar portability hacks that were meant to silence + warnings issued by gcc version 7.1 alone. + (Contributed by John Bowler) + Fixed and modernized the CMake file, and raised the minimum required + CMake version from 3.1 to 3.6. + (Contributed by Clinton Ingram, Timothy Lyanguzov, Tyler Kropp, et al.) + Allowed the configure script to disable the building of auxiliary tools + and tests, thus catching up with the CMake file. + (Contributed by Carlo Bramini) + Fixed a build issue on Mac. + (Contributed by Zixu Wang) + Moved the Autoconf macro files to scripts/autoconf. + Moved the CMake files (except for the main CMakeLists.txt) to + scripts/cmake and moved the list of their contributing authors to + scripts/cmake/AUTHORS.md + Updated the CI configurations and scripts. + Relicensed the CI scripts to the MIT License. + Improved the test coverage. + (Contributed by John Bowler) + Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement diff --git a/src/3rdparty/libpng/LICENSE b/src/3rdparty/libpng/LICENSE index 086d1c2fda6..25f298f0fcf 100644 --- a/src/3rdparty/libpng/LICENSE +++ b/src/3rdparty/libpng/LICENSE @@ -4,8 +4,8 @@ COPYRIGHT NOTICE, DISCLAIMER, and LICENSE PNG Reference Library License version 2 --------------------------------------- - * Copyright (c) 1995-2023 The PNG Reference Library Authors. - * Copyright (c) 2018-2023 Cosmin Truta. + * Copyright (c) 1995-2024 The PNG Reference Library Authors. + * Copyright (c) 2018-2024 Cosmin Truta. * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. * Copyright (c) 1996-1997 Andreas Dilger. * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README index dedd2c1639e..1f51a808f7f 100644 --- a/src/3rdparty/libpng/README +++ b/src/3rdparty/libpng/README @@ -1,4 +1,4 @@ -README for libpng version 1.6.40 +README for libpng version 1.6.41 ================================ See the note about version numbers near the top of `png.h`. diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt index 67b50788266..dbb60af61d1 100644 --- a/src/3rdparty/libpng/libpng-manual.txt +++ b/src/3rdparty/libpng/libpng-manual.txt @@ -1,6 +1,6 @@ libpng-manual.txt - A description on how to use and modify libpng - Copyright (c) 2018-2023 Cosmin Truta + Copyright (c) 2018-2024 Cosmin Truta Copyright (c) 1998-2018 Glenn Randers-Pehrson This document is released under the libpng license. @@ -9,9 +9,9 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng version 1.6.36, December 2018, through 1.6.40 - June 2023 + libpng version 1.6.36, December 2018, through 1.6.41 - January 2024 Updated and distributed by Cosmin Truta - Copyright (c) 2018-2023 Cosmin Truta + Copyright (c) 2018-2024 Cosmin Truta libpng versions 0.97, January 1998, through 1.6.35 - July 2018 Updated and distributed by Glenn Randers-Pehrson diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c index d6471b06ccd..e411381f8f9 100644 --- a/src/3rdparty/libpng/png.c +++ b/src/3rdparty/libpng/png.c @@ -1,7 +1,7 @@ /* png.c - location for general purpose libpng functions * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -14,27 +14,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_40 Your_png_h_is_not_version_1_6_40; - -#ifdef __GNUC__ -/* The version tests may need to be added to, but the problem warning has - * consistently been fixed in GCC versions which obtain wide-spread release. - * The problem is that many versions of GCC rearrange comparison expressions in - * the optimizer in such a way that the results of the comparison will change - * if signed integer overflow occurs. Such comparisons are not permitted in - * ANSI C90, however GCC isn't clever enough to work out that that do not occur - * below in png_ascii_from_fp and png_muldiv, so it produces a warning with - * -Wextra. Unfortunately this is highly dependent on the optimizer and the - * machine architecture so the warning comes and goes unpredictably and is - * impossible to "fix", even were that a good idea. - */ -#if __GNUC__ == 7 && __GNUC_MINOR__ == 1 -#define GCC_STRICT_OVERFLOW 1 -#endif /* GNU 7.1.x */ -#endif /* GNU */ -#ifndef GCC_STRICT_OVERFLOW -#define GCC_STRICT_OVERFLOW 0 -#endif +typedef png_libpng_version_1_6_41 Your_png_h_is_not_version_1_6_41; /* Tells libpng that we have already handled the first "num_bytes" bytes * of the PNG file signature. If the PNG data is embedded into another @@ -73,21 +53,21 @@ png_set_sig_bytes(png_structrp png_ptr, int num_bytes) int PNGAPI png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check) { - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + static const png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; if (num_to_check > 8) num_to_check = 8; else if (num_to_check < 1) - return (-1); + return -1; if (start > 7) - return (-1); + return -1; if (start + num_to_check > 8) num_to_check = 8 - start; - return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check))); + return memcmp(&sig[start], &png_signature[start], num_to_check); } #endif /* READ */ @@ -447,7 +427,6 @@ png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size), memset(info_ptr, 0, (sizeof *info_ptr)); } -/* The following API is not called internally */ void PNGAPI png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, int freer, png_uint_32 mask) @@ -686,9 +665,9 @@ png_voidp PNGAPI png_get_io_ptr(png_const_structrp png_ptr) { if (png_ptr == NULL) - return (NULL); + return NULL; - return (png_ptr->io_ptr); + return png_ptr->io_ptr; } #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) @@ -752,7 +731,7 @@ png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) { size_t pos = 0; - char number_buf[5]; /* enough for a four-digit year */ + char number_buf[5] = {0, 0, 0, 0, 0}; /* enough for a four-digit year */ # define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string)) # define APPEND_NUMBER(format, value)\ @@ -815,8 +794,8 @@ png_get_copyright(png_const_structrp png_ptr) return PNG_STRING_COPYRIGHT #else return PNG_STRING_NEWLINE \ - "libpng version 1.6.40" PNG_STRING_NEWLINE \ - "Copyright (c) 2018-2023 Cosmin Truta" PNG_STRING_NEWLINE \ + "libpng version 1.6.41" PNG_STRING_NEWLINE \ + "Copyright (c) 2018-2024 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ @@ -977,7 +956,7 @@ png_reset_zstream(png_structrp png_ptr) return Z_STREAM_ERROR; /* WARNING: this resets the window bits to the maximum! */ - return (inflateReset(&png_ptr->zstream)); + return inflateReset(&png_ptr->zstream); } #endif /* READ */ @@ -986,7 +965,7 @@ png_uint_32 PNGAPI png_access_version_number(void) { /* Version of *.c files used when building libpng */ - return((png_uint_32)PNG_LIBPNG_VER); + return (png_uint_32)PNG_LIBPNG_VER; } #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) @@ -2891,14 +2870,6 @@ png_pow10(int power) /* Function to format a floating point value in ASCII with a given * precision. */ -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic push -/* The problem arises below with exp_b10, which can never overflow because it - * comes, originally, from frexp and is therefore limited to a range which is - * typically +/-710 (log2(DBL_MAX)/log2(DBL_MIN)). - */ -#pragma GCC diagnostic warning "-Wstrict-overflow=2" -#endif /* GCC_STRICT_OVERFLOW */ void /* PRIVATE */ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size, double fp, unsigned int precision) @@ -3220,10 +3191,6 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size, /* Here on buffer too small. */ png_error(png_ptr, "ASCII conversion buffer too small"); } -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic pop -#endif /* GCC_STRICT_OVERFLOW */ - # endif /* FLOATING_POINT */ # ifdef PNG_FIXED_POINT_SUPPORTED @@ -3251,7 +3218,7 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, if (num <= 0x80000000) /* else overflowed */ { unsigned int ndigits = 0, first = 16 /* flag value */; - char digits[10]; + char digits[10] = {0}; while (num) { @@ -3336,15 +3303,6 @@ png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) * the nearest .00001). Overflow and divide by zero are signalled in * the result, a boolean - true on success, false on overflow. */ -#if GCC_STRICT_OVERFLOW /* from above */ -/* It is not obvious which comparison below gets optimized in such a way that - * signed overflow would change the result; looking through the code does not - * reveal any tests which have the form GCC complains about, so presumably the - * optimizer is moving an add or subtract into the 'if' somewhere. - */ -#pragma GCC diagnostic push -#pragma GCC diagnostic warning "-Wstrict-overflow=2" -#endif /* GCC_STRICT_OVERFLOW */ int png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, png_int_32 divisor) @@ -3459,9 +3417,6 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, return 0; } -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic pop -#endif /* GCC_STRICT_OVERFLOW */ #endif /* READ_GAMMA || INCH_CONVERSIONS */ #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h index cfc4841099d..d78c7799341 100644 --- a/src/3rdparty/libpng/png.h +++ b/src/3rdparty/libpng/png.h @@ -1,9 +1,9 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.40 + * libpng version 1.6.41 * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -15,7 +15,7 @@ * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.97, January 1998, through 1.6.35, July 2018: * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.40, June 2023: + * libpng versions 1.6.36, December 2018, through 1.6.41, January 2024: * Cosmin Truta * See also "Contributing Authors", below. */ @@ -27,8 +27,8 @@ * PNG Reference Library License version 2 * --------------------------------------- * - * * Copyright (c) 1995-2023 The PNG Reference Library Authors. - * * Copyright (c) 2018-2023 Cosmin Truta. + * * Copyright (c) 1995-2024 The PNG Reference Library Authors. + * * Copyright (c) 2018-2024 Cosmin Truta. * * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. * * Copyright (c) 1996-1997 Andreas Dilger. * * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -239,7 +239,7 @@ * ... * 1.5.30 15 10530 15.so.15.30[.0] * ... - * 1.6.40 16 10640 16.so.16.40[.0] + * 1.6.41 16 10641 16.so.16.41[.0] * * Henceforth the source version will match the shared-library major and * minor numbers; the shared-library major version number will be used for @@ -278,8 +278,8 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.40" -#define PNG_HEADER_VERSION_STRING " libpng version 1.6.40 - June 21, 2023\n" +#define PNG_LIBPNG_VER_STRING "1.6.41" +#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n" #define PNG_LIBPNG_VER_SONUM 16 #define PNG_LIBPNG_VER_DLLNUM 16 @@ -287,7 +287,7 @@ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 40 +#define PNG_LIBPNG_VER_RELEASE 41 /* This should be zero for a public release, or non-zero for a * development version. [Deprecated] @@ -318,7 +318,7 @@ * From version 1.0.1 it is: * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10640 /* 1.6.40 */ +#define PNG_LIBPNG_VER 10641 /* 1.6.41 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -428,7 +428,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_40; +typedef char* png_libpng_version_1_6_41; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * @@ -849,7 +849,7 @@ PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); #define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ /* Added to libpng-1.5.4 */ #define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ -#if INT_MAX >= 0x8000 /* else this might break */ +#if ~0U > 0xffffU /* or else this might break on a 16-bit machine */ #define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ #endif @@ -908,15 +908,15 @@ PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); /* Check sig[start] through sig[start + num_to_check - 1] to see if it's a * PNG file. Returns zero if the supplied bytes match the 8-byte PNG * signature, and non-zero otherwise. Having num_to_check == 0 or - * start > 7 will always fail (ie return non-zero). + * start > 7 will always fail (i.e. return non-zero). */ PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start, size_t num_to_check)); /* Simple signature checking function. This is the same as calling - * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + * png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) != 0). */ -#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) +#define png_check_sig(sig, n) (png_sig_cmp((sig), 0, (n)) != 0) /* Allocate and initialize png_ptr struct for reading, and any other memory. */ PNG_EXPORTA(4, png_structp, png_create_read_struct, @@ -1730,12 +1730,9 @@ PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 free_me, int num)); -/* Reassign responsibility for freeing existing data, whether allocated +/* Reassign the responsibility for freeing existing data, whether allocated * by libpng or by the application; this works on the png_info structure passed - * in, it does not change the state for other png_info structures. - * - * It is unlikely that this function works correctly as of 1.6.0 and using it - * may result either in memory leaks or double free of allocated data. + * in, without changing the state for other png_info structures. */ PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr, png_inforp info_ptr, int freer, png_uint_32 mask)); @@ -3207,11 +3204,18 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory, #ifdef PNG_MIPS_MSA_API_SUPPORTED # define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */ #endif -#define PNG_IGNORE_ADLER32 8 -#ifdef PNG_POWERPC_VSX_API_SUPPORTED -# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions supported */ +#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED +# define PNG_IGNORE_ADLER32 8 /* SOFTWARE: disable Adler32 check on IDAT */ #endif -#define PNG_OPTION_NEXT 12 /* Next option - numbers must be even */ +#ifdef PNG_POWERPC_VSX_API_SUPPORTED +# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions + * supported */ +#endif +#ifdef PNG_MIPS_MMI_API_SUPPORTED +# define PNG_MIPS_MMI 12 /* HARDWARE: MIPS MMI SIMD instructions supported */ +#endif + +#define PNG_OPTION_NEXT 14 /* Next option - numbers must be even */ /* Return values: NOTE: there are four values and 'off' is *not* zero */ #define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index 6671e3c3356..30c1aad52d7 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -1,9 +1,9 @@ /* pngconf.h - machine-configurable file for libpng * - * libpng version 1.6.40 + * libpng version 1.6.41 * - * Copyright (c) 2018-2022 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. diff --git a/src/3rdparty/libpng/pngerror.c b/src/3rdparty/libpng/pngerror.c index ec3a709b9d2..29ebda79437 100644 --- a/src/3rdparty/libpng/pngerror.c +++ b/src/3rdparty/libpng/pngerror.c @@ -1,7 +1,7 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -255,7 +255,7 @@ void png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, png_alloc_size_t value) { - char buffer[PNG_NUMBER_BUFFER_SIZE]; + char buffer[PNG_NUMBER_BUFFER_SIZE] = {0}; png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); } @@ -265,7 +265,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format, { png_alloc_size_t u; png_charp str; - char buffer[PNG_NUMBER_BUFFER_SIZE]; + char buffer[PNG_NUMBER_BUFFER_SIZE] = {0}; /* Avoid overflow by doing the negate in a png_alloc_size_t: */ u = (png_alloc_size_t)value; @@ -858,7 +858,7 @@ png_get_error_ptr(png_const_structrp png_ptr) if (png_ptr == NULL) return NULL; - return ((png_voidp)png_ptr->error_ptr); + return (png_voidp)png_ptr->error_ptr; } @@ -933,31 +933,25 @@ png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) #endif int /* PRIVATE */ -png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg) +png_safe_execute(png_imagep image, int (*function)(png_voidp), png_voidp arg) { - volatile png_imagep image = image_in; - volatile int result; - volatile png_voidp saved_error_buf; + png_voidp saved_error_buf = image->opaque->error_buf; jmp_buf safe_jmpbuf; + int result; - /* Safely execute function(arg) with png_error returning to this function. */ - saved_error_buf = image->opaque->error_buf; - result = setjmp(safe_jmpbuf) == 0; - - if (result != 0) + /* Safely execute function(arg), with png_error returning back here. */ + if (setjmp(safe_jmpbuf) == 0) { - image->opaque->error_buf = safe_jmpbuf; result = function(arg); + image->opaque->error_buf = saved_error_buf; + return result; } + /* On png_error, return via longjmp, pop the jmpbuf, and free the image. */ image->opaque->error_buf = saved_error_buf; - - /* And do the cleanup prior to any failure return. */ - if (result == 0) - png_image_free(image); - - return result; + png_image_free(image); + return 0; } #endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */ #endif /* READ || WRITE */ diff --git a/src/3rdparty/libpng/pngget.c b/src/3rdparty/libpng/pngget.c index 1490a032e1a..1084b268ff9 100644 --- a/src/3rdparty/libpng/pngget.c +++ b/src/3rdparty/libpng/pngget.c @@ -1,7 +1,7 @@ /* pngget.c - retrieval of values from info struct * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -28,22 +28,22 @@ png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, * valid tRNS chunk in this case. */ if (flag == PNG_INFO_tRNS && png_ptr->num_trans == 0) - return(0); + return 0; #endif - return(info_ptr->valid & flag); + return info_ptr->valid & flag; } - return(0); + return 0; } size_t PNGAPI png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->rowbytes); + return info_ptr->rowbytes; - return(0); + return 0; } #ifdef PNG_INFO_IMAGE_SUPPORTED @@ -51,9 +51,9 @@ png_bytepp PNGAPI png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->row_pointers); + return info_ptr->row_pointers; - return(0); + return 0; } #endif @@ -65,7 +65,7 @@ png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->width; - return (0); + return 0; } png_uint_32 PNGAPI @@ -74,7 +74,7 @@ png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->height; - return (0); + return 0; } png_byte PNGAPI @@ -83,7 +83,7 @@ png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->bit_depth; - return (0); + return 0; } png_byte PNGAPI @@ -92,7 +92,7 @@ png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->color_type; - return (0); + return 0; } png_byte PNGAPI @@ -101,7 +101,7 @@ png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->filter_type; - return (0); + return 0; } png_byte PNGAPI @@ -110,7 +110,7 @@ png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->interlace_type; - return (0); + return 0; } png_byte PNGAPI @@ -119,7 +119,7 @@ png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->compression_type; - return (0); + return 0; } png_uint_32 PNGAPI @@ -127,21 +127,20 @@ png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_x_pixels_per_meter"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", - "png_get_x_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->x_pixels_per_unit); - } + { + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return info_ptr->x_pixels_per_unit; + } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_uint_32 PNGAPI @@ -149,42 +148,41 @@ png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_y_pixels_per_meter"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", - "png_get_y_pixels_per_meter"); - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->y_pixels_per_unit); + return info_ptr->y_pixels_per_unit; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_uint_32 PNGAPI png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_pixels_per_meter"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter"); - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER && info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) - return (info_ptr->x_pixels_per_unit); + return info_ptr->x_pixels_per_unit; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } #ifdef PNG_FLOATING_POINT_SUPPORTED @@ -193,21 +191,21 @@ png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_READ_pHYs_SUPPORTED + png_debug(1, "in png_get_pixel_aspect_ratio"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); - if (info_ptr->x_pixels_per_unit != 0) - return ((float)((float)info_ptr->y_pixels_per_unit - /(float)info_ptr->x_pixels_per_unit)); + return (float)info_ptr->y_pixels_per_unit + / (float)info_ptr->x_pixels_per_unit; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return ((float)0.0); + return (float)0.0; } #endif @@ -217,6 +215,8 @@ png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_READ_pHYs_SUPPORTED + png_debug(1, "in png_get_pixel_aspect_ratio_fixed"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0 && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 && @@ -225,8 +225,6 @@ png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, { png_fixed_point res; - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed"); - /* The following casts work because a PNG 4 byte integer only has a valid * range of 0..2^31-1; otherwise the cast might overflow. */ @@ -247,80 +245,80 @@ png_int_32 PNGAPI png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_x_offset_microns"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->x_offset); + return info_ptr->x_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_int_32 PNGAPI png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_y_offset_microns"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->y_offset); + return info_ptr->y_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_int_32 PNGAPI png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_x_offset_pixels"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->x_offset); + return info_ptr->x_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_int_32 PNGAPI png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_y_offset_pixels"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->y_offset); + return info_ptr->y_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } #ifdef PNG_INCH_CONVERSIONS_SUPPORTED @@ -434,11 +432,11 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, { png_uint_32 retval = 0; + png_debug1(1, "in %s retrieval function", "pHYs"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", "pHYs"); - if (res_x != NULL) { *res_x = info_ptr->x_pixels_per_unit; @@ -464,7 +462,7 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, } } - return (retval); + return retval; } #endif /* pHYs */ #endif /* INCH_CONVERSIONS */ @@ -478,9 +476,9 @@ png_byte PNGAPI png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->channels); + return info_ptr->channels; - return (0); + return 0; } #ifdef PNG_READ_SUPPORTED @@ -488,9 +486,9 @@ png_const_bytep PNGAPI png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->signature); + return info_ptr->signature; - return (NULL); + return NULL; } #endif @@ -499,17 +497,17 @@ png_uint_32 PNGAPI png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, png_color_16p *background) { + png_debug1(1, "in %s retrieval function", "bKGD"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0 && background != NULL) { - png_debug1(1, "in %s retrieval function", "bKGD"); - *background = &(info_ptr->background); - return (PNG_INFO_bKGD); + return PNG_INFO_bKGD; } - return (0); + return 0; } #endif @@ -524,6 +522,8 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x, double *red_y, double *green_x, double *green_y, double *blue_x, double *blue_y) { + png_debug1(1, "in %s retrieval function", "cHRM"); + /* Quiet API change: this code used to only return the end points if a cHRM * chunk was present, but the end points can also come from iCCP or sRGB * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and @@ -533,8 +533,6 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) { - png_debug1(1, "in %s retrieval function", "cHRM"); - if (white_x != NULL) *white_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); @@ -559,10 +557,10 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, if (blue_y != NULL) *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, "cHRM blue Y"); - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } png_uint_32 PNGAPI @@ -571,11 +569,11 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, double *green_Y, double *green_Z, double *blue_X, double *blue_Y, double *blue_Z) { + png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) { - png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); - if (red_X != NULL) *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, "cHRM red X"); @@ -603,10 +601,10 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, if (blue_Z != NULL) *blue_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } # endif @@ -619,11 +617,11 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, png_fixed_point *int_blue_Z) { + png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) { - png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); - if (int_red_X != NULL) *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X; if (int_red_Y != NULL) @@ -642,10 +640,10 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y; if (int_blue_Z != NULL) *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z; - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } png_uint_32 PNGAPI @@ -675,10 +673,10 @@ png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, *blue_x = info_ptr->colorspace.end_points_xy.bluex; if (blue_y != NULL) *blue_y = info_ptr->colorspace.end_points_xy.bluey; - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } # endif #endif @@ -696,10 +694,10 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, file_gamma != NULL) { *file_gamma = info_ptr->colorspace.gamma; - return (PNG_INFO_gAMA); + return PNG_INFO_gAMA; } - return (0); + return 0; } # endif @@ -716,10 +714,10 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, { *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, "png_get_gAMA"); - return (PNG_INFO_gAMA); + return PNG_INFO_gAMA; } - return (0); + return 0; } # endif #endif @@ -735,10 +733,10 @@ png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr, (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL) { *file_srgb_intent = info_ptr->colorspace.rendering_intent; - return (PNG_INFO_sRGB); + return PNG_INFO_sRGB; } - return (0); + return 0; } #endif @@ -762,10 +760,10 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, */ if (compression_type != NULL) *compression_type = PNG_COMPRESSION_TYPE_BASE; - return (PNG_INFO_iCCP); + return PNG_INFO_iCCP; } - return (0); + return 0; } #endif @@ -775,13 +773,15 @@ int PNGAPI png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, png_sPLT_tpp spalettes) { + png_debug1(1, "in %s retrieval function", "sPLT"); + if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) { *spalettes = info_ptr->splt_palettes; return info_ptr->splt_palettes_num; } - return (0); + return 0; } #endif @@ -807,10 +807,10 @@ png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr, { *num_exif = info_ptr->num_exif; *exif = info_ptr->exif; - return (PNG_INFO_eXIf); + return PNG_INFO_eXIf; } - return (0); + return 0; } #endif @@ -825,10 +825,10 @@ png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL) { *hist = info_ptr->hist; - return (PNG_INFO_hIST); + return PNG_INFO_hIST; } - return (0); + return 0; } #endif @@ -841,7 +841,7 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, png_debug1(1, "in %s retrieval function", "IHDR"); if (png_ptr == NULL || info_ptr == NULL) - return (0); + return 0; if (width != NULL) *width = info_ptr->width; @@ -873,7 +873,7 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, info_ptr->compression_type, info_ptr->filter_type); - return (1); + return 1; } #ifdef PNG_oFFs_SUPPORTED @@ -890,10 +890,10 @@ png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr, *offset_x = info_ptr->x_offset; *offset_y = info_ptr->y_offset; *unit_type = (int)info_ptr->offset_unit_type; - return (PNG_INFO_oFFs); + return PNG_INFO_oFFs; } - return (0); + return 0; } #endif @@ -917,10 +917,10 @@ png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, *nparams = (int)info_ptr->pcal_nparams; *units = info_ptr->pcal_units; *params = info_ptr->pcal_params; - return (PNG_INFO_pCAL); + return PNG_INFO_pCAL; } - return (0); + return 0; } #endif @@ -932,6 +932,8 @@ png_uint_32 PNGAPI png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, png_fixed_point *width, png_fixed_point *height) { + png_debug1(1, "in %s retrieval function", "sCAL"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) { @@ -943,10 +945,10 @@ png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), "sCAL height"); - return (PNG_INFO_sCAL); + return PNG_INFO_sCAL; } - return(0); + return 0; } # endif /* FLOATING_ARITHMETIC */ # endif /* FIXED_POINT */ @@ -955,32 +957,36 @@ png_uint_32 PNGAPI png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, double *width, double *height) { + png_debug1(1, "in %s retrieval function", "sCAL(float)"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) { *unit = info_ptr->scal_unit; *width = atof(info_ptr->scal_s_width); *height = atof(info_ptr->scal_s_height); - return (PNG_INFO_sCAL); + return PNG_INFO_sCAL; } - return(0); + return 0; } # endif /* FLOATING POINT */ png_uint_32 PNGAPI png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, png_charpp width, png_charpp height) { + png_debug1(1, "in %s retrieval function", "sCAL(str)"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) { *unit = info_ptr->scal_unit; *width = info_ptr->scal_s_width; *height = info_ptr->scal_s_height; - return (PNG_INFO_sCAL); + return PNG_INFO_sCAL; } - return(0); + return 0; } #endif /* sCAL */ @@ -1015,7 +1021,7 @@ png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr, } } - return (retval); + return retval; } #endif /* pHYs */ @@ -1031,10 +1037,10 @@ png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr, *palette = info_ptr->palette; *num_palette = info_ptr->num_palette; png_debug1(3, "num_palette = %d", *num_palette); - return (PNG_INFO_PLTE); + return PNG_INFO_PLTE; } - return (0); + return 0; } #ifdef PNG_sBIT_SUPPORTED @@ -1048,10 +1054,10 @@ png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL) { *sig_bit = &(info_ptr->sig_bit); - return (PNG_INFO_sBIT); + return PNG_INFO_sBIT; } - return (0); + return 0; } #endif @@ -1062,7 +1068,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, { if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) { - png_debug1(1, "in 0x%lx retrieval function", + png_debug1(1, "in text retrieval function, chunk typeid = 0x%lx", (unsigned long)png_ptr->chunk_name); if (text_ptr != NULL) @@ -1077,7 +1083,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, if (num_text != NULL) *num_text = 0; - return(0); + return 0; } #endif @@ -1092,10 +1098,10 @@ png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr, (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL) { *mod_time = &(info_ptr->mod_time); - return (PNG_INFO_tIME); + return PNG_INFO_tIME; } - return (0); + return 0; } #endif @@ -1105,11 +1111,12 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) { png_uint_32 retval = 0; + + png_debug1(1, "in %s retrieval function", "tRNS"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0) { - png_debug1(1, "in %s retrieval function", "tRNS"); - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (trans_alpha != NULL) @@ -1141,7 +1148,7 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, } } - return (retval); + return retval; } #endif @@ -1156,7 +1163,7 @@ png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr, return info_ptr->unknown_chunks_num; } - return (0); + return 0; } #endif @@ -1252,7 +1259,7 @@ png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr) if (png_ptr != NULL && info_ptr != NULL) return png_ptr->num_palette_max; - return (-1); + return -1; } # endif #endif diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h index c7033ae176f..d768a8ef087 100644 --- a/src/3rdparty/libpng/pnglibconf.h +++ b/src/3rdparty/libpng/pnglibconf.h @@ -1,8 +1,8 @@ /* pnglibconf.h - library build configuration */ -/* libpng version 1.6.40 */ +/* libpng version 1.6.41 */ -/* Copyright (c) 2018-2023 Cosmin Truta */ +/* Copyright (c) 2018-2024 Cosmin Truta */ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ /* This code is released under the libpng license. */ @@ -27,6 +27,7 @@ #define PNG_COLORSPACE_SUPPORTED #define PNG_CONSOLE_IO_SUPPORTED #define PNG_CONVERT_tIME_SUPPORTED +/*#undef PNG_DISABLE_ADLER32_CHECK_SUPPORTED*/ #define PNG_EASY_ACCESS_SUPPORTED /*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ #define PNG_ERROR_TEXT_SUPPORTED @@ -41,6 +42,10 @@ #define PNG_INCH_CONVERSIONS_SUPPORTED #define PNG_INFO_IMAGE_SUPPORTED #define PNG_IO_STATE_SUPPORTED +/*#undef PNG_MIPS_MMI_API_SUPPORTED*/ +/*#undef PNG_MIPS_MMI_CHECK_SUPPORTED*/ +/*#undef PNG_MIPS_MSA_API_SUPPORTED*/ +/*#undef PNG_MIPS_MSA_CHECK_SUPPORTED*/ #define PNG_MNG_FEATURES_SUPPORTED #define PNG_POINTER_INDEXING_SUPPORTED /*#undef PNG_POWERPC_VSX_API_SUPPORTED*/ diff --git a/src/3rdparty/libpng/pngpread.c b/src/3rdparty/libpng/pngpread.c index e283627b77c..be640f77a9b 100644 --- a/src/3rdparty/libpng/pngpread.c +++ b/src/3rdparty/libpng/pngpread.c @@ -1,7 +1,7 @@ /* pngpread.c - read a png file in push mode * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -145,10 +145,10 @@ png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) num_to_check); png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); - if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) { if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0) png_error(png_ptr, "Not a PNG file"); else @@ -1089,7 +1089,7 @@ png_voidp PNGAPI png_get_progressive_ptr(png_const_structrp png_ptr) { if (png_ptr == NULL) - return (NULL); + return NULL; return png_ptr->io_ptr; } diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h index 7c19373f0b8..3a3e9d3564d 100644 --- a/src/3rdparty/libpng/pngpriv.h +++ b/src/3rdparty/libpng/pngpriv.h @@ -1,7 +1,7 @@ /* pngpriv.h - private declarations for use inside libpng * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -197,6 +197,18 @@ # endif #endif +#ifndef PNG_MIPS_MMI_OPT +# ifdef PNG_MIPS_MMI +# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) && defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# define PNG_MIPS_MMI_OPT 1 +# else +# define PNG_MIPS_MMI_OPT 0 +# endif +# else +# define PNG_MIPS_MMI_OPT 0 +# endif +#endif + #ifndef PNG_POWERPC_VSX_OPT # if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__) # define PNG_POWERPC_VSX_OPT 2 @@ -205,6 +217,14 @@ # endif #endif +#ifndef PNG_LOONGARCH_LSX_OPT +# if defined(__loongarch_sx) +# define PNG_LOONGARCH_LSX_OPT 1 +# else +# define PNG_LOONGARCH_LSX_OPT 0 +# endif +#endif + #ifndef PNG_INTEL_SSE_OPT # ifdef PNG_INTEL_SSE /* Only check for SSE if the build configuration has been modified to @@ -248,7 +268,6 @@ #endif #if PNG_MIPS_MSA_OPT > 0 -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa # ifndef PNG_MIPS_MSA_IMPLEMENTATION # if defined(__mips_msa) # if defined(__clang__) @@ -264,11 +283,28 @@ # ifndef PNG_MIPS_MSA_IMPLEMENTATION # define PNG_MIPS_MSA_IMPLEMENTATION 1 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips # endif #else # define PNG_MIPS_MSA_IMPLEMENTATION 0 #endif /* PNG_MIPS_MSA_OPT > 0 */ +#if PNG_MIPS_MMI_OPT > 0 +# ifndef PNG_MIPS_MMI_IMPLEMENTATION +# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) +# define PNG_MIPS_MMI_IMPLEMENTATION 2 +# else /* !defined __mips_loongson_mmi || _MIPS_SIM != _ABI64 */ +# define PNG_MIPS_MMI_IMPLEMENTATION 0 +# endif /* __mips_loongson_mmi && _MIPS_SIM == _ABI64 */ +# endif /* !PNG_MIPS_MMI_IMPLEMENTATION */ + +# if PNG_MIPS_MMI_IMPLEMENTATION > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips +# endif +#else +# define PNG_MIPS_MMI_IMPLEMENTATION 0 +#endif /* PNG_MIPS_MMI_OPT > 0 */ + #if PNG_POWERPC_VSX_OPT > 0 # define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx # define PNG_POWERPC_VSX_IMPLEMENTATION 1 @@ -276,6 +312,12 @@ # define PNG_POWERPC_VSX_IMPLEMENTATION 0 #endif +#if PNG_LOONGARCH_LSX_OPT > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_lsx +# define PNG_LOONGARCH_LSX_IMPLEMENTATION 1 +#else +# define PNG_LOONGARCH_LSX_IMPLEMENTATION 0 +#endif /* Is this a build of a DLL where compilation of the object modules requires * different preprocessor settings to those required for a simple library? If @@ -514,18 +556,8 @@ */ # include -# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ - defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) - /* We need to check that hasn't already been included earlier - * as it seems it doesn't agree with , yet we should really use - * if possible. - */ -# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) -# include -# endif -# else -# include -# endif +# include + # if defined(_AMIGA) && defined(__SASC) && defined(_M68881) /* Amiga SAS/C: We must include builtin FPU functions when compiling using * MATH=68881 @@ -1306,7 +1338,7 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); #endif -#if PNG_MIPS_MSA_OPT > 0 +#if PNG_MIPS_MSA_IMPLEMENTATION == 1 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop @@ -1323,6 +1355,23 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); #endif +#if PNG_MIPS_MMI_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_mmi,(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif + #if PNG_POWERPC_VSX_OPT > 0 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); @@ -1355,6 +1404,23 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); #endif +#if PNG_LOONGARCH_LSX_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif + /* Choose the best filter to use and filter the row data */ PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY); @@ -2094,17 +2160,27 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); #endif -#if PNG_MIPS_MSA_OPT > 0 -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa, +#if PNG_MIPS_MSA_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); #endif +# if PNG_MIPS_MMI_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips, + (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +# endif + # if PNG_INTEL_SSE_IMPLEMENTATION > 0 PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); # endif #endif +#if PNG_LOONGARCH_LSX_OPT > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx, + (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +#endif + PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, png_const_charp key, png_bytep new_key), PNG_EMPTY); diff --git a/src/3rdparty/libpng/pngread.c b/src/3rdparty/libpng/pngread.c index 96996ced5ba..008a41856b6 100644 --- a/src/3rdparty/libpng/pngread.c +++ b/src/3rdparty/libpng/pngread.c @@ -1,7 +1,7 @@ /* pngread.c - read a PNG file * - * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -568,7 +568,7 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) #endif #ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->transformations) + if (png_ptr->transformations || png_ptr->num_palette_max >= 0) png_do_read_transformations(png_ptr, &row_info); #endif @@ -785,7 +785,7 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED /* Report invalid palette index; added at libng-1.5.10 */ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max > png_ptr->num_palette) + png_ptr->num_palette_max >= png_ptr->num_palette) png_benign_error(png_ptr, "Read palette index exceeding num_palette"); #endif @@ -1049,6 +1049,8 @@ void PNGAPI png_read_png(png_structrp png_ptr, png_inforp info_ptr, int transforms, voidp params) { + png_debug(1, "in png_read_png"); + if (png_ptr == NULL || info_ptr == NULL) return; diff --git a/src/3rdparty/libpng/pngrtran.c b/src/3rdparty/libpng/pngrtran.c index 238f5afe7e8..16474741aac 100644 --- a/src/3rdparty/libpng/pngrtran.c +++ b/src/3rdparty/libpng/pngrtran.c @@ -1,7 +1,7 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -290,7 +290,7 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, int compose = 0; png_fixed_point file_gamma; - png_debug(1, "in png_set_alpha_mode"); + png_debug(1, "in png_set_alpha_mode_fixed"); if (png_rtran_ok(png_ptr, 0) == 0) return; @@ -970,7 +970,7 @@ void PNGFAPI png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, png_fixed_point red, png_fixed_point green) { - png_debug(1, "in png_set_rgb_to_gray"); + png_debug(1, "in png_set_rgb_to_gray_fixed"); /* Need the IHDR here because of the check on color_type below. */ /* TODO: fix this */ diff --git a/src/3rdparty/libpng/pngrutil.c b/src/3rdparty/libpng/pngrutil.c index 068ab193a33..d31dc21dae8 100644 --- a/src/3rdparty/libpng/pngrutil.c +++ b/src/3rdparty/libpng/pngrutil.c @@ -1,7 +1,7 @@ /* pngrutil.c - utilities to read a PNG file * - * Copyright (c) 2018-2022 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -26,7 +26,7 @@ png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) if (uval > PNG_UINT_31_MAX) png_error(png_ptr, "PNG unsigned integer out of range"); - return (uval); + return uval; } #if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) @@ -140,7 +140,7 @@ png_read_sig(png_structrp png_ptr, png_inforp info_ptr) if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) { if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0) png_error(png_ptr, "Not a PNG file"); else png_error(png_ptr, "PNG file corrupted by ASCII conversion"); @@ -171,7 +171,7 @@ png_read_chunk_header(png_structrp png_ptr) /* Put the chunk name into png_ptr->chunk_name. */ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); - png_debug2(0, "Reading %lx chunk, length = %lu", + png_debug2(0, "Reading chunk typeid = 0x%lx, length = %lu", (unsigned long)png_ptr->chunk_name, (unsigned long)length); /* Reset the crc and run it over the chunk name. */ @@ -238,10 +238,10 @@ png_crc_finish(png_structrp png_ptr, png_uint_32 skip) else png_chunk_error(png_ptr, "CRC error"); - return (1); + return 1; } - return (0); + return 0; } /* Compare the CRC stored in the PNG file with that calculated by libpng from @@ -277,11 +277,11 @@ png_crc_error(png_structrp png_ptr) if (need_crc != 0) { crc = png_get_uint_32(crc_bytes); - return ((int)(crc != png_ptr->crc)); + return crc != png_ptr->crc; } else - return (0); + return 0; } #if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ @@ -421,8 +421,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; } -#if ZLIB_VERNUM >= 0x1290 && \ - defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) +#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON) /* Turn off validation of the ADLER32 checksum in IDAT chunks */ ret = inflateValidate(&png_ptr->zstream, 0); diff --git a/src/3rdparty/libpng/pngset.c b/src/3rdparty/libpng/pngset.c index 3fc31feb0cb..eb1c8c7a35a 100644 --- a/src/3rdparty/libpng/pngset.c +++ b/src/3rdparty/libpng/pngset.c @@ -1,7 +1,7 @@ /* pngset.c - storage of image information into info struct * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -763,11 +763,11 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, { int i; - png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11U : - (unsigned long)png_ptr->chunk_name); + png_debug1(1, "in text storage function, chunk typeid = 0x%lx", + png_ptr == NULL ? 0xabadca11UL : (unsigned long)png_ptr->chunk_name); if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) - return(0); + return 0; /* Make sure we have enough space in the "text" array in info_struct * to hold all of the incoming text_ptr objects. This compare can't overflow @@ -947,7 +947,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, png_debug1(3, "transferred text chunk %d", info_ptr->num_text); } - return(0); + return 0; } #endif @@ -1063,6 +1063,8 @@ png_set_sPLT(png_const_structrp png_ptr, { png_sPLT_tp np; + png_debug1(1, "in %s storage function", "sPLT"); + if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) return; @@ -1537,7 +1539,7 @@ void PNGAPI png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, png_bytepp row_pointers) { - png_debug1(1, "in %s storage function", "rows"); + png_debug(1, "in png_set_rows"); if (png_ptr == NULL || info_ptr == NULL) return; @@ -1556,6 +1558,8 @@ png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, void PNGAPI png_set_compression_buffer_size(png_structrp png_ptr, size_t size) { + png_debug(1, "in png_set_compression_buffer_size"); + if (png_ptr == NULL) return; @@ -1627,6 +1631,8 @@ void PNGAPI png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max) { + png_debug(1, "in png_set_user_limits"); + /* Images with dimensions larger than these limits will be * rejected by png_set_IHDR(). To accept any PNG datastream * regardless of dimensions, set both limits to 0x7fffffff. @@ -1642,6 +1648,8 @@ png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max, void PNGAPI png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max) { + png_debug(1, "in png_set_chunk_cache_max"); + if (png_ptr != NULL) png_ptr->user_chunk_cache_max = user_chunk_cache_max; } @@ -1651,6 +1659,8 @@ void PNGAPI png_set_chunk_malloc_max(png_structrp png_ptr, png_alloc_size_t user_chunk_malloc_max) { + png_debug(1, "in png_set_chunk_malloc_max"); + if (png_ptr != NULL) png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; } diff --git a/src/3rdparty/libpng/pngtrans.c b/src/3rdparty/libpng/pngtrans.c index 1100f46ebec..62cb21edf1f 100644 --- a/src/3rdparty/libpng/pngtrans.c +++ b/src/3rdparty/libpng/pngtrans.c @@ -1,7 +1,7 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -103,10 +103,10 @@ png_set_interlace_handling(png_structrp png_ptr) if (png_ptr != 0 && png_ptr->interlaced != 0) { png_ptr->transformations |= PNG_INTERLACE; - return (7); + return 7; } - return (1); + return 1; } #endif @@ -498,6 +498,8 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) png_bytep dp = row; /* destination pointer */ png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */ + png_debug(1, "in png_do_strip_channel"); + /* At the start sp will point to the first byte to copy and dp to where * it is copied to. ep always points just beyond the end of the row, so * the loop simply copies (channels-1) channels until sp reaches ep. @@ -698,6 +700,8 @@ png_do_bgr(png_row_infop row_info, png_bytep row) void /* PRIVATE */ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) { + png_debug(1, "in png_do_check_palette_indexes"); + if (png_ptr->num_palette < (1 << row_info->bit_depth) && png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ { @@ -708,7 +712,7 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) * forms produced on either GCC or MSVC. */ int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width); - png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1; + png_bytep rp = png_ptr->row_buf + row_info->rowbytes; switch (row_info->bit_depth) { @@ -833,7 +837,7 @@ png_voidp PNGAPI png_get_user_transform_ptr(png_const_structrp png_ptr) { if (png_ptr == NULL) - return (NULL); + return NULL; return png_ptr->user_transform_ptr; } diff --git a/src/3rdparty/libpng/pngwrite.c b/src/3rdparty/libpng/pngwrite.c index 32f4bfbe7df..77e412f43d5 100644 --- a/src/3rdparty/libpng/pngwrite.c +++ b/src/3rdparty/libpng/pngwrite.c @@ -1,7 +1,7 @@ /* pngwrite.c - general routines to write a PNG file * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -369,7 +369,8 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr) png_error(png_ptr, "No IDATs written into file"); #ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED - if (png_ptr->num_palette_max > png_ptr->num_palette) + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= png_ptr->num_palette) png_benign_error(png_ptr, "Wrote palette index exceeding num_palette"); #endif @@ -714,12 +715,12 @@ png_write_row(png_structrp png_ptr, png_const_bytep row) /* 1.5.6: moved from png_struct to be a local structure: */ png_row_info row_info; - if (png_ptr == NULL) - return; - png_debug2(1, "in png_write_row (row %u, pass %d)", png_ptr->row_number, png_ptr->pass); + if (png_ptr == NULL) + return; + /* Initialize transformations and other stuff if first time */ if (png_ptr->row_number == 0 && png_ptr->pass == 0) { @@ -1210,6 +1211,8 @@ png_set_compression_strategy(png_structrp png_ptr, int strategy) void PNGAPI png_set_compression_window_bits(png_structrp png_ptr, int window_bits) { + png_debug(1, "in png_set_compression_window_bits"); + if (png_ptr == NULL) return; @@ -1293,6 +1296,8 @@ png_set_text_compression_strategy(png_structrp png_ptr, int strategy) void PNGAPI png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits) { + png_debug(1, "in png_set_text_compression_window_bits"); + if (png_ptr == NULL) return; @@ -1330,6 +1335,8 @@ png_set_text_compression_method(png_structrp png_ptr, int method) void PNGAPI png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn) { + png_debug(1, "in png_set_write_status_fn"); + if (png_ptr == NULL) return; @@ -1357,6 +1364,8 @@ void PNGAPI png_write_png(png_structrp png_ptr, png_inforp info_ptr, int transforms, voidp params) { + png_debug(1, "in png_write_png"); + if (png_ptr == NULL || info_ptr == NULL) return; diff --git a/src/3rdparty/libpng/pngwutil.c b/src/3rdparty/libpng/pngwutil.c index 01f0607c709..14cc4ce367f 100644 --- a/src/3rdparty/libpng/pngwutil.c +++ b/src/3rdparty/libpng/pngwutil.c @@ -1,7 +1,7 @@ /* pngwutil.c - utilities to write a PNG file * - * Copyright (c) 2018-2022 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -2311,7 +2311,7 @@ png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp, break; } - return (sum); + return sum; } static void /* PRIVATE */ @@ -2361,7 +2361,7 @@ png_setup_up_row(png_structrp png_ptr, size_t row_bytes, size_t lmins) break; } - return (sum); + return sum; } static void /* PRIVATE */ png_setup_up_row_only(png_structrp png_ptr, size_t row_bytes) @@ -2417,7 +2417,7 @@ png_setup_avg_row(png_structrp png_ptr, png_uint_32 bpp, break; } - return (sum); + return sum; } static void /* PRIVATE */ png_setup_avg_row_only(png_structrp png_ptr, png_uint_32 bpp, @@ -2500,7 +2500,7 @@ png_setup_paeth_row(png_structrp png_ptr, png_uint_32 bpp, break; } - return (sum); + return sum; } static void /* PRIVATE */ png_setup_paeth_row_only(png_structrp png_ptr, png_uint_32 bpp, diff --git a/src/3rdparty/libpng/qt_attribution.json b/src/3rdparty/libpng/qt_attribution.json index cf5aae3824d..3d0df998833 100644 --- a/src/3rdparty/libpng/qt_attribution.json +++ b/src/3rdparty/libpng/qt_attribution.json @@ -6,13 +6,13 @@ "Description": "libpng is the official PNG reference library.", "Homepage": "http://www.libpng.org/pub/png/libpng.html", - "Version": "1.6.40", - "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.40.tar.xz", + "Version": "1.6.41", + "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.41.tar.xz", "License": "libpng License and PNG Reference Library version 2", "LicenseId": "Libpng AND libpng-2.0", "LicenseFile": "LICENSE", - "Copyright": "Copyright (c) 1995-2023 The PNG Reference Library Authors -Copyright (c) 2000-2023 Cosmin Truta + "Copyright": "Copyright (c) 1995-2024 The PNG Reference Library Authors +Copyright (c) 2000-2024 Cosmin Truta Copyright (c) 1998-2018 Glenn Randers-Pehrson Copyright (c) 1996-1997 Andreas Dilger Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. From 1c8e420433b60892d488b8901ff11212a1dd888a Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Mon, 5 Feb 2024 11:14:55 +0100 Subject: [PATCH 35/58] Update bundled libpng to version 1.6.42 [ChangeLog][Third-Party Code] libpng was updated to version 1.6.42 Change-Id: Ie41c2df610fcd456af2bc4dee05dde90c426602b Reviewed-by: Qt CI Bot Reviewed-by: Eskil Abrahamsen Blomfeldt (cherry picked from commit a046bc19e451f6f2e42ac1fcddaf5ef3efc81f0d) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit cd59980f726b5254bd56197acc6f0cbe6d5f1f46) (cherry picked from commit 85ac5cb9796f40cd01cf585978a7ad54cc75f23d) (cherry picked from commit 982054d96f2a5a31f979706ef2a2e95d8ddfe433) Reviewed-by: Eirik Aavitsland (cherry picked from commit be146e820c77c21f6d013097e976d335411ca754) --- src/3rdparty/libpng/ANNOUNCE | 18 ++- src/3rdparty/libpng/CHANGES | 7 +- src/3rdparty/libpng/README | 2 +- src/3rdparty/libpng/libpng-manual.txt | 139 +++++++++++------------- src/3rdparty/libpng/png.c | 4 +- src/3rdparty/libpng/png.h | 16 +-- src/3rdparty/libpng/pngconf.h | 2 +- src/3rdparty/libpng/pnglibconf.h | 2 +- src/3rdparty/libpng/pngpriv.h | 10 +- src/3rdparty/libpng/qt_attribution.json | 4 +- 10 files changed, 105 insertions(+), 99 deletions(-) diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE index 800446b059b..44d6722d058 100644 --- a/src/3rdparty/libpng/ANNOUNCE +++ b/src/3rdparty/libpng/ANNOUNCE @@ -1,4 +1,4 @@ -libpng 1.6.41 - January 24, 2024 +libpng 1.6.42 - January 29, 2024 ================================ This is a public release of libpng, intended for use in production code. @@ -9,13 +9,13 @@ Files available for download Source files with LF line endings (for Unix/Linux): - * libpng-1.6.41.tar.xz (LZMA-compressed, recommended) - * libpng-1.6.41.tar.gz (deflate-compressed) + * libpng-1.6.42.tar.xz (LZMA-compressed, recommended) + * libpng-1.6.42.tar.gz (deflate-compressed) Source files with CRLF line endings (for Windows): - * lpng1641.7z (LZMA-compressed, recommended) - * lpng1641.zip (deflate-compressed) + * lpng1642.7z (LZMA-compressed, recommended) + * lpng1642.zip (deflate-compressed) Other information: @@ -25,6 +25,14 @@ Other information: * TRADEMARK.md +Changes from version 1.6.41 to version 1.6.42 +--------------------------------------------- + + * Fixed the implementation of the macro function `png_check_sig`. + This was an API regression, introduced in libpng-1.6.41. + (Reported by Matthieu Darbois) + + Changes from version 1.6.40 to version 1.6.41 --------------------------------------------- diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES index 2d9a57e439e..137761a815b 100644 --- a/src/3rdparty/libpng/CHANGES +++ b/src/3rdparty/libpng/CHANGES @@ -6134,7 +6134,7 @@ Version 1.6.41 [January 24, 2024] (Contributed by GuXiWei, JinBo and ZhangLixia) Fixed the run-time discovery of MIPS MSA hardware. (Contributed by Sui Jingfeng) - Fixed an off-by-one error in the function `png_do_check_palette_indexes`, + Fixed an off-by-one error in the function png_do_check_palette_indexes(), which failed to recognize errors that might have existed in the first column of a broken palette-encoded image. This was a benign regression accidentally introduced in libpng-1.6.33. No pixel was harmed. @@ -6161,6 +6161,11 @@ Version 1.6.41 [January 24, 2024] Improved the test coverage. (Contributed by John Bowler) +Version 1.6.42 [January 29, 2024] + Fixed the implementation of the macro function png_check_sig(). + This was an API regression, introduced in libpng-1.6.41. + (Reported by Matthieu Darbois) + Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README index 1f51a808f7f..0bf27bcfe6c 100644 --- a/src/3rdparty/libpng/README +++ b/src/3rdparty/libpng/README @@ -1,4 +1,4 @@ -README for libpng version 1.6.41 +README for libpng version 1.6.42 ================================ See the note about version numbers near the top of `png.h`. diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt index dbb60af61d1..eb24ef48312 100644 --- a/src/3rdparty/libpng/libpng-manual.txt +++ b/src/3rdparty/libpng/libpng-manual.txt @@ -9,7 +9,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng version 1.6.36, December 2018, through 1.6.41 - January 2024 + libpng version 1.6.36, December 2018, through 1.6.42 - January 2024 Updated and distributed by Cosmin Truta Copyright (c) 2018-2024 Cosmin Truta @@ -357,7 +357,7 @@ Customizing libpng. return ERROR; } - is_png = !png_sig_cmp(header, 0, number); + is_png = (png_sig_cmp(header, 0, number) == 0); if (!is_png) { return NOT_PNG; @@ -385,8 +385,7 @@ create the structure, so your application should check for that. if (!info_ptr) { - png_destroy_read_struct(&png_ptr, - (png_infopp)NULL, (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, NULL, NULL); return ERROR; } @@ -419,14 +418,13 @@ free any memory. if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr, - &end_info); + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return ERROR; } -Pass (png_infopp)NULL instead of &end_info if you didn't create -an end_info structure. +Pass NULL instead of &end_info if you didn't create an end_info +structure. If you would rather avoid the complexity of setjmp/longjmp issues, you can compile libpng with PNG_NO_SETJMP, in which case @@ -496,7 +494,7 @@ You can set up a callback function to handle any unknown chunks in the input stream. You must supply the function read_chunk_callback(png_structp png_ptr, - png_unknown_chunkp chunk); + png_unknown_chunkp chunk) { /* The unknown chunk structure contains your chunk data, along with similar data for any other @@ -547,9 +545,9 @@ a progress meter or the like. It's demonstrated in pngtest.c. You must supply a function void read_row_callback(png_structp png_ptr, - png_uint_32 row, int pass); + png_uint_32 row, int pass) { - /* put your code here */ + /* put your code here */ } (You can give it another name that you like instead of "read_row_callback") @@ -1181,21 +1179,21 @@ If you know your image size and pixel size ahead of time, you can allocate row_pointers prior to calling png_read_png() with if (height > PNG_UINT_32_MAX/(sizeof (png_byte))) - png_error (png_ptr, + png_error(png_ptr, "Image is too tall to process in memory"); if (width > PNG_UINT_32_MAX/pixel_size) - png_error (png_ptr, + png_error(png_ptr, "Image is too wide to process in memory"); row_pointers = png_malloc(png_ptr, height*(sizeof (png_bytep))); - for (int i=0; i PNG_SIZE_MAX/(width*pixel_size)) { - png_error(png_ptr,"image_data buffer would be too large"); - } + if (height > PNG_SIZE_MAX/(width*pixel_size)) + png_error(png_ptr, "image_data buffer would be too large"); - png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size); + png_bytep buffer = png_malloc(png_ptr, + height*width*pixel_size); - for (int i=0; i= 10504 png_set_scale_16(png_ptr); #else png_set_strip_16(png_ptr); #endif + } (The more accurate "png_set_scale_16()" API became available in libpng version 1.5.4). @@ -1901,7 +1900,7 @@ Note that png_set_filler() does not change the color type. If you want to do that, you can add a true alpha channel with if (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_GRAY) + color_type == PNG_COLOR_TYPE_GRAY) png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER); where "filler" contains the alpha value to assign to each pixel. @@ -1926,7 +1925,7 @@ with alpha. if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_rgb_to_gray(png_ptr, error_action, - double red_weight, double green_weight); + (double)red_weight, (double)green_weight); error_action = 1: silently do the conversion @@ -1949,8 +1948,8 @@ In the corresponding fixed point API the red_weight and green_weight values are simply scaled by 100,000: png_set_rgb_to_gray(png_ptr, error_action, - png_fixed_point red_weight, - png_fixed_point green_weight); + (png_fixed_point)red_weight, + (png_fixed_point)green_weight); If you have set error_action = 1 or 2, you can later check whether the image really was gray, after processing @@ -2186,9 +2185,8 @@ do your own check for number_of_rows*width*pixel_size if you are using a multiple-row buffer: /* Guard against integer overflow */ - if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) { - png_error(png_ptr,"image_data buffer would be too large"); - } + if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) + png_error(png_ptr, "image_data buffer would be too large"); Remember: Before you call png_read_update_info(), the png_get_*() functions return the values corresponding to the original PNG image. @@ -2408,12 +2406,11 @@ separate. if (!end_info) { - png_destroy_read_struct(&png_ptr, &info_ptr, - (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return ERROR; } - png_read_end(png_ptr, end_info); + png_read_end(png_ptr, end_info); If you are not interested, you should still call png_read_end() but you can pass NULL, avoiding the need to create an end_info structure. @@ -2421,7 +2418,7 @@ If you do this, libpng will not process any chunks after IDAT other than skipping over them and perhaps (depending on whether you have called png_set_crc_action) checking their CRCs while looking for the IEND chunk. - png_read_end(png_ptr, (png_infop)NULL); + png_read_end(png_ptr, NULL); If you don't call png_read_end(), then your file pointer will be left pointing to the first chunk after the last IDAT, which is probably @@ -2430,13 +2427,11 @@ the PNG datastream. When you are done, you can free all memory allocated by libpng like this: - png_destroy_read_struct(&png_ptr, &info_ptr, - &end_info); + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); or, if you didn't create an end_info structure, - png_destroy_read_struct(&png_ptr, &info_ptr, - (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); It is also possible to individually free the info_ptr members that point to libpng-allocated storage with the following function: @@ -2556,15 +2551,13 @@ png_infop info_ptr; if (!info_ptr) { - png_destroy_read_struct(&png_ptr, - (png_infopp)NULL, (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, NULL, NULL); return ERROR; } if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr, - (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return ERROR; } @@ -2597,8 +2590,7 @@ png_infop info_ptr; { if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr, - (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return ERROR; } @@ -2763,8 +2755,7 @@ both "png_ptr"; you can call them anything you like, such as png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { - png_destroy_write_struct(&png_ptr, - (png_infopp)NULL); + png_destroy_write_struct(&png_ptr, NULL); return ERROR; } @@ -2790,7 +2781,7 @@ section below for more information on the libpng error handling. if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_write_struct(&png_ptr, &info_ptr); + png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return ERROR; } @@ -2844,9 +2835,9 @@ a progress meter or the like. It's demonstrated in pngtest.c. You must supply a function void write_row_callback(png_structp png_ptr, png_uint_32 row, - int pass); + int pass) { - /* put your code here */ + /* put your code here */ } (You can give it another name that you like instead of "write_row_callback") @@ -3116,8 +3107,8 @@ width, height, bit_depth, and color_type must be the same in each call. png_set_eXIf_1(png_ptr, info_ptr, num_exif, exif); - exif - Exif profile (array of - png_byte) (PNG_INFO_eXIf) + exif - Exif profile (array of png_byte) + (PNG_INFO_eXIf) png_set_hIST(png_ptr, info_ptr, hist); @@ -3127,12 +3118,12 @@ width, height, bit_depth, and color_type must be the same in each call. png_set_tIME(png_ptr, info_ptr, mod_time); mod_time - time image was last modified - (PNG_VALID_tIME) + (PNG_INFO_tIME) png_set_bKGD(png_ptr, info_ptr, background); background - background color (of type - png_color_16p) (PNG_VALID_bKGD) + png_color_16p) (PNG_INFO_bKGD) png_set_text(png_ptr, info_ptr, text_ptr, num_text); @@ -4218,7 +4209,7 @@ png_create_read_struct_2() or png_create_write_struct_2() to register your own functions as described above. These functions also provide a void pointer that can be retrieved via - mem_ptr=png_get_mem_ptr(png_ptr); + mem_ptr = png_get_mem_ptr(png_ptr); Your replacement memory functions must have prototypes as follows: @@ -4515,7 +4506,7 @@ When PNG_DEBUG is defined but is zero, the macros aren't defined, but you can still use PNG_DEBUG to control your own debugging: #ifdef PNG_DEBUG - fprintf(stderr, ... + fprintf(stderr, ...); #endif When PNG_DEBUG = 1, the macros are defined, but only png_debug statements @@ -4692,7 +4683,7 @@ deprecated since libpng-1.0.16 and libpng-1.2.6. The function png_check_sig(sig, num) was replaced with - !png_sig_cmp(sig, 0, num) + png_sig_cmp(sig, 0, num) == 0 It has been deprecated since libpng-0.90. The function @@ -4756,8 +4747,8 @@ png_get_mmx_bitdepth_threshold(), png_get_mmx_rowbytes_threshold(), png_set_asm_flags(), and png_mmx_supported() We removed the obsolete png_check_sig(), png_memcpy_check(), and -png_memset_check() functions. Instead use !png_sig_cmp(), memcpy(), -and memset(), respectively. +png_memset_check() functions. Instead use png_sig_cmp() == 0, +memcpy(), and memset(), respectively. The function png_set_gray_1_2_4_to_8() was removed. It has been deprecated since libpng-1.0.18 and 1.2.9, when it was replaced with @@ -5239,7 +5230,7 @@ changed, and is unaffected by conditional compilation macros. It is the best choice for use in configure scripts for detecting the presence of any libpng version since 0.88. In an autoconf "configure.in" you could use - AC_CHECK_LIB(png, png_get_io_ptr, ... + AC_CHECK_LIB(png, png_get_io_ptr, ...) XV. Source code repository @@ -5248,12 +5239,12 @@ control. The git repository was built from old libpng-x.y.z.tar.gz files going back to version 0.70. You can access the git repository (read only) at - https://github.com/glennrp/libpng or + https://github.com/pnggroup/libpng or https://git.code.sf.net/p/libpng/code.git or you can browse it with a web browser at - https://github.com/glennrp/libpng or + https://github.com/pnggroup/libpng or https://sourceforge.net/p/libpng/code/ci/libpng16/tree/ Patches can be sent to png-mng-implement at lists.sourceforge.net or @@ -5263,7 +5254,7 @@ uploaded to the libpng bug tracker at or as a "pull request" to - https://github.com/glennrp/libpng/pulls + https://github.com/pnggroup/libpng/pulls We also accept patches built from the tar or zip distributions, and simple verbal descriptions of bug fixes, reported either to the diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c index e411381f8f9..cf9f361070f 100644 --- a/src/3rdparty/libpng/png.c +++ b/src/3rdparty/libpng/png.c @@ -14,7 +14,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_41 Your_png_h_is_not_version_1_6_41; +typedef png_libpng_version_1_6_42 Your_png_h_is_not_version_1_6_42; /* Tells libpng that we have already handled the first "num_bytes" bytes * of the PNG file signature. If the PNG data is embedded into another @@ -794,7 +794,7 @@ png_get_copyright(png_const_structrp png_ptr) return PNG_STRING_COPYRIGHT #else return PNG_STRING_NEWLINE \ - "libpng version 1.6.41" PNG_STRING_NEWLINE \ + "libpng version 1.6.42" PNG_STRING_NEWLINE \ "Copyright (c) 2018-2024 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h index d78c7799341..f537c5bb089 100644 --- a/src/3rdparty/libpng/png.h +++ b/src/3rdparty/libpng/png.h @@ -1,7 +1,7 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.41 + * libpng version 1.6.42 * * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson @@ -15,7 +15,7 @@ * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.97, January 1998, through 1.6.35, July 2018: * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.41, January 2024: + * libpng versions 1.6.36, December 2018, through 1.6.42, January 2024: * Cosmin Truta * See also "Contributing Authors", below. */ @@ -239,7 +239,7 @@ * ... * 1.5.30 15 10530 15.so.15.30[.0] * ... - * 1.6.41 16 10641 16.so.16.41[.0] + * 1.6.42 16 10641 16.so.16.41[.0] * * Henceforth the source version will match the shared-library major and * minor numbers; the shared-library major version number will be used for @@ -278,7 +278,7 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.41" +#define PNG_LIBPNG_VER_STRING "1.6.42" #define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n" #define PNG_LIBPNG_VER_SONUM 16 @@ -318,7 +318,7 @@ * From version 1.0.1 it is: * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10641 /* 1.6.41 */ +#define PNG_LIBPNG_VER 10641 /* 1.6.42 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -428,7 +428,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_41; +typedef char* png_libpng_version_1_6_42; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * @@ -914,9 +914,9 @@ PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start, size_t num_to_check)); /* Simple signature checking function. This is the same as calling - * png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) != 0). + * png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) == 0). */ -#define png_check_sig(sig, n) (png_sig_cmp((sig), 0, (n)) != 0) +#define png_check_sig(sig, n) (png_sig_cmp((sig), 0, (n)) == 0) /* DEPRECATED */ /* Allocate and initialize png_ptr struct for reading, and any other memory. */ PNG_EXPORTA(4, png_structp, png_create_read_struct, diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index 30c1aad52d7..99851f4f9c8 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -1,7 +1,7 @@ /* pngconf.h - machine-configurable file for libpng * - * libpng version 1.6.41 + * libpng version 1.6.42 * * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h index d768a8ef087..330453c1391 100644 --- a/src/3rdparty/libpng/pnglibconf.h +++ b/src/3rdparty/libpng/pnglibconf.h @@ -1,6 +1,6 @@ /* pnglibconf.h - library build configuration */ -/* libpng version 1.6.41 */ +/* libpng version 1.6.42 */ /* Copyright (c) 2018-2024 Cosmin Truta */ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h index 3a3e9d3564d..9bfdb713421 100644 --- a/src/3rdparty/libpng/pngpriv.h +++ b/src/3rdparty/libpng/pngpriv.h @@ -36,7 +36,7 @@ * still required (as of 2011-05-02.) */ #ifndef _POSIX_SOURCE -# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ +# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ #endif #ifndef PNG_VERSION_INFO_ONLY @@ -190,7 +190,8 @@ #endif /* PNG_ARM_NEON_OPT > 0 */ #ifndef PNG_MIPS_MSA_OPT -# if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# if defined(__mips_msa) && (__mips_isa_rev >= 5) && \ + defined(PNG_ALIGNED_MEMORY_SUPPORTED) # define PNG_MIPS_MSA_OPT 2 # else # define PNG_MIPS_MSA_OPT 0 @@ -199,7 +200,8 @@ #ifndef PNG_MIPS_MMI_OPT # ifdef PNG_MIPS_MMI -# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) && defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) && \ + defined(PNG_ALIGNED_MEMORY_SUPPORTED) # define PNG_MIPS_MMI_OPT 1 # else # define PNG_MIPS_MMI_OPT 0 @@ -231,7 +233,7 @@ * enable SSE optimizations. This means that these optimizations will * be off by default. See contrib/intel for more details. */ -# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \ +# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \ defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ (defined(_M_IX86_FP) && _M_IX86_FP >= 2) # define PNG_INTEL_SSE_OPT 1 diff --git a/src/3rdparty/libpng/qt_attribution.json b/src/3rdparty/libpng/qt_attribution.json index 3d0df998833..c85a5caf438 100644 --- a/src/3rdparty/libpng/qt_attribution.json +++ b/src/3rdparty/libpng/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "libpng is the official PNG reference library.", "Homepage": "http://www.libpng.org/pub/png/libpng.html", - "Version": "1.6.41", - "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.41.tar.xz", + "Version": "1.6.42", + "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.42.tar.xz", "License": "libpng License and PNG Reference Library version 2", "LicenseId": "Libpng AND libpng-2.0", "LicenseFile": "LICENSE", From 5ec7bcb613342297e1b7ad1c1847b2f96f560adb Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 8 Nov 2023 17:23:14 +0100 Subject: [PATCH 36/58] tst_bench_QImageReader: add a benchmark for raw QFatoryLoader operations This is Eirik's QtCore-only QTBUG-114253 reproducer added to the nearest fitting existing benchmark. Manual conflict resolutions: - [[maybe_unused]] -> Q_UNUSED (Qt 5 is C++11-only) - CMakeLists.txt -> qimagereader.pro Done-with: Eirik Aavitsland Task-number: QTBUG-114253 Change-Id: Iba68bedebae908af497267860e2b230db269787e Reviewed-by: Eirik Aavitsland (cherry picked from commit a5bcb41678ad7fe78ad3fac066094f6a614b6906) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 66cd58b2a569ae3423c319a65ab4f198c1c62714) (cherry picked from commit 1c35f22097a5e6d9234a23567aa3f08992d81770) (cherry picked from commit 4c0d1383d11039d42ad6cf1579f9512eb7461db7) Reviewed-by: Qt CI Bot Reviewed-by: Volker Hilsheimer --- .../gui/image/qimagereader/qimagereader.pro | 2 +- .../qimagereader/tst_bench_qimagereader.cpp | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/benchmarks/gui/image/qimagereader/qimagereader.pro b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro index 4ad41f66f6b..906152ea9ce 100644 --- a/tests/benchmarks/gui/image/qimagereader/qimagereader.pro +++ b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro @@ -1,4 +1,4 @@ -QT += testlib +QT += testlib core-private QT_FOR_CONFIG += gui-private TEMPLATE = app diff --git a/tests/benchmarks/gui/image/qimagereader/tst_bench_qimagereader.cpp b/tests/benchmarks/gui/image/qimagereader/tst_bench_qimagereader.cpp index 2903d5d9edb..894766c2c01 100644 --- a/tests/benchmarks/gui/image/qimagereader/tst_bench_qimagereader.cpp +++ b/tests/benchmarks/gui/image/qimagereader/tst_bench_qimagereader.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -55,6 +56,9 @@ public slots: void initTestCase(); private slots: + void rawFactoryLoader_keyMap(); + void rawFactoryLoader_instance(); + void readImage_data(); void readImage(); @@ -70,6 +74,7 @@ private slots: private: QList< QPair > images; // filename, format QString prefix; + QFactoryLoader m_loader{QImageIOHandlerFactoryInterface_iid, "/imageformats"}; }; tst_bench_QImageReader::tst_bench_QImageReader() @@ -106,6 +111,31 @@ void tst_bench_QImageReader::initTestCase() QFAIL("Can't find images directory!"); } +void tst_bench_QImageReader::rawFactoryLoader_keyMap() +{ + if (m_loader.keyMap().isEmpty()) + QSKIP("No image plugins found."); + + QBENCHMARK { + auto r = m_loader.keyMap(); + Q_UNUSED(r); + } +} + +void tst_bench_QImageReader::rawFactoryLoader_instance() +{ + if (m_loader.keyMap().isEmpty()) + QSKIP("No image plugins found."); + + const auto numInstances = m_loader.keyMap().uniqueKeys().size(); + + QBENCHMARK { + for (int i = 0; i < numInstances; ++i) + delete m_loader.instance(i); + } +} + + void tst_bench_QImageReader::readImage_data() { QTest::addColumn("fileName"); From 47fa5d4575cca3691f28f32201202e3235129431 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 31 Jan 2024 16:31:18 +0100 Subject: [PATCH 37/58] [docs] Fix C'n'P error in QTRY_VERIFY2 example It's not the _WITH_TIMEOUT variant (the timeout is missing). Amends a change preceding b24bb12f6a93b98e9bc44c99e151b995eb7cea71, the commit that moved all the documentation into qtestcase.qdoc in the first place. I didn't track the change back further than that. Change-Id: I79ccd84a5dbed20012fa1a2d3561945f8a7638d5 Reviewed-by: Ivan Solovev (cherry picked from commit 4af3cf275fc9f5e721fab6b05fc05cf7bdbe5c99) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit a06a78bb045aba46fec470cce5590a95eab0a30f) (cherry picked from commit 4994e92c097f495b105da5e0e4a103c1ceb72107) (cherry picked from commit 33ab262dffe8b82f047a6a87be834becb2da6c25) (cherry picked from commit 4b0e877b3c160542c2306b9f8c120caef3cad8cb) --- src/testlib/qtestcase.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testlib/qtestcase.qdoc b/src/testlib/qtestcase.qdoc index 73d1cc850b1..be9c6a35ec6 100644 --- a/src/testlib/qtestcase.qdoc +++ b/src/testlib/qtestcase.qdoc @@ -237,7 +237,7 @@ Example: \code - QTRY_VERIFY2_WITH_TIMEOUT(list.size() > 2, QByteArray::number(list.size()).constData()); + QTRY_VERIFY2(list.size() > 2, QByteArray::number(list.size()).constData()); \endcode \note This macro can only be used in a test function that is invoked From eab5176fecee033471265227543fb19b6407ebf0 Mon Sep 17 00:00:00 2001 From: Jonas Karlsson Date: Thu, 8 Feb 2024 17:01:05 +0100 Subject: [PATCH 38/58] Improve KTX file reading memory safety NOTE: While this is technically a cherry-pick some parts of the original change have been modified or removed. * Use qAddOverflow method for catching additions with overflow and handle these scenarios when reading the file. * Add 'safeSlice' method that checks that the byte array constructed is not out of bounds. * Return error if number of levels is higher than what is reasonable. * Add unit test with invalid KTX file previously causing a segmentation fault. This fixes CVE-2024-25580. Fixes: QTBUG-121918 Change-Id: Ie0824c32a5921de30cf07c1fc1b49a084e6d07b2 Reviewed-by: Eirik Aavitsland Reviewed-by: Qt CI Bot (cherry picked from commit 28ecb523ce8490bff38b251b3df703c72e057519) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit de5820c3f822b3dc0444d4aed16c6146c06f175d) (cherry picked from commit 115ea82fbceb3f013552c5e7d4280091defaeee2) (cherry picked from commit 818d4e56b61e73e9f4e6f7a8953d444360b4955c) (cherry picked from commit 39cbdde14554ce333f25d86b7c39c03a1baf1ddf) --- src/gui/util/qktxhandler.cpp | 136 ++++++++++++++---- src/gui/util/qktxhandler_p.h | 2 +- .../qtexturefilereader/qtexturefilereader.qrc | 1 + .../texturefiles/invalid.ktx | Bin 0 -> 69 bytes .../tst_qtexturefilereader.cpp | 11 ++ 5 files changed, 121 insertions(+), 29 deletions(-) create mode 100644 tests/auto/gui/util/qtexturefilereader/texturefiles/invalid.ktx diff --git a/src/gui/util/qktxhandler.cpp b/src/gui/util/qktxhandler.cpp index 0d98e974531..6a79e551096 100644 --- a/src/gui/util/qktxhandler.cpp +++ b/src/gui/util/qktxhandler.cpp @@ -73,7 +73,7 @@ struct KTXHeader { quint32 bytesOfKeyValueData; }; -static const quint32 headerSize = sizeof(KTXHeader); +static constexpr quint32 qktxh_headerSize = sizeof(KTXHeader); // Currently unused, declared for future reference struct KTXKeyValuePairItem { @@ -103,11 +103,36 @@ struct KTXMipmapLevel { */ }; +static bool qAddOverflow(quint32 v1, quint32 v2, quint32 *r) { + // unsigned additions are well-defined + *r = v1 + v2; + return v1 > quint32(v1 + v2); +} + +// Returns the nearest multiple of 4 greater than or equal to 'value' +static bool nearestMultipleOf4(quint32 value, quint32 *result) +{ + constexpr quint32 rounding = 4; + *result = 0; + if (qAddOverflow(value, rounding - 1, result)) + return true; + *result &= ~(rounding - 1); + return false; +} + +// Returns a slice with prechecked bounds +static QByteArray safeSlice(const QByteArray& array, quint32 start, quint32 length) +{ + quint32 end = 0; + if (qAddOverflow(start, length, &end) || end > quint32(array.length())) + return {}; + return QByteArray(array.data() + start, length); +} + bool QKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block) { - Q_UNUSED(suffix) - - return (qstrncmp(block.constData(), ktxIdentifier, KTX_IDENTIFIER_LENGTH) == 0); + Q_UNUSED(suffix); + return block.startsWith(QByteArray::fromRawData(ktxIdentifier, KTX_IDENTIFIER_LENGTH)); } QTextureFileData QKtxHandler::read() @@ -115,42 +140,97 @@ QTextureFileData QKtxHandler::read() if (!device()) return QTextureFileData(); - QByteArray buf = device()->readAll(); - const quint32 dataSize = quint32(buf.size()); - if (dataSize < headerSize || !canRead(QByteArray(), buf)) { - qCDebug(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData()); + const QByteArray buf = device()->readAll(); + if (size_t(buf.size()) > std::numeric_limits::max()) { + qWarning(lcQtGuiTextureIO, "Too big KTX file %s", logName().constData()); return QTextureFileData(); } - const KTXHeader *header = reinterpret_cast(buf.constData()); - if (!checkHeader(*header)) { - qCDebug(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData()); + if (!canRead(QByteArray(), buf)) { + qWarning(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData()); + return QTextureFileData(); + } + + if (buf.size() < qsizetype(qktxh_headerSize)) { + qWarning(lcQtGuiTextureIO, "Invalid KTX header size in %s", logName().constData()); + return QTextureFileData(); + } + + KTXHeader header; + memcpy(&header, buf.data(), qktxh_headerSize); + if (!checkHeader(header)) { + qWarning(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData()); return QTextureFileData(); } QTextureFileData texData; texData.setData(buf); - texData.setSize(QSize(decode(header->pixelWidth), decode(header->pixelHeight))); - texData.setGLFormat(decode(header->glFormat)); - texData.setGLInternalFormat(decode(header->glInternalFormat)); - texData.setGLBaseInternalFormat(decode(header->glBaseInternalFormat)); + texData.setSize(QSize(decode(header.pixelWidth), decode(header.pixelHeight))); + texData.setGLFormat(decode(header.glFormat)); + texData.setGLInternalFormat(decode(header.glInternalFormat)); + texData.setGLBaseInternalFormat(decode(header.glBaseInternalFormat)); - texData.setNumLevels(decode(header->numberOfMipmapLevels)); - quint32 offset = headerSize + decode(header->bytesOfKeyValueData); - const int maxLevels = qMin(texData.numLevels(), 32); // Cap iterations in case of corrupt file. - for (int i = 0; i < maxLevels; i++) { - if (offset + sizeof(KTXMipmapLevel) > dataSize) // Corrupt file; avoid oob read - break; - const KTXMipmapLevel *level = reinterpret_cast(buf.constData() + offset); - quint32 levelLen = decode(level->imageSize); - texData.setDataOffset(offset + sizeof(KTXMipmapLevel::imageSize), i); - texData.setDataLength(levelLen, i); - offset += sizeof(KTXMipmapLevel::imageSize) + levelLen + (3 - ((levelLen + 3) % 4)); + texData.setNumLevels(decode(header.numberOfMipmapLevels)); + + const quint32 bytesOfKeyValueData = decode(header.bytesOfKeyValueData); + quint32 headerKeyValueSize; + if (qAddOverflow(qktxh_headerSize, bytesOfKeyValueData, &headerKeyValueSize)) { + qWarning(lcQtGuiTextureIO, "Overflow in size of key value data in header of KTX file %s", + logName().constData()); + return QTextureFileData(); + } + + if (headerKeyValueSize >= quint32(buf.size())) { + qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData()); + return QTextureFileData(); + } + + // Technically, any number of levels is allowed but if the value is bigger than + // what is possible in KTX V2 (and what makes sense) we return an error. + // maxLevels = log2(max(width, height, depth)) + const int maxLevels = (sizeof(quint32) * 8) + - qCountLeadingZeroBits(std::max( + { header.pixelWidth, header.pixelHeight, header.pixelDepth })); + + if (texData.numLevels() > maxLevels) { + qWarning(lcQtGuiTextureIO, "Too many levels in KTX file %s", logName().constData()); + return QTextureFileData(); + } + + quint32 offset = headerKeyValueSize; + for (int level = 0; level < texData.numLevels(); level++) { + const auto imageSizeSlice = safeSlice(buf, offset, sizeof(quint32)); + if (imageSizeSlice.isEmpty()) { + qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData()); + return QTextureFileData(); + } + + const quint32 imageSize = decode(qFromUnaligned(imageSizeSlice.data())); + offset += sizeof(quint32); // overflow checked indirectly above + + texData.setDataOffset(offset, level); + texData.setDataLength(imageSize, level); + + // Add image data and padding to offset + quint32 padded = 0; + if (nearestMultipleOf4(imageSize, &padded)) { + qWarning(lcQtGuiTextureIO, "Overflow in KTX file %s", logName().constData()); + return QTextureFileData(); + } + + quint32 offsetNext; + if (qAddOverflow(offset, padded, &offsetNext)) { + qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData()); + return QTextureFileData(); + } + + offset = offsetNext; } if (!texData.isValid()) { - qCDebug(lcQtGuiTextureIO, "Invalid values in header of KTX file %s", logName().constData()); + qWarning(lcQtGuiTextureIO, "Invalid values in header of KTX file %s", + logName().constData()); return QTextureFileData(); } @@ -191,7 +271,7 @@ bool QKtxHandler::checkHeader(const KTXHeader &header) (decode(header.numberOfFaces) == 1)); } -quint32 QKtxHandler::decode(quint32 val) +quint32 QKtxHandler::decode(quint32 val) const { return inverseEndian ? qbswap(val) : val; } diff --git a/src/gui/util/qktxhandler_p.h b/src/gui/util/qktxhandler_p.h index f831e59d956..cdf1b2eaf89 100644 --- a/src/gui/util/qktxhandler_p.h +++ b/src/gui/util/qktxhandler_p.h @@ -68,7 +68,7 @@ public: private: bool checkHeader(const KTXHeader &header); - quint32 decode(quint32 val); + quint32 decode(quint32 val) const; bool inverseEndian = false; }; diff --git a/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc b/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc index 8aab86e1ffe..370b2b02f37 100644 --- a/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc +++ b/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc @@ -5,5 +5,6 @@ texturefiles/car_mips.ktx texturefiles/newlogo_srgb.astc texturefiles/newlogo.astc + texturefiles/invalid.ktx diff --git a/tests/auto/gui/util/qtexturefilereader/texturefiles/invalid.ktx b/tests/auto/gui/util/qtexturefilereader/texturefiles/invalid.ktx new file mode 100644 index 0000000000000000000000000000000000000000..68a92221db3c0fea63b5cbb5f9f3e972c58e4119 GIT binary patch literal 69 zcmZ4O9TK5nXt Date: Wed, 27 Dec 2023 15:27:41 +0100 Subject: [PATCH 39/58] QXcbWindow::handleLeaveNotifyEvent(): Consume when leaving geometry QXcbConnection::mousePressWindow() returns the XCB toplevel window, which has consumed the window system's last mouse press. When the function returns a valid pointer, QXcbWindow::handleLeaveNotifyEvent() didn't propagate the leave event to QWSI::handleLeaveEvent(). Instead, the leave event was ingored. That behavior is correct, e.g. when a button on the main window is pressed and the mouse hovers away from the button, with the mouse button continuously being pressed. It is not correct, if the mouse cursor leaves the main window. => Ignore the leave event only as long as the mouse cursor remains within mousePressWindow()->geometry(). => Deliver the leave event, when the mouse cursor leaves the window. Fixes: QTBUG-119864 Change-Id: I30a6ebedcd148285b9f17dfd87885ff67726b54c Reviewed-by: Liang Qi (cherry picked from commit ec24b36d3db82c340d9386951ea48c26f77c2923) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 39e9b6b24cae07e7d11973ee680f9722ad10cf08) (cherry picked from commit 45efad7207ba47319e37be4ca5a61ef57eef7705) (cherry picked from commit f34a3e6f975ff7eff02b5af51f24e899ed20bb9e) (cherry picked from commit 260d131771a2ffdb6e04d2b16dc76e881cbc9838) --- src/plugins/platforms/xcb/qxcbwindow.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 875517fe5fc..b830dd03be2 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2016,10 +2016,15 @@ static inline bool doCheckUnGrabAncestor(QXcbConnection *conn) return true; } -static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn = nullptr) +static bool windowContainsGlobalPoint(QXcbWindow *window, int x, int y) +{ + return window ? window->geometry().contains(window->mapFromGlobal(QPoint(x, y))) : false; +} + +static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn) { return ((doCheckUnGrabAncestor(conn) - && mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) + && mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) || (mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_INFERIOR) || detail == XCB_NOTIFY_DETAIL_VIRTUAL || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); @@ -2039,14 +2044,13 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in { connection()->setTime(timestamp); - const QPoint global = QPoint(root_x, root_y); - if (ignoreEnterEvent(mode, detail, connection()) || connection()->mousePressWindow()) return; // Updates scroll valuators, as user might have done some scrolling outside our X client. connection()->xi2UpdateScrollingDevices(); + const QPoint global = QPoint(root_x, root_y); const QPoint local(event_x, event_y); QWindowSystemInterface::handleEnterEvent(window(), local, global); } @@ -2056,8 +2060,11 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, { connection()->setTime(timestamp); - if (ignoreLeaveEvent(mode, detail, connection()) || connection()->mousePressWindow()) + QXcbWindow *mousePressWindow = connection()->mousePressWindow(); + if (ignoreLeaveEvent(mode, detail, connection()) + || (mousePressWindow && windowContainsGlobalPoint(mousePressWindow, root_x, root_y))) { return; + } // check if enter event is buffered auto event = connection()->eventQueue()->peek([](xcb_generic_event_t *event, int type) { @@ -2075,6 +2082,8 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); } else { QWindowSystemInterface::handleLeaveEvent(window()); + if (!windowContainsGlobalPoint(this, root_x, root_y)) + connection()->setMousePressWindow(nullptr); } free(enter); From d40b54a0e5b54a247549314b78a0d2ee7c410564 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 1 Feb 2024 11:03:46 +0100 Subject: [PATCH 40/58] Update bundled libjpeg-turbo to version 3.0.2 [ChangeLog][Third-Party Code] libjpeg-turbo was updated to version 3.0.2 Fixes: QTBUG-121737 Change-Id: I0085f0f859dd9c95ed203fd22bd9702fd1e9d721 Reviewed-by: Eskil Abrahamsen Blomfeldt (cherry picked from commit 972bd4ed46be6ad905f2cd8bd84776cf3f1f3220) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 27625a33c548e1330ad93f81567d357fe5f4d224) (cherry picked from commit 027724d66e649f51fee8f96fe1a2e48892848307) (cherry picked from commit acccb5d488e81747a8680ebc7d5890e29deaf98c) Reviewed-by: Eirik Aavitsland (cherry picked from commit 7c75dab2fd4b9247d6911d9445a87ff649895920) --- src/3rdparty/libjpeg/CMakeLists.txt | 3 +- src/3rdparty/libjpeg/COPYRIGHT.txt | 2 +- src/3rdparty/libjpeg/common.pri | 3 +- .../libjpeg/import_from_libjpeg_tarball.sh | 2 +- src/3rdparty/libjpeg/qt_attribution.json | 4 +- src/3rdparty/libjpeg/src/ChangeLog.md | 37 +++++++++++++++- src/3rdparty/libjpeg/src/jchuff.c | 38 +--------------- src/3rdparty/libjpeg/src/jconfig.h | 5 ++- src/3rdparty/libjpeg/src/jconfigint.h | 5 ++- src/3rdparty/libjpeg/src/jconfigint.h.in | 3 ++ src/3rdparty/libjpeg/src/jcphuff.c | 37 +--------------- src/3rdparty/libjpeg/src/jdapimin.c | 11 +++-- src/3rdparty/libjpeg/src/jerror.h | 4 +- src/3rdparty/libjpeg/src/jmemsys.h | 31 ------------- .../src/{jpeg_nbits_table.h => jpeg_nbits.c} | 38 +++++++++++++++- src/3rdparty/libjpeg/src/jpeg_nbits.h | 43 +++++++++++++++++++ src/3rdparty/libjpeg/src/jversion.h | 6 +-- 17 files changed, 150 insertions(+), 122 deletions(-) rename src/3rdparty/libjpeg/src/{jpeg_nbits_table.h => jpeg_nbits.c} (99%) create mode 100644 src/3rdparty/libjpeg/src/jpeg_nbits.h diff --git a/src/3rdparty/libjpeg/CMakeLists.txt b/src/3rdparty/libjpeg/CMakeLists.txt index 2fa234a3090..6b211e25423 100644 --- a/src/3rdparty/libjpeg/CMakeLists.txt +++ b/src/3rdparty/libjpeg/CMakeLists.txt @@ -61,7 +61,8 @@ set(JPEG_SOURCES src/jerror.c src/jfdctflt.c src/jmemmgr.c - src/jmemnobs.c) + src/jmemnobs.c + src/jpeg_nbits.c) qt_internal_add_3rdparty_library(BundledLibjpeg16bits STATIC diff --git a/src/3rdparty/libjpeg/COPYRIGHT.txt b/src/3rdparty/libjpeg/COPYRIGHT.txt index 5b6ff32c691..ce9d95bfebc 100644 --- a/src/3rdparty/libjpeg/COPYRIGHT.txt +++ b/src/3rdparty/libjpeg/COPYRIGHT.txt @@ -1,4 +1,4 @@ -Copyright (C) 2009-2023 D. R. Commander +Copyright (C) 2009-2024 D. R. Commander Copyright (C) 2015, 2020 Google, Inc. Copyright (C) 2019-2020 Arm Limited Copyright (C) 2015-2016, 2018 Matthieu Darbois diff --git a/src/3rdparty/libjpeg/common.pri b/src/3rdparty/libjpeg/common.pri index 92c25531cf1..4e20ae504ea 100644 --- a/src/3rdparty/libjpeg/common.pri +++ b/src/3rdparty/libjpeg/common.pri @@ -78,6 +78,7 @@ JPEG_SOURCES = \ $$PWD/src/jerror.c \ $$PWD/src/jfdctflt.c \ $$PWD/src/jmemmgr.c \ - $$PWD/src/jmemnobs.c + $$PWD/src/jmemnobs.c \ + $$PWD/src/jpeg_nbits.c TR_EXCLUDE += $$PWD/* diff --git a/src/3rdparty/libjpeg/import_from_libjpeg_tarball.sh b/src/3rdparty/libjpeg/import_from_libjpeg_tarball.sh index de3f3091ea7..fe8b41275fb 100755 --- a/src/3rdparty/libjpeg/import_from_libjpeg_tarball.sh +++ b/src/3rdparty/libjpeg/import_from_libjpeg_tarball.sh @@ -160,7 +160,7 @@ FILES=" jmemnobs.c jmemsys.h jmorecfg.h - jpeg_nbits_table.h + jpeg_nbits.h jquant1.c jquant2.c jsamplecomp.h diff --git a/src/3rdparty/libjpeg/qt_attribution.json b/src/3rdparty/libjpeg/qt_attribution.json index 79c8bd97fc3..3c5f9e03a52 100644 --- a/src/3rdparty/libjpeg/qt_attribution.json +++ b/src/3rdparty/libjpeg/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "The Independent JPEG Group's JPEG software", "Homepage": "http://libjpeg-turbo.virtualgl.org/", - "Version": "3.0.1", - "DownloadLocation": "https://sourceforge.net/projects/libjpeg-turbo/files/3.0.1/libjpeg-turbo-3.0.1.tar.gz", + "Version": "3.0.2", + "DownloadLocation": "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/3.0.2/libjpeg-turbo-3.0.2.tar.gz", "License": "Independent JPEG Group License and BSD 3-Clause \"New\" or \"Revised\" License and zlib License", "LicenseId": "IJG AND BSD-3-Clause AND Zlib", "LicenseFiles": [ "LICENSE", "ijg-license.txt", "zlib-license.txt"], diff --git a/src/3rdparty/libjpeg/src/ChangeLog.md b/src/3rdparty/libjpeg/src/ChangeLog.md index a4667851333..a929b62a8cd 100644 --- a/src/3rdparty/libjpeg/src/ChangeLog.md +++ b/src/3rdparty/libjpeg/src/ChangeLog.md @@ -1,3 +1,38 @@ +3.0.2 +===== + +### Significant changes relative to 3.0.1: + +1. Fixed a signed integer overflow in the `tj3CompressFromYUV8()`, +`tj3DecodeYUV8()`, `tj3DecompressToYUV8()`, and `tj3EncodeYUV8()` functions, +detected by the Clang and GCC undefined behavior sanitizers, that could be +triggered by setting the `align` parameter to an unreasonably large value. +This issue did not pose a security threat, but removing the warning made it +easier to detect actual security issues, should they arise in the future. + +2. Introduced a new parameter (`TJPARAM_MAXMEMORY` in the TurboJPEG C API and +`TJ.PARAM_MAXMEMORY` in the TurboJPEG Java API) and a corresponding TJBench +option (`-maxmemory`) for specifying the maximum amount of memory (in +megabytes) that will be allocated for intermediate buffers, which are used with +progressive JPEG compression and decompression, optimized baseline entropy +coding, lossless JPEG compression, and lossless transformation. The new +parameter and option serve the same purpose as the `max_memory_to_use` field in +the `jpeg_memory_mgr` struct in the libjpeg API, the `JPEGMEM` environment +variable, and the cjpeg/djpeg/jpegtran `-maxmemory` option. + +3. Introduced a new parameter (`TJPARAM_MAXPIXELS` in the TurboJPEG C API and +`TJ.PARAM_MAXPIXELS` in the TurboJPEG Java API) and a corresponding TJBench +option (`-maxpixels`) for specifying the maximum number of pixels that the +decompression, lossless transformation, and packed-pixel image loading +functions/methods will process. + +4. Fixed an error ("Unsupported color conversion request") that occurred when +attempting to decompress a 3-component lossless JPEG image without an Adobe +APP14 marker. The decompressor now assumes that a 3-component lossless JPEG +image without an Adobe APP14 marker uses the RGB colorspace if its component +IDs are 1, 2, and 3. + + 3.0.1 ===== @@ -2146,7 +2181,7 @@ and unit tests now work on those architectures. 0.0.93 ====== -### Significant changes since 0.0.91: +### Significant changes relative to 0.0.91: 1. 2982659: Fixed x86-64 build on FreeBSD systems diff --git a/src/3rdparty/libjpeg/src/jchuff.c b/src/3rdparty/libjpeg/src/jchuff.c index 3fede05f804..488c9b5c3a7 100644 --- a/src/3rdparty/libjpeg/src/jchuff.c +++ b/src/3rdparty/libjpeg/src/jchuff.c @@ -6,7 +6,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2009-2011, 2014-2016, 2018-2023, D. R. Commander. + * Copyright (C) 2009-2011, 2014-2016, 2018-2024, D. R. Commander. * Copyright (C) 2015, Matthieu Darbois. * Copyright (C) 2018, Matthias Räncker. * Copyright (C) 2020, Arm Limited. @@ -35,41 +35,7 @@ #include "jchuff.h" /* Declarations shared with jc*huff.c */ #endif #include - -/* - * NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be - * used for bit counting rather than the lookup table. This will reduce the - * memory footprint by 64k, which is important for some mobile applications - * that create many isolated instances of libjpeg-turbo (web browsers, for - * instance.) This may improve performance on some mobile platforms as well. - * This feature is enabled by default only on Arm processors, because some x86 - * chips have a slow implementation of bsr, and the use of clz/bsr cannot be - * shown to have a significant performance impact even on the x86 chips that - * have a fast implementation of it. When building for Armv6, you can - * explicitly disable the use of clz/bsr by adding -mthumb to the compiler - * flags (this defines __thumb__). - */ - -/* NOTE: Both GCC and Clang define __GNUC__ */ -#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \ - defined(_M_ARM) || defined(_M_ARM64) -#if !defined(__thumb__) || defined(__thumb2__) -#define USE_CLZ_INTRINSIC -#endif -#endif - -#ifdef USE_CLZ_INTRINSIC -#if defined(_MSC_VER) && !defined(__clang__) -#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x)) -#else -#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x)) -#endif -#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0) -#else -#include "jpeg_nbits_table.h" -#define JPEG_NBITS(x) (jpeg_nbits_table[x]) -#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x) -#endif +#include "jpeg_nbits.h" /* Expanded entropy encoder object for Huffman encoding. diff --git a/src/3rdparty/libjpeg/src/jconfig.h b/src/3rdparty/libjpeg/src/jconfig.h index a91be588e7b..1e03e166e77 100644 --- a/src/3rdparty/libjpeg/src/jconfig.h +++ b/src/3rdparty/libjpeg/src/jconfig.h @@ -2,9 +2,9 @@ #define JPEG_LIB_VERSION 80 -#define LIBJPEG_TURBO_VERSION 3.0.0 +#define LIBJPEG_TURBO_VERSION 3.0.2 -#define LIBJPEG_TURBO_VERSION_NUMBER 3000000 +#define LIBJPEG_TURBO_VERSION_NUMBER 3000002 #define C_ARITH_CODING_SUPPORTED 1 @@ -17,3 +17,4 @@ #endif #define NO_PUTENV + diff --git a/src/3rdparty/libjpeg/src/jconfigint.h b/src/3rdparty/libjpeg/src/jconfigint.h index a58061e52bb..afcb25d247c 100644 --- a/src/3rdparty/libjpeg/src/jconfigint.h +++ b/src/3rdparty/libjpeg/src/jconfigint.h @@ -4,11 +4,13 @@ #define BUILD "" +#define HIDDEN + #define INLINE inline #define PACKAGE_NAME "libjpeg-turbo" -#define VERSION "3.0.0" +#define VERSION "3.0.2" #if SIZE_MAX == 0xffffffff #define SIZEOF_SIZE_T 4 @@ -46,3 +48,4 @@ /* #undef WITH_SIMD */ #endif + diff --git a/src/3rdparty/libjpeg/src/jconfigint.h.in b/src/3rdparty/libjpeg/src/jconfigint.h.in index e7e66e74c02..5c14e32a1d1 100644 --- a/src/3rdparty/libjpeg/src/jconfigint.h.in +++ b/src/3rdparty/libjpeg/src/jconfigint.h.in @@ -1,6 +1,9 @@ /* libjpeg-turbo build number */ #define BUILD "@BUILD@" +/* How to hide global symbols. */ +#define HIDDEN @HIDDEN@ + /* Compiler's inline keyword */ #undef inline diff --git a/src/3rdparty/libjpeg/src/jcphuff.c b/src/3rdparty/libjpeg/src/jcphuff.c index 56e63bd62d3..484e2d857f0 100644 --- a/src/3rdparty/libjpeg/src/jcphuff.c +++ b/src/3rdparty/libjpeg/src/jcphuff.c @@ -6,7 +6,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2011, 2015, 2018, 2021-2022, D. R. Commander. + * Copyright (C) 2011, 2015, 2018, 2021-2022, 2024, D. R. Commander. * Copyright (C) 2016, 2018, 2022, Matthieu Darbois. * Copyright (C) 2020, Arm Limited. * Copyright (C) 2021, Alex Richardson. @@ -44,40 +44,7 @@ #ifdef C_PROGRESSIVE_SUPPORTED -/* - * NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be - * used for bit counting rather than the lookup table. This will reduce the - * memory footprint by 64k, which is important for some mobile applications - * that create many isolated instances of libjpeg-turbo (web browsers, for - * instance.) This may improve performance on some mobile platforms as well. - * This feature is enabled by default only on Arm processors, because some x86 - * chips have a slow implementation of bsr, and the use of clz/bsr cannot be - * shown to have a significant performance impact even on the x86 chips that - * have a fast implementation of it. When building for Armv6, you can - * explicitly disable the use of clz/bsr by adding -mthumb to the compiler - * flags (this defines __thumb__). - */ - -/* NOTE: Both GCC and Clang define __GNUC__ */ -#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \ - defined(_M_ARM) || defined(_M_ARM64) -#if !defined(__thumb__) || defined(__thumb2__) -#define USE_CLZ_INTRINSIC -#endif -#endif - -#ifdef USE_CLZ_INTRINSIC -#if defined(_MSC_VER) && !defined(__clang__) -#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x)) -#else -#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x)) -#endif -#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0) -#else -#include "jpeg_nbits_table.h" -#define JPEG_NBITS(x) (jpeg_nbits_table[x]) -#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x) -#endif +#include "jpeg_nbits.h" /* Expanded entropy encoder object for progressive Huffman encoding. */ diff --git a/src/3rdparty/libjpeg/src/jdapimin.c b/src/3rdparty/libjpeg/src/jdapimin.c index 51ca552dad8..30d92841a8c 100644 --- a/src/3rdparty/libjpeg/src/jdapimin.c +++ b/src/3rdparty/libjpeg/src/jdapimin.c @@ -6,7 +6,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2016, 2022, D. R. Commander. + * Copyright (C) 2016, 2022, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -160,9 +160,12 @@ default_decompress_parms(j_decompress_ptr cinfo) int cid1 = cinfo->comp_info[1].component_id; int cid2 = cinfo->comp_info[2].component_id; - if (cid0 == 1 && cid1 == 2 && cid2 == 3) - cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ - else if (cid0 == 82 && cid1 == 71 && cid2 == 66) + if (cid0 == 1 && cid1 == 2 && cid2 == 3) { + if (cinfo->master->lossless) + cinfo->jpeg_color_space = JCS_RGB; /* assume RGB w/out marker */ + else + cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ + } else if (cid0 == 82 && cid1 == 71 && cid2 == 66) cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ else { TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); diff --git a/src/3rdparty/libjpeg/src/jerror.h b/src/3rdparty/libjpeg/src/jerror.h index 39362fdd477..71ba03e2a3e 100644 --- a/src/3rdparty/libjpeg/src/jerror.h +++ b/src/3rdparty/libjpeg/src/jerror.h @@ -7,7 +7,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2014, 2017, 2021-2022, D. R. Commander. + * Copyright (C) 2014, 2017, 2021-2023, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -111,7 +111,7 @@ JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") #if JPEG_LIB_VERSION >= 70 JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined") #endif -JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_BACKING_STORE, "Memory limit exceeded") JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") diff --git a/src/3rdparty/libjpeg/src/jmemsys.h b/src/3rdparty/libjpeg/src/jmemsys.h index 9229550afde..ac09ef4c36d 100644 --- a/src/3rdparty/libjpeg/src/jmemsys.h +++ b/src/3rdparty/libjpeg/src/jmemsys.h @@ -99,24 +99,6 @@ EXTERN(size_t) jpeg_mem_available(j_common_ptr cinfo, size_t min_bytes_needed, #define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ -#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ - -typedef unsigned short XMSH; /* type of extended-memory handles */ -typedef unsigned short EMSH; /* type of expanded-memory handles */ - -typedef union { - short file_handle; /* DOS file handle if it's a temp file */ - XMSH xms_handle; /* handle if it's a chunk of XMS */ - EMSH ems_handle; /* handle if it's a chunk of EMS */ -} handle_union; - -#endif /* USE_MSDOS_MEMMGR */ - -#ifdef USE_MAC_MEMMGR /* Mac-specific junk */ -#include -#endif /* USE_MAC_MEMMGR */ - - typedef struct backing_store_struct *backing_store_ptr; typedef struct backing_store_struct { @@ -130,22 +112,9 @@ typedef struct backing_store_struct { void (*close_backing_store) (j_common_ptr cinfo, backing_store_ptr info); /* Private fields for system-dependent backing-store management */ -#ifdef USE_MSDOS_MEMMGR - /* For the MS-DOS manager (jmemdos.c), we need: */ - handle_union handle; /* reference to backing-store storage object */ - char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ -#else -#ifdef USE_MAC_MEMMGR - /* For the Mac manager (jmemmac.c), we need: */ - short temp_file; /* file reference number to temp file */ - FSSpec tempSpec; /* the FSSpec for the temp file */ - char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ -#else /* For a typical implementation with temp files, we need: */ FILE *temp_file; /* stdio reference to temp file */ char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ -#endif -#endif } backing_store_info; diff --git a/src/3rdparty/libjpeg/src/jpeg_nbits_table.h b/src/3rdparty/libjpeg/src/jpeg_nbits.c similarity index 99% rename from src/3rdparty/libjpeg/src/jpeg_nbits_table.h rename to src/3rdparty/libjpeg/src/jpeg_nbits.c index fcf73878c31..c8ee6b056cb 100644 --- a/src/3rdparty/libjpeg/src/jpeg_nbits_table.h +++ b/src/3rdparty/libjpeg/src/jpeg_nbits.c @@ -1,4 +1,32 @@ -static const unsigned char jpeg_nbits_table[65536] = { +/* + * Copyright (C) 2024, D. R. Commander. + * + * For conditions of distribution and use, see the accompanying README.ijg + * file. + */ + +#include "jpeg_nbits.h" +#include "jconfigint.h" + + +#ifndef USE_CLZ_INTRINSIC + +#define INCLUDE_JPEG_NBITS_TABLE + +/* When building for x86[-64] with the SIMD extensions enabled, the C Huffman + * encoders can reuse jpeg_nbits_table from the SSE2 baseline Huffman encoder. + */ +#if (defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || \ + defined(_M_X64)) && defined(WITH_SIMD) +#undef INCLUDE_JPEG_NBITS_TABLE +#endif + +#endif + + +#ifdef INCLUDE_JPEG_NBITS_TABLE + +const unsigned char HIDDEN jpeg_nbits_table[65536] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, @@ -4096,3 +4124,11 @@ static const unsigned char jpeg_nbits_table[65536] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; + +#else + +/* Suppress compiler warnings about empty translation unit. */ + +typedef int dummy_jpeg_nbits_table; + +#endif diff --git a/src/3rdparty/libjpeg/src/jpeg_nbits.h b/src/3rdparty/libjpeg/src/jpeg_nbits.h new file mode 100644 index 00000000000..6481a1228d1 --- /dev/null +++ b/src/3rdparty/libjpeg/src/jpeg_nbits.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014, 2021, 2024, D. R. Commander. + * Copyright (C) 2014, Olle Liljenzin. + * Copyright (C) 2020, Arm Limited. + * + * For conditions of distribution and use, see the accompanying README.ijg + * file. + */ + +/* + * NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be + * used for bit counting rather than the lookup table. This will reduce the + * memory footprint by 64k, which is important for some mobile applications + * that create many isolated instances of libjpeg-turbo (web browsers, for + * instance.) This may improve performance on some mobile platforms as well. + * This feature is enabled by default only on Arm processors, because some x86 + * chips have a slow implementation of bsr, and the use of clz/bsr cannot be + * shown to have a significant performance impact even on the x86 chips that + * have a fast implementation of it. When building for Armv6, you can + * explicitly disable the use of clz/bsr by adding -mthumb to the compiler + * flags (this defines __thumb__). + */ + +/* NOTE: Both GCC and Clang define __GNUC__ */ +#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \ + defined(_M_ARM) || defined(_M_ARM64) +#if !defined(__thumb__) || defined(__thumb2__) +#define USE_CLZ_INTRINSIC +#endif +#endif + +#ifdef USE_CLZ_INTRINSIC +#if defined(_MSC_VER) && !defined(__clang__) +#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x)) +#else +#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x)) +#endif +#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0) +#else +extern const unsigned char jpeg_nbits_table[65536]; +#define JPEG_NBITS(x) (jpeg_nbits_table[x]) +#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x) +#endif diff --git a/src/3rdparty/libjpeg/src/jversion.h b/src/3rdparty/libjpeg/src/jversion.h index f9ad5c29c99..5c127dc635a 100644 --- a/src/3rdparty/libjpeg/src/jversion.h +++ b/src/3rdparty/libjpeg/src/jversion.h @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2012-2023, D. R. Commander. + * Copyright (C) 2010, 2012-2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -37,7 +37,7 @@ */ #define JCOPYRIGHT \ - "Copyright (C) 2009-2023 D. R. Commander\n" \ + "Copyright (C) 2009-2024 D. R. Commander\n" \ "Copyright (C) 2015, 2020 Google, Inc.\n" \ "Copyright (C) 2019-2020 Arm Limited\n" \ "Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \ @@ -52,4 +52,4 @@ "Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding" #define JCOPYRIGHT_SHORT \ - "Copyright (C) 1991-2023 The libjpeg-turbo Project and many others" + "Copyright (C) 1991-2024 The libjpeg-turbo Project and many others" From d37f2b3a362f4027dd4955f288578062cf87adcf Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 20 Feb 2024 08:07:38 +0100 Subject: [PATCH 41/58] QPainter: fix assert when drawing bitmaps at very near to .5 coord The code assumed that the rounding of a floating point value, and the rounding of the sum of that value and an integer, would always snap in the same direction. But because of accuracy limits (independently of the rounding function employed), that is not always the case for fractions very near to .5. Fixes: QTBUG-122451 Change-Id: I0825d42e6be7f6e3397760a5e9be5dddca42dcdc Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Qt CI Bot (cherry picked from commit a43d86fe1c0bc9d352f67c134a9ee5f754aea5e6) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 824d2936010bb46322d29eeb708bee0cee87d081) (cherry picked from commit 0f09f744b093d7bb06451622f0a75cc787b015ad) (cherry picked from commit bea4d640a25b8606dec7488ff2f12b8f9be7824e) (cherry picked from commit 17d29130b9cb3faaa90a78ab7737b1c8918c40ea) --- src/gui/painting/qpaintengine_raster.cpp | 14 ++++++++------ tests/auto/gui/painting/qpainter/tst_qpainter.cpp | 11 +++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 5564ab287c7..56957c2e534 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3462,16 +3462,18 @@ void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSp // Boundaries int w = image.width(); int h = image.height(); - int ymax = qMin(qRound(pos.y() + h), d->rasterBuffer->height()); - int ymin = qMax(qRound(pos.y()), 0); - int xmax = qMin(qRound(pos.x() + w), d->rasterBuffer->width()); - int xmin = qMax(qRound(pos.x()), 0); + int px = qRound(pos.x()); + int py = qRound(pos.y()); + int ymax = qMin(py + h, d->rasterBuffer->height()); + int ymin = qMax(py, 0); + int xmax = qMin(px + w, d->rasterBuffer->width()); + int xmin = qMax(px, 0); - int x_offset = xmin - qRound(pos.x()); + int x_offset = xmin - px; QImage::Format format = image.format(); for (int y = ymin; y < ymax; ++y) { - const uchar *src = image.scanLine(y - qRound(pos.y())); + const uchar *src = image.scanLine(y - py); if (format == QImage::Format_MonoLSB) { for (int x = 0; x < xmax - xmin; ++x) { int src_x = x + x_offset; diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index d7c3f95f1de..bfc77b0831e 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -84,6 +84,7 @@ private slots: #endif void drawPixmapFragments(); void drawPixmapNegativeScale(); + void drawPixmapRounding(); void drawLine_data(); void drawLine(); @@ -799,6 +800,16 @@ void tst_QPainter::drawPixmapNegativeScale() QVERIFY(resultImage.pixel(12, 8) == qRgba(0, 0, 0, 255)); // and right strip is now black } +void tst_QPainter::drawPixmapRounding() +{ + // Just test that we don't assert + QBitmap bm(8, 8); + QImage out(64, 64, QImage::Format_RGB32); + QPainter p(&out); + qreal y = 26.499999999999996; + p.drawPixmap(QPointF(0, y), bm); +} + void tst_QPainter::drawLine_data() { QTest::addColumn("line"); From ad0b5aa79bc2a4d4bf090d79a116ddc45bccf20f Mon Sep 17 00:00:00 2001 From: Elias Toivola Date: Mon, 19 Feb 2024 12:03:36 +0200 Subject: [PATCH 42/58] Windows 7: blacklist tests that fail from low screen resolution When OpenNebula was updated in CI, new Windows provisions defaulted to 800x600 resolution which caused some tests to fail. Adding new display settings to the Windows registry in tier-2 provisioning scripts worked on Windows 10/11 but issues with Windows 7 persists, one of my suspicions is that Windows 7 VM spawns a new empty video subkey in the registry when it's launched by a module in Coin run, which happens after provisioning scripts are run and done. This issue is blocking Qt 5.15 integrations, so for now it is best to blacklist the tests that fail from the 800x600 screen resolution. Task-number: QTQAINFRA-6145 Change-Id: I6ee6cb44c0036873d893bceb080cd867faad0385 Reviewed-by: Qt CI Bot Reviewed-by: Tarja Sundqvist --- tests/auto/widgets/widgets/qmainwindow/BLACKLIST | 1 + tests/auto/widgets/widgets/qopenglwidget/BLACKLIST | 3 +++ 2 files changed, 4 insertions(+) diff --git a/tests/auto/widgets/widgets/qmainwindow/BLACKLIST b/tests/auto/widgets/widgets/qmainwindow/BLACKLIST index a03ea11f40e..1acf272391d 100644 --- a/tests/auto/widgets/widgets/qmainwindow/BLACKLIST +++ b/tests/auto/widgets/widgets/qmainwindow/BLACKLIST @@ -1,2 +1,3 @@ [resizeDocks] winrt +windows-7sp1 # QTQAINFRA-6145 diff --git a/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST index 6c31a8d1d6c..b1c4279c845 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST +++ b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST @@ -2,3 +2,6 @@ windows-10 msvc-2017 sles-15.4 # QTBUG-104241 +# QTQAINFRA-6145 +[clearAndGrab] +windows-7sp1 \ No newline at end of file From c4b785ab95469b468ab69604f052e7f79e17a9bd Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 27 Feb 2024 10:35:49 +0100 Subject: [PATCH 43/58] Windows: clean up System Tray Icon message icon The handle is not owned by the Shell, we have to clear it up ourselves. The documentation is not clear about how long the handle needs to be kept alive, so store the icon when we create it as a member of the private, and clean it up when it need to be recreated, or when the QSystemTrayIcon instance gets destroyed. Conflict resolution needed as 94809cdec004611bdb8531304e6c74761014876b had not been cherry-picked back to 6.5. Fixes: QTBUG-96348 Fixes: QTBUG-62945 Change-Id: I6f93f29a415cde2cfe4e1b296295783c15b4da4b Reviewed-by: Oliver Wolff (cherry picked from commit afb74a86d8cd1ac6463fa804300480967101d7d7) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 59ff87dc911840669699c0a09acb2fd7ffa012fe) (cherry picked from commit 5bdb2bacefc8b09c8f5da0973e5d7f8720b777aa) Reviewed-by: Volker Hilsheimer (cherry picked from commit fd5487188db787b7d35b3aff070a81a59cc68058) (cherry picked from commit 65a49b6bd5cbd6a178662d0ab6f3e1486dd24c6d) --- .../platforms/windows/qwindowssystemtrayicon.cpp | 10 +++++++++- src/plugins/platforms/windows/qwindowssystemtrayicon.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp index 6745a7dd3f3..5173a5467a3 100644 --- a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp +++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp @@ -278,6 +278,10 @@ void QWindowsSystemTrayIcon::showMessage(const QString &title, const QString &me size = largeIcon; } QPixmap pm = icon.pixmap(size); + if (m_hMessageIcon) { + DestroyIcon(m_hMessageIcon); + m_hMessageIcon = nullptr; + } if (pm.isNull()) { tnd.dwInfoFlags = NIIF_INFO; } else { @@ -286,7 +290,8 @@ void QWindowsSystemTrayIcon::showMessage(const QString &title, const QString &me pm.size().width(), pm.size().height(), size.width(), size.height()); pm = pm.scaled(size, Qt::IgnoreAspectRatio); } - tnd.hBalloonIcon = qt_pixmapToWinHICON(pm); + m_hMessageIcon = qt_pixmapToWinHICON(pm); + tnd.hBalloonIcon = m_hMessageIcon; } tnd.hWnd = m_hwnd; tnd.uTimeout = msecsIn <= 0 ? UINT(10000) : UINT(msecsIn); // 10s default @@ -344,7 +349,10 @@ void QWindowsSystemTrayIcon::ensureCleanup() } if (m_hIcon != nullptr) DestroyIcon(m_hIcon); + if (m_hMessageIcon != nullptr) + DestroyIcon(m_hMessageIcon); m_hIcon = nullptr; + m_hMessageIcon = nullptr; m_menu = nullptr; // externally owned m_toolTip.clear(); } diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.h b/src/plugins/platforms/windows/qwindowssystemtrayicon.h index 16c172494bd..d74f3d0071b 100644 --- a/src/plugins/platforms/windows/qwindowssystemtrayicon.h +++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.h @@ -91,6 +91,7 @@ private: QString m_toolTip; HWND m_hwnd = nullptr; HICON m_hIcon = nullptr; + HICON m_hMessageIcon = nullptr; mutable QPointer m_menu; bool m_ignoreNextMouseRelease = false; bool m_visible = false; From d6f1933dfa1c192fd88596c908a7ab779b5e7b5f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 20 Feb 2024 19:01:00 +0100 Subject: [PATCH 44/58] QDBusUtil: document the D-Bus signature grammar The specification doesn't provide an explicit grammar, so I turned the prose into ABNF for easier reference. The goal is both to aid review of the validateSingleType() function and to eventually use this to write a parser that doesn't use, or at least limits, recursion. Change-Id: I21f81aa83cde356ab48105ea98f066024e0b7b5e Reviewed-by: Juha Vuolle Reviewed-by: Thiago Macieira (cherry picked from commit 476d2a7392ee26294d1230f0c5031fe6bb4a0f26) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit c49366a54387eae2467db7efd288fd51d8114857) (cherry picked from commit 4c1935f227e1c3ecca0bc325d0b5222c5ecffcfc) (cherry picked from commit 50d46911cc19859791888b9a23c6742e09f91e93) (cherry picked from commit 32075f1960677aea75863b517c6070648762f84c) --- src/dbus/qdbusutil.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/dbus/qdbusutil.cpp b/src/dbus/qdbusutil.cpp index 25e973853eb..888169b1cce 100644 --- a/src/dbus/qdbusutil.cpp +++ b/src/dbus/qdbusutil.cpp @@ -244,6 +244,21 @@ static const char oneLetterTypes[] = "vsogybnqiuxtdh"; static const char basicTypes[] = "sogybnqiuxtdh"; static const char fixedTypes[] = "ybnqiuxtdh"; +/* + D-Bus signature grammar (in ABNF), as of 0.42 (2023-08-21): + https://dbus.freedesktop.org/doc/dbus-specification.html#type-system + + = * + = / / / + = "y" / "b" / "n" / "q" / "i" / "u" / "x" / "t" / "d" / "h" + = "s" / "o" / "g" + = / + = "v" + = "(" 1* ")" + = "a" ( / ) + = "{" "}" +*/ + static bool isBasicType(int c) { return c != DBUS_TYPE_INVALID && strchr(basicTypes, c) != nullptr; From 5b06f836b9876023754f8f056b97e097c76b2bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20K=C3=B6hne?= Date: Wed, 31 Jan 2024 11:48:58 +0100 Subject: [PATCH 45/58] SQLite: Update SQLite to v3.45.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ChangeLog][Third-Party Code] Updated SQLite to v3.45.1 Change-Id: I8083d0750e52b1035919821c25cef9855afea2f9 Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim (cherry picked from commit 40a87ca1b421457fc2a31cf385eb5a0eda83486f) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 2c53d990f7c5f77b58a2b5550c2bf6d0adc306a6) (cherry picked from commit 5de945fb3c500f2a67d60f5ec71cd87c632aade4) (cherry picked from commit 4053e0557b2048ec38c067be4a743ca85492651e) (cherry picked from commit 051fa3cfa896ce7ab3023e6f87bb5eca5d11e534) --- src/3rdparty/sqlite/qt_attribution.json | 4 +- src/3rdparty/sqlite/sqlite3.c | 220 ++++++++++++++---------- src/3rdparty/sqlite/sqlite3.h | 6 +- 3 files changed, 137 insertions(+), 93 deletions(-) diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json index 036aa756bb5..640a926fca0 100644 --- a/src/3rdparty/sqlite/qt_attribution.json +++ b/src/3rdparty/sqlite/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Homepage": "https://www.sqlite.org/", - "Version": "3.45.0", - "DownloadLocation": "https://www.sqlite.org/2023/sqlite-amalgamation-3450000.zip", + "Version": "3.45.1", + "DownloadLocation": "https://www.sqlite.org/2024/sqlite-amalgamation-3450100.zip", "License": "Public Domain", "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." } diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 6e6dc8a6c8c..139ee46a6a9 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.45.0. By combining all the individual C code files into this +** version 3.45.1. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** 1066602b2b1976fe58b5150777cced894af1. +** e876e51a0ed5c5b3126f52e532044363a014. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -459,9 +459,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.45.0" -#define SQLITE_VERSION_NUMBER 3045000 -#define SQLITE_SOURCE_ID "2024-01-15 17:01:13 1066602b2b1976fe58b5150777cced894af17c803e068f5918390d6915b46e1d" +#define SQLITE_VERSION "3.45.1" +#define SQLITE_VERSION_NUMBER 3045001 +#define SQLITE_SOURCE_ID "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257cc467a" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -43408,11 +43408,16 @@ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ #if SQLITE_MAX_MMAP_SIZE>0 if( pFd->mmapSizeMax>0 ){ + /* Ensure that there is always at least a 256 byte buffer of addressable + ** memory following the returned page. If the database is corrupt, + ** SQLite may overread the page slightly (in practice only a few bytes, + ** but 256 is safe, round, number). */ + const int nEofBuffer = 256; if( pFd->pMapRegion==0 ){ int rc = unixMapfile(pFd, -1); if( rc!=SQLITE_OK ) return rc; } - if( pFd->mmapSize >= iOff+nAmt ){ + if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ *pp = &((u8 *)pFd->pMapRegion)[iOff]; pFd->nFetchOut++; } @@ -50765,6 +50770,11 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ #if SQLITE_MAX_MMAP_SIZE>0 if( pFd->mmapSizeMax>0 ){ + /* Ensure that there is always at least a 256 byte buffer of addressable + ** memory following the returned page. If the database is corrupt, + ** SQLite may overread the page slightly (in practice only a few bytes, + ** but 256 is safe, round, number). */ + const int nEofBuffer = 256; if( pFd->pMapRegion==0 ){ int rc = winMapfile(pFd, -1); if( rc!=SQLITE_OK ){ @@ -50773,7 +50783,7 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ return rc; } } - if( pFd->mmapSize >= iOff+nAmt ){ + if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ assert( pFd->pMapRegion!=0 ); *pp = &((u8 *)pFd->pMapRegion)[iOff]; pFd->nFetchOut++; @@ -76402,7 +76412,10 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ } pPage = pCur->pPage; - assert( pPage->isInit ); + if( sqlite3FaultSim(412) ) pPage->isInit = 0; + if( !pPage->isInit ){ + return SQLITE_CORRUPT_BKPT; + } if( !pPage->leaf ){ int idx = pCur->ix; rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); @@ -166812,7 +166825,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); - if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0; + if( pOrderBy && pOrderBy->nExpr>=BMS ){ + pOrderBy = 0; + wctrlFlags &= ~WHERE_WANT_DISTINCT; + } /* The number of tables in the FROM clause is limited by the number of ** bits in a Bitmask @@ -184749,6 +184765,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*); +SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk); + #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ #endif /* _FTSINT_H */ @@ -188471,7 +188489,7 @@ static int fts3ShadowName(const char *zName){ ** Implementation of the xIntegrity() method on the FTS3/FTS4 virtual ** table. */ -static int fts3Integrity( +static int fts3IntegrityMethod( sqlite3_vtab *pVtab, /* The virtual table to be checked */ const char *zSchema, /* Name of schema in which pVtab lives */ const char *zTabname, /* Name of the pVTab table */ @@ -188479,30 +188497,21 @@ static int fts3Integrity( char **pzErr /* Write error message here */ ){ Fts3Table *p = (Fts3Table*)pVtab; - char *zSql; int rc; - char *zErr = 0; + int bOk = 0; - assert( pzErr!=0 ); - assert( *pzErr==0 ); UNUSED_PARAMETER(isQuick); - zSql = sqlite3_mprintf( - "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", - zSchema, zTabname, zTabname); - if( zSql==0 ){ - return SQLITE_NOMEM; - } - rc = sqlite3_exec(p->db, zSql, 0, 0, &zErr); - sqlite3_free(zSql); - if( (rc&0xff)==SQLITE_CORRUPT ){ - *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", - p->bFts4 ? 4 : 3, zSchema, zTabname); - }else if( rc!=SQLITE_OK ){ + rc = sqlite3Fts3IntegrityCheck(p, &bOk); + assert( rc!=SQLITE_CORRUPT_VTAB || bOk==0 ); + if( rc!=SQLITE_OK && rc!=SQLITE_CORRUPT_VTAB ){ *pzErr = sqlite3_mprintf("unable to validate the inverted index for" " FTS%d table %s.%s: %s", - p->bFts4 ? 4 : 3, zSchema, zTabname, zErr); + p->bFts4 ? 4 : 3, zSchema, zTabname, sqlite3_errstr(rc)); + }else if( bOk==0 ){ + *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", + p->bFts4 ? 4 : 3, zSchema, zTabname); } - sqlite3_free(zErr); + sqlite3Fts3SegmentsClose(p); return SQLITE_OK; } @@ -188533,7 +188542,7 @@ static const sqlite3_module fts3Module = { /* xRelease */ fts3ReleaseMethod, /* xRollbackTo */ fts3RollbackToMethod, /* xShadowName */ fts3ShadowName, - /* xIntegrity */ fts3Integrity, + /* xIntegrity */ fts3IntegrityMethod, }; /* @@ -200087,7 +200096,7 @@ static u64 fts3ChecksumIndex( ** If an error occurs (e.g. an OOM or IO error), return an SQLite error ** code. The final value of *pbOk is undefined in this case. */ -static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ +SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ int rc = SQLITE_OK; /* Return code */ u64 cksum1 = 0; /* Checksum based on FTS index contents */ u64 cksum2 = 0; /* Checksum based on %_content contents */ @@ -200165,7 +200174,7 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ sqlite3_finalize(pStmt); } - *pbOk = (cksum1==cksum2); + *pbOk = (rc==SQLITE_OK && cksum1==cksum2); return rc; } @@ -200205,7 +200214,7 @@ static int fts3DoIntegrityCheck( ){ int rc; int bOk = 0; - rc = fts3IntegrityCheck(p, &bOk); + rc = sqlite3Fts3IntegrityCheck(p, &bOk); if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB; return rc; } @@ -203758,6 +203767,16 @@ static void jsonAppendChar(JsonString *p, char c){ } } +/* Remove a single character from the end of the string +*/ +static void jsonStringTrimOneChar(JsonString *p){ + if( p->eErr==0 ){ + assert( p->nUsed>0 ); + p->nUsed--; + } +} + + /* Make sure there is a zero terminator on p->zBuf[] ** ** Return true on success. Return false if an OOM prevents this @@ -203765,7 +203784,7 @@ static void jsonAppendChar(JsonString *p, char c){ */ static int jsonStringTerminate(JsonString *p){ jsonAppendChar(p, 0); - p->nUsed--; + jsonStringTrimOneChar(p); return p->eErr==0; } @@ -205231,8 +205250,8 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8]; n = 9; } - if( i+sz+n > pParse->nBlob - && i+sz+n > pParse->nBlob-pParse->delta + if( (i64)i+sz+n > pParse->nBlob + && (i64)i+sz+n > pParse->nBlob-pParse->delta ){ sz = 0; n = 0; @@ -205282,6 +205301,7 @@ static u32 jsonTranslateBlobToText( } case JSONB_INT: case JSONB_FLOAT: { + if( sz==0 ) goto malformed_jsonb; jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz); break; } @@ -205290,6 +205310,7 @@ static u32 jsonTranslateBlobToText( sqlite3_uint64 u = 0; const char *zIn = (const char*)&pParse->aBlob[i+n]; int bOverflow = 0; + if( sz==0 ) goto malformed_jsonb; if( zIn[0]=='-' ){ jsonAppendChar(pOut, '-'); k++; @@ -205312,6 +205333,7 @@ static u32 jsonTranslateBlobToText( case JSONB_FLOAT5: { /* Float literal missing digits beside "." */ u32 k = 0; const char *zIn = (const char*)&pParse->aBlob[i+n]; + if( sz==0 ) goto malformed_jsonb; if( zIn[0]=='-' ){ jsonAppendChar(pOut, '-'); k++; @@ -205425,11 +205447,12 @@ static u32 jsonTranslateBlobToText( jsonAppendChar(pOut, '['); j = i+n; iEnd = j+sz; - while( jeErr==0 ){ j = jsonTranslateBlobToText(pParse, j, pOut); jsonAppendChar(pOut, ','); } - if( sz>0 ) pOut->nUsed--; + if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); jsonAppendChar(pOut, ']'); break; } @@ -205438,17 +205461,18 @@ static u32 jsonTranslateBlobToText( jsonAppendChar(pOut, '{'); j = i+n; iEnd = j+sz; - while( jeErr==0 ){ j = jsonTranslateBlobToText(pParse, j, pOut); jsonAppendChar(pOut, (x++ & 1) ? ',' : ':'); } - if( x & 1 ) pOut->eErr |= JSTRING_MALFORMED; - if( sz>0 ) pOut->nUsed--; + if( (x & 1)!=0 || j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); jsonAppendChar(pOut, '}'); break; } default: { + malformed_jsonb: pOut->eErr |= JSTRING_MALFORMED; break; } @@ -206375,6 +206399,38 @@ jsonInsertIntoBlob_patherror: return; } +/* +** If pArg is a blob that seems like a JSONB blob, then initialize +** p to point to that JSONB and return TRUE. If pArg does not seem like +** a JSONB blob, then return FALSE; +** +** This routine is only called if it is already known that pArg is a +** blob. The only open question is whether or not the blob appears +** to be a JSONB blob. +*/ +static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){ + u32 n, sz = 0; + p->aBlob = (u8*)sqlite3_value_blob(pArg); + p->nBlob = (u32)sqlite3_value_bytes(pArg); + if( p->nBlob==0 ){ + p->aBlob = 0; + return 0; + } + if( NEVER(p->aBlob==0) ){ + return 0; + } + if( (p->aBlob[0] & 0x0f)<=JSONB_OBJECT + && (n = jsonbPayloadSize(p, 0, &sz))>0 + && sz+n==p->nBlob + && ((p->aBlob[0] & 0x0f)>JSONB_FALSE || sz==0) + ){ + return 1; + } + p->aBlob = 0; + p->nBlob = 0; + return 0; +} + /* ** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob, ** from the SQL function argument pArg. Return a pointer to the new @@ -206431,29 +206487,24 @@ rebuild_from_cache: return p; } if( eType==SQLITE_BLOB ){ - u32 n, sz = 0; - p->aBlob = (u8*)sqlite3_value_blob(pArg); - p->nBlob = (u32)sqlite3_value_bytes(pArg); - if( p->nBlob==0 ){ - goto json_pfa_malformed; + if( jsonArgIsJsonb(pArg,p) ){ + if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){ + goto json_pfa_oom; + } + return p; } - if( NEVER(p->aBlob==0) ){ - goto json_pfa_oom; - } - if( (p->aBlob[0] & 0x0f)>JSONB_OBJECT ){ - goto json_pfa_malformed; - } - n = jsonbPayloadSize(p, 0, &sz); - if( n==0 - || sz+n!=p->nBlob - || ((p->aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0) - ){ - goto json_pfa_malformed; - } - if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){ - goto json_pfa_oom; - } - return p; + /* If the blob is not valid JSONB, fall through into trying to cast + ** the blob into text which is then interpreted as JSON. (tag-20240123-a) + ** + ** This goes against all historical documentation about how the SQLite + ** JSON functions were suppose to work. From the beginning, blob was + ** reserved for expansion and a blob value should have raised an error. + ** But it did not, due to a bug. And many applications came to depend + ** upon this buggy behavior, espeically when using the CLI and reading + ** JSON text using readfile(), which returns a blob. For this reason + ** we will continue to support the bug moving forward. + ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d + */ } p->zJson = (char*)sqlite3_value_text(pArg); p->nJson = sqlite3_value_bytes(pArg); @@ -207429,12 +207480,12 @@ static void jsonValidFunc( return; } case SQLITE_BLOB: { - if( (flags & 0x0c)!=0 && jsonFuncArgMightBeBinary(argv[0]) ){ + if( jsonFuncArgMightBeBinary(argv[0]) ){ if( flags & 0x04 ){ /* Superficial checking only - accomplished by the ** jsonFuncArgMightBeBinary() call above. */ res = 1; - }else{ + }else if( flags & 0x08 ){ /* Strict checking. Check by translating BLOB->TEXT->BLOB. If ** no errors occur, call that a "strict check". */ JsonParse px; @@ -207445,8 +207496,11 @@ static void jsonValidFunc( iErr = jsonbValidityCheck(&px, 0, px.nBlob, 1); res = iErr==0; } + break; } - break; + /* Fall through into interpreting the input as text. See note + ** above at tag-20240123-a. */ + /* no break */ deliberate_fall_through } default: { JsonParse px; @@ -207571,7 +207625,7 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ if( isFinal ){ if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); }else{ - pStr->nUsed--; + jsonStringTrimOneChar(pStr); } return; }else if( isFinal ){ @@ -207581,7 +207635,7 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); - pStr->nUsed--; + jsonStringTrimOneChar(pStr); } }else{ sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); @@ -207691,7 +207745,7 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ if( isFinal ){ if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); }else{ - pStr->nUsed--; + jsonStringTrimOneChar(pStr); } return; }else if( isFinal ){ @@ -207701,7 +207755,7 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); - pStr->nUsed--; + jsonStringTrimOneChar(pStr); } }else{ sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); @@ -208182,13 +208236,9 @@ static int jsonEachFilter( memset(&p->sParse, 0, sizeof(p->sParse)); p->sParse.nJPRef = 1; p->sParse.db = p->db; - if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ - if( jsonFuncArgMightBeBinary(argv[0]) ){ - p->sParse.nBlob = sqlite3_value_bytes(argv[0]); - p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]); - }else{ - goto json_each_malformed_input; - } + if( jsonFuncArgMightBeBinary(argv[0]) ){ + p->sParse.nBlob = sqlite3_value_bytes(argv[0]); + p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]); }else{ p->sParse.zJson = (char*)sqlite3_value_text(argv[0]); p->sParse.nJson = sqlite3_value_bytes(argv[0]); @@ -250497,7 +250547,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2024-01-15 17:01:13 1066602b2b1976fe58b5150777cced894af17c803e068f5918390d6915b46e1d", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257cc467a", -1, SQLITE_TRANSIENT); } /* @@ -250528,27 +250578,21 @@ static int fts5IntegrityMethod( char **pzErr /* Write error message here */ ){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - Fts5Config *pConfig = pTab->p.pConfig; - char *zSql; - char *zErr = 0; int rc; + assert( pzErr!=0 && *pzErr==0 ); UNUSED_PARAM(isQuick); - zSql = sqlite3_mprintf( - "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", - zSchema, zTabname, pConfig->zName); - if( zSql==0 ) return SQLITE_NOMEM; - rc = sqlite3_exec(pConfig->db, zSql, 0, 0, &zErr); - sqlite3_free(zSql); + rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0); if( (rc&0xff)==SQLITE_CORRUPT ){ *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", zSchema, zTabname); }else if( rc!=SQLITE_OK ){ *pzErr = sqlite3_mprintf("unable to validate the inverted index for" " FTS5 table %s.%s: %s", - zSchema, zTabname, zErr); + zSchema, zTabname, sqlite3_errstr(rc)); } - sqlite3_free(zErr); + sqlite3Fts5IndexCloseReader(pTab->p.pIndex); + return SQLITE_OK; } diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index c2d2456dde6..4fdfde004eb 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.45.0" -#define SQLITE_VERSION_NUMBER 3045000 -#define SQLITE_SOURCE_ID "2024-01-15 17:01:13 1066602b2b1976fe58b5150777cced894af17c803e068f5918390d6915b46e1d" +#define SQLITE_VERSION "3.45.1" +#define SQLITE_VERSION_NUMBER 3045001 +#define SQLITE_SOURCE_ID "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257cc467a" /* ** CAPI3REF: Run-Time Library Version Numbers From 961b5050a4672349c3be0226b55158339cb3b195 Mon Sep 17 00:00:00 2001 From: Ahmad Samir Date: Thu, 29 Feb 2024 19:06:02 +0200 Subject: [PATCH 46/58] androiddeployqt: fix QDirIterator::next() usage The code inside the loop body uses it.next() twice, however hasNext() is called only once; each call to next() advances the iterator. Amends 4041610cb202699a47268975e5aaecaa1f182c0a. Change-Id: Idb96cfbddc56e0d7ed38ab1b0279f40592c75175 Reviewed-by: Assam Boudjelthia (cherry picked from commit 56e151663ebfd4fc0876d33f22c81f0218339914) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 6a74a3c4c6bf0af2297a32ec659fc2311f7e5126) (cherry picked from commit 2cec73ae80ad0c86b5c6628f1864e53ef33cdf4f) (cherry picked from commit 99b52e4a575dc57c3aafc94f87c45f36483b740b) (cherry picked from commit fe3b9bcd4cf45c20843ba32be6ef54d806735942) --- src/tools/androiddeployqt/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index 200e897f191..aded9f31c77 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -2332,8 +2332,9 @@ void checkAndWarnGradleLongPaths(const QString &outputDirectory) QDirIterator it(outputDirectory, QStringList(QStringLiteral("*.java")), QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { - if (it.next().size() >= MAX_PATH) - longFileNames.append(it.next()); + const QString &filePath = it.next(); + if (filePath.size() >= MAX_PATH) + longFileNames.append(filePath); } if (!longFileNames.isEmpty()) { From a0e40120f06cadf97737789a72106ce8017d3a01 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 7 Mar 2024 08:27:24 +0100 Subject: [PATCH 47/58] XCB: Unset the connection's mousePressWindow if it's this window In some rare cases it can delete the window before this is handled by other calls, so rather than crashing we clean up. Change-Id: Iddcd9890f0c13f4130626b0ed9c5b32f5890208d Reviewed-by: Axel Spoerl (cherry picked from commit b8f9a8681347476f4db1719b38a67d7f9d3c74be) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit be78514b206aff3152a239c188fcc4e7aba5439a) (cherry picked from commit a86cd4dbeeacc42f095db5ada0f0ea59f390465c) (cherry picked from commit a6ff25079d5aeb6655f4c301c52d90304d1b3745) (cherry picked from commit 3707fbdbc9f38ea91f0dfedce1ad7c4f8d27d0ad) --- src/plugins/platforms/xcb/qxcbwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index b830dd03be2..51d1b73e0b1 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -552,6 +552,8 @@ void QXcbWindow::destroy() doFocusOut(); if (connection()->mouseGrabber() == this) connection()->setMouseGrabber(nullptr); + if (connection()->mousePressWindow() == this) + connection()->setMousePressWindow(nullptr); if (m_syncCounter && connection()->hasXSync()) xcb_sync_destroy_counter(xcb_connection(), m_syncCounter); From e64c054631ed86e249ecd82082ce42ed79303805 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 5 Mar 2024 10:42:01 +0100 Subject: [PATCH 48/58] Update bundled libpng to version 1.6.43 [ChangeLog][Third-Party Code] libpng was updated to version 1.6.43 Fixes: QTBUG-122989 Change-Id: Id439e64010bc3f6752f5589d663827a91f009173 Reviewed-by: Qt CI Bot Reviewed-by: Eskil Abrahamsen Blomfeldt (cherry picked from commit 210f2004dffae149c857d8d79d51eb996643ad4a) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit e1f069e65de96906438f5bec75708bec93d2bee5) (cherry picked from commit 566fe27f4aa2e8b7116b6be21ca3f8c1961d2baa) (cherry picked from commit 394b6d96b589ca2fb523f58986c71eb030096586) Reviewed-by: Eirik Aavitsland (cherry picked from commit d15a975ed751b8a5484a25a9036c90f97b053e1d) --- src/3rdparty/libpng/ANNOUNCE | 75 +++++++++++-------------- src/3rdparty/libpng/CHANGES | 32 ++++++++++- src/3rdparty/libpng/README | 12 ++-- src/3rdparty/libpng/libpng-manual.txt | 6 +- src/3rdparty/libpng/png.c | 41 +++++++------- src/3rdparty/libpng/png.h | 25 ++++----- src/3rdparty/libpng/pngconf.h | 2 +- src/3rdparty/libpng/pnglibconf.h | 2 +- src/3rdparty/libpng/pngpread.c | 8 +++ src/3rdparty/libpng/pngread.c | 6 +- src/3rdparty/libpng/pngrtran.c | 28 ++++----- src/3rdparty/libpng/qt_attribution.json | 4 +- 12 files changed, 133 insertions(+), 108 deletions(-) diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE index 44d6722d058..bc147adb78b 100644 --- a/src/3rdparty/libpng/ANNOUNCE +++ b/src/3rdparty/libpng/ANNOUNCE @@ -1,5 +1,5 @@ -libpng 1.6.42 - January 29, 2024 -================================ +libpng 1.6.43 - February 23, 2024 +================================= This is a public release of libpng, intended for use in production code. @@ -9,13 +9,13 @@ Files available for download Source files with LF line endings (for Unix/Linux): - * libpng-1.6.42.tar.xz (LZMA-compressed, recommended) - * libpng-1.6.42.tar.gz (deflate-compressed) + * libpng-1.6.43.tar.xz (LZMA-compressed, recommended) + * libpng-1.6.43.tar.gz (deflate-compressed) Source files with CRLF line endings (for Windows): - * lpng1642.7z (LZMA-compressed, recommended) - * lpng1642.zip (deflate-compressed) + * lpng1643.7z (LZMA-compressed, recommended) + * lpng1643.zip (deflate-compressed) Other information: @@ -25,47 +25,36 @@ Other information: * TRADEMARK.md -Changes from version 1.6.41 to version 1.6.42 +Changes from version 1.6.42 to version 1.6.43 --------------------------------------------- - * Fixed the implementation of the macro function `png_check_sig`. - This was an API regression, introduced in libpng-1.6.41. - (Reported by Matthieu Darbois) - - -Changes from version 1.6.40 to version 1.6.41 ---------------------------------------------- - - * Added SIMD-optimized code for the Loongarch LSX hardware. - (Contributed by GuXiWei, JinBo and ZhangLixia) - * Fixed the run-time discovery of MIPS MSA hardware. - (Contributed by Sui Jingfeng) - * Fixed an off-by-one error in the function `png_do_check_palette_indexes`, - which failed to recognize errors that might have existed in the first - column of a broken palette-encoded image. This was a benign regression - accidentally introduced in libpng-1.6.33. No pixel was harmed. - (Contributed by Adam Richter; reviewed by John Bowler) - * Fixed, improved and modernized the contrib/pngminus programs, i.e., - png2pnm.c and pnm2png.c - * Removed old and peculiar portability hacks that were meant to silence - warnings issued by gcc version 7.1 alone. + * Fixed the row width check in png_check_IHDR(). + This corrected a bug that was specific to the 16-bit platforms, + and removed a spurious compiler warning from the 64-bit builds. + (Reported by Jacek Caban; fixed by John Bowler) + * Added eXIf chunk support to the push-mode reader in pngpread.c. + (Contributed by Chris Blume) + * Added contrib/pngexif for the benefit of the users who would like + to inspect the content of eXIf chunks. + * Added contrib/conftest/basic.dfa, a basic build-time configuration. (Contributed by John Bowler) - * Fixed and modernized the CMake file, and raised the minimum required - CMake version from 3.1 to 3.6. - (Contributed by Clinton Ingram, Timothy Lyanguzov, Tyler Kropp, et al.) - * Allowed the configure script to disable the building of auxiliary tools - and tests, thus catching up with the CMake file. - (Contributed by Carlo Bramini) - * Fixed a build issue on Mac. - (Contributed by Zixu Wang) - * Moved the Autoconf macro files to scripts/autoconf. - * Moved the CMake files (except for the main CMakeLists.txt) to - scripts/cmake and moved the list of their contributing authors to - scripts/cmake/AUTHORS.md - * Updated the CI configurations and scripts. - * Relicensed the CI scripts to the MIT License. - * Improved the test coverage. + * Fixed a preprocessor condition in pngread.c that broke build-time + configurations like contrib/conftest/pngcp.dfa. (Contributed by John Bowler) + * Added CMake build support for LoongArch LSX. + (Contributed by GuXiWei) + * Fixed a CMake build error that occurred under a peculiar state of the + dependency tree. This was a regression introduced in libpng-1.6.41. + (Contributed by Dan Rosser) + * Marked the installed libpng headers as system headers in CMake. + (Contributed by Benjamin Buch) + * Updated the build support for RISCOS. + (Contributed by Cameron Cawley) + * Updated the makefiles to allow cross-platform builds to initialize + conventional make variables like AR and ARFLAGS. + * Added various improvements to the CI scripts in areas like version + consistency verification and text linting. + * Added version consistency verification to pngtest.c also. Send comments/corrections/commendations to png-mng-implement at lists.sf.net. diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES index 137761a815b..441b57ecf1a 100644 --- a/src/3rdparty/libpng/CHANGES +++ b/src/3rdparty/libpng/CHANGES @@ -6130,7 +6130,7 @@ Version 1.6.40 [June 21, 2023] Cleaned up the code, the build scripts, and the documentation. Version 1.6.41 [January 24, 2024] - Added SIMD-optimized code for the Loongarch LSX hardware. + Added SIMD-optimized code for the LoongArch LSX hardware. (Contributed by GuXiWei, JinBo and ZhangLixia) Fixed the run-time discovery of MIPS MSA hardware. (Contributed by Sui Jingfeng) @@ -6165,6 +6165,36 @@ Version 1.6.42 [January 29, 2024] Fixed the implementation of the macro function png_check_sig(). This was an API regression, introduced in libpng-1.6.41. (Reported by Matthieu Darbois) + Fixed and updated the libpng manual. + +Version 1.6.43 [February 23, 2024] + Fixed the row width check in png_check_IHDR(). + This corrected a bug that was specific to the 16-bit platforms, + and removed a spurious compiler warning from the 64-bit builds. + (Reported by Jacek Caban; fixed by John Bowler) + Added eXIf chunk support to the push-mode reader in pngpread.c. + (Contributed by Chris Blume) + Added contrib/pngexif for the benefit of the users who would like + to inspect the content of eXIf chunks. + Added contrib/conftest/basic.dfa, a basic build-time configuration. + (Contributed by John Bowler) + Fixed a preprocessor condition in pngread.c that broke build-time + configurations like contrib/conftest/pngcp.dfa. + (Contributed by John Bowler) + Added CMake build support for LoongArch LSX. + (Contributed by GuXiWei) + Fixed a CMake build error that occurred under a peculiar state of the + dependency tree. This was a regression introduced in libpng-1.6.41. + (Contributed by Dan Rosser) + Marked the installed libpng headers as system headers in CMake. + (Contributed by Benjamin Buch) + Updated the build support for RISCOS. + (Contributed by Cameron Cawley) + Updated the makefiles to allow cross-platform builds to initialize + conventional make variables like AR and ARFLAGS. + Added various improvements to the CI scripts in areas like version + consistency verification and text linting. + Added version consistency verification to pngtest.c also. Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Subscription is required; visit diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README index 0bf27bcfe6c..a6ca3ae9f94 100644 --- a/src/3rdparty/libpng/README +++ b/src/3rdparty/libpng/README @@ -1,4 +1,4 @@ -README for libpng version 1.6.42 +README for libpng version 1.6.43 ================================ See the note about version numbers near the top of `png.h`. @@ -142,10 +142,11 @@ Files included in this distribution pngwrite.c => High-level write functions pngwtran.c => Write data transformations pngwutil.c => Write utility functions - arm/ => Optimized code for the ARM platform - intel/ => Optimized code for the INTEL-SSE2 platform - mips/ => Optimized code for the MIPS platform - powerpc/ => Optimized code for the PowerPC platform + arm/ => Optimized code for ARM Neon + intel/ => Optimized code for INTEL SSE2 + loongarch/ => Optimized code for LoongArch LSX + mips/ => Optimized code for MIPS MSA and MIPS MMI + powerpc/ => Optimized code for PowerPC VSX ci/ => Scripts for continuous integration contrib/ => External contributions arm-neon/ => Optimized code for the ARM-NEON platform @@ -158,6 +159,7 @@ Files included in this distribution libtests/ => Test programs oss-fuzz/ => Files used by the OSS-Fuzz project for fuzz-testing libpng + pngexif/ => Program to inspect the EXIF information in PNG files pngminim/ => Minimal decoder, encoder, and progressive decoder programs demonstrating the use of pngusr.dfa pngminus/ => Simple pnm2png and png2pnm programs diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt index eb24ef48312..79880575994 100644 --- a/src/3rdparty/libpng/libpng-manual.txt +++ b/src/3rdparty/libpng/libpng-manual.txt @@ -9,7 +9,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng version 1.6.36, December 2018, through 1.6.42 - January 2024 + libpng version 1.6.36, December 2018, through 1.6.43 - February 2024 Updated and distributed by Cosmin Truta Copyright (c) 2018-2024 Cosmin Truta @@ -1178,11 +1178,11 @@ where row_pointers is an array of pointers to the pixel data for each row: If you know your image size and pixel size ahead of time, you can allocate row_pointers prior to calling png_read_png() with - if (height > PNG_UINT_32_MAX/(sizeof (png_byte))) + if (height > PNG_UINT_32_MAX / (sizeof (png_bytep))) png_error(png_ptr, "Image is too tall to process in memory"); - if (width > PNG_UINT_32_MAX/pixel_size) + if (width > PNG_UINT_32_MAX / pixel_size) png_error(png_ptr, "Image is too wide to process in memory"); diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c index cf9f361070f..9ed31570092 100644 --- a/src/3rdparty/libpng/png.c +++ b/src/3rdparty/libpng/png.c @@ -14,7 +14,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_42 Your_png_h_is_not_version_1_6_42; +typedef png_libpng_version_1_6_43 Your_png_h_is_not_version_1_6_43; /* Tells libpng that we have already handled the first "num_bytes" bytes * of the PNG file signature. If the PNG data is embedded into another @@ -794,7 +794,7 @@ png_get_copyright(png_const_structrp png_ptr) return PNG_STRING_COPYRIGHT #else return PNG_STRING_NEWLINE \ - "libpng version 1.6.42" PNG_STRING_NEWLINE \ + "libpng version 1.6.43" PNG_STRING_NEWLINE \ "Copyright (c) 2018-2024 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ @@ -1821,14 +1821,14 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, } # ifdef PNG_WARNINGS_SUPPORTED else - { - char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */ + { + char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */ - pos = png_safecat(message, (sizeof message), pos, - png_format_number(number, number+(sizeof number), - PNG_NUMBER_FORMAT_x, value)); - pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */ - } + pos = png_safecat(message, (sizeof message), pos, + png_format_number(number, number+(sizeof number), + PNG_NUMBER_FORMAT_x, value)); + pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */ + } # endif /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ pos = png_safecat(message, (sizeof message), pos, reason); @@ -2511,17 +2511,6 @@ png_colorspace_set_rgb_coefficients(png_structrp png_ptr) #endif /* COLORSPACE */ -#ifdef __GNUC__ -/* This exists solely to work round a warning from GNU C. */ -static int /* PRIVATE */ -png_gt(size_t a, size_t b) -{ - return a > b; -} -#else -# define png_gt(a,b) ((a) > (b)) -#endif - void /* PRIVATE */ png_check_IHDR(png_const_structrp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, @@ -2543,8 +2532,16 @@ png_check_IHDR(png_const_structrp png_ptr, error = 1; } - if (png_gt(((width + 7) & (~7U)), - ((PNG_SIZE_MAX + /* The bit mask on the first line below must be at least as big as a + * png_uint_32. "~7U" is not adequate on 16-bit systems because it will + * be an unsigned 16-bit value. Casting to (png_alloc_size_t) makes the + * type of the result at least as bit (in bits) as the RHS of the > operator + * which also avoids a common warning on 64-bit systems that the comparison + * of (png_uint_32) against the constant value on the RHS will always be + * false. + */ + if (((width + 7) & ~(png_alloc_size_t)7) > + (((PNG_SIZE_MAX - 48 /* big_row_buf hack */ - 1) /* filter byte */ / 8) /* 8-byte RGBA pixels */ diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h index f537c5bb089..83d39031260 100644 --- a/src/3rdparty/libpng/png.h +++ b/src/3rdparty/libpng/png.h @@ -1,7 +1,7 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.42 + * libpng version 1.6.43 * * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson @@ -15,7 +15,7 @@ * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.97, January 1998, through 1.6.35, July 2018: * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.42, January 2024: + * libpng versions 1.6.36, December 2018, through 1.6.43, February 2024: * Cosmin Truta * See also "Contributing Authors", below. */ @@ -239,7 +239,7 @@ * ... * 1.5.30 15 10530 15.so.15.30[.0] * ... - * 1.6.42 16 10641 16.so.16.41[.0] + * 1.6.43 16 10643 16.so.16.43[.0] * * Henceforth the source version will match the shared-library major and * minor numbers; the shared-library major version number will be used for @@ -255,9 +255,6 @@ * to the info_ptr or png_ptr members through png.h, and the compiled * application is loaded with a different version of the library. * - * DLLNUM will change each time there are forward or backward changes - * in binary compatibility (e.g., when a new feature is added). - * * See libpng.txt or libpng.3 for more information. The PNG specification * is available as a W3C Recommendation and as an ISO/IEC Standard; see * @@ -278,19 +275,21 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.42" +#define PNG_LIBPNG_VER_STRING "1.6.43" #define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n" -#define PNG_LIBPNG_VER_SONUM 16 -#define PNG_LIBPNG_VER_DLLNUM 16 +/* The versions of shared library builds should stay in sync, going forward */ +#define PNG_LIBPNG_VER_SHAREDLIB 16 +#define PNG_LIBPNG_VER_SONUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ +#define PNG_LIBPNG_VER_DLLNUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 41 +#define PNG_LIBPNG_VER_RELEASE 43 /* This should be zero for a public release, or non-zero for a - * development version. [Deprecated] + * development version. */ #define PNG_LIBPNG_VER_BUILD 0 @@ -318,7 +317,7 @@ * From version 1.0.1 it is: * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10641 /* 1.6.42 */ +#define PNG_LIBPNG_VER 10643 /* 1.6.43 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -428,7 +427,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_42; +typedef char* png_libpng_version_1_6_43; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index 99851f4f9c8..000d7b1a8a6 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -1,7 +1,7 @@ /* pngconf.h - machine-configurable file for libpng * - * libpng version 1.6.42 + * libpng version 1.6.43 * * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h index 330453c1391..83f09fbe773 100644 --- a/src/3rdparty/libpng/pnglibconf.h +++ b/src/3rdparty/libpng/pnglibconf.h @@ -1,6 +1,6 @@ /* pnglibconf.h - library build configuration */ -/* libpng version 1.6.42 */ +/* libpng version 1.6.43 */ /* Copyright (c) 2018-2024 Cosmin Truta */ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ diff --git a/src/3rdparty/libpng/pngpread.c b/src/3rdparty/libpng/pngpread.c index be640f77a9b..ffab19c08c0 100644 --- a/src/3rdparty/libpng/pngpread.c +++ b/src/3rdparty/libpng/pngpread.c @@ -294,6 +294,14 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); } +#endif +#ifdef PNG_READ_eXIf_SUPPORTED + else if (png_ptr->chunk_name == png_eXIf) + { + PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_eXIf(png_ptr, info_ptr, png_ptr->push_length); + } + #endif #ifdef PNG_READ_sRGB_SUPPORTED else if (chunk_name == png_sRGB) diff --git a/src/3rdparty/libpng/pngread.c b/src/3rdparty/libpng/pngread.c index 008a41856b6..07a39df6e2e 100644 --- a/src/3rdparty/libpng/pngread.c +++ b/src/3rdparty/libpng/pngread.c @@ -568,7 +568,11 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) #endif #ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->transformations || png_ptr->num_palette_max >= 0) + if (png_ptr->transformations +# ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + || png_ptr->num_palette_max >= 0 +# endif + ) png_do_read_transformations(png_ptr, &row_info); #endif diff --git a/src/3rdparty/libpng/pngrtran.c b/src/3rdparty/libpng/pngrtran.c index 16474741aac..1526123e025 100644 --- a/src/3rdparty/libpng/pngrtran.c +++ b/src/3rdparty/libpng/pngrtran.c @@ -297,14 +297,13 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); - /* Validate the value to ensure it is in a reasonable range. The value + /* Validate the value to ensure it is in a reasonable range. The value * is expected to be 1 or greater, but this range test allows for some - * viewing correction values. The intent is to weed out users of this API - * who use the inverse of the gamma value accidentally! Since some of these - * values are reasonable this may have to be changed: + * viewing correction values. The intent is to weed out the API users + * who might use the inverse of the gamma value accidentally! * - * 1.6.x: changed from 0.07..3 to 0.01..100 (to accommodate the optimal 16-bit - * gamma of 36, and its reciprocal.) + * In libpng 1.6.0, we changed from 0.07..3 to 0.01..100, to accommodate + * the optimal 16-bit gamma of 36 and its reciprocal. */ if (output_gamma < 1000 || output_gamma > 10000000) png_error(png_ptr, "output gamma out of expected range"); @@ -441,7 +440,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, int i; png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); for (i = 0; i < num_palette; i++) png_ptr->quantize_index[i] = (png_byte)i; } @@ -458,7 +457,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, /* Initialize an array to sort colors */ png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); /* Initialize the quantize_sort array */ for (i = 0; i < num_palette; i++) @@ -592,11 +591,9 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, /* Initialize palette index arrays */ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * - (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * - (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); /* Initialize the sort array */ for (i = 0; i < num_palette; i++) @@ -761,12 +758,11 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, size_t num_entries = ((size_t)1 << total_bits); png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, - (png_alloc_size_t)(num_entries * (sizeof (png_byte)))); + (png_alloc_size_t)(num_entries)); - distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries * - (sizeof (png_byte)))); + distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)num_entries); - memset(distance, 0xff, num_entries * (sizeof (png_byte))); + memset(distance, 0xff, num_entries); for (i = 0; i < num_palette; i++) { diff --git a/src/3rdparty/libpng/qt_attribution.json b/src/3rdparty/libpng/qt_attribution.json index c85a5caf438..7ba436e3bd1 100644 --- a/src/3rdparty/libpng/qt_attribution.json +++ b/src/3rdparty/libpng/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "libpng is the official PNG reference library.", "Homepage": "http://www.libpng.org/pub/png/libpng.html", - "Version": "1.6.42", - "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.42.tar.xz", + "Version": "1.6.43", + "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.43.tar.xz", "License": "libpng License and PNG Reference Library version 2", "LicenseId": "Libpng AND libpng-2.0", "LicenseFile": "LICENSE", From b3573f5ad82c194bc8581bc9aed5d41b8c451f1b Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Tue, 12 Mar 2024 20:38:22 +0100 Subject: [PATCH 49/58] SQLite: Update SQLite to v3.45.2 [ChangeLog][Third-Party Code] Updated SQLite to v3.45.2 Change-Id: I3b841bc009f2e0ed6dcfa1b93cbb8bce0cd9ad47 Reviewed-by: Volker Hilsheimer (cherry picked from commit 91f8d1de37aa3a74af83ed997c1686f10e2fed72) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 9478e25284ccd04208c384d026ee3740ddcd82fd) (cherry picked from commit 2fa41e1ea3e0afd2d251162d117d371c3ae46024) (cherry picked from commit 225c6d53d6103c211fa36d7c224f9af2cbb483c5) (cherry picked from commit dd9698343ee2f6b7ff9db44e240a31fca3b89866) --- src/3rdparty/sqlite/qt_attribution.json | 4 +- src/3rdparty/sqlite/sqlite3.c | 295 +++++++++++++++++------- src/3rdparty/sqlite/sqlite3.h | 8 +- 3 files changed, 220 insertions(+), 87 deletions(-) diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json index 640a926fca0..8ba77342047 100644 --- a/src/3rdparty/sqlite/qt_attribution.json +++ b/src/3rdparty/sqlite/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Homepage": "https://www.sqlite.org/", - "Version": "3.45.1", - "DownloadLocation": "https://www.sqlite.org/2024/sqlite-amalgamation-3450100.zip", + "Version": "3.45.2", + "DownloadLocation": "https://www.sqlite.org/2024/sqlite-amalgamation-3450200.zip", "License": "Public Domain", "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." } diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 139ee46a6a9..55ca309401b 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.45.1. By combining all the individual C code files into this +** version 3.45.2. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** e876e51a0ed5c5b3126f52e532044363a014. +** d8cd6d49b46a395b13955387d05e9e1a2a47. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -459,9 +459,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.45.1" -#define SQLITE_VERSION_NUMBER 3045001 -#define SQLITE_SOURCE_ID "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257cc467a" +#define SQLITE_VERSION "3.45.2" +#define SQLITE_VERSION_NUMBER 3045002 +#define SQLITE_SOURCE_ID "2024-03-12 11:06:23 d8cd6d49b46a395b13955387d05e9e1a2a47e54fb99f3c9b59835bbefad6af77" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -733,6 +733,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. **
  • The application must not modify the SQL statement text passed into ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. +**
  • The application must not dereference the arrays or string pointers +** passed as the 3rd and 4th callback parameters after it returns. ** */ SQLITE_API int sqlite3_exec( @@ -15097,6 +15099,7 @@ SQLITE_PRIVATE u32 sqlite3TreeTrace; ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing ** 0x00020000 Transform DISTINCT into GROUP BY ** 0x00040000 SELECT tree dump after all code has been generated +** 0x00080000 NOT NULL strength reduction */ /* @@ -19346,6 +19349,7 @@ struct NameContext { #define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */ #define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */ #define NC_NoSelect 0x080000 /* Do not descend into sub-selects */ +#define NC_Where 0x100000 /* Processing WHERE clause of a SELECT */ #define NC_OrderAgg 0x8000000 /* Has an aggregate other than count/min/max */ /* @@ -19369,6 +19373,7 @@ struct Upsert { Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */ u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */ + u8 isDup; /* True if 2nd or later with same pUpsertIdx */ /* Above this point is the parse tree for the ON CONFLICT clauses. ** The next group of fields stores intermediate data. */ void *pToFree; /* Free memory when deleting the Upsert object */ @@ -21444,7 +21449,7 @@ SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*); SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*); SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); -SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); +SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*,Upsert*); SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert*,Index*); SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert*); @@ -31309,6 +31314,7 @@ SQLITE_API void sqlite3_str_vappendf( if( xtype==etFLOAT ){ iRound = -precision; }else if( xtype==etGENERIC ){ + if( precision==0 ) precision = 1; iRound = precision; }else{ iRound = precision+1; @@ -35199,6 +35205,9 @@ do_atof_calc: u64 s2; rr[0] = (double)s; s2 = (u64)rr[0]; +#if defined(_MSC_VER) && _MSC_VER<1700 + if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } +#endif rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); if( e>0 ){ while( e>=100 ){ @@ -35641,7 +35650,7 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou assert( p->n>0 ); assert( p->nzBuf) ); p->iDP = p->n + exp; - if( iRound<0 ){ + if( iRound<=0 ){ iRound = p->iDP - iRound; if( iRound==0 && p->zBuf[i+1]>='5' ){ iRound = 1; @@ -53262,6 +53271,14 @@ SQLITE_API unsigned char *sqlite3_serialize( pOut = 0; }else{ sz = sqlite3_column_int64(pStmt, 0)*szPage; + if( sz==0 ){ + sqlite3_reset(pStmt); + sqlite3_exec(db, "BEGIN IMMEDIATE; COMMIT;", 0, 0, 0); + rc = sqlite3_step(pStmt); + if( rc==SQLITE_ROW ){ + sz = sqlite3_column_int64(pStmt, 0)*szPage; + } + } if( piSize ) *piSize = sz; if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ pOut = 0; @@ -77088,7 +77105,10 @@ static int fillInCell( n = nHeader + nPayload; testcase( n==3 ); testcase( n==4 ); - if( n<4 ) n = 4; + if( n<4 ){ + n = 4; + pPayload[nPayload] = 0; + } *pnSize = n; assert( nSrc<=nPayload ); testcase( nSrcpBt->nPreformatSize; - if( szNew<4 ) szNew = 4; + if( szNew<4 ){ + szNew = 4; + newCell[3] = 0; + } if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){ CellInfo info; pPage->xParseCell(pPage, newCell, &info); @@ -88379,6 +88402,23 @@ static void serialGet( pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real; } } +static int serialGet7( + const unsigned char *buf, /* Buffer to deserialize from */ + Mem *pMem /* Memory cell to write value into */ +){ + u64 x = FOUR_BYTE_UINT(buf); + u32 y = FOUR_BYTE_UINT(buf+4); + x = (x<<32) + y; + assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); + swapMixedEndianFloat(x); + memcpy(&pMem->u.r, &x, sizeof(x)); + if( IsNaN(x) ){ + pMem->flags = MEM_Null; + return 1; + } + pMem->flags = MEM_Real; + return 0; +} SQLITE_PRIVATE void sqlite3VdbeSerialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ @@ -89058,7 +89098,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( }else if( serial_type==0 ){ rc = -1; }else if( serial_type==7 ){ - sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); + serialGet7(&aKey1[d1], &mem1); rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); }else{ i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]); @@ -89083,14 +89123,18 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( }else if( serial_type==0 ){ rc = -1; }else{ - sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); if( serial_type==7 ){ - if( mem1.u.ru.r ){ + if( serialGet7(&aKey1[d1], &mem1) ){ + rc = -1; /* mem1 is a NaN */ + }else if( mem1.u.ru.r ){ rc = -1; }else if( mem1.u.r>pRhs->u.r ){ rc = +1; + }else{ + assert( rc==0 ); } }else{ + sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r); } } @@ -89160,7 +89204,14 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( /* RHS is null */ else{ serial_type = aKey1[idx1]; - rc = (serial_type!=0 && serial_type!=10); + if( serial_type==0 + || serial_type==10 + || (serial_type==7 && serialGet7(&aKey1[d1], &mem1)!=0) + ){ + assert( rc==0 ); + }else{ + rc = 1; + } } if( rc!=0 ){ @@ -94858,7 +94909,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ } } }else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){ - if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ + if( (flags1 & MEM_Str)!=0 ){ + pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); + }else if( (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn1->flags & MEM_Int ); testcase( pIn1->flags & MEM_Real ); testcase( pIn1->flags & MEM_IntReal ); @@ -94867,7 +94920,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str; } - if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ + if( (flags3 & MEM_Str)!=0 ){ + pIn3->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); + }else if( (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn3->flags & MEM_Int ); testcase( pIn3->flags & MEM_Real ); testcase( pIn3->flags & MEM_IntReal ); @@ -106212,6 +106267,8 @@ static void resolveAlias( assert( iCol>=0 && iColnExpr ); pOrig = pEList->a[iCol].pExpr; assert( pOrig!=0 ); + assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ); + if( pExpr->pAggInfo ) return; db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( db->mallocFailed ){ @@ -107097,6 +107154,19 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ** resolved. This prevents "column" from being counted as having been ** referenced, which might prevent a SELECT from being erroneously ** marked as correlated. + ** + ** 2024-03-28: Beware of aggregates. A bare column of aggregated table + ** can still evaluate to NULL even though it is marked as NOT NULL. + ** Example: + ** + ** CREATE TABLE t1(a INT NOT NULL); + ** SELECT a, a IS NULL, a IS NOT NULL, count(*) FROM t1; + ** + ** The "a IS NULL" and "a IS NOT NULL" expressions cannot be optimized + ** here because at the time this case is hit, we do not yet know whether + ** or not t1 is being aggregated. We have to assume the worst and omit + ** the optimization. The only time it is safe to apply this optimization + ** is within the WHERE clause. */ case TK_NOTNULL: case TK_ISNULL: { @@ -107107,19 +107177,36 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ anRef[i] = p->nRef; } sqlite3WalkExpr(pWalker, pExpr->pLeft); - if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ - testcase( ExprHasProperty(pExpr, EP_OuterON) ); - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - pExpr->u.iValue = (pExpr->op==TK_NOTNULL); - pExpr->flags |= EP_IntValue; - pExpr->op = TK_INTEGER; - - for(i=0, p=pNC; p && ipNext, i++){ - p->nRef = anRef[i]; - } - sqlite3ExprDelete(pParse->db, pExpr->pLeft); - pExpr->pLeft = 0; + if( IN_RENAME_OBJECT ) return WRC_Prune; + if( sqlite3ExprCanBeNull(pExpr->pLeft) ){ + /* The expression can be NULL. So the optimization does not apply */ + return WRC_Prune; } + + for(i=0, p=pNC; p; p=p->pNext, i++){ + if( (p->ncFlags & NC_Where)==0 ){ + return WRC_Prune; /* Not in a WHERE clause. Unsafe to optimize. */ + } + } + testcase( ExprHasProperty(pExpr, EP_OuterON) ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x80000 ){ + sqlite3DebugPrintf( + "NOT NULL strength reduction converts the following to %d:\n", + pExpr->op==TK_NOTNULL + ); + sqlite3ShowExpr(pExpr); + } +#endif /* TREETRACE_ENABLED */ + pExpr->u.iValue = (pExpr->op==TK_NOTNULL); + pExpr->flags |= EP_IntValue; + pExpr->op = TK_INTEGER; + for(i=0, p=pNC; p && ipNext, i++){ + p->nRef = anRef[i]; + } + sqlite3ExprDelete(pParse->db, pExpr->pLeft); + pExpr->pLeft = 0; return WRC_Prune; } @@ -108019,7 +108106,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; } + sNC.ncFlags |= NC_Where; if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; + sNC.ncFlags &= ~NC_Where; /* Resolve names in table-valued-function arguments */ for(i=0; ipSrc->nSrc; i++){ @@ -128947,13 +129036,13 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ double r1, r2; const char *zVal; r1 = sqlite3_value_double(pValue); - sqlite3_str_appendf(pStr, "%!.15g", r1); + sqlite3_str_appendf(pStr, "%!0.15g", r1); zVal = sqlite3_str_value(pStr); if( zVal ){ sqlite3AtoF(zVal, &r2, pStr->nChar, SQLITE_UTF8); if( r1!=r2 ){ sqlite3_str_reset(pStr); - sqlite3_str_appendf(pStr, "%!.20e", r1); + sqlite3_str_appendf(pStr, "%!0.20e", r1); } } break; @@ -129255,7 +129344,7 @@ static void replaceFunc( } if( zPattern[0]==0 ){ assert( sqlite3_value_type(argv[1])!=SQLITE_NULL ); - sqlite3_result_value(context, argv[0]); + sqlite3_result_text(context, (const char*)zStr, nStr, SQLITE_TRANSIENT); return; } nPattern = sqlite3_value_bytes(argv[1]); @@ -133175,7 +133264,7 @@ SQLITE_PRIVATE void sqlite3Insert( pNx->iDataCur = iDataCur; pNx->iIdxCur = iIdxCur; if( pNx->pUpsertTarget ){ - if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx) ){ + if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx, pUpsert) ){ goto insert_cleanup; } } @@ -139474,31 +139563,7 @@ SQLITE_PRIVATE void sqlite3Pragma( int mxCol; /* Maximum non-virtual column number */ if( pObjTab && pObjTab!=pTab ) continue; - if( !IsOrdinaryTable(pTab) ){ -#ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3_vtab *pVTab; - int a1; - if( !IsVirtual(pTab) ) continue; - if( pTab->nCol<=0 ){ - const char *zMod = pTab->u.vtab.azArg[0]; - if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; - } - sqlite3ViewGetColumnNames(pParse, pTab); - if( pTab->u.vtab.p==0 ) continue; - pVTab = pTab->u.vtab.p->pVtab; - if( NEVER(pVTab==0) ) continue; - if( NEVER(pVTab->pModule==0) ) continue; - if( pVTab->pModule->iVersion<4 ) continue; - if( pVTab->pModule->xIntegrity==0 ) continue; - sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); - pTab->nTabRef++; - sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF); - a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); - integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, a1); -#endif - continue; - } + if( !IsOrdinaryTable(pTab) ) continue; if( isQuick || HasRowid(pTab) ){ pPk = 0; r2 = 0; @@ -139633,6 +139698,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** is REAL, we have to load the actual data using OP_Column ** to reliably determine if the value is a NULL. */ sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3); + sqlite3ColumnDefault(v, pTab, j, 3); jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk); VdbeCoverage(v); } @@ -139823,6 +139889,38 @@ SQLITE_PRIVATE void sqlite3Pragma( } } } + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Second pass to invoke the xIntegrity method on all virtual + ** tables. + */ + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + sqlite3_vtab *pVTab; + int a1; + if( pObjTab && pObjTab!=pTab ) continue; + if( IsOrdinaryTable(pTab) ) continue; + if( !IsVirtual(pTab) ) continue; + if( pTab->nCol<=0 ){ + const char *zMod = pTab->u.vtab.azArg[0]; + if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; + } + sqlite3ViewGetColumnNames(pParse, pTab); + if( pTab->u.vtab.p==0 ) continue; + pVTab = pTab->u.vtab.p->pVtab; + if( NEVER(pVTab==0) ) continue; + if( NEVER(pVTab->pModule==0) ) continue; + if( pVTab->pModule->iVersion<4 ) continue; + if( pVTab->pModule->xIntegrity==0 ) continue; + sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); + pTab->nTabRef++; + sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF); + a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, a1); + continue; + } +#endif } { static const int iLn = VDBE_OFFSET_LINENO(2); @@ -153460,7 +153558,8 @@ SQLITE_PRIVATE Upsert *sqlite3UpsertNew( SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( Parse *pParse, /* The parsing context */ SrcList *pTabList, /* Table into which we are inserting */ - Upsert *pUpsert /* The ON CONFLICT clauses */ + Upsert *pUpsert, /* The ON CONFLICT clauses */ + Upsert *pAll /* Complete list of all ON CONFLICT clauses */ ){ Table *pTab; /* That table into which we are inserting */ int rc; /* Result code */ @@ -153563,6 +153662,14 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( continue; } pUpsert->pUpsertIdx = pIdx; + if( sqlite3UpsertOfIndex(pAll,pIdx)!=pUpsert ){ + /* Really this should be an error. The isDup ON CONFLICT clause will + ** never fire. But this problem was not discovered until three years + ** after multi-CONFLICT upsert was added, and so we silently ignore + ** the problem to prevent breaking applications that might actually + ** have redundant ON CONFLICT clauses. */ + pUpsert->isDup = 1; + } break; } if( pUpsert->pUpsertIdx==0 ){ @@ -153589,9 +153696,13 @@ SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert *pUpsert){ Upsert *pNext; if( NEVER(pUpsert==0) ) return 0; pNext = pUpsert->pNextUpsert; - if( pNext==0 ) return 1; - if( pNext->pUpsertTarget==0 ) return 1; - if( pNext->pUpsertIdx==0 ) return 1; + while( 1 /*exit-by-return*/ ){ + if( pNext==0 ) return 1; + if( pNext->pUpsertTarget==0 ) return 1; + if( pNext->pUpsertIdx==0 ) return 1; + if( !pNext->isDup ) return 0; + pNext = pNext->pNextUpsert; + } return 0; } @@ -204785,6 +204896,7 @@ json_parse_restart: case '[': { /* Parse array */ iThis = pParse->nBlob; + assert( i<=(u32)pParse->nJson ); jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0); iStart = pParse->nBlob; if( pParse->oom ) return -1; @@ -205183,6 +205295,10 @@ static void jsonReturnStringAsBlob(JsonString *pStr){ JsonParse px; memset(&px, 0, sizeof(px)); jsonStringTerminate(pStr); + if( pStr->eErr ){ + sqlite3_result_error_nomem(pStr->pCtx); + return; + } px.zJson = pStr->zBuf; px.nJson = pStr->nUsed; px.db = sqlite3_context_db_handle(pStr->pCtx); @@ -206508,8 +206624,9 @@ rebuild_from_cache: } p->zJson = (char*)sqlite3_value_text(pArg); p->nJson = sqlite3_value_bytes(pArg); + if( db->mallocFailed ) goto json_pfa_oom; if( p->nJson==0 ) goto json_pfa_malformed; - if( NEVER(p->zJson==0) ) goto json_pfa_oom; + assert( p->zJson!=0 ); if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){ if( flgs & JSON_KEEPERROR ){ p->nErr = 1; @@ -206675,10 +206792,10 @@ static void jsonDebugPrintBlob( if( sz==0 && x<=JSONB_FALSE ){ sqlite3_str_append(pOut, "\n", 1); }else{ - u32 i; + u32 j; sqlite3_str_appendall(pOut, ": \""); - for(i=iStart+n; iaBlob[i]; + for(j=iStart+n; jaBlob[j]; if( c<0x20 || c>=0x7f ) c = '.'; sqlite3_str_append(pOut, (char*)&c, 1); } @@ -208086,6 +208203,9 @@ static int jsonEachColumn( case JEACH_VALUE: { u32 i = jsonSkipLabel(p); jsonReturnFromBlob(&p->sParse, i, ctx, 1); + if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){ + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } break; } case JEACH_TYPE: { @@ -208132,9 +208252,9 @@ static int jsonEachColumn( case JEACH_JSON: { if( p->sParse.zJson==0 ){ sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob, - SQLITE_STATIC); + SQLITE_TRANSIENT); }else{ - sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); + sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_TRANSIENT); } break; } @@ -209160,11 +209280,9 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ ** Clear the Rtree.pNodeBlob object */ static void nodeBlobReset(Rtree *pRtree){ - if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){ - sqlite3_blob *pBlob = pRtree->pNodeBlob; - pRtree->pNodeBlob = 0; - sqlite3_blob_close(pBlob); - } + sqlite3_blob *pBlob = pRtree->pNodeBlob; + pRtree->pNodeBlob = 0; + sqlite3_blob_close(pBlob); } /* @@ -209208,7 +209326,6 @@ static int nodeAcquire( &pRtree->pNodeBlob); } if( rc ){ - nodeBlobReset(pRtree); *ppNode = 0; /* If unable to open an sqlite3_blob on the desired row, that can only ** be because the shadow tables hold erroneous data. */ @@ -209268,6 +209385,7 @@ static int nodeAcquire( } *ppNode = pNode; }else{ + nodeBlobReset(pRtree); if( pNode ){ pRtree->nNodeRef--; sqlite3_free(pNode); @@ -209412,6 +209530,7 @@ static void nodeGetCoord( int iCoord, /* Which coordinate to extract */ RtreeCoord *pCoord /* OUT: Space to write result to */ ){ + assert( iCellzData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); } @@ -209601,7 +209720,9 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){ sqlite3_finalize(pCsr->pReadAux); sqlite3_free(pCsr); pRtree->nCursor--; - nodeBlobReset(pRtree); + if( pRtree->nCursor==0 && pRtree->inWrTrans==0 ){ + nodeBlobReset(pRtree); + } return SQLITE_OK; } @@ -210186,7 +210307,11 @@ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ int rc = SQLITE_OK; RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); if( rc==SQLITE_OK && ALWAYS(p) ){ - *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); + if( p->iCell>=NCELL(pNode) ){ + rc = SQLITE_ABORT; + }else{ + *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); + } } return rc; } @@ -210204,6 +210329,7 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ if( rc ) return rc; if( NEVER(p==0) ) return SQLITE_OK; + if( p->iCell>=NCELL(pNode) ) return SQLITE_ABORT; if( i==0 ){ sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); }else if( i<=pRtree->nDim2 ){ @@ -211685,8 +211811,7 @@ constraint: */ static int rtreeBeginTransaction(sqlite3_vtab *pVtab){ Rtree *pRtree = (Rtree *)pVtab; - assert( pRtree->inWrTrans==0 ); - pRtree->inWrTrans++; + pRtree->inWrTrans = 1; return SQLITE_OK; } @@ -211700,6 +211825,9 @@ static int rtreeEndTransaction(sqlite3_vtab *pVtab){ nodeBlobReset(pRtree); return SQLITE_OK; } +static int rtreeRollback(sqlite3_vtab *pVtab){ + return rtreeEndTransaction(pVtab); +} /* ** The xRename method for rtree module virtual tables. @@ -211818,7 +211946,7 @@ static sqlite3_module rtreeModule = { rtreeBeginTransaction, /* xBegin - begin transaction */ rtreeEndTransaction, /* xSync - sync transaction */ rtreeEndTransaction, /* xCommit - commit transaction */ - rtreeEndTransaction, /* xRollback - rollback transaction */ + rtreeRollback, /* xRollback - rollback transaction */ 0, /* xFindFunction - function overloading */ rtreeRename, /* xRename - rename the table */ rtreeSavepoint, /* xSavepoint */ @@ -245377,23 +245505,26 @@ static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){ static void fts5TokendataIterNext(Fts5Iter *pIter, int bFrom, i64 iFrom){ int ii; Fts5TokenDataIter *pT = pIter->pTokenDataIter; + Fts5Index *pIndex = pIter->pIndex; for(ii=0; iinIter; ii++){ Fts5Iter *p = pT->apIter[ii]; if( p->base.bEof==0 && (p->base.iRowid==pIter->base.iRowid || (bFrom && p->base.iRowidpIndex, p, bFrom, iFrom); + fts5MultiIterNext(pIndex, p, bFrom, iFrom); while( bFrom && p->base.bEof==0 && p->base.iRowidpIndex->rc==SQLITE_OK + && pIndex->rc==SQLITE_OK ){ - fts5MultiIterNext(p->pIndex, p, 0, 0); + fts5MultiIterNext(pIndex, p, 0, 0); } } } - fts5IterSetOutputsTokendata(pIter); + if( pIndex->rc==SQLITE_OK ){ + fts5IterSetOutputsTokendata(pIter); + } } /* @@ -250547,7 +250678,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257cc467a", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2024-03-12 11:06:23 d8cd6d49b46a395b13955387d05e9e1a2a47e54fb99f3c9b59835bbefad6af77", -1, SQLITE_TRANSIENT); } /* diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index 4fdfde004eb..c9fc77fb860 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.45.1" -#define SQLITE_VERSION_NUMBER 3045001 -#define SQLITE_SOURCE_ID "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257cc467a" +#define SQLITE_VERSION "3.45.2" +#define SQLITE_VERSION_NUMBER 3045002 +#define SQLITE_SOURCE_ID "2024-03-12 11:06:23 d8cd6d49b46a395b13955387d05e9e1a2a47e54fb99f3c9b59835bbefad6af77" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -420,6 +420,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. **
  • The application must not modify the SQL statement text passed into ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. +**
  • The application must not dereference the arrays or string pointers +** passed as the 3rd and 4th callback parameters after it returns. ** */ SQLITE_API int sqlite3_exec( From 1b6f0972849e8455b891157d4e2c59ef808686e3 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 16 Feb 2024 19:46:56 +0100 Subject: [PATCH 50/58] PCRE2: upgrade to 10.43 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apart from some source code reshuffling, 10.43's JIT has dropped its support for ARMv5. [ChangeLog][Third-Party Code] PCRE2 was updated to version 10.43. Change-Id: I7909f0a9358f38282f5eaeacd2eb10529b47e63c Reviewed-by: Volker Hilsheimer Reviewed-by: Kai Köhne (cherry picked from commit 909d881e7539bc77ab79650782ae91372fb4ee83) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 18d15404cbbbb87547e7a99623650d5ed69898c9) (cherry picked from commit 179164ef1400dc18b6a1cb2a5bf6d22bd670b5b3) (cherry picked from commit b65a76a8a438d099da63f62e2b8de7a764ba950c) (cherry picked from commit ecfd3fb2f533a5b30f654c7a19ebfc97e167d892) --- src/3rdparty/pcre2/AUTHORS | 6 +- src/3rdparty/pcre2/LICENCE | 6 +- .../pcre2/import_from_pcre2_tarball.sh | 15 +- src/3rdparty/pcre2/pcre2.pro | 1 + src/3rdparty/pcre2/qt_attribution.json | 18 +- src/3rdparty/pcre2/src/config.h | 8 +- src/3rdparty/pcre2/src/pcre2.h | 30 +- src/3rdparty/pcre2/src/pcre2_auto_possess.c | 16 +- src/3rdparty/pcre2/src/pcre2_chartables.c | 12 +- src/3rdparty/pcre2/src/pcre2_chkdint.c | 96 + src/3rdparty/pcre2/src/pcre2_compile.c | 1283 ++-- src/3rdparty/pcre2/src/pcre2_context.c | 46 +- src/3rdparty/pcre2/src/pcre2_dfa_match.c | 167 +- src/3rdparty/pcre2/src/pcre2_error.c | 9 +- src/3rdparty/pcre2/src/pcre2_find_bracket.c | 10 +- src/3rdparty/pcre2/src/pcre2_internal.h | 155 +- src/3rdparty/pcre2/src/pcre2_intmodedep.h | 57 +- src/3rdparty/pcre2/src/pcre2_jit_compile.c | 1281 ++-- src/3rdparty/pcre2/src/pcre2_jit_match.c | 16 +- src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h | 53 +- src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h | 1061 ++- src/3rdparty/pcre2/src/pcre2_maketables.c | 8 +- src/3rdparty/pcre2/src/pcre2_match.c | 469 +- src/3rdparty/pcre2/src/pcre2_match_data.c | 12 + src/3rdparty/pcre2/src/pcre2_study.c | 104 +- src/3rdparty/pcre2/src/pcre2_substring.c | 7 +- src/3rdparty/pcre2/src/pcre2_ucd.c | 5720 +++++++++-------- src/3rdparty/pcre2/src/pcre2_ucp.h | 48 +- src/3rdparty/pcre2/src/pcre2_ucptables.c | 529 +- src/3rdparty/pcre2/src/pcre2_valid_utf.c | 48 +- src/3rdparty/pcre2/src/pcre2_xclass.c | 53 +- .../allocator_src/sljitExecAllocatorApple.c | 133 + .../allocator_src/sljitExecAllocatorCore.c | 330 + .../allocator_src/sljitExecAllocatorFreeBSD.c | 89 + .../allocator_src/sljitExecAllocatorPosix.c | 62 + .../allocator_src/sljitExecAllocatorWindows.c | 40 + .../sljitProtExecAllocatorNetBSD.c | 72 + .../sljitProtExecAllocatorPosix.c | 172 + .../allocator_src/sljitWXExecAllocatorPosix.c | 141 + .../sljitWXExecAllocatorWindows.c | 102 + src/3rdparty/pcre2/src/sljit/sljitConfig.h | 26 +- src/3rdparty/pcre2/src/sljit/sljitConfigCPU.h | 188 + .../pcre2/src/sljit/sljitConfigInternal.h | 338 +- src/3rdparty/pcre2/src/sljit/sljitLir.c | 1756 ++--- src/3rdparty/pcre2/src/sljit/sljitLir.h | 938 ++- .../pcre2/src/sljit/sljitNativeARM_32.c | 1953 ++++-- .../pcre2/src/sljit/sljitNativeARM_64.c | 1285 +++- .../pcre2/src/sljit/sljitNativeARM_T2_32.c | 1305 +++- .../pcre2/src/sljit/sljitNativeMIPS_32.c | 172 +- .../pcre2/src/sljit/sljitNativeMIPS_64.c | 78 +- .../pcre2/src/sljit/sljitNativeMIPS_common.c | 1177 +++- .../pcre2/src/sljit/sljitNativePPC_32.c | 153 +- .../pcre2/src/sljit/sljitNativePPC_64.c | 152 +- .../pcre2/src/sljit/sljitNativePPC_common.c | 755 ++- .../pcre2/src/sljit/sljitNativeRISCV_32.c | 71 +- .../pcre2/src/sljit/sljitNativeRISCV_64.c | 43 +- .../pcre2/src/sljit/sljitNativeRISCV_common.c | 655 +- .../pcre2/src/sljit/sljitNativeS390X.c | 1256 +++- .../pcre2/src/sljit/sljitNativeX86_32.c | 465 +- .../pcre2/src/sljit/sljitNativeX86_64.c | 446 +- .../pcre2/src/sljit/sljitNativeX86_common.c | 3125 ++++++--- src/corelib/text/qregularexpression.cpp | 3 +- 62 files changed, 20026 insertions(+), 8799 deletions(-) create mode 100644 src/3rdparty/pcre2/src/pcre2_chkdint.c create mode 100644 src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c create mode 100644 src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c create mode 100644 src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c create mode 100644 src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c create mode 100644 src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c create mode 100644 src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c create mode 100644 src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c create mode 100644 src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c create mode 100644 src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c create mode 100644 src/3rdparty/pcre2/src/sljit/sljitConfigCPU.h diff --git a/src/3rdparty/pcre2/AUTHORS b/src/3rdparty/pcre2/AUTHORS index 11ef898b250..9669f7755ad 100644 --- a/src/3rdparty/pcre2/AUTHORS +++ b/src/3rdparty/pcre2/AUTHORS @@ -8,7 +8,7 @@ Email domain: gmail.com Retired from University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2022 University of Cambridge +Copyright (c) 1997-2024 University of Cambridge All rights reserved @@ -19,7 +19,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2010-2022 Zoltan Herczeg +Copyright(c) 2010-2024 Zoltan Herczeg All rights reserved. @@ -30,7 +30,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2009-2022 Zoltan Herczeg +Copyright(c) 2009-2024 Zoltan Herczeg All rights reserved. #### diff --git a/src/3rdparty/pcre2/LICENCE b/src/3rdparty/pcre2/LICENCE index 2f3cd5cac53..3c1ef032dec 100644 --- a/src/3rdparty/pcre2/LICENCE +++ b/src/3rdparty/pcre2/LICENCE @@ -26,7 +26,7 @@ Email domain: gmail.com Retired from University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2022 University of Cambridge +Copyright (c) 1997-2024 University of Cambridge All rights reserved. @@ -37,7 +37,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Email domain: freemail.hu -Copyright(c) 2010-2022 Zoltan Herczeg +Copyright(c) 2010-2024 Zoltan Herczeg All rights reserved. @@ -48,7 +48,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Email domain: freemail.hu -Copyright(c) 2009-2022 Zoltan Herczeg +Copyright(c) 2009-2024 Zoltan Herczeg All rights reserved. diff --git a/src/3rdparty/pcre2/import_from_pcre2_tarball.sh b/src/3rdparty/pcre2/import_from_pcre2_tarball.sh index 4a454b059be..007e0699a51 100755 --- a/src/3rdparty/pcre2/import_from_pcre2_tarball.sh +++ b/src/3rdparty/pcre2/import_from_pcre2_tarball.sh @@ -83,6 +83,7 @@ FILES=" LICENCE src/pcre2_auto_possess.c + src/pcre2_chkdint.c src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c @@ -115,9 +116,9 @@ FILES=" src/pcre2_ucptables.c src/pcre2_valid_utf.c src/pcre2_xclass.c + src/sljit/sljitConfigCPU.h src/sljit/sljitConfig.h src/sljit/sljitConfigInternal.h - src/sljit/sljitExecAllocator.c src/sljit/sljitLir.c src/sljit/sljitLir.h src/sljit/sljitNativeARM_32.c @@ -136,9 +137,15 @@ FILES=" src/sljit/sljitNativeX86_32.c src/sljit/sljitNativeX86_64.c src/sljit/sljitNativeX86_common.c - src/sljit/sljitProtExecAllocator.c - src/sljit/sljitUtils.c - src/sljit/sljitWXExecAllocator.c + src/sljit/allocator_src/sljitExecAllocatorPosix.c + src/sljit/allocator_src/sljitProtExecAllocatorPosix.c + src/sljit/allocator_src/sljitWXExecAllocatorPosix.c + src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c + src/sljit/allocator_src/sljitExecAllocatorWindows.c + src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c + src/sljit/allocator_src/sljitExecAllocatorApple.c + src/sljit/allocator_src/sljitWXExecAllocatorWindows.c + src/sljit/allocator_src/sljitExecAllocatorCore.c " for i in $FILES; do diff --git a/src/3rdparty/pcre2/pcre2.pro b/src/3rdparty/pcre2/pcre2.pro index fd5f15623b2..1cb778eb04e 100644 --- a/src/3rdparty/pcre2/pcre2.pro +++ b/src/3rdparty/pcre2/pcre2.pro @@ -28,6 +28,7 @@ macos:contains(QT_ARCHS, "arm64"): QMAKE_CFLAGS += -Xarch_arm64 -DPCRE2_DISABLE_ SOURCES += \ $$PWD/src/pcre2_auto_possess.c \ $$PWD/src/pcre2_chartables.c \ + $$PWD/src/pcre2_chkdint.c \ $$PWD/src/pcre2_compile.c \ $$PWD/src/pcre2_config.c \ $$PWD/src/pcre2_context.c \ diff --git a/src/3rdparty/pcre2/qt_attribution.json b/src/3rdparty/pcre2/qt_attribution.json index 2d8c6586578..6dc8e9ceefc 100644 --- a/src/3rdparty/pcre2/qt_attribution.json +++ b/src/3rdparty/pcre2/qt_attribution.json @@ -7,13 +7,13 @@ "Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.", "Homepage": "http://www.pcre.org/", - "Version": "10.42", - "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.bz2", - "License": "BSD 3-clause \"New\" or \"Revised\" License", - "LicenseId": "BSD-3-Clause", + "Version": "10.43", + "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.43/pcre2-10.43.tar.bz2", + "License": "BSD 3-clause \"New\" or \"Revised\" License with PCRE2 binary-like Packages Exception", + "LicenseId": "LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception", "LicenseFile": "LICENCE", - "Copyright": "Copyright (c) 1997-2022 University of Cambridge -Copyright (c) 2010-2022 Zoltan Herczeg" + "Copyright": "Copyright (c) 1997-2024 University of Cambridge +Copyright (c) 2010-2024 Zoltan Herczeg" }, { "Id": "pcre2-sljit", @@ -24,11 +24,11 @@ Copyright (c) 2010-2022 Zoltan Herczeg" "Path": "src/sljit", "Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.", "Homepage": "http://www.pcre.org/", - "Version": "10.42", - "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.bz2", + "Version": "10.43", + "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.43/pcre2-10.43.tar.bz2", "License": "BSD 2-clause \"Simplified\" License", "LicenseId": "BSD-2-Clause", "LicenseFile": "LICENCE-SLJIT", - "Copyright": "Copyright (c) 2009-2022 Zoltan Herczeg" + "Copyright": "Copyright (c) 2009-2024 Zoltan Herczeg" } ] diff --git a/src/3rdparty/pcre2/src/config.h b/src/3rdparty/pcre2/src/config.h index eeade9d9ce2..72518dca5fc 100644 --- a/src/3rdparty/pcre2/src/config.h +++ b/src/3rdparty/pcre2/src/config.h @@ -14,13 +14,15 @@ #define MAX_NAME_SIZE 32 #define NEWLINE_DEFAULT 2 #define PARENS_NEST_LIMIT 250 +#define MAX_VARLOOKBEHIND 255 #define SUPPORT_UNICODE +#define PCRE2_EXPORT /* man 3 pcre2jit for a list of supported platforms; - as PCRE2 10.22, stable JIT support is available for: - - ARM 32-bit (v5, v7, and Thumb2) + as PCRE2 10.43, stable JIT support is available for: + - ARM 32-bit (v7 and Thumb2) - ARM 64-bit - Intel x86 32-bit and 64-bit - MIPS 32-bit and 64-bit @@ -32,7 +34,7 @@ #if !defined(PCRE2_DISABLE_JIT) && (\ /* ARM */ \ (defined(__GNUC__) \ - && (defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(__aarch64__))) \ + && (defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__aarch64__))) \ /* x86 32/64 */ \ || defined(__i386) || defined(__i386__) || defined(_M_IX86) \ || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) \ diff --git a/src/3rdparty/pcre2/src/pcre2.h b/src/3rdparty/pcre2/src/pcre2.h index 1cbecd0e86e..d7a8ff5201e 100644 --- a/src/3rdparty/pcre2/src/pcre2.h +++ b/src/3rdparty/pcre2/src/pcre2.h @@ -5,7 +5,7 @@ /* This is the public header file for the PCRE library, second API, to be #included by applications that call PCRE2 functions. - Copyright (c) 2016-2021 University of Cambridge + Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE2_MAJOR 10 -#define PCRE2_MINOR 42 +#define PCRE2_MINOR 43 #define PCRE2_PRERELEASE -#define PCRE2_DATE 2022-12-11 +#define PCRE2_DATE 2024-02-16 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE2, the appropriate @@ -153,6 +153,12 @@ D is inspected during pcre2_dfa_match() execution #define PCRE2_EXTRA_ESCAPED_CR_IS_LF 0x00000010u /* C */ #define PCRE2_EXTRA_ALT_BSUX 0x00000020u /* C */ #define PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK 0x00000040u /* C */ +#define PCRE2_EXTRA_CASELESS_RESTRICT 0x00000080u /* C */ +#define PCRE2_EXTRA_ASCII_BSD 0x00000100u /* C */ +#define PCRE2_EXTRA_ASCII_BSS 0x00000200u /* C */ +#define PCRE2_EXTRA_ASCII_BSW 0x00000400u /* C */ +#define PCRE2_EXTRA_ASCII_POSIX 0x00000800u /* C */ +#define PCRE2_EXTRA_ASCII_DIGIT 0x00001000u /* C */ /* These are for pcre2_jit_compile(). */ @@ -180,11 +186,12 @@ pcre2_jit_match() ignores the latter since it bypasses all sanity checks). */ #define PCRE2_SUBSTITUTE_UNSET_EMPTY 0x00000400u /* pcre2_substitute() only */ #define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u /* pcre2_substitute() only */ #define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u /* pcre2_substitute() only */ -#define PCRE2_NO_JIT 0x00002000u /* Not for pcre2_dfa_match() */ +#define PCRE2_NO_JIT 0x00002000u /* not for pcre2_dfa_match() */ #define PCRE2_COPY_MATCHED_SUBJECT 0x00004000u #define PCRE2_SUBSTITUTE_LITERAL 0x00008000u /* pcre2_substitute() only */ #define PCRE2_SUBSTITUTE_MATCHED 0x00010000u /* pcre2_substitute() only */ #define PCRE2_SUBSTITUTE_REPLACEMENT_ONLY 0x00020000u /* pcre2_substitute() only */ +#define PCRE2_DISABLE_RECURSELOOP_CHECK 0x00040000u /* not for pcre2_dfa_match() or pcre2_jit_match() */ /* Options for pcre2_pattern_convert(). */ @@ -399,6 +406,7 @@ released, the numbers must not be changed. */ #define PCRE2_ERROR_CONVERT_SYNTAX (-64) #define PCRE2_ERROR_INTERNAL_DUPMATCH (-65) #define PCRE2_ERROR_DFA_UINVALID_UTF (-66) +#define PCRE2_ERROR_INVALIDOFFSET (-67) /* Request types for pcre2_pattern_info() */ @@ -575,7 +583,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_config(uint32_t, void *); PCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \ pcre2_general_context_copy(pcre2_general_context *); \ PCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \ - pcre2_general_context_create(void *(*)(PCRE2_SIZE, void *), \ + pcre2_general_context_create(void *(*)(size_t, void *), \ void (*)(void *, void *), void *); \ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ pcre2_general_context_free(pcre2_general_context *); @@ -595,6 +603,8 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_compile_extra_options(pcre2_compile_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_max_pattern_length(pcre2_compile_context *, PCRE2_SIZE); \ +PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ + pcre2_set_max_varlookbehind(pcre2_compile_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_newline(pcre2_compile_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ @@ -628,7 +638,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_recursion_limit(pcre2_match_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_recursion_memory_management(pcre2_match_context *, \ - void *(*)(PCRE2_SIZE, void *), void (*)(void *, void *), void *); + void *(*)(size_t, void *), void (*)(void *, void *), void *); #define PCRE2_CONVERT_CONTEXT_FUNCTIONS \ PCRE2_EXP_DECL pcre2_convert_context *PCRE2_CALL_CONVENTION \ @@ -687,6 +697,8 @@ PCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \ pcre2_get_mark(pcre2_match_data *); \ PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \ pcre2_get_match_data_size(pcre2_match_data *); \ +PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \ + pcre2_get_match_data_heapframes_size(pcre2_match_data *); \ PCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \ pcre2_get_ovector_count(pcre2_match_data *); \ PCRE2_EXP_DECL PCRE2_SIZE *PCRE2_CALL_CONVENTION \ @@ -722,7 +734,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_substring_number_from_name(const pcre2_code *, PCRE2_SPTR); \ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ - pcre2_substring_list_free(PCRE2_SPTR *); \ + pcre2_substring_list_free(PCRE2_UCHAR **); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_substring_list_get(pcre2_match_data *, PCRE2_UCHAR ***, PCRE2_SIZE **); @@ -771,7 +783,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ pcre2_jit_free_unused_memory(pcre2_general_context *); \ PCRE2_EXP_DECL pcre2_jit_stack *PCRE2_CALL_CONVENTION \ - pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, pcre2_general_context *); \ + pcre2_jit_stack_create(size_t, size_t, pcre2_general_context *); \ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ pcre2_jit_stack_assign(pcre2_match_context *, pcre2_jit_callback, void *); \ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ @@ -851,6 +863,7 @@ pcre2_compile are called by application code. */ #define pcre2_general_context_free PCRE2_SUFFIX(pcre2_general_context_free_) #define pcre2_get_error_message PCRE2_SUFFIX(pcre2_get_error_message_) #define pcre2_get_mark PCRE2_SUFFIX(pcre2_get_mark_) +#define pcre2_get_match_data_heapframes_size PCRE2_SUFFIX(pcre2_get_match_data_heapframes_size_) #define pcre2_get_match_data_size PCRE2_SUFFIX(pcre2_get_match_data_size_) #define pcre2_get_ovector_pointer PCRE2_SUFFIX(pcre2_get_ovector_pointer_) #define pcre2_get_ovector_count PCRE2_SUFFIX(pcre2_get_ovector_count_) @@ -886,6 +899,7 @@ pcre2_compile are called by application code. */ #define pcre2_set_glob_separator PCRE2_SUFFIX(pcre2_set_glob_separator_) #define pcre2_set_heap_limit PCRE2_SUFFIX(pcre2_set_heap_limit_) #define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_) +#define pcre2_set_max_varlookbehind PCRE2_SUFFIX(pcre2_set_max_varlookbehind_) #define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_) #define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_) #define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_) diff --git a/src/3rdparty/pcre2/src/pcre2_auto_possess.c b/src/3rdparty/pcre2/src/pcre2_auto_possess.c index 419fd490018..210d13d37aa 100644 --- a/src/3rdparty/pcre2/src/pcre2_auto_possess.c +++ b/src/3rdparty/pcre2/src/pcre2_auto_possess.c @@ -560,6 +560,8 @@ matches to an empty string (also represented by a non-zero value). */ for(;;) { + PCRE2_SPTR bracode; + /* All operations move the code pointer forward. Therefore infinite recursions are not possible. */ @@ -617,7 +619,8 @@ for(;;) recursions. (This could be improved by keeping a list of group numbers that are called by recursion.) */ - switch(*(code - GET(code, 1))) + bracode = code - GET(code, 1); + switch(*bracode) { case OP_CBRA: case OP_SCBRA: @@ -636,16 +639,19 @@ for(;;) break; /* Atomic sub-patterns and assertions can always auto-possessify their - last iterator. However, if the group was entered as a result of checking - a previous iterator, this is not possible. */ + last iterator except for variable length lookbehinds. However, if the + group was entered as a result of checking a previous iterator, this is + not possible. */ case OP_ASSERT: case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: case OP_ONCE: return !entered_a_group; + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + return (bracode[1+LINK_SIZE] == OP_VREVERSE)? FALSE : !entered_a_group; + /* Non-atomic assertions - don't possessify last iterator. This needs more thought. */ diff --git a/src/3rdparty/pcre2/src/pcre2_chartables.c b/src/3rdparty/pcre2/src/pcre2_chartables.c index 861914d1ac3..7362c3f2345 100644 --- a/src/3rdparty/pcre2/src/pcre2_chartables.c +++ b/src/3rdparty/pcre2/src/pcre2_chartables.c @@ -5,7 +5,8 @@ /* This file was automatically written by the pcre2_dftables auxiliary program. It contains character tables that are used when no external tables are passed to PCRE2 by the application that calls it. The tables -are used only for characters whose code values are less than 256. */ +are used only for characters whose code values are less than 256, and +only relevant if not in UCP mode. */ /* This set of tables was written in the C locale. */ @@ -18,13 +19,6 @@ PCRE2 is configured with --enable-rebuild-chartables. However, you can run pcre2_dftables manually with the -L option to build tables using the LC_ALL locale. */ -/* The following #include is present because without it gcc 4.x may remove -the array definition from the final binary if PCRE2 is built into a static -library and dead code stripping is activated. This leads to link errors. -Pulling in the header ensures that the array gets flagged as "someone -outside this compilation unit might reference this" and so it will always -be supplied to the linker. */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -163,7 +157,7 @@ graph, print, punct, and cntrl. Other classes are built from combinations. */ 0x02 letter 0x04 lower case letter 0x08 decimal digit - 0x10 alphanumeric or '_' + 0x10 word (alphanumeric or '_') */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ diff --git a/src/3rdparty/pcre2/src/pcre2_chkdint.c b/src/3rdparty/pcre2/src/pcre2_chkdint.c new file mode 100644 index 00000000000..d04f6f8cf1a --- /dev/null +++ b/src/3rdparty/pcre2/src/pcre2_chkdint.c @@ -0,0 +1,96 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 2023 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. +----------------------------------------------------------------------------- +*/ + +/* This file contains functions to implement checked integer operation */ + +#ifndef PCRE2_PCRE2TEST +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" +#endif + +/************************************************* +* Checked Integer Multiplication * +*************************************************/ + +/* +Arguments: + r A pointer to PCRE2_SIZE to store the answer + a, b Two integers + +Returns: Bool indicating if the operation overflows + +It is modeled after C23's interface +The INT64_OR_DOUBLE type is a 64-bit integer type when available, +otherwise double. */ + +BOOL +PRIV(ckd_smul)(PCRE2_SIZE *r, int a, int b) +{ +#ifdef HAVE_BUILTIN_MUL_OVERFLOW +PCRE2_SIZE m; + +if (__builtin_mul_overflow(a, b, &m)) return TRUE; + +*r = m; +#else +INT64_OR_DOUBLE m; + +#ifdef PCRE2_DEBUG +if (a < 0 || b < 0) abort(); +#endif + +m = (INT64_OR_DOUBLE)a * (INT64_OR_DOUBLE)b; + +#if defined INT64_MAX || defined int64_t +if (sizeof(m) > sizeof(*r) && m > (INT64_OR_DOUBLE)PCRE2_SIZE_MAX) return TRUE; +*r = (PCRE2_SIZE)m; +#else +if (m > PCRE2_SIZE_MAX) return TRUE; +*r = m; +#endif + +#endif + +return FALSE; +} + +/* End of pcre_chkdint.c */ diff --git a/src/3rdparty/pcre2/src/pcre2_compile.c b/src/3rdparty/pcre2/src/pcre2_compile.c index edf7e82e6ee..8b364977c46 100644 --- a/src/3rdparty/pcre2/src/pcre2_compile.c +++ b/src/3rdparty/pcre2/src/pcre2_compile.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -118,17 +118,17 @@ them will be able to (i.e. assume a 64-bit world). */ #ifdef SUPPORT_UNICODE static unsigned int - add_list_to_class_internal(uint8_t *, PCRE2_UCHAR **, uint32_t, + add_list_to_class_internal(uint8_t *, PCRE2_UCHAR **, uint32_t, uint32_t, compile_block *, const uint32_t *, unsigned int); #endif static int - compile_regex(uint32_t, PCRE2_UCHAR **, uint32_t **, int *, uint32_t, - uint32_t *, uint32_t *, uint32_t *, uint32_t *, branch_chain *, - compile_block *, PCRE2_SIZE *); + compile_regex(uint32_t, uint32_t, PCRE2_UCHAR **, uint32_t **, int *, + uint32_t, uint32_t *, uint32_t *, uint32_t *, uint32_t *, branch_chain *, + open_capitem *, compile_block *, PCRE2_SIZE *); static int - get_branchlength(uint32_t **, int *, int *, parsed_recurse_check *, + get_branchlength(uint32_t **, int *, int *, int *, parsed_recurse_check *, compile_block *); static BOOL @@ -694,8 +694,8 @@ static uint32_t chartypeoffset[] = { now all in a single string, to reduce the number of relocations when a shared library is dynamically loaded. The list of lengths is terminated by a zero length entry. The first three must be alpha, lower, upper, as this is assumed -for handling case independence. The indices for graph, print, and punct are -needed, so identify them. */ +for handling case independence. The indices for several classes are needed, so +identify them. */ static const char posix_names[] = STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0 @@ -706,9 +706,11 @@ static const char posix_names[] = static const uint8_t posix_name_lengths[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; -#define PC_GRAPH 8 -#define PC_PRINT 9 -#define PC_PUNCT 10 +#define PC_DIGIT 7 +#define PC_GRAPH 8 +#define PC_PRINT 9 +#define PC_PUNCT 10 +#define PC_XDIGIT 13 /* Table of class bit maps for each POSIX class. Each class is formed from a base map, with an optional addition or removal of another map. Then, for some @@ -721,20 +723,20 @@ absolute value of the third field has these meanings: 0 => no tweaking, 1 => remove vertical space characters, 2 => remove underscore. */ static const int posix_class_maps[] = { - cbit_word, cbit_digit, -2, /* alpha */ - cbit_lower, -1, 0, /* lower */ - cbit_upper, -1, 0, /* upper */ - cbit_word, -1, 2, /* alnum - word without underscore */ - cbit_print, cbit_cntrl, 0, /* ascii */ - cbit_space, -1, 1, /* blank - a GNU extension */ - cbit_cntrl, -1, 0, /* cntrl */ - cbit_digit, -1, 0, /* digit */ - cbit_graph, -1, 0, /* graph */ - cbit_print, -1, 0, /* print */ - cbit_punct, -1, 0, /* punct */ - cbit_space, -1, 0, /* space */ - cbit_word, -1, 0, /* word - a Perl extension */ - cbit_xdigit,-1, 0 /* xdigit */ + cbit_word, cbit_digit, -2, /* alpha */ + cbit_lower, -1, 0, /* lower */ + cbit_upper, -1, 0, /* upper */ + cbit_word, -1, 2, /* alnum - word without underscore */ + cbit_print, cbit_cntrl, 0, /* ascii */ + cbit_space, -1, 1, /* blank - a GNU extension */ + cbit_cntrl, -1, 0, /* cntrl */ + cbit_digit, -1, 0, /* digit */ + cbit_graph, -1, 0, /* graph */ + cbit_print, -1, 0, /* print */ + cbit_punct, -1, 0, /* punct */ + cbit_space, -1, 0, /* space */ + cbit_word, -1, 0, /* word - a Perl extension */ + cbit_xdigit, -1, 0 /* xdigit */ }; #ifdef SUPPORT_UNICODE @@ -756,7 +758,7 @@ static int posix_substitutes[] = { PT_PXPUNCT, 0, /* punct */ PT_PXSPACE, 0, /* space */ /* Xps is POSIX space, but from 8.34 */ PT_WORD, 0, /* word */ /* Perl and POSIX space are the same */ - -1, 0 /* xdigit, treat as non-UCP */ + PT_PXXDIGIT, 0 /* xdigit */ /* Perl has additional hex digits */ }; #define POSIX_SUBSIZE (sizeof(posix_substitutes) / (2*sizeof(uint32_t))) #endif /* SUPPORT_UNICODE */ @@ -779,13 +781,15 @@ are allowed. */ PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_UCP|PCRE2_UNGREEDY) #define PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS \ - (PCRE2_EXTRA_MATCH_LINE|PCRE2_EXTRA_MATCH_WORD) + (PCRE2_EXTRA_MATCH_LINE|PCRE2_EXTRA_MATCH_WORD|PCRE2_EXTRA_CASELESS_RESTRICT) #define PUBLIC_COMPILE_EXTRA_OPTIONS \ (PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS| \ PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES|PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL| \ PCRE2_EXTRA_ESCAPED_CR_IS_LF|PCRE2_EXTRA_ALT_BSUX| \ - PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) + PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK|PCRE2_EXTRA_ASCII_BSD| \ + PCRE2_EXTRA_ASCII_BSS|PCRE2_EXTRA_ASCII_BSW|PCRE2_EXTRA_ASCII_POSIX| \ + PCRE2_EXTRA_ASCII_DIGIT) /* Compile time error code numbers. They are given names so that they can more easily be tracked. When a new number is added, the tables called eint1 and @@ -804,7 +808,7 @@ enum { ERR0 = COMPILE_ERROR_BASE, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90, - ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99 }; + ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99, ERR100 }; /* This is a table of start-of-pattern options such as (*UTF) and settings such as (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward @@ -817,7 +821,8 @@ enum { PSO_OPT, /* Value is an option bit */ PSO_BSR, /* Value is a \R type */ PSO_LIMH, /* Read integer value for heap limit */ PSO_LIMM, /* Read integer value for match limit */ - PSO_LIMD }; /* Read integer value for depth limit */ + PSO_LIMD /* Read integer value for depth limit */ + }; typedef struct pso { const uint8_t *name; @@ -828,7 +833,7 @@ typedef struct pso { /* NB: STRING_UTFn_RIGHTPAR contains the length as well */ -static pso pso_list[] = { +static const pso pso_list[] = { { (uint8_t *)STRING_UTFn_RIGHTPAR, PSO_OPT, PCRE2_UTF }, { (uint8_t *)STRING_UTF_RIGHTPAR, 4, PSO_OPT, PCRE2_UTF }, { (uint8_t *)STRING_UCP_RIGHTPAR, 4, PSO_OPT, PCRE2_UCP }, @@ -1059,24 +1064,24 @@ for (;;) case META_SKIP: fprintf(stderr, "META (*SKIP)"); break; case META_THEN: fprintf(stderr, "META (*THEN)"); break; - case META_OPTIONS: fprintf(stderr, "META_OPTIONS 0x%02x", *pptr++); break; + case META_OPTIONS: + fprintf(stderr, "META_OPTIONS 0x%08x 0x%08x", pptr[0], pptr[1]); + pptr += 2; + break; case META_LOOKBEHIND: - fprintf(stderr, "META (?<= %d offset=", meta_arg); - GETOFFSET(offset, pptr); - fprintf(stderr, "%zd", offset); + fprintf(stderr, "META (?<= %d %d", meta_arg, *pptr); + pptr += 2; break; case META_LOOKBEHIND_NA: - fprintf(stderr, "META (*naplb: %d offset=", meta_arg); - GETOFFSET(offset, pptr); - fprintf(stderr, "%zd", offset); + fprintf(stderr, "META (*naplb: %d %d", meta_arg, *pptr); + pptr += 2; break; case META_LOOKBEHINDNOT: - fprintf(stderr, "META (?= ptrend) return FALSE; - c = *p; - if (IS_DIGIT(c)) continue; - if (c == CHAR_RIGHT_CURLY_BRACKET) break; - if (c == CHAR_COMMA) - { - if (had_comma) return FALSE; - had_comma = TRUE; - } - else return FALSE; + had_minimum = TRUE; + while (++pp < ptrend && IS_DIGIT(*pp)) {} } -/* The only error from read_number() is for a number that is too big. */ +while (pp < ptrend && (*pp == CHAR_SPACE || *pp == CHAR_HT)) pp++; +if (pp >= ptrend) return FALSE; -p = *ptrptr; -if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &min, errorcodeptr)) - goto EXIT; - -if (*p == CHAR_RIGHT_CURLY_BRACKET) +if (*pp == CHAR_RIGHT_CURLY_BRACKET) { - p++; - max = min; + if (!had_minimum) return FALSE; } else { - if (*(++p) != CHAR_RIGHT_CURLY_BRACKET) + if (*pp++ != CHAR_COMMA) return FALSE; + while (pp < ptrend && (*pp == CHAR_SPACE || *pp == CHAR_HT)) pp++; + if (pp >= ptrend) return FALSE; + if (IS_DIGIT(*pp)) { - if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &max, - errorcodeptr)) - goto EXIT; + while (++pp < ptrend && IS_DIGIT(*pp)) {} + } + else if (!had_minimum) return FALSE; + while (pp < ptrend && (*pp == CHAR_SPACE || *pp == CHAR_HT)) pp++; + if (pp >= ptrend || *pp != CHAR_RIGHT_CURLY_BRACKET) return FALSE; + } + +/* Now process the quantifier for real. We know it must be {n} or (n,} or {,m} +or {n,m}. The only error that read_number() can return is for a number that is +too big. If *errorcodeptr is returned as zero it means no number was found. */ + +/* Deal with {,m} or n too big. If we successfully read m there is no need to +check m >= n because n defaults to zero. */ + +if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &min, errorcodeptr)) + { + if (*errorcodeptr != 0) goto EXIT; /* n too big */ + p++; /* Skip comma and subsequent spaces */ + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; + if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &max, errorcodeptr)) + { + if (*errorcodeptr != 0) goto EXIT; /* m too big */ + } + } + +/* Have read one number. Deal with {n} or {n,} or {n,m} */ + +else + { + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; + if (*p == CHAR_RIGHT_CURLY_BRACKET) + { + max = min; + } + else /* Handle {n,} or {n,m} */ + { + p++; /* Skip comma and subsequent spaces */ + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; + if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &max, errorcodeptr)) + { + if (*errorcodeptr != 0) goto EXIT; /* m too big */ + } + if (max < min) { *errorcodeptr = ERR4; goto EXIT; } } - p++; } +/* Valid quantifier exists */ + +while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; +p++; yield = TRUE; if (minp != NULL) *minp = (uint32_t)min; if (maxp != NULL) *maxp = (uint32_t)max; @@ -1491,6 +1536,7 @@ Arguments: chptr points to a returned data character errorcodeptr points to the errorcode variable (containing zero) options the current options bits + xoptions the current extra options bits isclass TRUE if inside a character class cb compile data block or NULL when called from pcre2_substitute() @@ -1502,10 +1548,12 @@ Returns: zero => a data character int PRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr, - int *errorcodeptr, uint32_t options, uint32_t extra_options, BOOL isclass, + int *errorcodeptr, uint32_t options, uint32_t xoptions, BOOL isclass, compile_block *cb) { BOOL utf = (options & PCRE2_UTF) != 0; +BOOL alt_bsux = + ((options & PCRE2_ALT_BSUX) | (xoptions & PCRE2_EXTRA_ALT_BSUX)) != 0; PCRE2_SPTR ptr = *ptrptr; uint32_t c, cc; int escape = 0; @@ -1539,7 +1587,7 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0) if (i > 0) { c = (uint32_t)i; - if (c == CHAR_CR && (extra_options & PCRE2_EXTRA_ESCAPED_CR_IS_LF) != 0) + if (c == CHAR_CR && (xoptions & PCRE2_EXTRA_ESCAPED_CR_IS_LF) != 0) c = CHAR_LF; } else /* Negative table entry */ @@ -1557,6 +1605,10 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0) { PCRE2_SPTR p = ptr + 1; + /* Perl ignores spaces and tabs after { */ + + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; + /* \N{U+ can be handled by the \x{ code. However, this construction is not valid in EBCDIC environments because it specifies a Unicode character, not a codepoint in the local code. For example \N{U+0041} @@ -1571,7 +1623,7 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0) #else if (utf) { - ptr = p + 1; + ptr = p + 2; escape = 0; /* Not a fancy escape after all */ goto COME_FROM_NU; } @@ -1602,8 +1654,6 @@ else int s; PCRE2_SPTR oldptr; BOOL overflow; - BOOL alt_bsux = - ((options & PCRE2_ALT_BSUX) | (extra_options & PCRE2_EXTRA_ALT_BSUX)) != 0; /* Filter calls from pcre2_substitute(). */ @@ -1632,7 +1682,9 @@ else is set. Otherwise, \u must be followed by exactly four hex digits or, if PCRE2_EXTRA_ALT_BSUX is set, by any number of hex digits in braces. Otherwise it is a lowercase u letter. This gives some compatibility with - ECMAScript (aka JavaScript). */ + ECMAScript (aka JavaScript). Unlike other braced items, white space is NOT + allowed. When \u{ is not followed by hex digits, a special return is given + because otherwise \u{ 12} (for example) would be treated as u{12}. */ case CHAR_u: if (!alt_bsux) *errorcodeptr = ERR37; else @@ -1641,11 +1693,11 @@ else if (ptr >= ptrend) break; if (*ptr == CHAR_LEFT_CURLY_BRACKET && - (extra_options & PCRE2_EXTRA_ALT_BSUX) != 0) + (xoptions & PCRE2_EXTRA_ALT_BSUX) != 0) { PCRE2_SPTR hptr = ptr + 1; - cc = 0; + cc = 0; while (hptr < ptrend && (xc = XDIGIT(*hptr)) != 0xff) { if ((cc & 0xf0000000) != 0) /* Test for 32-bit overflow */ @@ -1661,7 +1713,11 @@ else if (hptr == ptr + 1 || /* No hex digits */ hptr >= ptrend || /* Hit end of input */ *hptr != CHAR_RIGHT_CURLY_BRACKET) /* No } terminator */ - break; /* Hex escape not recognized */ + { + escape = ESC_ub; /* Special return */ + ptr++; /* Skip { */ + break; /* Hex escape not recognized */ + } c = cc; /* Accept the code point */ ptr = hptr + 1; @@ -1685,7 +1741,7 @@ else if (c > 0x10ffffU) *errorcodeptr = ERR77; else if (c >= 0xd800 && c <= 0xdfff && - (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) + (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) *errorcodeptr = ERR73; } else if (c > MAX_NON_UTF_CHAR) *errorcodeptr = ERR77; @@ -1741,12 +1797,16 @@ else if (*ptr == CHAR_LEFT_CURLY_BRACKET) { PCRE2_SPTR p = ptr + 1; + + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; if (!read_number(&p, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s, errorcodeptr)) { if (*errorcodeptr == 0) escape = ESC_k; /* No number found */ break; } + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; + if (p >= ptrend || *p != CHAR_RIGHT_CURLY_BRACKET) { *errorcodeptr = ERR57; @@ -1842,56 +1902,64 @@ else break; /* \o is a relatively new Perl feature, supporting a more general way of - specifying character codes in octal. The only supported form is \o{ddd}. */ + specifying character codes in octal. The only supported form is \o{ddd}, + with optional spaces or tabs after { and before }. */ case CHAR_o: if (ptr >= ptrend || *ptr++ != CHAR_LEFT_CURLY_BRACKET) { ptr--; *errorcodeptr = ERR55; + break; } - else if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET) - *errorcodeptr = ERR78; - else + + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; + if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET) { - c = 0; - overflow = FALSE; - while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) - { - cc = *ptr++; - if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ + *errorcodeptr = ERR78; + break; + } + + c = 0; + overflow = FALSE; + while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) + { + cc = *ptr++; + if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ #if PCRE2_CODE_UNIT_WIDTH == 32 - if (c >= 0x20000000l) { overflow = TRUE; break; } + if (c >= 0x20000000l) { overflow = TRUE; break; } #endif - c = (c << 3) + (cc - CHAR_0); + c = (c << 3) + (cc - CHAR_0); #if PCRE2_CODE_UNIT_WIDTH == 8 - if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; } + if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; } #elif PCRE2_CODE_UNIT_WIDTH == 16 - if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; } + if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; } #elif PCRE2_CODE_UNIT_WIDTH == 32 - if (utf && c > 0x10ffffU) { overflow = TRUE; break; } + if (utf && c > 0x10ffffU) { overflow = TRUE; break; } #endif - } - if (overflow) - { - while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++; - *errorcodeptr = ERR34; - } - else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET) - { - if (utf && c >= 0xd800 && c <= 0xdfff && - (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) - { - ptr--; - *errorcodeptr = ERR73; - } - } - else + } + + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; + + if (overflow) + { + while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++; + *errorcodeptr = ERR34; + } + else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET) + { + if (utf && c >= 0xd800 && c <= 0xdfff && + (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) { ptr--; - *errorcodeptr = ERR64; + *errorcodeptr = ERR73; } } + else + { + ptr--; + *errorcodeptr = ERR64; + } break; /* When PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX is set, \x must be followed @@ -1919,10 +1987,13 @@ else { if (ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET) { + ptr++; + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; + #ifndef EBCDIC COME_FROM_NU: #endif - if (++ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET) + if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET) { *errorcodeptr = ERR78; break; @@ -1945,6 +2016,12 @@ else } } + /* Perl ignores spaces and tabs before } */ + + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; + + /* On overflow, skip remaining hex digits */ + if (overflow) { while (ptr < ptrend && XDIGIT(*ptr) != 0xff) ptr++; @@ -1953,17 +2030,17 @@ else else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET) { if (utf && c >= 0xd800 && c <= 0xdfff && - (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) + (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) { ptr--; *errorcodeptr = ERR73; } } - /* If the sequence of hex digits does not end with '}', give an error. - We used just to recognize this construct and fall through to the normal - \x handling, but nowadays Perl gives an error, which seems much more - sensible, so we do too. */ + /* If the sequence of hex digits (followed by optional space) does not + end with '}', give an error. We used just to recognize this construct + and fall through to the normal \x handling, but nowadays Perl gives an + error, which seems much more sensible, so we do too. */ else { @@ -2117,7 +2194,11 @@ if (c == CHAR_LEFT_CURLY_BRACKET) { if (ptr >= cb->end_pattern) goto ERROR_RETURN; c = *ptr++; +#if PCRE2_CODE_UNIT_WIDTH != 8 + while (c == '_' || c == '-' || (c <= 0xff && isspace(c))) +#else while (c == '_' || c == '-' || isspace(c)) +#endif { if (ptr >= cb->end_pattern) goto ERROR_RETURN; c = *ptr++; @@ -2355,12 +2436,13 @@ return -1; /* This function is called from parse_regex() below whenever it needs to read the name of a subpattern or a (*VERB) or an (*alpha_assertion). The initial -pointer must be to the character before the name. If that character is '*' we -are reading a verb or alpha assertion name. The pointer is updated to point -after the name, for a VERB or alpha assertion name, or after tha name's -terminator for a subpattern name. Returning both the offset and the name -pointer is redundant information, but some callers use one and some the other, -so it is simplest just to return both. +pointer must be to the preceding character. If that character is '*' we are +reading a verb or alpha assertion name. The pointer is updated to point after +the name, for a VERB or alpha assertion name, or after tha name's terminator +for a subpattern name. Returning both the offset and the name pointer is +redundant information, but some callers use one and some the other, so it is +simplest just to return both. When the name is in braces, spaces and tabs are +allowed (and ignored) at either end. Arguments: ptrptr points to the character pointer variable @@ -2383,9 +2465,13 @@ read_name(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, BOOL utf, uint32_t terminator, int *errorcodeptr, compile_block *cb) { PCRE2_SPTR ptr = *ptrptr; -BOOL is_group = (*ptr != CHAR_ASTERISK); +BOOL is_group = (*ptr++ != CHAR_ASTERISK); +BOOL is_braced = terminator == CHAR_RIGHT_CURLY_BRACKET; -if (++ptr >= ptrend) /* No characters in name */ +if (is_braced) + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; + +if (ptr >= ptrend) /* No characters in name */ { *errorcodeptr = is_group? ERR62: /* Subpattern name expected */ ERR60; /* Verb not recognized or malformed */ @@ -2464,6 +2550,8 @@ if (is_group) *errorcodeptr = ERR62; /* Subpattern name expected */ goto FAILED; } + if (is_braced) + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; if (ptr >= ptrend || *ptr != (PCRE2_UCHAR)terminator) { *errorcodeptr = ERR42; @@ -2532,6 +2620,85 @@ return parsed_pattern; +/************************************************* +* Handle \d, \D, \s, \S, \w, \W * +*************************************************/ + +/* This function is called from parse_regex() below, both for freestanding +escapes, and those within classes, to handle those escapes that may change when +Unicode property support is requested. Note that PCRE2_UCP will never be set +without Unicode support because that is checked when pcre2_compile() is called. + +Arguments: + escape the ESC_... value + parsed_pattern where to add the code + options options bits + xoptions extra options bits + +Returns: updated value of parsed_pattern +*/ +static uint32_t * +handle_escdsw(int escape, uint32_t *parsed_pattern, uint32_t options, + uint32_t xoptions) +{ +uint32_t ascii_option = 0; +uint32_t prop = ESC_p; + +switch(escape) + { + case ESC_D: + prop = ESC_P; + /* Fall through */ + case ESC_d: + ascii_option = PCRE2_EXTRA_ASCII_BSD; + break; + + case ESC_S: + prop = ESC_P; + /* Fall through */ + case ESC_s: + ascii_option = PCRE2_EXTRA_ASCII_BSS; + break; + + case ESC_W: + prop = ESC_P; + /* Fall through */ + case ESC_w: + ascii_option = PCRE2_EXTRA_ASCII_BSW; + break; + } + +if ((options & PCRE2_UCP) == 0 || (xoptions & ascii_option) != 0) + { + *parsed_pattern++ = META_ESCAPE + escape; + } +else + { + *parsed_pattern++ = META_ESCAPE + prop; + switch(escape) + { + case ESC_d: + case ESC_D: + *parsed_pattern++ = (PT_PC << 16) | ucp_Nd; + break; + + case ESC_s: + case ESC_S: + *parsed_pattern++ = PT_SPACE << 16; + break; + + case ESC_w: + case ESC_W: + *parsed_pattern++ = PT_WORD << 16; + break; + } + } + +return parsed_pattern; +} + + + /************************************************* * Parse regex and identify named groups * *************************************************/ @@ -2560,6 +2727,7 @@ typedef struct nest_save { uint16_t max_group; uint16_t flags; uint32_t options; + uint32_t xoptions; } nest_save; #define NSF_RESET 0x0001u @@ -2575,6 +2743,10 @@ the main compiling phase. */ PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| \ PCRE2_UNGREEDY) +#define PARSE_TRACKED_EXTRA_OPTIONS (PCRE2_EXTRA_CASELESS_RESTRICT| \ + PCRE2_EXTRA_ASCII_BSD|PCRE2_EXTRA_ASCII_BSS|PCRE2_EXTRA_ASCII_BSW| \ + PCRE2_EXTRA_ASCII_DIGIT|PCRE2_EXTRA_ASCII_POSIX) + /* States used for analyzing ranges in character classes. The two OK values must be last. */ @@ -2609,9 +2781,11 @@ uint32_t *verbstartptr = NULL; uint32_t *previous_callout = NULL; uint32_t *parsed_pattern = cb->parsed_pattern; uint32_t *parsed_pattern_end = cb->parsed_pattern_end; +uint32_t *this_parsed_item = NULL; +uint32_t *prev_parsed_item = NULL; uint32_t meta_quantifier = 0; uint32_t add_after_mark = 0; -uint32_t extra_options = cb->cx->extra_options; +uint32_t xoptions = cb->cx->extra_options; uint16_t nest_depth = 0; int after_manual_callout = 0; int expect_cond_assert = 0; @@ -2635,12 +2809,12 @@ nest_save *top_nest, *end_nests; /* Insert leading items for word and line matching (features provided for the benefit of pcre2grep). */ -if ((extra_options & PCRE2_EXTRA_MATCH_LINE) != 0) +if ((xoptions & PCRE2_EXTRA_MATCH_LINE) != 0) { *parsed_pattern++ = META_CIRCUMFLEX; *parsed_pattern++ = META_NOCAPTURE; } -else if ((extra_options & PCRE2_EXTRA_MATCH_WORD) != 0) +else if ((xoptions & PCRE2_EXTRA_MATCH_WORD) != 0) { *parsed_pattern++ = META_ESCAPE + ESC_b; *parsed_pattern++ = META_NOCAPTURE; @@ -2691,6 +2865,7 @@ while (ptr < ptrend) int prev_expect_cond_assert; uint32_t min_repeat = 0, max_repeat = 0; uint32_t set, unset, *optset; + uint32_t xset, xunset, *xoptset; uint32_t terminator; uint32_t prev_meta_quantifier; BOOL prev_okquantifier; @@ -2709,6 +2884,17 @@ while (ptr < ptrend) goto FAILED; /* Parentheses too deeply nested */ } + /* If the last time round this loop something was added, parsed_pattern will + no longer be equal to this_parsed_item. Remember where the previous item + started and reset for the next item. Note that sometimes round the loop, + nothing gets added (e.g. for ignored white space). */ + + if (this_parsed_item != parsed_pattern) + { + prev_parsed_item = this_parsed_item; + this_parsed_item = parsed_pattern; + } + /* Get next input character, save its position for callout handling. */ thisptr = ptr; @@ -2817,7 +3003,7 @@ while (ptr < ptrend) if ((options & PCRE2_ALT_VERBNAMES) != 0) { escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - cb->cx->extra_options, FALSE, cb); + xoptions, FALSE, cb); if (errorcode != 0) goto FAILED; } else escape = 0; /* Treat all as literal */ @@ -2831,6 +3017,11 @@ while (ptr < ptrend) *parsed_pattern++ = c; break; + case ESC_ub: + *parsed_pattern++ = CHAR_u; + PARSED_LITERAL(CHAR_LEFT_CURLY_BRACKET, parsed_pattern); + break; + case ESC_Q: inescq = TRUE; break; @@ -2917,8 +3108,11 @@ while (ptr < ptrend) !read_repeat_counts(&tempptr, ptrend, NULL, NULL, &errorcode)))) { if (after_manual_callout-- <= 0) + { parsed_pattern = manage_callouts(thisptr, &previous_callout, auto_callout, parsed_pattern, cb); + this_parsed_item = parsed_pattern; /* New start for current item */ + } } /* If expect_cond_assert is 2, we have just passed (?( and are expecting an @@ -2995,7 +3189,6 @@ while (ptr < ptrend) continue; /* Next character in pattern */ } - /* Process the next item in the main part of a pattern. */ switch(c) @@ -3010,11 +3203,11 @@ while (ptr < ptrend) case CHAR_BACKSLASH: tempptr = ptr; escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - cb->cx->extra_options, FALSE, cb); + xoptions, FALSE, cb); if (errorcode != 0) { ESCAPE_FAILED: - if ((extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) + if ((xoptions & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) goto FAILED; ptr = tempptr; if (ptr >= ptrend) c = CHAR_BACKSLASH; else @@ -3088,6 +3281,16 @@ while (ptr < ptrend) *parsed_pattern++ = META_ESCAPE + escape; break; + /* This is a special return that happens only in EXTRA_ALT_BSUX mode, + when \u{ is not followed by hex digits and }. It requests two literal + characters, u and { and we need this, as otherwise \u{ 12} (for example) + would be treated as u{12} now that spaces are allowed in quantifiers. */ + + case ESC_ub: + *parsed_pattern++ = CHAR_u; + PARSED_LITERAL(CHAR_LEFT_CURLY_BRACKET, parsed_pattern); + break; + case ESC_X: #ifndef SUPPORT_UNICODE errorcode = ERR45; /* Supported only with Unicode support */ @@ -3107,9 +3310,7 @@ while (ptr < ptrend) *parsed_pattern++ = META_ESCAPE + escape; break; - /* Escapes that change in UCP mode. Note that PCRE2_UCP will never be set - without Unicode support because it is checked when pcre2_compile() is - called. */ + /* Escapes that may change in UCP mode. */ case ESC_d: case ESC_D: @@ -3118,33 +3319,8 @@ while (ptr < ptrend) case ESC_w: case ESC_W: okquantifier = TRUE; - if ((options & PCRE2_UCP) == 0) - { - *parsed_pattern++ = META_ESCAPE + escape; - } - else - { - *parsed_pattern++ = META_ESCAPE + - ((escape == ESC_d || escape == ESC_s || escape == ESC_w)? - ESC_p : ESC_P); - switch(escape) - { - case ESC_d: - case ESC_D: - *parsed_pattern++ = (PT_PC << 16) | ucp_Nd; - break; - - case ESC_s: - case ESC_S: - *parsed_pattern++ = PT_SPACE << 16; - break; - - case ESC_w: - case ESC_W: - *parsed_pattern++ = PT_WORD << 16; - break; - } - } + parsed_pattern = handle_escdsw(escape, parsed_pattern, options, + xoptions); break; /* Unicode property matching */ @@ -3206,7 +3382,8 @@ while (ptr < ptrend) if (errorcode != 0) goto ESCAPE_FAILED; } - /* Not a numerical recursion */ + /* Not a numerical recursion. Perl allows spaces and tabs after { and + before } but not for other delimiters. */ if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen, &errorcode, cb)) goto ESCAPE_FAILED; @@ -3273,7 +3450,8 @@ while (ptr < ptrend) /* ---- Quantifier post-processing ---- */ - /* Check that a quantifier is allowed after the previous item. */ + /* Check that a quantifier is allowed after the previous item. This + guarantees that there is a previous item. */ CHECK_QUANTIFIER: if (!prev_okquantifier) @@ -3288,7 +3466,7 @@ while (ptr < ptrend) wrapping it in non-capturing brackets, but we have to allow for a preceding (*MARK) for when (*ACCEPT) has an argument. */ - if (parsed_pattern[-1] == META_ACCEPT) + if (*prev_parsed_item == META_ACCEPT) { uint32_t *p; for (p = parsed_pattern - 1; p >= verbstartptr; p--) p[1] = p[0]; @@ -3507,18 +3685,24 @@ while (ptr < ptrend) class_range_state = RANGE_NO; - /* When PCRE2_UCP is set, some of the POSIX classes are converted to - use Unicode properties \p or \P or, in one case, \h or \H. The - substitutes table has two values per class, containing the type and - value of a \p or \P item. The special cases are specified with a - negative type: a non-zero value causes \h or \H to be used, and a zero - value falls through to behave like a non-UCP POSIX class. */ + /* When PCRE2_UCP is set, unless PCRE2_EXTRA_ASCII_POSIX is set, some + of the POSIX classes are converted to use Unicode properties \p or \P + or, in one case, \h or \H. The substitutes table has two values per + class, containing the type and value of a \p or \P item. The special + cases are specified with a negative type: a non-zero value causes \h or + \H to be used, and a zero value falls through to behave like a non-UCP + POSIX class. There are now also some extra options that force ASCII for + some classes. */ #ifdef SUPPORT_UNICODE - if ((options & PCRE2_UCP) != 0) + if ((options & PCRE2_UCP) != 0 && + (xoptions & PCRE2_EXTRA_ASCII_POSIX) == 0 && + !((xoptions & PCRE2_EXTRA_ASCII_DIGIT) != 0 && + (posix_class == PC_DIGIT || posix_class == PC_XDIGIT))) { int ptype = posix_substitutes[2*posix_class]; int pvalue = posix_substitutes[2*posix_class + 1]; + if (ptype >= 0) { *parsed_pattern++ = META_ESCAPE + (posix_negate? ESC_P : ESC_p); @@ -3587,11 +3771,11 @@ while (ptr < ptrend) { tempptr = ptr; escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - cb->cx->extra_options, TRUE, cb); + xoptions, TRUE, cb); if (errorcode != 0) { - if ((extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) + if ((xoptions & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) goto FAILED; ptr = tempptr; if (ptr >= ptrend) c = CHAR_BACKSLASH; else @@ -3605,7 +3789,7 @@ while (ptr < ptrend) { case 0: /* Escaped character code point is in c */ char_is_literal = FALSE; - goto CLASS_LITERAL; + goto CLASS_LITERAL; /* (a few lines above) */ case ESC_b: c = CHAR_BS; /* \b is backspace in a class */ @@ -3656,7 +3840,7 @@ while (ptr < ptrend) *parsed_pattern++ = META_ESCAPE + escape; break; - /* These escapes are converted to Unicode property tests when + /* These escapes may be converted to Unicode property tests when PCRE2_UCP is set. */ case ESC_d: @@ -3665,33 +3849,8 @@ while (ptr < ptrend) case ESC_S: case ESC_w: case ESC_W: - if ((options & PCRE2_UCP) == 0) - { - *parsed_pattern++ = META_ESCAPE + escape; - } - else - { - *parsed_pattern++ = META_ESCAPE + - ((escape == ESC_d || escape == ESC_s || escape == ESC_w)? - ESC_p : ESC_P); - switch(escape) - { - case ESC_d: - case ESC_D: - *parsed_pattern++ = (PT_PC << 16) | ucp_Nd; - break; - - case ESC_s: - case ESC_S: - *parsed_pattern++ = PT_SPACE << 16; - break; - - case ESC_w: - case ESC_W: - *parsed_pattern++ = PT_WORD << 16; - break; - } - } + parsed_pattern = handle_escdsw(escape, parsed_pattern, options, + xoptions); break; /* Explicit Unicode property matching */ @@ -3890,6 +4049,7 @@ while (ptr < ptrend) top_nest->nest_depth = nest_depth; top_nest->flags = NSF_ATOMICSR; top_nest->options = options & PARSE_TRACKED_OPTIONS; + top_nest->xoptions = xoptions & PARSE_TRACKED_EXTRA_OPTIONS; } break; #else /* SUPPORT_UNICODE */ @@ -4022,6 +4182,7 @@ while (ptr < ptrend) top_nest->nest_depth = nest_depth; top_nest->flags = 0; top_nest->options = options & PARSE_TRACKED_OPTIONS; + top_nest->xoptions = xoptions & PARSE_TRACKED_EXTRA_OPTIONS; /* Start of non-capturing group that resets the capture count for each branch. */ @@ -4036,24 +4197,28 @@ while (ptr < ptrend) ptr++; } - /* Scan for options imnsxJU to be set or unset. */ + /* Scan for options imnrsxJU to be set or unset. */ else { BOOL hyphenok = TRUE; uint32_t oldoptions = options; + uint32_t oldxoptions = xoptions; top_nest->reset_group = 0; top_nest->max_group = 0; set = unset = 0; optset = &set; + xset = xunset = 0; + xoptset = &xset; - /* ^ at the start unsets imnsx and disables the subsequent use of - */ + /* ^ at the start unsets irmnsx and disables the subsequent use of - */ if (ptr < ptrend && *ptr == CHAR_CIRCUMFLEX_ACCENT) { options &= ~(PCRE2_CASELESS|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| PCRE2_DOTALL|PCRE2_EXTENDED|PCRE2_EXTENDED_MORE); + xoptions &= ~(PCRE2_EXTRA_CASELESS_RESTRICT); hyphenok = FALSE; ptr++; } @@ -4071,9 +4236,51 @@ while (ptr < ptrend) goto FAILED; } optset = &unset; + xoptset = &xunset; hyphenok = FALSE; break; + /* There are some two-character sequences that start with 'a'. */ + + case CHAR_a: + if (ptr < ptrend) + { + if (*ptr == CHAR_D) + { + *xoptset |= PCRE2_EXTRA_ASCII_BSD; + ptr++; + break; + } + if (*ptr == CHAR_P) + { + *xoptset |= (PCRE2_EXTRA_ASCII_POSIX|PCRE2_EXTRA_ASCII_DIGIT); + ptr++; + break; + } + if (*ptr == CHAR_S) + { + *xoptset |= PCRE2_EXTRA_ASCII_BSS; + ptr++; + break; + } + if (*ptr == CHAR_T) + { + *xoptset |= PCRE2_EXTRA_ASCII_DIGIT; + ptr++; + break; + } + if (*ptr == CHAR_W) + { + *xoptset |= PCRE2_EXTRA_ASCII_BSW; + ptr++; + break; + } + } + *xoptset |= PCRE2_EXTRA_ASCII_BSD|PCRE2_EXTRA_ASCII_BSS| + PCRE2_EXTRA_ASCII_BSW| + PCRE2_EXTRA_ASCII_DIGIT|PCRE2_EXTRA_ASCII_POSIX; + break; + case CHAR_J: /* Record that it changed in the external options */ *optset |= PCRE2_DUPNAMES; cb->external_flags |= PCRE2_JCHANGED; @@ -4082,6 +4289,7 @@ while (ptr < ptrend) case CHAR_i: *optset |= PCRE2_CASELESS; break; case CHAR_m: *optset |= PCRE2_MULTILINE; break; case CHAR_n: *optset |= PCRE2_NO_AUTO_CAPTURE; break; + case CHAR_r: *xoptset|= PCRE2_EXTRA_CASELESS_RESTRICT; break; case CHAR_s: *optset |= PCRE2_DOTALL; break; case CHAR_U: *optset |= PCRE2_UNGREEDY; break; @@ -4112,6 +4320,7 @@ while (ptr < ptrend) unset |= PCRE2_EXTENDED_MORE; options = (options | set) & (~unset); + xoptions = (xoptions | xset) & (~xunset); /* If the options ended with ')' this is not the start of a nested group with option changes, so the options change at this level. @@ -4132,10 +4341,11 @@ while (ptr < ptrend) /* If nothing changed, no need to record. */ - if (options != oldoptions) + if (options != oldoptions || xoptions != oldxoptions) { *parsed_pattern++ = META_OPTIONS; *parsed_pattern++ = options; + *parsed_pattern++ = xoptions; } } /* End options processing */ break; /* End default case after (? */ @@ -4605,6 +4815,7 @@ while (ptr < ptrend) top_nest->nest_depth = nest_depth; top_nest->flags = NSF_CONDASSERT; top_nest->options = options & PARSE_TRACKED_OPTIONS; + top_nest->xoptions = xoptions & PARSE_TRACKED_EXTRA_OPTIONS; } break; @@ -4738,6 +4949,7 @@ while (ptr < ptrend) if (top_nest != NULL && top_nest->nest_depth == nest_depth) { options = (options & ~PARSE_TRACKED_OPTIONS) | top_nest->options; + xoptions = (xoptions & ~PARSE_TRACKED_EXTRA_OPTIONS) | top_nest->xoptions; if ((top_nest->flags & NSF_RESET) != 0 && top_nest->max_group > cb->bracount) cb->bracount = top_nest->max_group; @@ -4780,12 +4992,12 @@ parsed_pattern = manage_callouts(ptr, &previous_callout, auto_callout, /* Insert trailing items for word and line matching (features provided for the benefit of pcre2grep). */ -if ((extra_options & PCRE2_EXTRA_MATCH_LINE) != 0) +if ((xoptions & PCRE2_EXTRA_MATCH_LINE) != 0) { *parsed_pattern++ = META_KET; *parsed_pattern++ = META_DOLLAR; } -else if ((extra_options & PCRE2_EXTRA_MATCH_WORD) != 0) +else if ((xoptions & PCRE2_EXTRA_MATCH_WORD) != 0) { *parsed_pattern++ = META_KET; *parsed_pattern++ = META_ESCAPE + ESC_b; @@ -4862,6 +5074,8 @@ for (;;) case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: if (!skipassert) return code; /* Fall through */ @@ -4913,7 +5127,8 @@ for (;;) * Get othercase range * *************************************************/ -/* This function is passed the start and end of a class range in UCP mode. It +/* This function is passed the start and end of a class range in UCP mode. For +single characters the range may be just one character long. The function searches up the characters, looking for ranges of characters in the "other" case. Each call returns the next one, updating the start address. A character with multiple other cases is returned on its own with a special return value. @@ -4923,31 +5138,44 @@ Arguments: d end value ocptr where to put start of othercase range odptr where to put end of othercase range + restricted TRUE if caseless restriction applies Yield: -1 when no more 0 when a range is returned - >0 the CASESET offset for char with multiple other cases - in this case, ocptr contains the original + >0 the CASESET offset for char with multiple other cases; + for this return, *ocptr contains the original */ static int get_othercase_range(uint32_t *cptr, uint32_t d, uint32_t *ocptr, - uint32_t *odptr) + uint32_t *odptr, BOOL restricted) { uint32_t c, othercase, next; unsigned int co; /* Find the first character that has an other case. If it has multiple other -cases, return its case offset value. */ +cases, return its case offset value. When CASELESS_RESTRICT is set, ignore the +multi-case entries that begin with ASCII values. In 32-bit mode, a value +greater than the Unicode maximum ends the range. */ for (c = *cptr; c <= d; c++) { - if ((co = UCD_CASESET(c)) != 0) +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c > MAX_UTF_CODE_POINT) return -1; +#endif + if ((co = UCD_CASESET(c)) != 0 && + (!restricted || PRIV(ucd_caseless_sets)[co] > 127)) { *ocptr = c++; /* Character that has the set */ *cptr = c; /* Rest of input range */ return (int)co; } + + /* This is not a valid multiple-case character. Check that the single other + case is different to the original. We don't need to check "restricted" here + because the non-ASCII characters with multiple cases that include an ASCII + character don't have a different "othercase". */ + if ((othercase = UCD_OTHERCASE(c)) != c) break; } @@ -4988,7 +5216,8 @@ add_to_class(). Arguments: classbits the bit map for characters < 256 uchardptr points to the pointer for extra data - options the options word + options the options bits + xoptions the extra options bits cb compile data start start of range character end end of range character @@ -4999,7 +5228,8 @@ Returns: the number of < 256 characters added static unsigned int add_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr, - uint32_t options, compile_block *cb, uint32_t start, uint32_t end) + uint32_t options, uint32_t xoptions, compile_block *cb, uint32_t start, + uint32_t end) { uint32_t c; uint32_t classbits_end = (end <= 0xff ? end : 0xff); @@ -5007,8 +5237,8 @@ unsigned int n8 = 0; /* If caseless matching is required, scan the range and process alternate cases. In Unicode, there are 8-bit characters that have alternate cases that -are greater than 255 and vice-versa. Sometimes we can just extend the original -range. */ +are greater than 255 and vice-versa (though these may be ignored if caseless +restriction is in force). Sometimes we can just extend the original range. */ if ((options & PCRE2_CASELESS) != 0) { @@ -5021,20 +5251,23 @@ if ((options & PCRE2_CASELESS) != 0) options &= ~PCRE2_CASELESS; /* Remove for recursive calls */ c = start; - while ((rc = get_othercase_range(&c, end, &oc, &od)) >= 0) + while ((rc = get_othercase_range(&c, end, &oc, &od, + (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)) >= 0) { /* Handle a single character that has more than one other case. */ - if (rc > 0) n8 += add_list_to_class_internal(classbits, uchardptr, options, cb, - PRIV(ucd_caseless_sets) + rc, oc); + if (rc > 0) n8 += add_list_to_class_internal(classbits, uchardptr, + options, xoptions, cb, PRIV(ucd_caseless_sets) + rc, oc); /* Do nothing if the other case range is within the original range. */ - else if (oc >= cb->class_range_start && od <= cb->class_range_end) continue; + else if (oc >= cb->class_range_start && od <= cb->class_range_end) + continue; - /* Extend the original range if there is overlap, noting that if oc < c, we - can't have od > end because a subrange is always shorter than the basic - range. Otherwise, use a recursive call to add the additional range. */ + /* Extend the original range if there is overlap, noting that if oc < c, + we can't have od > end because a subrange is always shorter than the + basic range. Otherwise, use a recursive call to add the additional range. + */ else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */ else if (od > end && oc <= end + 1) @@ -5042,10 +5275,13 @@ if ((options & PCRE2_CASELESS) != 0) end = od; /* Extend upwards */ if (end > classbits_end) classbits_end = (end <= 0xff ? end : 0xff); } - else n8 += add_to_class_internal(classbits, uchardptr, options, cb, oc, od); + else n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, + cb, oc, od); } } else +#else + (void)xoptions; /* Avoid compiler warning */ #endif /* SUPPORT_UNICODE */ /* Not UTF mode */ @@ -5141,7 +5377,8 @@ add_to_class_internal(), with which it is mutually recursive. Arguments: classbits the bit map for characters < 256 uchardptr points to the pointer for extra data - options the options word + options the options bits + xoptions the extra options bits cb contains pointers to tables etc. p points to row of 32-bit values, terminated by NOTACHAR except character to omit; this is used when adding lists of @@ -5154,7 +5391,8 @@ Returns: the number of < 256 characters added static unsigned int add_list_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr, - uint32_t options, compile_block *cb, const uint32_t *p, unsigned int except) + uint32_t options, uint32_t xoptions, compile_block *cb, const uint32_t *p, + unsigned int except) { unsigned int n8 = 0; while (p[0] < NOTACHAR) @@ -5163,7 +5401,8 @@ while (p[0] < NOTACHAR) if (p[0] != except) { while(p[n+1] == p[0] + n + 1) n++; - n8 += add_to_class_internal(classbits, uchardptr, options, cb, p[0], p[n]); + n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, cb, + p[0], p[n]); } p += n + 1; } @@ -5183,7 +5422,8 @@ to avoid duplication when handling case-independence. Arguments: classbits the bit map for characters < 256 uchardptr points to the pointer for extra data - options the options word + options the options bits + xoptions the extra options bits cb compile data start start of range character end end of range character @@ -5194,11 +5434,12 @@ Returns: the number of < 256 characters added static unsigned int add_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, - compile_block *cb, uint32_t start, uint32_t end) + uint32_t xoptions, compile_block *cb, uint32_t start, uint32_t end) { cb->class_range_start = start; cb->class_range_end = end; -return add_to_class_internal(classbits, uchardptr, options, cb, start, end); +return add_to_class_internal(classbits, uchardptr, options, xoptions, cb, + start, end); } @@ -5215,7 +5456,8 @@ case-independence. Arguments: classbits the bit map for characters < 256 uchardptr points to the pointer for extra data - options the options word + options the options bits + xoptions the extra options bits cb contains pointers to tables etc. p points to row of 32-bit values, terminated by NOTACHAR except character to omit; this is used when adding lists of @@ -5228,7 +5470,7 @@ Returns: the number of < 256 characters added static unsigned int add_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, - compile_block *cb, const uint32_t *p, unsigned int except) + uint32_t xoptions, compile_block *cb, const uint32_t *p, unsigned int except) { unsigned int n8 = 0; while (p[0] < NOTACHAR) @@ -5239,7 +5481,8 @@ while (p[0] < NOTACHAR) while(p[n+1] == p[0] + n + 1) n++; cb->class_range_start = p[0]; cb->class_range_end = p[n]; - n8 += add_to_class_internal(classbits, uchardptr, options, cb, p[0], p[n]); + n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, cb, + p[0], p[n]); } p += n + 1; } @@ -5258,7 +5501,8 @@ vertical whitespace to a class. The list must be in order. Arguments: classbits the bit map for characters < 256 uchardptr points to the pointer for extra data - options the options word + options the options bits + xoptions the extra options bits cb contains pointers to tables etc. p points to row of 32-bit values, terminated by NOTACHAR @@ -5268,16 +5512,16 @@ Returns: the number of < 256 characters added static unsigned int add_not_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, - uint32_t options, compile_block *cb, const uint32_t *p) + uint32_t options, uint32_t xoptions, compile_block *cb, const uint32_t *p) { BOOL utf = (options & PCRE2_UTF) != 0; unsigned int n8 = 0; if (p[0] > 0) - n8 += add_to_class(classbits, uchardptr, options, cb, 0, p[0] - 1); + n8 += add_to_class(classbits, uchardptr, options, xoptions, cb, 0, p[0] - 1); while (p[0] < NOTACHAR) { while (p[1] == p[0] + 1) p++; - n8 += add_to_class(classbits, uchardptr, options, cb, p[0] + 1, + n8 += add_to_class(classbits, uchardptr, options, xoptions, cb, p[0] + 1, (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1); p++; } @@ -5368,6 +5612,7 @@ real compile phase. The value of lengthptr distinguishes the two phases. Arguments: optionsptr pointer to the option bits + xoptionsptr pointer to the extra option bits codeptr points to the pointer to the current code point pptrptr points to the current parsed pattern pointer errorcodeptr points to error code variable @@ -5376,6 +5621,7 @@ Arguments: reqcuptr place to put the last required code unit reqcuflagsptr place to put the last required code unit flags bcptr points to current branch chain + open_caps points to current capitem cb contains pointers to tables etc. lengthptr NULL during the real compile phase points to length accumulator during pre-compile phase @@ -5386,9 +5632,10 @@ Returns: 0 There's been an error, *errorcodeptr is non-zero */ static int -compile_branch(uint32_t *optionsptr, PCRE2_UCHAR **codeptr, uint32_t **pptrptr, - int *errorcodeptr, uint32_t *firstcuptr, uint32_t *firstcuflagsptr, - uint32_t *reqcuptr, uint32_t *reqcuflagsptr, branch_chain *bcptr, +compile_branch(uint32_t *optionsptr, uint32_t *xoptionsptr, + PCRE2_UCHAR **codeptr, uint32_t **pptrptr, int *errorcodeptr, + uint32_t *firstcuptr, uint32_t *firstcuflagsptr, uint32_t *reqcuptr, + uint32_t *reqcuflagsptr, branch_chain *bcptr, open_capitem *open_caps, compile_block *cb, PCRE2_SIZE *lengthptr) { int bravalue = 0; @@ -5398,6 +5645,7 @@ uint32_t repeat_min = 0, repeat_max = 0; /* To please picky compilers */ uint32_t greedy_default, greedy_non_default; uint32_t repeat_type, op_type; uint32_t options = *optionsptr; /* May change dynamically */ +uint32_t xoptions = *xoptionsptr; /* May change dynamically */ uint32_t firstcu, reqcu; uint32_t zeroreqcu, zerofirstcu; uint32_t escape; @@ -5423,8 +5671,8 @@ const uint8_t *cbits = cb->cbits; uint8_t classbits[32]; /* We can fish out the UTF setting once and for all into a BOOL, but we must -not do this for other options (e.g. PCRE2_EXTENDED) because they may change -dynamically as we process the pattern. */ +not do this for other options (e.g. PCRE2_EXTENDED) that may change dynamically +as we process the pattern. */ #ifdef SUPPORT_UNICODE BOOL utf = (options & PCRE2_UTF) != 0; @@ -5633,8 +5881,8 @@ for (;; pptr++) If the class contains characters outside the 0-255 range, a different opcode is compiled. It may optionally have a bit map for characters < 256, - but those above are are explicitly listed afterwards. A flag code unit - tells whether the bitmap is present, and whether this is a negated class or + but those above are explicitly listed afterwards. A flag code unit tells + whether the bitmap is present, and whether this is a negated class or not. */ case META_CLASS_NOT: @@ -5675,11 +5923,14 @@ for (;; pptr++) /* For caseless UTF or UCP mode, check whether this character has more than one other case. If so, generate a special OP_NOTPROP item instead of - OP_NOTI. */ + OP_NOTI. When restricted by PCRE2_EXTRA_CASELESS_RESTRICT, ignore any + caseless set that starts with an ASCII character. */ #ifdef SUPPORT_UNICODE if ((utf||ucp) && (options & PCRE2_CASELESS) != 0 && - (d = UCD_CASESET(c)) != 0) + (d = UCD_CASESET(c)) != 0 && + ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) == 0 || + PRIV(ucd_caseless_sets)[d] > 127)) { *code++ = OP_NOTPROP; *code++ = PT_CLIST; @@ -5687,7 +5938,7 @@ for (;; pptr++) break; /* We are finished with this class */ } #endif - /* Char has only one other case, or UCP not available */ + /* Char has only one other (usable) case, or UCP not available */ *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT; code += PUTCHAR(c, code); @@ -5697,7 +5948,9 @@ for (;; pptr++) /* Handle character classes that contain more than just one literal character. If there are exactly two characters in a positive class, see if they are case partners. This can be optimized to generate a caseless single - character match (which also sets first/required code units if relevant). */ + character match (which also sets first/required code units if relevant). + When casing restrictions apply, ignore a caseless set if both characters + are ASCII. */ if (meta == META_CLASS && pptr[1] < META_END && pptr[2] < META_END && pptr[3] == META_CLASS_END) @@ -5705,7 +5958,9 @@ for (;; pptr++) uint32_t c = pptr[1]; #ifdef SUPPORT_UNICODE - if (UCD_CASESET(c) == 0) + if (UCD_CASESET(c) == 0 || + ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 && + c < 128 && pptr[2] < 128)) #endif { uint32_t d; @@ -5797,41 +6052,45 @@ for (;; pptr++) XCL_PROP/XCL_NOTPROP directly, which is done here. */ #ifdef SUPPORT_UNICODE - if ((options & PCRE2_UCP) != 0) switch(posix_class) + if ((options & PCRE2_UCP) != 0 && + (xoptions & PCRE2_EXTRA_ASCII_POSIX) == 0) { - case PC_GRAPH: - case PC_PRINT: - case PC_PUNCT: - *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; - *class_uchardata++ = (PCRE2_UCHAR) - ((posix_class == PC_GRAPH)? PT_PXGRAPH : - (posix_class == PC_PRINT)? PT_PXPRINT : PT_PXPUNCT); - *class_uchardata++ = 0; - xclass_has_prop = TRUE; - goto CONTINUE_CLASS; + switch(posix_class) + { + case PC_GRAPH: + case PC_PRINT: + case PC_PUNCT: + *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; + *class_uchardata++ = (PCRE2_UCHAR) + ((posix_class == PC_GRAPH)? PT_PXGRAPH : + (posix_class == PC_PRINT)? PT_PXPRINT : PT_PXPUNCT); + *class_uchardata++ = 0; + xclass_has_prop = TRUE; + goto CONTINUE_CLASS; - /* For the other POSIX classes (ascii, xdigit) we are going to - fall through to the non-UCP case and build a bit map for - characters with code points less than 256. However, if we are in - a negated POSIX class, characters with code points greater than - 255 must either all match or all not match, depending on whether - the whole class is not or is negated. For example, for - [[:^ascii:]... they must all match, whereas for [^[:^xdigit:]... - they must not. + /* For the other POSIX classes (ex: ascii) we are going to + fall through to the non-UCP case and build a bit map for + characters with code points less than 256. However, if we are in + a negated POSIX class, characters with code points greater than + 255 must either all match or all not match, depending on whether + the whole class is not or is negated. For example, for + [[:^ascii:]... they must all match, whereas for [^[:^ascii:]... + they must not. - In the special case where there are no xclass items, this is - automatically handled by the use of OP_CLASS or OP_NCLASS, but an - explicit range is needed for OP_XCLASS. Setting a flag here - causes the range to be generated later when it is known that - OP_XCLASS is required. In the 8-bit library this is relevant only in - utf mode, since no wide characters can exist otherwise. */ + In the special case where there are no xclass items, this is + automatically handled by the use of OP_CLASS or OP_NCLASS, but an + explicit range is needed for OP_XCLASS. Setting a flag here + causes the range to be generated later when it is known that + OP_XCLASS is required. In the 8-bit library this is relevant only in + utf mode, since no wide characters can exist otherwise. */ - default: + default: #if PCRE2_CODE_UNIT_WIDTH == 8 - if (utf) + if (utf) #endif - match_all_or_no_wide_chars |= local_negate; - break; + match_all_or_no_wide_chars |= local_negate; + break; + } } #endif /* SUPPORT_UNICODE */ @@ -5957,22 +6216,24 @@ for (;; pptr++) case ESC_h: (void)add_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, cb, PRIV(hspace_list), NOTACHAR); + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(hspace_list), + NOTACHAR); break; case ESC_H: (void)add_not_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, cb, PRIV(hspace_list)); + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(hspace_list)); break; case ESC_v: (void)add_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, cb, PRIV(vspace_list), NOTACHAR); + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(vspace_list), + NOTACHAR); break; case ESC_V: (void)add_not_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, cb, PRIV(vspace_list)); + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(vspace_list)); break; /* If Unicode is not supported, \P and \p are not allowed and are @@ -6046,32 +6307,32 @@ for (;; pptr++) if (C <= CHAR_i) { class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, C + uc, - ((D < CHAR_i)? D : CHAR_i) + uc); + add_to_class(classbits, &class_uchardata, options, xoptions, + cb, C + uc, ((D < CHAR_i)? D : CHAR_i) + uc); C = CHAR_j; } if (C <= D && C <= CHAR_r) { class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, C + uc, - ((D < CHAR_r)? D : CHAR_r) + uc); + add_to_class(classbits, &class_uchardata, options, xoptions, + cb, C + uc, ((D < CHAR_r)? D : CHAR_r) + uc); C = CHAR_s; } if (C <= D) { class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, C + uc, - D + uc); + add_to_class(classbits, &class_uchardata, options, xoptions, + cb, C + uc, D + uc); } } else #endif /* Not an EBCDIC special range */ - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, c, d); + class_has_8bitchar += add_to_class(classbits, &class_uchardata, + options, xoptions, cb, c, d); goto CONTINUE_CLASS; /* Go get the next char in the class */ } /* End of range handling */ @@ -6079,7 +6340,8 @@ for (;; pptr++) /* Handle a single character. */ class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, meta, meta); + add_to_class(classbits, &class_uchardata, options, xoptions, cb, + meta, meta); } /* Continue to the next item in the class. */ @@ -6124,11 +6386,11 @@ for (;; pptr++) characters > 255 are in or not in the class, so any that were explicitly given as well can be ignored. - In the UCP case, if certain negated POSIX classes ([:^ascii:] or - [^:xdigit:]) were present in a class, we either have to match or not match - all wide characters (depending on whether the whole class is or is not - negated). This requirement is indicated by match_all_or_no_wide_chars being - true. We do this by including an explicit range, which works in both cases. + In the UCP case, if certain negated POSIX classes (ex: [:^ascii:]) were + were present in a class, we either have to match or not match all wide + characters (depending on whether the whole class is or is not negated). + This requirement is indicated by match_all_or_no_wide_chars being true. + We do this by including an explicit range, which works in both cases. This applies only in UTF and 16-bit and 32-bit non-UTF modes, since there cannot be any wide characters in 8-bit non-UTF mode. @@ -6232,7 +6494,7 @@ for (;; pptr++) case META_ACCEPT: cb->had_accept = had_accept = TRUE; - for (oc = cb->open_caps; + for (oc = open_caps; oc != NULL && oc->assert_depth >= cb->assert_depth; oc = oc->next) { @@ -6317,6 +6579,7 @@ for (;; pptr++) case META_OPTIONS: *optionsptr = options = *(++pptr); + *xoptionsptr = xoptions = *(++pptr); greedy_default = ((options & PCRE2_UNGREEDY) != 0); greedy_non_default = greedy_default ^ 1; req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0; @@ -6562,7 +6825,8 @@ for (;; pptr++) if ((group_return = compile_regex( - options, /* The option state */ + options, /* The options state */ + xoptions, /* The extra options state */ &tempcode, /* Where to put code (updated) */ &pptr, /* Input pointer (updated) */ errorcodeptr, /* Where to put an error message */ @@ -6572,6 +6836,7 @@ for (;; pptr++) &subreqcu, /* For possible last char */ &subreqcuflags, bcptr, /* Current branch chain */ + open_caps, /* Pointer to capture stack */ cb, /* Compile data block */ (lengthptr == NULL)? NULL : /* Actual compile phase */ &length_prevgroup /* Pre-compile phase */ @@ -7112,15 +7377,12 @@ for (;; pptr++) /* In the pre-compile phase, we don't actually do the replication. We just adjust the length as if we had. Do some paranoid checks for - potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit - integer type when available, otherwise double. */ + potential integer overflow. */ if (lengthptr != NULL) { - PCRE2_SIZE delta = replicate*(1 + LINK_SIZE); - if ((INT64_OR_DOUBLE)replicate* - (INT64_OR_DOUBLE)(1 + LINK_SIZE) > - (INT64_OR_DOUBLE)INT_MAX || + PCRE2_SIZE delta; + if (PRIV(ckd_smul)(&delta, replicate, 1 + LINK_SIZE) || OFLOW_MAX - *lengthptr < delta) { *errorcodeptr = ERR20; @@ -7282,15 +7544,12 @@ for (;; pptr++) { /* In the pre-compile phase, we don't actually do the replication. We just adjust the length as if we had. Do some paranoid checks for - potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit - integer type when available, otherwise double. */ + potential integer overflow. */ if (lengthptr != NULL) { - PCRE2_SIZE delta = (repeat_min - 1)*length_prevgroup; - if ((INT64_OR_DOUBLE)(repeat_min - 1)* - (INT64_OR_DOUBLE)length_prevgroup > - (INT64_OR_DOUBLE)INT_MAX || + PCRE2_SIZE delta; + if (PRIV(ckd_smul)(&delta, repeat_min - 1, length_prevgroup) || OFLOW_MAX - *lengthptr < delta) { *errorcodeptr = ERR20; @@ -7334,21 +7593,19 @@ for (;; pptr++) just adjust the length as if we had. For each repetition we must add 1 to the length for BRAZERO and for all but the last repetition we must add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some - paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type - is a 64-bit integer type when available, otherwise double. */ + paranoid checks to avoid integer overflow. */ if (lengthptr != NULL && repeat_max > 0) { - PCRE2_SIZE delta = repeat_max*(length_prevgroup + 1 + 2 + 2*LINK_SIZE) - - 2 - 2*LINK_SIZE; /* Last one doesn't nest */ - if ((INT64_OR_DOUBLE)repeat_max * - (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE) - > (INT64_OR_DOUBLE)INT_MAX || - OFLOW_MAX - *lengthptr < delta) + PCRE2_SIZE delta; + if (PRIV(ckd_smul)(&delta, repeat_max, + length_prevgroup + 1 + 2 + 2*LINK_SIZE) || + OFLOW_MAX + (2 + 2*LINK_SIZE) - *lengthptr < delta) { *errorcodeptr = ERR20; return 0; } + delta -= (2 + 2*LINK_SIZE); /* Last one doesn't nest */ *lengthptr += delta; } @@ -7901,7 +8158,7 @@ for (;; pptr++) done. However, there's an option, in case anyone was relying on it. */ if (cb->assert_depth > 0 && meta_arg == ESC_K && - (cb->cx->extra_options & PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) == 0) + (xoptions & PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) == 0) { *errorcodeptr = ERR99; return 0; @@ -7909,23 +8166,41 @@ for (;; pptr++) /* For the rest (including \X when Unicode is supported - if not it's faulted at parse time), the OP value is the escape value when PCRE2_UCP is - not set; if it is set, these escapes do not show up here because they are - converted into Unicode property tests in parse_regex(). Note that \b and \B - do a one-character lookbehind, and \A also behaves as if it does. */ + not set; if it is set, most of them do not show up here because they are + converted into Unicode property tests in parse_regex(). - if (meta_arg == ESC_C) cb->external_flags |= PCRE2_HASBKC; /* Record */ - if ((meta_arg == ESC_b || meta_arg == ESC_B || meta_arg == ESC_A) && - cb->max_lookbehind == 0) - cb->max_lookbehind = 1; + In non-UTF mode, and for both 32-bit modes, we turn \C into OP_ALLANY + instead of OP_ANYBYTE so that it works in DFA mode and in lookbehinds. + There are special UCP codes for \B and \b which are used in UCP mode unless + "word" matching is being forced to ASCII. - /* In non-UTF mode, and for both 32-bit modes, we turn \C into OP_ALLANY - instead of OP_ANYBYTE so that it works in DFA mode and in lookbehinds. */ + Note that \b and \B do a one-character lookbehind, and \A also behaves as + if it does. */ + switch(meta_arg) + { + case ESC_C: + cb->external_flags |= PCRE2_HASBKC; /* Record */ #if PCRE2_CODE_UNIT_WIDTH == 32 - *code++ = (meta_arg == ESC_C)? OP_ALLANY : meta_arg; + meta_arg = OP_ALLANY; #else - *code++ = (!utf && meta_arg == ESC_C)? OP_ALLANY : meta_arg; + if (!utf) meta_arg = OP_ALLANY; #endif + break; + + case ESC_B: + case ESC_b: + if ((options & PCRE2_UCP) != 0 && (xoptions & PCRE2_EXTRA_ASCII_BSW) == 0) + meta_arg = (meta_arg == ESC_B)? OP_NOT_UCP_WORD_BOUNDARY : + OP_UCP_WORD_BOUNDARY; + /* Fall through */ + + case ESC_A: + if (cb->max_lookbehind == 0) cb->max_lookbehind = 1; + break; + } + + *code++ = meta_arg; break; /* End META_ESCAPE */ @@ -7953,13 +8228,16 @@ for (;; pptr++) /* For caseless UTF or UCP mode, check whether this character has more than one other case. If so, generate a special OP_PROP item instead of OP_CHARI. - */ + When casing restrictions apply, ignore caseless sets that start with an + ASCII character. */ #ifdef SUPPORT_UNICODE if ((utf||ucp) && (options & PCRE2_CASELESS) != 0) { uint32_t caseset = UCD_CASESET(meta); - if (caseset != 0) + if (caseset != 0 && + ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) == 0 || + PRIV(ucd_caseless_sets)[caseset] > 127)) { *code++ = OP_PROP; *code++ = PT_CLIST; @@ -8075,6 +8353,7 @@ the two phases. Arguments: options option bits, including any changes for this subpattern + xoptions extra option bits, ditto codeptr -> the address of the current code pointer pptrptr -> the address of the current parsed pattern pointer errorcodeptr -> pointer to error code variable @@ -8094,10 +8373,11 @@ Returns: 0 There has been an error */ static int -compile_regex(uint32_t options, PCRE2_UCHAR **codeptr, uint32_t **pptrptr, - int *errorcodeptr, uint32_t skipunits, uint32_t *firstcuptr, - uint32_t *firstcuflagsptr, uint32_t *reqcuptr, uint32_t *reqcuflagsptr, - branch_chain *bcptr, compile_block *cb, PCRE2_SIZE *lengthptr) +compile_regex(uint32_t options, uint32_t xoptions, PCRE2_UCHAR **codeptr, + uint32_t **pptrptr, int *errorcodeptr, uint32_t skipunits, + uint32_t *firstcuptr, uint32_t *firstcuflagsptr, uint32_t *reqcuptr, + uint32_t *reqcuflagsptr, branch_chain *bcptr, open_capitem *open_caps, + compile_block *cb, PCRE2_SIZE *lengthptr) { PCRE2_UCHAR *code = *codeptr; PCRE2_UCHAR *last_branch = code; @@ -8109,6 +8389,7 @@ int okreturn = 1; uint32_t *pptr = *pptrptr; uint32_t firstcu, reqcu; uint32_t lookbehindlength; +uint32_t lookbehindminlength; uint32_t firstcuflags, reqcuflags; uint32_t branchfirstcu, branchreqcu; uint32_t branchfirstcuflags, branchreqcuflags; @@ -8151,9 +8432,10 @@ lookbehind = *code == OP_ASSERTBACK || if (lookbehind) { lookbehindlength = META_DATA(pptr[-1]); + lookbehindminlength = *pptr; pptr += SIZEOFFSET; } -else lookbehindlength = 0; +else lookbehindlength = lookbehindminlength = 0; /* If this is a capturing subpattern, add to the chain of open capturing items so that we can detect them if (*ACCEPT) is encountered. Note that only OP_CBRA @@ -8164,9 +8446,9 @@ if (*code == OP_CBRA) { capnumber = GET2(code, 1 + LINK_SIZE); capitem.number = capnumber; - capitem.next = cb->open_caps; + capitem.next = open_caps; capitem.assert_depth = cb->assert_depth; - cb->open_caps = &capitem; + open_caps = &capitem; } /* Offset is set zero to mark that this bracket is still open */ @@ -8180,22 +8462,39 @@ for (;;) { int branch_return; - /* Insert OP_REVERSE if this is as lookbehind assertion. */ + /* Insert OP_REVERSE or OP_VREVERSE if this is a lookbehind assertion. There + is only a single mimimum length for the whole assertion. When the mimimum + length is LOOKBEHIND_MAX it means that all branches are of fixed length, + though not necessarily the same length. In this case, the original OP_REVERSE + can be used. It can also be used if a branch in a variable length lookbehind + has the same maximum and minimum. Otherwise, use OP_VREVERSE, which has both + maximum and minimum values. */ if (lookbehind && lookbehindlength > 0) { - *code++ = OP_REVERSE; - PUTINC(code, 0, lookbehindlength); - length += 1 + LINK_SIZE; + if (lookbehindminlength == LOOKBEHIND_MAX || + lookbehindminlength == lookbehindlength) + { + *code++ = OP_REVERSE; + PUT2INC(code, 0, lookbehindlength); + length += 1 + IMM2_SIZE; + } + else + { + *code++ = OP_VREVERSE; + PUT2INC(code, 0, lookbehindminlength); + PUT2INC(code, 0, lookbehindlength); + length += 1 + 2*IMM2_SIZE; + } } /* Now compile the branch; in the pre-compile phase its length gets added into the length. */ if ((branch_return = - compile_branch(&options, &code, &pptr, errorcodeptr, &branchfirstcu, - &branchfirstcuflags, &branchreqcu, &branchreqcuflags, &bc, - cb, (lengthptr == NULL)? NULL : &length)) == 0) + compile_branch(&options, &xoptions, &code, &pptr, errorcodeptr, + &branchfirstcu, &branchfirstcuflags, &branchreqcu, &branchreqcuflags, + &bc, open_caps, cb, (lengthptr == NULL)? NULL : &length)) == 0) return 0; /* If a branch can match an empty string, so can the whole group. */ @@ -8293,10 +8592,6 @@ for (;;) PUT(code, 1, (int)(code - start_bracket)); code += 1 + LINK_SIZE; - /* If it was a capturing subpattern, remove the block from the chain. */ - - if (capnumber > 0) cb->open_caps = cb->open_caps->next; - /* Set values to pass back */ *codeptr = code; @@ -8339,8 +8634,8 @@ for (;;) code += 1 + LINK_SIZE; } - /* Set the lookbehind length (if not in a lookbehind the value will be zero) - and then advance past the vertical bar. */ + /* Set the maximum lookbehind length for the next branch (if not in a + lookbehind the value will be zero) and then advance past the vertical bar. */ lookbehindlength = META_DATA(*pptr); pptr++; @@ -9051,13 +9346,13 @@ return pptr; *************************************************/ /* This is called for nested groups within a branch of a lookbehind whose -length is being computed. If all the branches in the nested group have the same -length, that is OK. On entry, the pointer must be at the first element after -the group initializing code. On exit it points to OP_KET. Caching is used to -improve processing speed when the same capturing group occurs many times. +length is being computed. On entry, the pointer must be at the first element +after the group initializing code. On exit it points to OP_KET. Caching is used +to improve processing speed when the same capturing group occurs many times. Arguments: pptrptr pointer to pointer in the parsed pattern + minptr where to return the minimum length isinline FALSE if a reference or recursion; TRUE for inline group errcodeptr pointer to the errorcode lcptr pointer to the loop counter @@ -9065,15 +9360,17 @@ Arguments: recurses chain of recurse_check to catch mutual recursion cb pointer to the compile data -Returns: the group length or a negative number +Returns: the maximum group length or a negative number */ static int -get_grouplength(uint32_t **pptrptr, BOOL isinline, int *errcodeptr, int *lcptr, - int group, parsed_recurse_check *recurses, compile_block *cb) +get_grouplength(uint32_t **pptrptr, int *minptr, BOOL isinline, int *errcodeptr, + int *lcptr, int group, parsed_recurse_check *recurses, compile_block *cb) { -int branchlength; +uint32_t *gi = cb->groupinfo + 2 * group; +int branchlength, branchminlength; int grouplength = -1; +int groupminlength = INT_MAX; /* The cache can be used only if there is no possibility of there being two groups with the same number. We do not need to set the end pointer for a group @@ -9082,11 +9379,12 @@ an inline group. */ if (group > 0 && (cb->external_flags & PCRE2_DUPCAPUSED) == 0) { - uint32_t groupinfo = cb->groupinfo[group]; + uint32_t groupinfo = gi[0]; if ((groupinfo & GI_NOT_FIXED_LENGTH) != 0) return -1; if ((groupinfo & GI_SET_FIXED_LENGTH) != 0) { if (isinline) *pptrptr = parsed_skip(*pptrptr, PSKIP_KET); + *minptr = gi[1]; return groupinfo & GI_FIXED_LENGTH_MASK; } } @@ -9095,20 +9393,26 @@ if (group > 0 && (cb->external_flags & PCRE2_DUPCAPUSED) == 0) for(;;) { - branchlength = get_branchlength(pptrptr, errcodeptr, lcptr, recurses, cb); + branchlength = get_branchlength(pptrptr, &branchminlength, errcodeptr, lcptr, + recurses, cb); if (branchlength < 0) goto ISNOTFIXED; - if (grouplength == -1) grouplength = branchlength; - else if (grouplength != branchlength) goto ISNOTFIXED; + if (branchlength > grouplength) grouplength = branchlength; + if (branchminlength < groupminlength) groupminlength = branchminlength; if (**pptrptr == META_KET) break; *pptrptr += 1; /* Skip META_ALT */ } if (group > 0) - cb->groupinfo[group] |= (uint32_t)(GI_SET_FIXED_LENGTH | grouplength); + { + gi[0] |= (uint32_t)(GI_SET_FIXED_LENGTH | grouplength); + gi[1] = groupminlength; + } + +*minptr = groupminlength; return grouplength; ISNOTFIXED: -if (group > 0) cb->groupinfo[group] |= GI_NOT_FIXED_LENGTH; +if (group > 0) gi[0] |= GI_NOT_FIXED_LENGTH; return -1; } @@ -9118,27 +9422,30 @@ return -1; * Find length of a parsed branch * *************************************************/ -/* Return a fixed length for a branch in a lookbehind, giving an error if the -length is not fixed. On entry, *pptrptr points to the first element inside the -branch. On exit it is set to point to the ALT or KET. +/* Return fixed maximum and minimum lengths for a branch in a lookbehind, +giving an error if the length is not limited. On entry, *pptrptr points to the +first element inside the branch. On exit it is set to point to the ALT or KET. Arguments: pptrptr pointer to pointer in the parsed pattern + minptr where to return the minimum length errcodeptr pointer to error code lcptr pointer to loop counter recurses chain of recurse_check to catch mutual recursion cb pointer to compile block -Returns: the length, or a negative value on error +Returns: the maximum length, or a negative value on error */ static int -get_branchlength(uint32_t **pptrptr, int *errcodeptr, int *lcptr, +get_branchlength(uint32_t **pptrptr, int *minptr, int *errcodeptr, int *lcptr, parsed_recurse_check *recurses, compile_block *cb) { int branchlength = 0; -int grouplength; +int branchminlength = 0; +int grouplength, groupminlength; uint32_t lastitemlength = 0; +uint32_t lastitemminlength = 0; uint32_t *pptr = *pptrptr; PCRE2_SIZE offset; parsed_recurse_check this_recurse; @@ -9162,10 +9469,12 @@ for (;; pptr++) uint32_t escape; uint32_t group = 0; uint32_t itemlength = 0; + uint32_t itemminlength = 0; + uint32_t min, max; if (*pptr < META_END) { - itemlength = 1; + itemlength = itemminlength = 1; } else switch (META_CODE(*pptr)) @@ -9200,24 +9509,24 @@ for (;; pptr++) break; case META_OPTIONS: - pptr += 1; + pptr += 2; break; case META_BIGVALUE: - itemlength = 1; + itemlength = itemminlength = 1; pptr += 1; break; case META_CLASS: case META_CLASS_NOT: - itemlength = 1; + itemlength = itemminlength = 1; pptr = parsed_skip(pptr, PSKIP_CLASS); if (pptr == NULL) goto PARSED_SKIP_FAILED; break; case META_CLASS_EMPTY_NOT: case META_DOT: - itemlength = 1; + itemlength = itemminlength = 1; break; case META_CALLOUT_NUMBER: @@ -9228,14 +9537,19 @@ for (;; pptr++) pptr += 3 + SIZEOFFSET; break; - /* Only some escapes consume a character. Of those, \R and \X are never - allowed because they might match more than character. \C is allowed only in - 32-bit and non-UTF 8/16-bit modes. */ + /* Only some escapes consume a character. Of those, \R can match one or two + characters, but \X is never allowed because it matches an unknown number of + characters. \C is allowed only in 32-bit and non-UTF 8/16-bit modes. */ case META_ESCAPE: escape = META_DATA(*pptr); - if (escape == ESC_R || escape == ESC_X) return -1; - if (escape > ESC_b && escape < ESC_Z) + if (escape == ESC_X) return -1; + if (escape == ESC_R) + { + itemminlength = 1; + itemlength = 2; + } + else if (escape > ESC_b && escape < ESC_Z) { #if PCRE2_CODE_UNIT_WIDTH != 32 if ((cb->external_options & PCRE2_UTF) != 0 && escape == ESC_C) @@ -9244,7 +9558,7 @@ for (;; pptr++) return -1; } #endif - itemlength = 1; + itemlength = itemminlength = 1; if (escape == ESC_p || escape == ESC_P) pptr++; /* Skip prop data */ } break; @@ -9400,14 +9714,15 @@ for (;; pptr++) in the cache. */ gptr++; - grouplength = get_grouplength(&gptr, FALSE, errcodeptr, lcptr, group, - &this_recurse, cb); + grouplength = get_grouplength(&gptr, &groupminlength, FALSE, errcodeptr, + lcptr, group, &this_recurse, cb); if (grouplength < 0) { if (*errcodeptr == 0) goto ISNOTFIXED; return -1; /* Error already set */ } itemlength = grouplength; + itemminlength = groupminlength; break; /* A (DEFINE) group is never obeyed inline and so it does not contribute to @@ -9445,41 +9760,44 @@ for (;; pptr++) case META_SCRIPT_RUN: pptr++; CHECK_GROUP: - grouplength = get_grouplength(&pptr, TRUE, errcodeptr, lcptr, group, - recurses, cb); + grouplength = get_grouplength(&pptr, &groupminlength, TRUE, errcodeptr, + lcptr, group, recurses, cb); if (grouplength < 0) return -1; itemlength = grouplength; + itemminlength = groupminlength; break; + case META_QUERY: + case META_QUERY_PLUS: + case META_QUERY_QUERY: + min = 0; + max = 1; + goto REPETITION; + /* Exact repetition is OK; variable repetition is not. A repetition of zero must subtract the length that has already been added. */ case META_MINMAX: case META_MINMAX_PLUS: case META_MINMAX_QUERY: - if (pptr[1] == pptr[2]) + min = pptr[1]; + max = pptr[2]; + pptr += 2; + + REPETITION: + if (max != REPEAT_UNLIMITED) { - switch(pptr[1]) + if (lastitemlength != 0 && /* Should not occur, but just in case */ + max != 0 && + (INT_MAX - branchlength)/lastitemlength < max - 1) { - case 0: - branchlength -= lastitemlength; - break; - - case 1: - itemlength = 0; - break; - - default: /* Check for integer overflow */ - if (lastitemlength != 0 && /* Should not occur, but just in case */ - INT_MAX/lastitemlength < pptr[1] - 1) - { - *errcodeptr = ERR87; /* Integer overflow; lookbehind too big */ - return -1; - } - itemlength = (pptr[1] - 1) * lastitemlength; - break; + *errcodeptr = ERR87; /* Integer overflow; lookbehind too big */ + return -1; } - pptr += 2; + if (min == 0) branchminlength -= lastitemminlength; + else itemminlength = (min - 1) * lastitemminlength; + if (max == 0) branchlength -= lastitemlength; + else itemlength = (max - 1) * lastitemlength; break; } /* Fall through */ @@ -9493,7 +9811,9 @@ for (;; pptr++) } /* Add the item length to the branchlength, checking for integer overflow and - for the branch length exceeding the limit. */ + for the branch length exceeding the overall limit. Later, if there is at + least one variable-length branch in the group, there is a test for the + (smaller) variable-length branch length limit. */ if (INT_MAX - branchlength < (int)itemlength || (branchlength += itemlength) > LOOKBEHIND_MAX) @@ -9502,13 +9822,17 @@ for (;; pptr++) return -1; } + branchminlength += itemminlength; + /* Save this item length for use if the next item is a quantifier. */ lastitemlength = itemlength; + lastitemminlength = itemminlength; } EXIT: *pptrptr = pptr; +*minptr = branchminlength; return branchlength; PARSED_SKIP_FAILED: @@ -9523,9 +9847,9 @@ return -1; *************************************************/ /* This function is called for each lookbehind, to set the lengths in its -branches. An error occurs if any branch does not have a fixed length that is -less than the maximum (65535). On exit, the pointer must be left on the final -ket. +branches. An error occurs if any branch does not have a limited maximum length +that is less than the limit (65535). On exit, the pointer must be left on the +final ket. The function also maintains the max_lookbehind value. Any lookbehind branch that contains a nested lookbehind may actually look further back than the @@ -9548,16 +9872,27 @@ set_lookbehind_lengths(uint32_t **pptrptr, int *errcodeptr, int *lcptr, parsed_recurse_check *recurses, compile_block *cb) { PCRE2_SIZE offset; -int branchlength; uint32_t *bptr = *pptrptr; +uint32_t *gbptr = bptr; +int maxlength = 0; +int minlength = INT_MAX; +BOOL variable = FALSE; READPLUSOFFSET(offset, bptr); /* Offset for error messages */ *pptrptr += SIZEOFFSET; +/* Each branch can have a different maximum length, but we can keep only a +single minimum for the whole group, because there's nowhere to save individual +values in the META_ALT item. */ + do { + int branchlength, branchminlength; + *pptrptr += 1; - branchlength = get_branchlength(pptrptr, errcodeptr, lcptr, recurses, cb); + branchlength = get_branchlength(pptrptr, &branchminlength, errcodeptr, lcptr, + recurses, cb); + if (branchlength < 0) { /* The errorcode and offset may already be set from a nested lookbehind. */ @@ -9565,12 +9900,37 @@ do if (cb->erroroffset == PCRE2_UNSET) cb->erroroffset = offset; return FALSE; } + + if (branchlength != branchminlength) variable = TRUE; + if (branchminlength < minlength) minlength = branchminlength; + if (branchlength > maxlength) maxlength = branchlength; if (branchlength > cb->max_lookbehind) cb->max_lookbehind = branchlength; *bptr |= branchlength; /* branchlength never more than 65535 */ bptr = *pptrptr; } while (*bptr == META_ALT); +/* If any branch is of variable length, the whole lookbehind is of variable +length. If the maximum length of any branch exceeds the maximum for variable +lookbehinds, give an error. Otherwise, the minimum length is set in the word +that follows the original group META value. For a fixed-length lookbehind, this +is set to LOOKBEHIND_MAX, to indicate that each branch is of a fixed (but +possibly different) length. */ + +if (variable) + { + gbptr[1] = minlength; + if ((uint32_t)maxlength > cb->max_varlookbehind) + { + *errcodeptr = ERR100; + cb->erroroffset = offset; + return FALSE; + } + } +else gbptr[1] = LOOKBEHIND_MAX; + + +gbptr[1] = variable? minlength : LOOKBEHIND_MAX; return TRUE; } @@ -9703,7 +10063,6 @@ for (; *pptr != META_END; pptr++) break; case META_BIGVALUE: - case META_OPTIONS: case META_POSIX: case META_POSIX_NEG: pptr += 1; @@ -9712,6 +10071,7 @@ for (; *pptr != META_END; pptr++) case META_MINMAX: case META_MINMAX_QUERY: case META_MINMAX_PLUS: + case META_OPTIONS: pptr += 2; break; @@ -9820,12 +10180,15 @@ if (errorptr == NULL || erroroffset == NULL) return NULL; *errorptr = ERR0; *erroroffset = 0; -/* There must be a pattern! */ +/* There must be a pattern, but NULL is allowed with zero length. */ if (pattern == NULL) { - *errorptr = ERR16; - return NULL; + if (patlen == 0) pattern = (PCRE2_SPTR)""; else + { + *errorptr = ERR16; + return NULL; + } } /* A NULL compile context means "use a default context" */ @@ -9890,13 +10253,13 @@ cb.external_options = options; cb.groupinfo = stack_groupinfo; cb.had_recurse = FALSE; cb.lastcapture = 0; -cb.max_lookbehind = 0; +cb.max_lookbehind = 0; /* Max encountered */ +cb.max_varlookbehind = ccontext->max_varlookbehind; /* Limit */ cb.name_entry_size = 0; cb.name_table = NULL; cb.named_groups = named_groups; cb.named_group_list_size = NAMED_GROUP_LIST_SIZE; cb.names_found = 0; -cb.open_caps = NULL; cb.parens_depth = 0; cb.parsed_pattern = stack_parsed_pattern; cb.req_varyopt = 0; @@ -9949,7 +10312,7 @@ if ((options & PCRE2_LITERAL) == 0) for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++) { uint32_t c, pp; - pso *p = pso_list + i; + const pso *p = pso_list + i; if (patlen - skipatstart - 2 >= p->length && PRIV(strncmp_c8)(ptr + skipatstart + 2, (char *)(p->name), @@ -10158,39 +10521,36 @@ cb.parsed_pattern_end = cb.parsed_pattern + parsed_size_needed + 1; errorcode = parse_regex(ptr, cb.external_options, &has_lookbehind, &cb); if (errorcode != 0) goto HAD_CB_ERROR; -/* Workspace is needed to remember information about numbered groups: whether a -group can match an empty string and what its fixed length is. This is done to -avoid the possibility of recursive references causing very long compile times -when checking these features. Unnumbered groups do not have this exposure since -they cannot be referenced. We use an indexed vector for this purpose. If there -are sufficiently few groups, the default vector on the stack, as set up above, -can be used. Otherwise we have to get/free a special vector. The vector must be -initialized to zero. */ - -if (cb.bracount >= GROUPINFO_DEFAULT_SIZE) - { - cb.groupinfo = ccontext->memctl.malloc( - (cb.bracount + 1)*sizeof(uint32_t), ccontext->memctl.memory_data); - if (cb.groupinfo == NULL) - { - errorcode = ERR21; - cb.erroroffset = 0; - goto HAD_CB_ERROR; - } - } -memset(cb.groupinfo, 0, (cb.bracount + 1) * sizeof(uint32_t)); - -/* If there were any lookbehinds, scan the parsed pattern to figure out their -lengths. */ +/* If there are any lookbehinds, scan the parsed pattern to figure out their +lengths. Workspace is needed to remember whether numbered groups are or are not +of limited length, and if limited, what the minimum and maximum lengths are. +This caching saves re-computing the length of any group that is referenced more +than once, which is particularly relevant when recursion is involved. +Unnumbered groups do not have this exposure because they cannot be referenced. +If there are sufficiently few groups, the default index vector on the stack, as +set up above, can be used. Otherwise we have to get/free some heap memory. The +vector must be initialized to zero. */ if (has_lookbehind) { int loopcount = 0; + if (cb.bracount >= GROUPINFO_DEFAULT_SIZE/2) + { + cb.groupinfo = ccontext->memctl.malloc( + (2 * (cb.bracount + 1))*sizeof(uint32_t), ccontext->memctl.memory_data); + if (cb.groupinfo == NULL) + { + errorcode = ERR21; + cb.erroroffset = 0; + goto HAD_CB_ERROR; + } + } + memset(cb.groupinfo, 0, (2 * cb.bracount + 1) * sizeof(uint32_t)); errorcode = check_lookbehinds(cb.parsed_pattern, NULL, NULL, &cb, &loopcount); if (errorcode != 0) goto HAD_CB_ERROR; } -/* For debugging, there is a function that shows the parsed data vector. */ +/* For debugging, there is a function that shows the parsed pattern vector. */ #ifdef DEBUG_SHOW_PARSED fprintf(stderr, "+++ Pre-scan complete:\n"); @@ -10227,8 +10587,9 @@ pptr = cb.parsed_pattern; code = cworkspace; *code = OP_BRA; -(void)compile_regex(cb.external_options, &code, &pptr, &errorcode, 0, &firstcu, - &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, &length); +(void)compile_regex(cb.external_options, ccontext->extra_options, &code, &pptr, + &errorcode, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, NULL, + &cb, &length); if (errorcode != 0) goto HAD_CB_ERROR; /* Offset is in cb.erroroffset */ @@ -10306,7 +10667,6 @@ cb.start_code = codestart; cb.req_varyopt = 0; cb.had_accept = FALSE; cb.had_pruneorskip = FALSE; -cb.open_caps = NULL; /* If any named groups were found, create the name/number table from the list created in the pre-pass. */ @@ -10325,8 +10685,9 @@ of the function here. */ pptr = cb.parsed_pattern; code = (PCRE2_UCHAR *)codestart; *code = OP_BRA; -regexrc = compile_regex(re->overall_options, &code, &pptr, &errorcode, 0, - &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, NULL); +regexrc = compile_regex(re->overall_options, ccontext->extra_options, &code, + &pptr, &errorcode, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, + NULL, &cb, NULL); if (regexrc < 0) re->flags |= PCRE2_MATCH_EMPTY; re->top_bracket = cb.bracount; re->top_backref = cb.top_backref; diff --git a/src/3rdparty/pcre2/src/pcre2_context.c b/src/3rdparty/pcre2/src/pcre2_context.c index 8e05ede50c2..0bc2ea0b047 100644 --- a/src/3rdparty/pcre2/src/pcre2_context.c +++ b/src/3rdparty/pcre2/src/pcre2_context.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -139,7 +139,9 @@ const pcre2_compile_context PRIV(default_compile_context) = { BSR_DEFAULT, /* Backslash R default */ NEWLINE_DEFAULT, /* Newline convention */ PARENS_NEST_LIMIT, /* As it says */ - 0 }; /* Extra options */ + 0, /* Extra options */ + MAX_VARLOOKBEHIND /* As it says */ + }; /* The create function copies the default into the new memory, but must override the default memory handling functions if a gcontext was provided. */ @@ -228,49 +230,48 @@ return ccontext; PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION pcre2_general_context_copy(pcre2_general_context *gcontext) { -pcre2_general_context *new = +pcre2_general_context *newcontext = gcontext->memctl.malloc(sizeof(pcre2_real_general_context), gcontext->memctl.memory_data); -if (new == NULL) return NULL; -memcpy(new, gcontext, sizeof(pcre2_real_general_context)); -return new; +if (newcontext == NULL) return NULL; +memcpy(newcontext, gcontext, sizeof(pcre2_real_general_context)); +return newcontext; } PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION pcre2_compile_context_copy(pcre2_compile_context *ccontext) { -pcre2_compile_context *new = +pcre2_compile_context *newcontext = ccontext->memctl.malloc(sizeof(pcre2_real_compile_context), ccontext->memctl.memory_data); -if (new == NULL) return NULL; -memcpy(new, ccontext, sizeof(pcre2_real_compile_context)); -return new; +if (newcontext == NULL) return NULL; +memcpy(newcontext, ccontext, sizeof(pcre2_real_compile_context)); +return newcontext; } PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION pcre2_match_context_copy(pcre2_match_context *mcontext) { -pcre2_match_context *new = +pcre2_match_context *newcontext = mcontext->memctl.malloc(sizeof(pcre2_real_match_context), mcontext->memctl.memory_data); -if (new == NULL) return NULL; -memcpy(new, mcontext, sizeof(pcre2_real_match_context)); -return new; +if (newcontext == NULL) return NULL; +memcpy(newcontext, mcontext, sizeof(pcre2_real_match_context)); +return newcontext; } - PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION pcre2_convert_context_copy(pcre2_convert_context *ccontext) { -pcre2_convert_context *new = +pcre2_convert_context *newcontext = ccontext->memctl.malloc(sizeof(pcre2_real_convert_context), ccontext->memctl.memory_data); -if (new == NULL) return NULL; -memcpy(new, ccontext, sizeof(pcre2_real_convert_context)); -return new; +if (newcontext == NULL) return NULL; +memcpy(newcontext, ccontext, sizeof(pcre2_real_convert_context)); +return newcontext; } @@ -370,6 +371,13 @@ switch(newline) } } +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_max_varlookbehind(pcre2_compile_context *ccontext, uint32_t limit) +{ +ccontext->max_varlookbehind = limit; +return 0; +} + PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit) { diff --git a/src/3rdparty/pcre2/src/pcre2_dfa_match.c b/src/3rdparty/pcre2/src/pcre2_dfa_match.c index b16e594cc06..caae65248ff 100644 --- a/src/3rdparty/pcre2/src/pcre2_dfa_match.c +++ b/src/3rdparty/pcre2/src/pcre2_dfa_match.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -168,7 +168,7 @@ static const uint8_t coptable[] = { 0, /* KetRmax */ 0, /* KetRmin */ 0, /* KetRpos */ - 0, /* Reverse */ + 0, 0, /* Reverse, Vreverse */ 0, /* Assert */ 0, /* Assert not */ 0, /* Assert behind */ @@ -187,7 +187,8 @@ static const uint8_t coptable[] = { 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ 0, 0, /* COMMIT, COMMIT_ARG */ 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */ - 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */ + 0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */ + 0, 0 /* \B and \b in UCP mode */ }; /* This table identifies those opcodes that inspect a character. It is used to @@ -245,7 +246,7 @@ static const uint8_t poptable[] = { 0, /* KetRmax */ 0, /* KetRmin */ 0, /* KetRpos */ - 0, /* Reverse */ + 0, 0, /* Reverse, Vreverse */ 0, /* Assert */ 0, /* Assert not */ 0, /* Assert behind */ @@ -264,7 +265,8 @@ static const uint8_t poptable[] = { 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ 0, 0, /* COMMIT, COMMIT_ARG */ 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */ - 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */ + 0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */ + 1, 1 /* \B and \b in UCP mode */ }; /* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W, @@ -426,7 +428,7 @@ overflow. */ else { - uint32_t newsize = (rws->size >= UINT32_MAX/2)? UINT32_MAX/2 : rws->size * 2; + uint32_t newsize = (rws->size >= UINT32_MAX/(sizeof(int)*2))? UINT32_MAX/sizeof(int) : rws->size * 2; uint32_t newsizeK = newsize/(1024/sizeof(int)); if (newsizeK + mb->heap_used > mb->heap_limit) @@ -589,7 +591,7 @@ if (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT) end_code = this_start_code; do { - size_t back = (size_t)GET(end_code, 2+LINK_SIZE); + size_t back = (size_t)GET2(end_code, 2+LINK_SIZE); if (back > max_back) max_back = back; end_code += GET(end_code, 1); } @@ -633,8 +635,8 @@ if (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT) end_code = this_start_code; do { - uint32_t revlen = (end_code[1+LINK_SIZE] == OP_REVERSE)? 1 + LINK_SIZE : 0; - size_t back = (revlen == 0)? 0 : (size_t)GET(end_code, 2+LINK_SIZE); + uint32_t revlen = (end_code[1+LINK_SIZE] == OP_REVERSE)? 1 + IMM2_SIZE : 0; + size_t back = (revlen == 0)? 0 : (size_t)GET2(end_code, 2+LINK_SIZE); if (back <= gone_back) { int bstate = (int)(end_code - start_code + 1 + LINK_SIZE + revlen); @@ -1100,6 +1102,8 @@ for (;;) /*-----------------------------------------------------------------*/ case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: { int left_word, right_word; @@ -1112,13 +1116,13 @@ for (;;) #endif GETCHARTEST(d, temp); #ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) + if (codevalue == OP_UCP_WORD_BOUNDARY || + codevalue == OP_NOT_UCP_WORD_BOUNDARY) { - if (d == '_') left_word = TRUE; else - { - uint32_t cat = UCD_CATEGORY(d); - left_word = (cat == ucp_L || cat == ucp_N); - } + int chartype = UCD_CHARTYPE(d); + int category = PRIV(ucp_gentype)[chartype]; + left_word = (category == ucp_L || category == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc); } else #endif @@ -1137,13 +1141,13 @@ for (;;) mb->last_used_ptr = temp; } #ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) + if (codevalue == OP_UCP_WORD_BOUNDARY || + codevalue == OP_NOT_UCP_WORD_BOUNDARY) { - if (c == '_') right_word = TRUE; else - { - uint32_t cat = UCD_CATEGORY(c); - right_word = (cat == ucp_L || cat == ucp_N); - } + int chartype = UCD_CHARTYPE(c); + int category = PRIV(ucp_gentype)[chartype]; + right_word = (category == ucp_L || category == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc); } else #endif @@ -1151,7 +1155,9 @@ for (;;) } else right_word = FALSE; - if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY)) + if ((left_word == right_word) == + (codevalue == OP_NOT_WORD_BOUNDARY || + codevalue == OP_NOT_UCP_WORD_BOUNDARY)) { ADD_ACTIVE(state_offset + 1, 0); } } break; @@ -1168,6 +1174,7 @@ for (;;) if (clen > 0) { BOOL OK; + int chartype; const uint32_t *cp; const ucd_record * prop = GET_UCD(c); switch(code[1]) @@ -1177,8 +1184,9 @@ for (;;) break; case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; + chartype = prop->chartype; + OK = chartype == ucp_Lu || chartype == ucp_Ll || + chartype == ucp_Lt; break; case PT_GC: @@ -1201,8 +1209,9 @@ for (;;) /* These are specials for combination cases. */ case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N; break; /* Perl space used to exclude VT, but from Perl 5.18 it is included, @@ -1225,12 +1234,20 @@ for (;;) break; case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc; break; case PT_CLIST: +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c > MAX_UTF_CODE_POINT) + { + OK = FALSE; + break; + } +#endif cp = PRIV(ucd_caseless_sets) + code[2]; for (;;) { @@ -1440,6 +1457,7 @@ for (;;) if (clen > 0) { BOOL OK; + int chartype; const uint32_t *cp; const ucd_record * prop = GET_UCD(c); switch(code[2]) @@ -1449,8 +1467,8 @@ for (;;) break; case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; + chartype = prop->chartype; + OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; break; case PT_GC: @@ -1473,8 +1491,9 @@ for (;;) /* These are specials for combination cases. */ case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N; break; /* Perl space used to exclude VT, but from Perl 5.18 it is included, @@ -1497,12 +1516,20 @@ for (;;) break; case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc; break; case PT_CLIST: +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c > MAX_UTF_CODE_POINT) + { + OK = FALSE; + break; + } +#endif cp = PRIV(ucd_caseless_sets) + code[3]; for (;;) { @@ -1695,6 +1722,7 @@ for (;;) if (clen > 0) { BOOL OK; + int chartype; const uint32_t *cp; const ucd_record * prop = GET_UCD(c); switch(code[2]) @@ -1704,8 +1732,8 @@ for (;;) break; case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; + chartype = prop->chartype; + OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; break; case PT_GC: @@ -1728,8 +1756,9 @@ for (;;) /* These are specials for combination cases. */ case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N; break; /* Perl space used to exclude VT, but from Perl 5.18 it is included, @@ -1752,12 +1781,20 @@ for (;;) break; case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc; break; case PT_CLIST: +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c > MAX_UTF_CODE_POINT) + { + OK = FALSE; + break; + } +#endif cp = PRIV(ucd_caseless_sets) + code[3]; for (;;) { @@ -1975,6 +2012,7 @@ for (;;) if (clen > 0) { BOOL OK; + int chartype; const uint32_t *cp; const ucd_record * prop = GET_UCD(c); switch(code[1 + IMM2_SIZE + 1]) @@ -1984,8 +2022,8 @@ for (;;) break; case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; + chartype = prop->chartype; + OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; break; case PT_GC: @@ -2009,8 +2047,9 @@ for (;;) /* These are specials for combination cases. */ case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N; break; /* Perl space used to exclude VT, but from Perl 5.18 it is included, @@ -2033,12 +2072,20 @@ for (;;) break; case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc; break; case PT_CLIST: +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c > MAX_UTF_CODE_POINT) + { + OK = FALSE; + break; + } +#endif cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2]; for (;;) { @@ -2894,7 +2941,6 @@ for (;;) int *local_workspace; PCRE2_SIZE *local_offsets; RWS_anchor *rws = (RWS_anchor *)RWS; - dfa_recursion_info *ri; PCRE2_SPTR callpat = start_code + GET(code, 1); uint32_t recno = (callpat == mb->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE); @@ -2911,18 +2957,24 @@ for (;;) rws->free -= RWS_RSIZE + RWS_OVEC_RSIZE; /* Check for repeating a recursion without advancing the subject - pointer. This should catch convoluted mutual recursions. (Some simple - cases are caught at compile time.) */ + pointer or last used character. This should catch convoluted mutual + recursions. (Some simple cases are caught at compile time.) */ - for (ri = mb->recursive; ri != NULL; ri = ri->prevrec) - if (recno == ri->group_num && ptr == ri->subject_position) + for (dfa_recursion_info *ri = mb->recursive; + ri != NULL; + ri = ri->prevrec) + { + if (recno == ri->group_num && ptr == ri->subject_position && + mb->last_used_ptr == ri->last_used_ptr) return PCRE2_ERROR_RECURSELOOP; + } /* Remember this recursion and where we started it so as to catch infinite loops. */ new_recursive.group_num = recno; new_recursive.subject_position = ptr; + new_recursive.last_used_ptr = mb->last_used_ptr; new_recursive.prevrec = mb->recursive; mb->recursive = &new_recursive; @@ -3424,7 +3476,7 @@ anchored = (options & (PCRE2_ANCHORED|PCRE2_DFA_RESTART)) != 0 || where to start. */ startline = (re->flags & PCRE2_STARTLINE) != 0; -firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0; +firstline = !anchored && (re->overall_options & PCRE2_FIRSTLINE) != 0; bumpalong_limit = end_subject; /* Initialize and set up the fixed fields in the callout block, with a pointer @@ -3994,8 +4046,9 @@ for (;;) match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject); match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject); } + match_data->subject_length = length; match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject); - match_data->rightchar = (PCRE2_SIZE)( mb->last_used_ptr - subject); + match_data->rightchar = (PCRE2_SIZE)(mb->last_used_ptr - subject); match_data->startchar = (PCRE2_SIZE)(start_match - subject); match_data->rc = rc; diff --git a/src/3rdparty/pcre2/src/pcre2_error.c b/src/3rdparty/pcre2/src/pcre2_error.c index 09904c03e3b..1569f6315f5 100644 --- a/src/3rdparty/pcre2/src/pcre2_error.c +++ b/src/3rdparty/pcre2/src/pcre2_error.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2021 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -82,7 +82,7 @@ static const unsigned char compile_error_texts[] = "missing closing parenthesis\0" /* 15 */ "reference to non-existent subpattern\0" - "pattern passed as NULL\0" + "pattern passed as NULL with non-zero length\0" "unrecognised compile-time option bit(s)\0" "missing ) after (?# comment\0" "parentheses are too deeply nested\0" @@ -93,7 +93,7 @@ static const unsigned char compile_error_texts[] = "internal error: code overflow\0" "missing closing parenthesis for condition\0" /* 25 */ - "lookbehind assertion is not fixed length\0" + "length of lookbehind assertion is not limited\0" "a relative value of zero is not allowed\0" "conditional subpattern contains more than two branches\0" "assertion expected after (?( or (?(?C)\0" @@ -187,6 +187,8 @@ static const unsigned char compile_error_texts[] = "too many capturing groups (maximum 65535)\0" "atomic assertion expected after (?( or (?(?C)\0" "\\K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK)\0" + /* 100 */ + "branch too long in variable-length lookbehind assertion\0" ; /* Match-time and UTF error texts are in the same format. */ @@ -272,6 +274,7 @@ static const unsigned char match_error_texts[] = /* 65 */ "internal error - duplicate substitution match\0" "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\0" + "INTERNAL ERROR: invalid substring offset\0" ; diff --git a/src/3rdparty/pcre2/src/pcre2_find_bracket.c b/src/3rdparty/pcre2/src/pcre2_find_bracket.c index 70baa1394f5..1290c5e9de1 100644 --- a/src/3rdparty/pcre2/src/pcre2_find_bracket.c +++ b/src/3rdparty/pcre2/src/pcre2_find_bracket.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2018 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -41,9 +41,9 @@ POSSIBILITY OF SUCH DAMAGE. /* This module contains a single function that scans through a compiled pattern until it finds a capturing bracket with the given number, or, if the number is -negative, an instance of OP_REVERSE for a lookbehind. The function is called -from pcre2_compile.c and also from pcre2_study.c when finding the minimum -matching length. */ +negative, an instance of OP_REVERSE or OP_VREVERSE for a lookbehind. The +function is called from pcre2_compile.c and also from pcre2_study.c when +finding the minimum matching length. */ #ifdef HAVE_CONFIG_H @@ -85,7 +85,7 @@ for (;;) /* Handle lookbehind */ - else if (c == OP_REVERSE) + else if (c == OP_REVERSE || c == OP_VREVERSE) { if (number < 0) return (PCRE2_UCHAR *)code; code += PRIV(OP_lengths)[c]; diff --git a/src/3rdparty/pcre2/src/pcre2_internal.h b/src/3rdparty/pcre2/src/pcre2_internal.h index 92dd3138d4a..e5808182e67 100644 --- a/src/3rdparty/pcre2/src/pcre2_internal.h +++ b/src/3rdparty/pcre2/src/pcre2_internal.h @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -51,6 +51,24 @@ pcre2test.c with CODE_UNIT_WIDTH == 0. */ #error The use of both EBCDIC and SUPPORT_UNICODE is not supported. #endif +/* When compiling one of the libraries, the value of PCRE2_CODE_UNIT_WIDTH must +be 8, 16, or 32. AutoTools and CMake ensure that this is always the case, but +other other building methods may not, so here is a check. It is cut out when +building pcre2test, bcause that sets the value to zero. No other source should +be including this file. There is no explicit way of forcing a compile to be +abandoned, but trying to include a non-existent file seems cleanest. Otherwise +there will be many irrelevant consequential errors. */ + +#if (!defined PCRE2_BUILDING_PCRE2TEST && !defined PCRE2_DFTABLES) && \ + (!defined PCRE2_CODE_UNIT_WIDTH || \ + (PCRE2_CODE_UNIT_WIDTH != 8 && \ + PCRE2_CODE_UNIT_WIDTH != 16 && \ + PCRE2_CODE_UNIT_WIDTH != 32)) +#error PCRE2_CODE_UNIT_WIDTH must be defined as 8, 16, or 32. +#include +#endif + + /* Standard C headers */ #include @@ -119,20 +137,20 @@ only if it is not already set. */ #ifndef PCRE2_EXP_DECL # ifdef _WIN32 # ifndef PCRE2_STATIC -# define PCRE2_EXP_DECL extern __declspec(dllexport) -# define PCRE2_EXP_DEFN __declspec(dllexport) +# define PCRE2_EXP_DECL extern __declspec(dllexport) +# define PCRE2_EXP_DEFN __declspec(dllexport) # else -# define PCRE2_EXP_DECL extern +# define PCRE2_EXP_DECL extern PCRE2_EXPORT # define PCRE2_EXP_DEFN # endif # else # ifdef __cplusplus -# define PCRE2_EXP_DECL extern "C" +# define PCRE2_EXP_DECL extern "C" PCRE2_EXPORT # else -# define PCRE2_EXP_DECL extern +# define PCRE2_EXP_DECL extern PCRE2_EXPORT # endif # ifndef PCRE2_EXP_DEFN -# define PCRE2_EXP_DEFN PCRE2_EXP_DECL +# define PCRE2_EXP_DEFN PCRE2_EXP_DECL # endif # endif #endif @@ -156,8 +174,8 @@ pcre2_match() because of the way it backtracks. */ #define PCRE2_SPTR CUSTOM_SUBJECT_PTR #endif -/* When checking for integer overflow in pcre2_compile(), we need to handle -large integers. If a 64-bit integer type is available, we can use that. +/* When checking for integer overflow, we need to handle large integers. +If a 64-bit integer type is available, we can use that. Otherwise we have to cast to double, which of course requires floating point arithmetic. Handle this by defining a macro for the appropriate type. */ @@ -1281,7 +1299,7 @@ match. */ #define PT_ALNUM 6 /* Alphanumeric - the union of L and N */ #define PT_SPACE 7 /* Perl space - general category Z plus 9,10,12,13 */ #define PT_PXSPACE 8 /* POSIX space - Z plus 9,10,11,12,13 */ -#define PT_WORD 9 /* Word - L plus N plus underscore */ +#define PT_WORD 9 /* Word - L, N, Mn, or Pc */ #define PT_CLIST 10 /* Pseudo-property: match character list */ #define PT_UCNC 11 /* Universal Character nameable character */ #define PT_BIDICL 12 /* Specified bidi class */ @@ -1297,6 +1315,7 @@ table. */ #define PT_PXGRAPH 14 /* [:graph:] - characters that mark the paper */ #define PT_PXPRINT 15 /* [:print:] - [:graph:] plus non-control spaces */ #define PT_PXPUNCT 16 /* [:punct:] - punctuation characters */ +#define PT_PXXDIGIT 17 /* [:xdigit:] - hex digits */ /* This value is used when parsing \p and \P escapes to indicate that neither \p{script:...} nor \p{scx:...} has been encountered. */ @@ -1327,6 +1346,12 @@ mode rather than an escape sequence. It is also used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves like \N. +ESC_ub is a special return from check_escape() when, in BSUX mode, \u{ is not +followed by hex digits and }, in which case it should mean a literal "u" +followed by a literal "{". This hack is necessary for cases like \u{ 12} +because without it, this is interpreted as u{12} now that spaces are allowed in +quantifiers. + Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in check_escape(). There are tests in the code for an escape greater than ESC_b and less than ESC_Z to detect the types that may be repeated. These are the @@ -1336,7 +1361,7 @@ consume a character, that code will have to change. */ enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H, ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z, - ESC_E, ESC_Q, ESC_g, ESC_k }; + ESC_E, ESC_Q, ESC_g, ESC_k, ESC_ub }; /********************** Opcode definitions ******************/ @@ -1372,8 +1397,8 @@ enum { OP_SOD, /* 1 Start of data: \A */ OP_SOM, /* 2 Start of match (subject + offset): \G */ OP_SET_SOM, /* 3 Set start of match (\K) */ - OP_NOT_WORD_BOUNDARY, /* 4 \B */ - OP_WORD_BOUNDARY, /* 5 \b */ + OP_NOT_WORD_BOUNDARY, /* 4 \B -- see also OP_NOT_UCP_WORD_BOUNDARY */ + OP_WORD_BOUNDARY, /* 5 \b -- see also OP_UCP_WORD_BOUNDARY */ OP_NOT_DIGIT, /* 6 \D */ OP_DIGIT, /* 7 \d */ OP_NOT_WHITESPACE, /* 8 \S */ @@ -1547,78 +1572,85 @@ enum { /* The assertions must come before BRA, CBRA, ONCE, and COND. */ OP_REVERSE, /* 125 Move pointer back - used in lookbehind assertions */ - OP_ASSERT, /* 126 Positive lookahead */ - OP_ASSERT_NOT, /* 127 Negative lookahead */ - OP_ASSERTBACK, /* 128 Positive lookbehind */ - OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */ - OP_ASSERT_NA, /* 130 Positive non-atomic lookahead */ - OP_ASSERTBACK_NA, /* 131 Positive non-atomic lookbehind */ + OP_VREVERSE, /* 126 Move pointer back - variable */ + OP_ASSERT, /* 127 Positive lookahead */ + OP_ASSERT_NOT, /* 128 Negative lookahead */ + OP_ASSERTBACK, /* 129 Positive lookbehind */ + OP_ASSERTBACK_NOT, /* 130 Negative lookbehind */ + OP_ASSERT_NA, /* 131 Positive non-atomic lookahead */ + OP_ASSERTBACK_NA, /* 132 Positive non-atomic lookbehind */ /* ONCE, SCRIPT_RUN, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately after the assertions, with ONCE first, as there's a test for >= ONCE for a subpattern that isn't an assertion. The POS versions must immediately follow the non-POS versions in each case. */ - OP_ONCE, /* 132 Atomic group, contains captures */ - OP_SCRIPT_RUN, /* 133 Non-capture, but check characters' scripts */ - OP_BRA, /* 134 Start of non-capturing bracket */ - OP_BRAPOS, /* 135 Ditto, with unlimited, possessive repeat */ - OP_CBRA, /* 136 Start of capturing bracket */ - OP_CBRAPOS, /* 137 Ditto, with unlimited, possessive repeat */ - OP_COND, /* 138 Conditional group */ + OP_ONCE, /* 133 Atomic group, contains captures */ + OP_SCRIPT_RUN, /* 134 Non-capture, but check characters' scripts */ + OP_BRA, /* 135 Start of non-capturing bracket */ + OP_BRAPOS, /* 136 Ditto, with unlimited, possessive repeat */ + OP_CBRA, /* 137 Start of capturing bracket */ + OP_CBRAPOS, /* 138 Ditto, with unlimited, possessive repeat */ + OP_COND, /* 139 Conditional group */ /* These five must follow the previous five, in the same order. There's a check for >= SBRA to distinguish the two sets. */ - OP_SBRA, /* 139 Start of non-capturing bracket, check empty */ - OP_SBRAPOS, /* 149 Ditto, with unlimited, possessive repeat */ - OP_SCBRA, /* 141 Start of capturing bracket, check empty */ - OP_SCBRAPOS, /* 142 Ditto, with unlimited, possessive repeat */ - OP_SCOND, /* 143 Conditional group, check empty */ + OP_SBRA, /* 140 Start of non-capturing bracket, check empty */ + OP_SBRAPOS, /* 141 Ditto, with unlimited, possessive repeat */ + OP_SCBRA, /* 142 Start of capturing bracket, check empty */ + OP_SCBRAPOS, /* 143 Ditto, with unlimited, possessive repeat */ + OP_SCOND, /* 144 Conditional group, check empty */ /* The next two pairs must (respectively) be kept together. */ - OP_CREF, /* 144 Used to hold a capture number as condition */ - OP_DNCREF, /* 145 Used to point to duplicate names as a condition */ - OP_RREF, /* 146 Used to hold a recursion number as condition */ - OP_DNRREF, /* 147 Used to point to duplicate names as a condition */ - OP_FALSE, /* 148 Always false (used by DEFINE and VERSION) */ - OP_TRUE, /* 149 Always true (used by VERSION) */ + OP_CREF, /* 145 Used to hold a capture number as condition */ + OP_DNCREF, /* 146 Used to point to duplicate names as a condition */ + OP_RREF, /* 147 Used to hold a recursion number as condition */ + OP_DNRREF, /* 148 Used to point to duplicate names as a condition */ + OP_FALSE, /* 149 Always false (used by DEFINE and VERSION) */ + OP_TRUE, /* 150 Always true (used by VERSION) */ - OP_BRAZERO, /* 150 These two must remain together and in this */ - OP_BRAMINZERO, /* 151 order. */ - OP_BRAPOSZERO, /* 152 */ + OP_BRAZERO, /* 151 These two must remain together and in this */ + OP_BRAMINZERO, /* 152 order. */ + OP_BRAPOSZERO, /* 153 */ /* These are backtracking control verbs */ - OP_MARK, /* 153 always has an argument */ - OP_PRUNE, /* 154 */ - OP_PRUNE_ARG, /* 155 same, but with argument */ - OP_SKIP, /* 156 */ - OP_SKIP_ARG, /* 157 same, but with argument */ - OP_THEN, /* 158 */ - OP_THEN_ARG, /* 159 same, but with argument */ - OP_COMMIT, /* 160 */ - OP_COMMIT_ARG, /* 161 same, but with argument */ + OP_MARK, /* 154 always has an argument */ + OP_PRUNE, /* 155 */ + OP_PRUNE_ARG, /* 156 same, but with argument */ + OP_SKIP, /* 157 */ + OP_SKIP_ARG, /* 158 same, but with argument */ + OP_THEN, /* 159 */ + OP_THEN_ARG, /* 160 same, but with argument */ + OP_COMMIT, /* 161 */ + OP_COMMIT_ARG, /* 162 same, but with argument */ /* These are forced failure and success verbs. FAIL and ACCEPT do accept an argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL) without the need for a special opcode. */ - OP_FAIL, /* 162 */ - OP_ACCEPT, /* 163 */ - OP_ASSERT_ACCEPT, /* 164 Used inside assertions */ - OP_CLOSE, /* 165 Used before OP_ACCEPT to close open captures */ + OP_FAIL, /* 163 */ + OP_ACCEPT, /* 164 */ + OP_ASSERT_ACCEPT, /* 165 Used inside assertions */ + OP_CLOSE, /* 166 Used before OP_ACCEPT to close open captures */ /* This is used to skip a subpattern with a {0} quantifier */ - OP_SKIPZERO, /* 166 */ + OP_SKIPZERO, /* 167 */ /* This is used to identify a DEFINE group during compilation so that it can be checked for having only one branch. It is changed to OP_FALSE before compilation finishes. */ - OP_DEFINE, /* 167 */ + OP_DEFINE, /* 168 */ + + /* These opcodes replace their normal counterparts in UCP mode when + PCRE2_EXTRA_ASCII_BSW is not set. */ + + OP_NOT_UCP_WORD_BOUNDARY, /* 169 */ + OP_UCP_WORD_BOUNDARY, /* 170 */ /* This is not an opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors - there have been @@ -1664,7 +1696,7 @@ some cases doesn't actually use these names at all). */ "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \ "Recurse", "Callout", "CalloutStr", \ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ - "Reverse", "Assert", "Assert not", \ + "Reverse", "VReverse", "Assert", "Assert not", \ "Assert back", "Assert back not", \ "Non-atomic assert", "Non-atomic assert back", \ "Once", \ @@ -1679,7 +1711,7 @@ some cases doesn't actually use these names at all). */ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ "*THEN", "*THEN", "*COMMIT", "*COMMIT", "*FAIL", \ "*ACCEPT", "*ASSERT_ACCEPT", \ - "Close", "Skip zero", "Define" + "Close", "Skip zero", "Define", "\\B (ucp)", "\\b (ucp)" /* This macro defines the length of fixed length operations in the compiled @@ -1746,7 +1778,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1+LINK_SIZE, /* KetRmax */ \ 1+LINK_SIZE, /* KetRmin */ \ 1+LINK_SIZE, /* KetRpos */ \ - 1+LINK_SIZE, /* Reverse */ \ + 1+IMM2_SIZE, /* Reverse */ \ + 1+2*IMM2_SIZE, /* VReverse */ \ 1+LINK_SIZE, /* Assert */ \ 1+LINK_SIZE, /* Assert not */ \ 1+LINK_SIZE, /* Assert behind */ \ @@ -1775,7 +1808,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1, 3, /* COMMIT, COMMIT_ARG */ \ 1, 1, 1, /* FAIL, ACCEPT, ASSERT_ACCEPT */ \ 1+IMM2_SIZE, 1, /* CLOSE, SKIPZERO */ \ - 1 /* DEFINE */ + 1, /* DEFINE */ \ + 1, 1 /* \B and \b in UCP mode */ /* A magic value for OP_RREF to indicate the "any recursion" condition. */ @@ -2042,6 +2076,9 @@ extern void * _pcre2_memmove(void *, const void *, size_t); #endif #endif /* PCRE2_CODE_UNIT_WIDTH */ + +extern BOOL PRIV(ckd_smul)(PCRE2_SIZE *, int, int); + #endif /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */ /* End of pcre2_internal.h */ diff --git a/src/3rdparty/pcre2/src/pcre2_intmodedep.h b/src/3rdparty/pcre2/src/pcre2_intmodedep.h index 390e737a6ef..5fcddce5fe1 100644 --- a/src/3rdparty/pcre2/src/pcre2_intmodedep.h +++ b/src/3rdparty/pcre2/src/pcre2_intmodedep.h @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -572,6 +572,7 @@ typedef struct pcre2_real_compile_context { uint16_t newline_convention; uint32_t parens_nest_limit; uint32_t extra_options; + uint32_t max_varlookbehind; } pcre2_real_compile_context; /* The real match context structure. */ @@ -605,12 +606,12 @@ defined specially because it is required in pcre2_serialize_decode() when copying the size from possibly unaligned memory into a variable of the same type. Use a macro rather than a typedef to avoid compiler warnings when this file is included multiple times by pcre2test. LOOKBEHIND_MAX specifies the -largest lookbehind that is supported. (OP_REVERSE in a pattern has a 16-bit -argument in 8-bit and 16-bit modes, so we need no more than a 16-bit field -here.) */ +largest lookbehind that is supported. (OP_REVERSE and OP_VREVERSE in a pattern +have 16-bit arguments in 8-bit and 16-bit modes, so we need no more than a +16-bit field here.) */ #undef CODE_BLOCKSIZE_TYPE -#define CODE_BLOCKSIZE_TYPE size_t +#define CODE_BLOCKSIZE_TYPE PCRE2_SIZE #undef LOOKBEHIND_MAX #define LOOKBEHIND_MAX UINT16_MAX @@ -658,6 +659,7 @@ typedef struct pcre2_real_match_data { PCRE2_SPTR mark; /* Pointer to last mark */ struct heapframe *heapframes; /* Backtracking frames heap memory */ PCRE2_SIZE heapframes_size; /* Malloc-ed size */ + PCRE2_SIZE subject_length; /* Subject length */ PCRE2_SIZE leftchar; /* Offset to leftmost code unit */ PCRE2_SIZE rightchar; /* Offset to rightmost code unit */ PCRE2_SIZE startchar; /* Offset to starting code unit */ @@ -675,8 +677,8 @@ typedef struct pcre2_real_match_data { #ifndef PCRE2_PCRE2TEST -/* Structures for checking for mutual recursion when scanning compiled or -parsed code. */ +/* Structures for checking for mutual function recursion when scanning compiled +or parsed code. */ typedef struct recurse_check { struct recurse_check *prev; @@ -688,7 +690,7 @@ typedef struct parsed_recurse_check { uint32_t *groupptr; } parsed_recurse_check; -/* Structure for building a cache when filling in recursion offsets. */ +/* Structure for building a cache when filling in pattern recursion offsets. */ typedef struct recurse_cache { PCRE2_SPTR group; @@ -734,7 +736,6 @@ typedef struct compile_block { uint16_t name_entry_size; /* Size of each entry */ uint16_t parens_depth; /* Depth of nested parentheses */ uint16_t assert_depth; /* Depth of nested assertions */ - open_capitem *open_caps; /* Chain of open capture items */ named_group *named_groups; /* Points to vector in pre-compile */ uint32_t named_group_list_size; /* Number of entries in the list */ uint32_t external_options; /* External (initial) options */ @@ -752,10 +753,11 @@ typedef struct compile_block { uint32_t class_range_end; /* Overall class range end */ PCRE2_UCHAR nl[4]; /* Newline string when fixed length */ uint32_t req_varyopt; /* "After variable item" flag for reqbyte */ - int max_lookbehind; /* Maximum lookbehind (characters) */ + uint32_t max_varlookbehind; /* Limit for variable lookbehinds */ + int max_lookbehind; /* Maximum lookbehind encountered (characters) */ BOOL had_accept; /* (*ACCEPT) encountered */ BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ - BOOL had_recurse; /* Had a recursion or subroutine call */ + BOOL had_recurse; /* Had a pattern recursion or subroutine call */ BOOL dupnames; /* Duplicate names exist */ } compile_block; @@ -773,6 +775,7 @@ call within the pattern when running pcre2_dfa_match(). */ typedef struct dfa_recursion_info { struct dfa_recursion_info *prevrec; PCRE2_SPTR subject_position; + PCRE2_SPTR last_used_ptr; uint32_t group_num; } dfa_recursion_info; @@ -793,7 +796,7 @@ typedef struct heapframe { PCRE2_SIZE length; /* Used for character, string, or code lengths */ PCRE2_SIZE back_frame; /* Amount to subtract on RRETURN */ PCRE2_SIZE temp_size; /* Used for short-term PCRE2_SIZE values */ - uint32_t rdepth; /* "Recursion" depth */ + uint32_t rdepth; /* Function "recursion" depth within pcre2_match() */ uint32_t group_frame_type; /* Type information for group frames */ uint32_t temp_32[4]; /* Used for short-term 32-bit or BOOL values */ uint8_t return_id; /* Where to go on in internal "return" */ @@ -826,14 +829,15 @@ typedef struct heapframe { allows for exactly the right size ovector for the number of capturing parentheses. (See also the comment for pcre2_real_match_data above.) */ - PCRE2_SPTR eptr; /* MUST BE FIRST */ - PCRE2_SPTR start_match; /* Can be adjusted by \K */ - PCRE2_SPTR mark; /* Most recent mark on the success path */ - uint32_t current_recurse; /* Current (deepest) recursion number */ - uint32_t capture_last; /* Most recent capture */ - PCRE2_SIZE last_group_offset; /* Saved offset to most recent group frame */ - PCRE2_SIZE offset_top; /* Offset after highest capture */ - PCRE2_SIZE ovector[131072]; /* Must be last in the structure */ + PCRE2_SPTR eptr; /* MUST BE FIRST */ + PCRE2_SPTR start_match; /* Can be adjusted by \K */ + PCRE2_SPTR mark; /* Most recent mark on the success path */ + PCRE2_SPTR recurse_last_used; /* Last character used at time of pattern recursion */ + uint32_t current_recurse; /* Group number of current (deepest) pattern recursion */ + uint32_t capture_last; /* Most recent capture */ + PCRE2_SIZE last_group_offset; /* Saved offset to most recent group frame */ + PCRE2_SIZE offset_top; /* Offset after highest capture */ + PCRE2_SIZE ovector[131072]; /* Must be last in the structure */ } heapframe; /* This typedef is a check that the size of the heapframe structure is a @@ -858,7 +862,7 @@ doing traditional NFA matching (pcre2_match() and friends). */ typedef struct match_block { pcre2_memctl memctl; /* For general use */ - PCRE2_SIZE heap_limit; /* As it says */ + uint32_t heap_limit; /* As it says */ uint32_t match_limit; /* As it says */ uint32_t match_limit_depth; /* As it says */ uint32_t match_call_count; /* Number of times a new frame is created */ @@ -875,10 +879,11 @@ typedef struct match_block { uint16_t name_count; /* Number of names in name table */ uint16_t name_entry_size; /* Size of entry in names table */ PCRE2_SPTR name_table; /* Table of group names */ - PCRE2_SPTR start_code; /* For use when recursing */ + PCRE2_SPTR start_code; /* For use in pattern recursion */ PCRE2_SPTR start_subject; /* Start of the subject string */ PCRE2_SPTR check_subject; /* Where UTF-checked from */ - PCRE2_SPTR end_subject; /* End of the subject string */ + PCRE2_SPTR end_subject; /* Usable end of the subject string */ + PCRE2_SPTR true_end_subject; /* Actual end of the subject string */ PCRE2_SPTR end_match_ptr; /* Subject position at end match */ PCRE2_SPTR start_used_ptr; /* Earliest consulted character */ PCRE2_SPTR last_used_ptr; /* Latest consulted character */ @@ -886,7 +891,7 @@ typedef struct match_block { PCRE2_SPTR nomatch_mark; /* Mark pointer to pass back on failure */ PCRE2_SPTR verb_ecode_ptr; /* For passing back info */ PCRE2_SPTR verb_skip_ptr; /* For passing back a (*SKIP) name */ - uint32_t verb_current_recurse; /* Current recurse when (*VERB) happens */ + uint32_t verb_current_recurse; /* Current recursion group when (*VERB) happens */ uint32_t moptions; /* Match options */ uint32_t poptions; /* Pattern options */ uint32_t skip_arg_count; /* For counting SKIP_ARGs */ @@ -911,7 +916,7 @@ typedef struct dfa_match_block { PCRE2_SPTR last_used_ptr; /* Latest consulted character */ const uint8_t *tables; /* Character tables */ PCRE2_SIZE start_offset; /* The start offset value */ - PCRE2_SIZE heap_limit; /* As it says */ + uint32_t heap_limit; /* As it says */ PCRE2_SIZE heap_used; /* As it says */ uint32_t match_limit; /* As it says */ uint32_t match_limit_depth; /* As it says */ @@ -926,7 +931,7 @@ typedef struct dfa_match_block { pcre2_callout_block *cb; /* Points to a callout block */ void *callout_data; /* To pass back to callouts */ int (*callout)(pcre2_callout_block *,void *); /* Callout function or NULL */ - dfa_recursion_info *recursive; /* Linked list of recursion data */ + dfa_recursion_info *recursive; /* Linked list of pattern recursion data */ } dfa_match_block; #endif /* PCRE2_PCRE2TEST */ diff --git a/src/3rdparty/pcre2/src/pcre2_jit_compile.c b/src/3rdparty/pcre2/src/pcre2_jit_compile.c index 0afd27c5eed..050063ec6d1 100644 --- a/src/3rdparty/pcre2/src/pcre2_jit_compile.c +++ b/src/3rdparty/pcre2/src/pcre2_jit_compile.c @@ -43,6 +43,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "config.h" #endif +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#include +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ + #include "pcre2_internal.h" #ifdef SUPPORT_JIT @@ -236,12 +242,21 @@ code generator. It is allocated by compile_matchingpath, and contains the arguments for compile_backtrackingpath. Must be the first member of its descendants. */ typedef struct backtrack_common { - /* Concatenation stack. */ + /* Backtracking path of an opcode, which falls back + to our opcode, if it cannot resume matching. */ struct backtrack_common *prev; - jump_list *nextbacktracks; - /* Internal stack (for component operators). */ + /* Backtracks for opcodes without backtracking path. + These opcodes are between 'prev' and the current + opcode, and they never resume the match. */ + jump_list *simple_backtracks; + /* Internal backtracking list for block constructs + which contains other opcodes, such as brackets, + asserts, conditionals, etc. */ struct backtrack_common *top; - jump_list *topbacktracks; + /* Backtracks used internally by the opcode. For component + opcodes, this list is also used by those opcodes without + backtracking path which follows the 'top' backtrack. */ + jump_list *own_backtracks; /* Opcode pointer. */ PCRE2_SPTR cc; } backtrack_common; @@ -338,6 +353,12 @@ typedef struct recurse_backtrack { BOOL inlined_pattern; } recurse_backtrack; +typedef struct vreverse_backtrack { + backtrack_common common; + /* Return to the matching path. */ + struct sljit_label *matchingpath; +} vreverse_backtrack; + #define OP_THEN_TRAP OP_TABLE_LENGTH typedef struct then_trap_backtrack { @@ -404,7 +425,9 @@ typedef struct compiler_common { sljit_s32 match_end_ptr; /* Points to the marked string. */ sljit_s32 mark_ptr; - /* Recursive control verb management chain. */ + /* Head of the recursive control verb management chain. + Each item must have a previous offset and type + (see control_types) values. See do_search_mark. */ sljit_s32 control_head_ptr; /* Points to the last matched capture block index. */ sljit_s32 capture_last_ptr; @@ -474,12 +497,15 @@ typedef struct compiler_common { jump_list *stackalloc; jump_list *revertframes; jump_list *wordboundary; + jump_list *ucp_wordboundary; jump_list *anynewline; jump_list *hspace; jump_list *vspace; jump_list *casefulcmp; jump_list *caselesscmp; jump_list *reset_match; + /* Same as reset_match, but resets the STR_PTR as well. */ + jump_list *restart_match; BOOL unset_backref; BOOL alt_circumflex; #ifdef SUPPORT_UNICODE @@ -636,8 +662,8 @@ the start pointers when the end of the capturing group has not yet reached. */ sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) #define OP_FLAGS(op, dst, dstw, type) \ sljit_emit_op_flags(compiler, (op), (dst), (dstw), (type)) -#define CMOV(type, dst_reg, src, srcw) \ - sljit_emit_cmov(compiler, (type), (dst_reg), (src), (srcw)) +#define SELECT(type, dst_reg, src1, src1w, src2_reg) \ + sljit_emit_select(compiler, (type), (dst_reg), (src1), (src1w), (src2_reg)) #define GET_LOCAL_BASE(dst, dstw, offset) \ sljit_get_local_base(compiler, (dst), (dstw), (offset)) @@ -857,6 +883,21 @@ SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); return count; } +static BOOL find_vreverse(PCRE2_SPTR cc) +{ + SLJIT_ASSERT(*cc == OP_ASSERTBACK || *cc == OP_ASSERTBACK_NOT || *cc == OP_ASSERTBACK_NA); + + do + { + if (cc[1 + LINK_SIZE] == OP_VREVERSE) + return TRUE; + cc += GET(cc, 1); + } + while (*cc == OP_ALT); + + return FALSE; +} + /* Functions whose might need modification for all new supported opcodes: next_opcode check_opcode_types @@ -927,6 +968,7 @@ switch(*cc) case OP_KETRMIN: case OP_KETRPOS: case OP_REVERSE: + case OP_VREVERSE: case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: @@ -963,6 +1005,8 @@ switch(*cc) case OP_ASSERT_ACCEPT: case OP_CLOSE: case OP_SKIPZERO: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: return cc + PRIV(OP_lengths)[*cc]; case OP_CHAR: @@ -1231,34 +1275,37 @@ while (cc < ccend) return TRUE; } -#define EARLY_FAIL_ENHANCE_MAX (1 + 3) +#define EARLY_FAIL_ENHANCE_MAX (3 + 3) /* -start: - 0 - skip / early fail allowed - 1 - only early fail with range allowed - >1 - (start - 1) early fail is processed + Start represent the number of allowed early fail enhancements -return: current number of iterators enhanced with fast fail + The 0-2 values has a special meaning: + 0 - skip is allowed for all iterators + 1 - fail is allowed for all iterators + 2 - fail is allowed for greedy iterators + 3 - only ranged early fail is allowed + >3 - (start - 3) number of remaining ranged early fails allowed + +return: the updated value of start */ -static int detect_early_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, - sljit_s32 depth, int start, BOOL fast_forward_allowed) +static int detect_early_fail(compiler_common *common, PCRE2_SPTR cc, + int *private_data_start, sljit_s32 depth, int start) { PCRE2_SPTR begin = cc; PCRE2_SPTR next_alt; PCRE2_SPTR end; PCRE2_SPTR accelerated_start; -BOOL prev_fast_forward_allowed; int result = 0; -int count; +int count, prev_count; SLJIT_ASSERT(*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA); SLJIT_ASSERT(*cc != OP_CBRA || common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] != 0); SLJIT_ASSERT(start < EARLY_FAIL_ENHANCE_MAX); next_alt = cc + GET(cc, 1); -if (*next_alt == OP_ALT) - fast_forward_allowed = FALSE; +if (*next_alt == OP_ALT && start < 1) + start = 1; do { @@ -1282,6 +1329,8 @@ do case OP_CIRCM: case OP_DOLL: case OP_DOLLM: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: /* Zero width assertions. */ cc++; continue; @@ -1299,21 +1348,22 @@ do case OP_HSPACE: case OP_NOT_VSPACE: case OP_VSPACE: - fast_forward_allowed = FALSE; + if (count < 1) + count = 1; cc++; continue; case OP_ANYNL: case OP_EXTUNI: - fast_forward_allowed = FALSE; - if (count == 0) - count = 1; + if (count < 3) + count = 3; cc++; continue; case OP_NOTPROP: case OP_PROP: - fast_forward_allowed = FALSE; + if (count < 1) + count = 1; cc += 1 + 2; continue; @@ -1321,17 +1371,22 @@ do case OP_CHARI: case OP_NOT: case OP_NOTI: - fast_forward_allowed = FALSE; + if (count < 1) + count = 1; cc += 2; #ifdef SUPPORT_UNICODE if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif continue; - case OP_TYPESTAR: case OP_TYPEMINSTAR: - case OP_TYPEPLUS: case OP_TYPEMINPLUS: + if (count == 2) + count = 3; + /* Fall through */ + + case OP_TYPESTAR: + case OP_TYPEPLUS: case OP_TYPEPOSSTAR: case OP_TYPEPOSPLUS: /* The type or prop opcode is skipped in the next iteration. */ @@ -1343,14 +1398,18 @@ do break; } - if (count == 0) + if (count < 3) + count = 3; + continue; + + case OP_TYPEEXACT: + if (count < 1) count = 1; - fast_forward_allowed = FALSE; + cc += 1 + IMM2_SIZE; continue; case OP_TYPEUPTO: case OP_TYPEMINUPTO: - case OP_TYPEEXACT: case OP_TYPEPOSUPTO: cc += IMM2_SIZE; /* Fall through */ @@ -1359,37 +1418,40 @@ do case OP_TYPEMINQUERY: case OP_TYPEPOSQUERY: /* The type or prop opcode is skipped in the next iteration. */ - fast_forward_allowed = FALSE; - if (count == 0) - count = 1; + if (count < 3) + count = 3; cc += 1; continue; - case OP_STAR: case OP_MINSTAR: - case OP_PLUS: case OP_MINPLUS: + case OP_MINSTARI: + case OP_MINPLUSI: + case OP_NOTMINSTAR: + case OP_NOTMINPLUS: + case OP_NOTMINSTARI: + case OP_NOTMINPLUSI: + if (count == 2) + count = 3; + /* Fall through */ + + case OP_STAR: + case OP_PLUS: case OP_POSSTAR: case OP_POSPLUS: case OP_STARI: - case OP_MINSTARI: case OP_PLUSI: - case OP_MINPLUSI: case OP_POSSTARI: case OP_POSPLUSI: case OP_NOTSTAR: - case OP_NOTMINSTAR: case OP_NOTPLUS: - case OP_NOTMINPLUS: case OP_NOTPOSSTAR: case OP_NOTPOSPLUS: case OP_NOTSTARI: - case OP_NOTMINSTARI: case OP_NOTPLUSI: - case OP_NOTMINPLUSI: case OP_NOTPOSSTARI: case OP_NOTPOSPLUSI: accelerated_start = cc; @@ -1399,9 +1461,17 @@ do #endif break; + case OP_EXACT: + if (count < 1) + count = 1; + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + continue; + case OP_UPTO: case OP_MINUPTO: - case OP_EXACT: case OP_POSUPTO: case OP_UPTOI: case OP_MINUPTOI: @@ -1430,9 +1500,8 @@ do case OP_NOTQUERYI: case OP_NOTMINQUERYI: case OP_NOTPOSQUERYI: - fast_forward_allowed = FALSE; - if (count == 0) - count = 1; + if (count < 3) + count = 3; cc += 2; #ifdef SUPPORT_UNICODE if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); @@ -1452,10 +1521,14 @@ do switch (*cc) { - case OP_CRSTAR: case OP_CRMINSTAR: - case OP_CRPLUS: case OP_CRMINPLUS: + if (count == 2) + count = 3; + /* Fall through */ + + case OP_CRSTAR: + case OP_CRPLUS: case OP_CRPOSSTAR: case OP_CRPOSPLUS: cc++; @@ -1464,44 +1537,60 @@ do case OP_CRRANGE: case OP_CRMINRANGE: case OP_CRPOSRANGE: + if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE)) + { + /* Exact repeat. */ + cc += 1 + 2 * IMM2_SIZE; + if (count < 1) + count = 1; + continue; + } + cc += 2 * IMM2_SIZE; /* Fall through */ case OP_CRQUERY: case OP_CRMINQUERY: case OP_CRPOSQUERY: cc++; - if (count == 0) - count = 1; - /* Fall through */ + if (count < 3) + count = 3; + continue; + default: - accelerated_start = NULL; - fast_forward_allowed = FALSE; + /* No repeat. */ + if (count < 1) + count = 1; continue; } break; - case OP_ONCE: case OP_BRA: case OP_CBRA: - end = cc + GET(cc, 1); + prev_count = count; + if (count < 1) + count = 1; - prev_fast_forward_allowed = fast_forward_allowed; - fast_forward_allowed = FALSE; if (depth >= 4) break; - end = bracketend(cc) - (1 + LINK_SIZE); - if (*end != OP_KET || (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)) + if (count < 3 && cc[GET(cc, 1)] == OP_ALT) + count = 3; + + end = bracketend(cc); + if (end[-1 - LINK_SIZE] != OP_KET || (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)) break; - count = detect_early_fail(common, cc, private_data_start, depth + 1, count, prev_fast_forward_allowed); + prev_count = detect_early_fail(common, cc, private_data_start, depth + 1, prev_count); + + if (prev_count > count) + count = prev_count; if (PRIVATE_DATA(cc) != 0) common->private_data_ptrs[begin - common->start] = 1; if (count < EARLY_FAIL_ENHANCE_MAX) { - cc = end + (1 + LINK_SIZE); + cc = end; continue; } break; @@ -1514,55 +1603,52 @@ do continue; } - if (accelerated_start != NULL) + if (accelerated_start == NULL) + break; + + if (count == 0) { - if (count == 0) - { - count++; + common->fast_forward_bc_ptr = accelerated_start; + common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_skip; + *private_data_start += sizeof(sljit_sw); + count = 4; + } + else if (count < 3) + { + common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail; - if (fast_forward_allowed) - { - common->fast_forward_bc_ptr = accelerated_start; - common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_skip; - *private_data_start += sizeof(sljit_sw); - } - else - { - common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail; + if (common->early_fail_start_ptr == 0) + common->early_fail_start_ptr = *private_data_start; - if (common->early_fail_start_ptr == 0) - common->early_fail_start_ptr = *private_data_start; + *private_data_start += sizeof(sljit_sw); + common->early_fail_end_ptr = *private_data_start; - *private_data_start += sizeof(sljit_sw); - common->early_fail_end_ptr = *private_data_start; + if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) + return EARLY_FAIL_ENHANCE_MAX; - if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) - return EARLY_FAIL_ENHANCE_MAX; - } - } - else - { - common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail_range; + count = 4; + } + else + { + common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail_range; - if (common->early_fail_start_ptr == 0) - common->early_fail_start_ptr = *private_data_start; + if (common->early_fail_start_ptr == 0) + common->early_fail_start_ptr = *private_data_start; - *private_data_start += 2 * sizeof(sljit_sw); - common->early_fail_end_ptr = *private_data_start; + *private_data_start += 2 * sizeof(sljit_sw); + common->early_fail_end_ptr = *private_data_start; - if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) - return EARLY_FAIL_ENHANCE_MAX; - } + if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) + return EARLY_FAIL_ENHANCE_MAX; - /* Cannot be part of a repeat. */ - common->private_data_ptrs[begin - common->start] = 1; count++; - - if (count < EARLY_FAIL_ENHANCE_MAX) - continue; } - break; + /* Cannot be part of a repeat. */ + common->private_data_ptrs[begin - common->start] = 1; + + if (count >= EARLY_FAIL_ENHANCE_MAX) + break; } if (*cc != OP_ALT && *cc != OP_KET) @@ -1795,7 +1881,6 @@ while (cc < ccend) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: - case OP_ASSERTBACK_NA: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRAPOS: @@ -1807,6 +1892,19 @@ while (cc < ccend) bracketlen = 1 + LINK_SIZE; break; + case OP_ASSERTBACK_NA: + common->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw); + + if (find_vreverse(cc)) + { + common->private_data_ptrs[cc + 1 - common->start] = 1; + private_data_ptr += sizeof(sljit_sw); + } + + bracketlen = 1 + LINK_SIZE; + break; + case OP_CBRAPOS: case OP_SCBRAPOS: common->private_data_ptrs[cc - common->start] = private_data_ptr; @@ -2106,6 +2204,9 @@ while (cc < ccend) case OP_CALLOUT: case OP_CALLOUT_STR: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); break; @@ -2261,7 +2362,7 @@ int i; for (i = 0; i < RECURSE_TMP_REG_COUNT; i++) { SLJIT_ASSERT(status->tmp_regs[i] >= 0); - SLJIT_ASSERT(sljit_get_register_index(status->saved_tmp_regs[i]) < 0 || status->tmp_regs[i] == status->saved_tmp_regs[i]); + SLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, status->saved_tmp_regs[i]) < 0 || status->tmp_regs[i] == status->saved_tmp_regs[i]); status->store_bases[i] = -1; } @@ -2281,7 +2382,7 @@ SLJIT_ASSERT(load_base > 0 && store_base > 0); if (status->store_bases[next_tmp_reg] == -1) { /* Preserve virtual registers. */ - if (sljit_get_register_index(status->saved_tmp_regs[next_tmp_reg]) < 0) + if (sljit_get_register_index(SLJIT_GP_REGISTER, status->saved_tmp_regs[next_tmp_reg]) < 0) OP1(SLJIT_MOV, status->saved_tmp_regs[next_tmp_reg], 0, tmp_reg, 0); } else @@ -2310,7 +2411,7 @@ for (i = 0; i < RECURSE_TMP_REG_COUNT; i++) OP1(SLJIT_MOV, SLJIT_MEM1(status->store_bases[next_tmp_reg]), status->store_offsets[next_tmp_reg], tmp_reg, 0); /* Restore virtual registers. */ - if (sljit_get_register_index(saved_tmp_reg) < 0) + if (sljit_get_register_index(SLJIT_GP_REGISTER, saved_tmp_reg) < 0) OP1(SLJIT_MOV, tmp_reg, 0, saved_tmp_reg, 0); } @@ -3047,8 +3148,16 @@ if (*cc == OP_COND || *cc == OP_SCOND) has_alternatives = FALSE; cc = next_opcode(common, cc); + if (has_alternatives) + { + if (*cc == OP_REVERSE) + cc += 1 + IMM2_SIZE; + else if (*cc == OP_VREVERSE) + cc += 1 + 2 * IMM2_SIZE; + current_offset = common->then_offsets + (cc - common->start); + } while (cc < end) { @@ -3057,7 +3166,18 @@ while (cc < end) else { if (*cc == OP_ALT && has_alternatives) - current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start); + { + cc += 1 + LINK_SIZE; + + if (*cc == OP_REVERSE) + cc += 1 + IMM2_SIZE; + else if (*cc == OP_VREVERSE) + cc += 1 + 2 * IMM2_SIZE; + + current_offset = common->then_offsets + (cc - common->start); + continue; + } + if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) *current_offset = 1; cc = next_opcode(common, cc); @@ -3081,7 +3201,7 @@ return (value & (value - 1)) == 0; static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label) { -while (list) +while (list != NULL) { /* sljit_set_label is clever enough to do nothing if either the jump or the label is NULL. */ @@ -3239,7 +3359,7 @@ if (size == sizeof(sljit_sw)) return; } -if (sljit_get_register_index(TMP3) >= 0 && !sljit_has_cpu_feature(SLJIT_HAS_ZERO_REGISTER)) +if (sljit_get_register_index(SLJIT_GP_REGISTER, TMP3) >= 0 && !sljit_has_cpu_feature(SLJIT_HAS_ZERO_REGISTER)) { OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); src = TMP3; @@ -3818,9 +3938,9 @@ if (common->invalid_utf) { OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); } } #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ @@ -4058,9 +4178,9 @@ if (common->utf) OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400); if (options & READ_CHAR_UPDATE_STR_PTR) - CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0); + SELECT(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0, STR_PTR); if (max >= 0xd800) - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, 0x10000); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, 0x10000, TMP1); } else { @@ -4085,15 +4205,46 @@ if (common->invalid_utf) { OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); } } #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ #endif /* SUPPORT_UNICODE */ } +static void skip_valid_char(compiler_common *common) +{ +DEFINE_COMPILER; +#if (defined SUPPORT_UNICODE) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) +struct sljit_jump *jump; +#endif + +#if (defined SUPPORT_UNICODE) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) + if (common->utf) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if PCRE2_CODE_UNIT_WIDTH == 8 + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +#elif PCRE2_CODE_UNIT_WIDTH == 16 + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xd800); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + JUMPHERE(jump); + return; + } +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +} + #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 static BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass) @@ -4135,6 +4286,7 @@ if (negated) if (common->invalid_utf) { + OP1(SLJIT_MOV, TMP1, 0, TMP2, 0); add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); @@ -4242,7 +4394,7 @@ if (common->utf && negated) { OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400); - CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0); + SELECT(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0, STR_PTR); } else { @@ -4399,7 +4551,7 @@ of the character (>= 0xc0). Return char value in TMP1. */ DEFINE_COMPILER; struct sljit_jump *jump; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); @@ -4445,7 +4597,7 @@ DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_jump *compare; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0x20); jump = JUMP(SLJIT_NOT_ZERO); @@ -4487,7 +4639,7 @@ struct sljit_label *three_byte_entry; struct sljit_label *exit_invalid_label; struct sljit_jump *exit_invalid[11]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc2); @@ -4522,7 +4674,7 @@ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0x20000); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0x20000, TMP1); exit_invalid[2] = NULL; } else @@ -4537,7 +4689,7 @@ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2d800); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0xd800); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0xd800, TMP1); exit_invalid[3] = NULL; } else @@ -4548,7 +4700,7 @@ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); exit_invalid[4] = NULL; } else @@ -4565,7 +4717,7 @@ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0, TMP1); exit_invalid[5] = NULL; } else @@ -4575,7 +4727,7 @@ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc10000); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000, TMP1); exit_invalid[6] = NULL; } else @@ -4612,7 +4764,7 @@ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); exit_invalid[10] = NULL; } else @@ -4643,7 +4795,7 @@ struct sljit_label *skip_start; struct sljit_label *three_byte_exit; struct sljit_jump *jump[5]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); if (common->nltype != NLTYPE_ANY) { @@ -4734,7 +4886,7 @@ struct sljit_label *exit_ok_label; struct sljit_label *exit_invalid_label; struct sljit_jump *exit_invalid[7]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0); @@ -4825,7 +4977,7 @@ static void do_utfpeakcharback(compiler_common *common) DEFINE_COMPILER; struct sljit_jump *jump[2]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); @@ -4868,7 +5020,7 @@ struct sljit_label *three_byte_entry; struct sljit_label *exit_invalid_label; struct sljit_jump *exit_invalid[8]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0); @@ -4905,7 +5057,7 @@ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, -0xd800); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, -0xd800, TMP1); exit_invalid[2] = NULL; } else @@ -4915,7 +5067,7 @@ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); exit_invalid[3] = NULL; } else @@ -4940,7 +5092,7 @@ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000, TMP1); exit_invalid[5] = NULL; } else @@ -5000,7 +5152,7 @@ undefined for invalid characters. */ DEFINE_COMPILER; struct sljit_jump *exit_invalid[3]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); /* TMP2 contains the high surrogate. */ exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00); @@ -5033,7 +5185,7 @@ char value in TMP1. */ DEFINE_COMPILER; struct sljit_jump *exit_invalid[2]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); /* TMP2 contains the high surrogate. */ exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); @@ -5062,7 +5214,7 @@ static void do_utfmoveback_invalid(compiler_common *common) DEFINE_COMPILER; struct sljit_jump *exit_invalid[3]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); exit_invalid[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x400); exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0); @@ -5091,7 +5243,7 @@ DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_jump *exit_invalid[3]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); @@ -5140,7 +5292,7 @@ SLJIT_ASSERT(record->caseset == 0 && record->other_case == 0); SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 12); -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); #if PCRE2_CODE_UNIT_WIDTH == 32 if (!common->utf) @@ -5180,7 +5332,7 @@ SLJIT_ASSERT(record->caseset == 0 && record->other_case == 0); SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 12); -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); #if PCRE2_CODE_UNIT_WIDTH == 32 if (!common->utf) @@ -5379,7 +5531,7 @@ else if (common->utf) { OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x400); - CMOV(SLJIT_LESS, STR_PTR, TMP2, 0); + SELECT(SLJIT_LESS, STR_PTR, TMP2, 0, STR_PTR); } else { @@ -5486,6 +5638,8 @@ while (TRUE) case OP_CIRCM: case OP_DOLL: case OP_DOLLM: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: /* Zero width assertions. */ cc++; continue; @@ -5869,6 +6023,7 @@ static BOOL check_fast_forward_char_pair_simd(compiler_common *common, fast_forw { sljit_s32 i, j, max_i = 0, max_j = 0; sljit_u32 max_pri = 0; + sljit_s32 max_offset = max_fast_forward_char_pair_offset(); PCRE2_UCHAR a1, a2, a_pri, b1, b2, b_pri; for (i = max - 1; i >= 1; i--) @@ -5879,7 +6034,7 @@ static BOOL check_fast_forward_char_pair_simd(compiler_common *common, fast_forw a2 = chars[i].chars[1]; a_pri = chars[i].last_count; - j = i - max_fast_forward_char_pair_offset(); + j = i - max_offset; if (j < 0) j = 0; @@ -5935,7 +6090,7 @@ if (has_match_end) OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offset + 1)); OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0); - CMOV(SLJIT_GREATER, STR_END, TMP1, 0); + SELECT(SLJIT_GREATER, STR_END, TMP1, 0, STR_END); } #ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD @@ -6138,7 +6293,7 @@ if (common->match_end_ptr != 0) OP2(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS)); OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0); - CMOV(SLJIT_GREATER, STR_END, TMP1, 0); + SELECT(SLJIT_GREATER, STR_END, TMP1, 0, STR_END); } else { @@ -6368,7 +6523,7 @@ if (JIT_HAS_FAST_FORWARD_CHAR_SIMD && (common->nltype == NLTYPE_FIXED || common- if (common->mode != PCRE2_JIT_COMPLETE) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); - CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); } } } @@ -6430,7 +6585,7 @@ if (common->match_end_ptr != 0) OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0); - CMOV(SLJIT_GREATER, STR_END, TMP1, 0); + SELECT(SLJIT_GREATER, STR_END, TMP1, 0, STR_END); } start = LABEL(); @@ -6567,13 +6722,14 @@ DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_label *mainloop; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); GET_LOCAL_BASE(TMP1, 0, 0); /* Drop frames until we reach STACK_TOP. */ mainloop = LABEL(); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), -SSIZE_OF(sw)); -jump = CMP(SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0); +OP2U(SLJIT_SUB | SLJIT_SET_SIG_LESS_EQUAL | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0); +jump = JUMP(SLJIT_SIG_LESS_EQUAL); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); if (HAS_VIRTUAL_REGISTERS) @@ -6594,7 +6750,8 @@ else JUMPTO(SLJIT_JUMP, mainloop); JUMPHERE(jump); -jump = CMP(SLJIT_NOT_ZERO /* SIG_LESS */, TMP2, 0, SLJIT_IMM, 0); +sljit_set_current_flags(compiler, SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE | SLJIT_SET_SIG_LESS_EQUAL | SLJIT_SET_Z); +jump = JUMP(SLJIT_NOT_ZERO /* SIG_LESS */); /* End of reverting values. */ OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); @@ -6615,7 +6772,17 @@ else JUMPTO(SLJIT_JUMP, mainloop); } -static void check_wordboundary(compiler_common *common) +#ifdef SUPPORT_UNICODE +#define UCPCAT(bit) (1 << (bit)) +#define UCPCAT2(bit1, bit2) (UCPCAT(bit1) | UCPCAT(bit2)) +#define UCPCAT3(bit1, bit2, bit3) (UCPCAT(bit1) | UCPCAT(bit2) | UCPCAT(bit3)) +#define UCPCAT_RANGE(start, end) (((1 << ((end) + 1)) - 1) - ((1 << (start)) - 1)) +#define UCPCAT_L UCPCAT_RANGE(ucp_Ll, ucp_Lu) +#define UCPCAT_N UCPCAT_RANGE(ucp_Nd, ucp_No) +#define UCPCAT_ALL ((1 << (ucp_Zs + 1)) - 1) +#endif + +static void check_wordboundary(compiler_common *common, BOOL ucp) { DEFINE_COMPILER; struct sljit_jump *skipread; @@ -6629,9 +6796,10 @@ jump_list *invalid_utf2 = NULL; struct sljit_jump *jump; #endif /* PCRE2_CODE_UNIT_WIDTH != 8 || SUPPORT_UNICODE */ +SLJIT_UNUSED_ARG(ucp); SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); -sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); /* Get type of the previous char, and put it to TMP3. */ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); @@ -6668,19 +6836,12 @@ else /* Testing char type. */ #ifdef SUPPORT_UNICODE -if (common->ucp) +if (ucp) { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); - jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - JUMPHERE(jump); - OP1(SLJIT_MOV, TMP3, 0, TMP2, 0); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP1, 0); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N); + OP_FLAGS(SLJIT_MOV, TMP3, 0, SLJIT_NOT_ZERO); } else #endif /* SUPPORT_UNICODE */ @@ -6714,18 +6875,12 @@ peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf2); valid_utf = LABEL(); -if (common->ucp) +if (ucp) { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); - jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - JUMPHERE(jump); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP1, 0); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); } else #endif /* SUPPORT_UNICODE */ @@ -7003,7 +7158,7 @@ while (i < len) else { OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, char_list[i]); - CMOV(SLJIT_ZERO, TMP2, TMP1, 0); + SELECT(SLJIT_ZERO, TMP2, TMP1, 0, TMP2); } i++; } @@ -7017,7 +7172,7 @@ if (j != 0) { j--; OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, char_list[i] & 0xff); - CMOV(SLJIT_ZERO, TMP2, TMP1, 0); + SELECT(SLJIT_ZERO, TMP2, TMP1, 0, TMP2); } } @@ -7042,7 +7197,7 @@ static void check_anynewline(compiler_common *common) /* Check whether TMP1 contains a newline character. TMP2 destroyed. */ DEFINE_COMPILER; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); @@ -7069,7 +7224,7 @@ static void check_hspace(compiler_common *common) /* Check whether TMP1 contains a newline character. TMP2 destroyed. */ DEFINE_COMPILER; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x09); OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); @@ -7108,7 +7263,7 @@ static void check_vspace(compiler_common *common) /* Check whether TMP1 contains a newline character. TMP2 destroyed. */ DEFINE_COMPILER; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); @@ -7150,7 +7305,7 @@ else char2_reg = RETURN_ADDR; } -sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); if (char1_reg == STR_END) @@ -7237,7 +7392,7 @@ if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, else if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS) opt_type = 2; -sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, char1_reg, 0); @@ -7464,16 +7619,6 @@ return cc; #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 -#define SET_TYPE_OFFSET(value) \ - if ((value) != typeoffset) \ - { \ - if ((value) < typeoffset) \ - OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \ - else \ - OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \ - } \ - typeoffset = (value); - #define SET_CHAR_OFFSET(value) \ if ((value) != charoffset) \ { \ @@ -7498,7 +7643,6 @@ static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHA #define XCLASS_SCRIPT_EXTENSION_NOTPROP 0x080 #define XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR 0x100 #define XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0 0x200 - #endif /* SUPPORT_UNICODE */ static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) @@ -7516,9 +7660,10 @@ BOOL utf = common->utf; #ifdef SUPPORT_UNICODE sljit_u32 unicode_status = 0; +sljit_u32 category_list = 0; +sljit_u32 items; int typereg = TMP1; const sljit_u32 *other_cases; -sljit_uw typeoffset; #endif /* SUPPORT_UNICODE */ /* Scanning the necessary info. */ @@ -7535,6 +7680,7 @@ if (cc[-1] & XCL_MAP) while (*cc != XCL_END) { compares++; + if (*cc == XCL_SINGLE) { cc ++; @@ -7561,6 +7707,7 @@ while (*cc != XCL_END) { SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); cc++; + if (*cc == PT_CLIST && cc[-1] == XCL_PROP) { other_cases = PRIV(ucd_caseless_sets) + cc[1]; @@ -7577,24 +7724,36 @@ while (*cc != XCL_END) min = 0; } + items = 0; + switch(*cc) { case PT_ANY: /* Any either accepts everything or ignored. */ if (cc[-1] == XCL_PROP) - { - compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); - if (list == backtracks) - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - return; - } + items = UCPCAT_ALL; + else + compares--; break; case PT_LAMP: + items = UCPCAT3(ucp_Lu, ucp_Ll, ucp_Lt); + break; + case PT_GC: + items = UCPCAT_RANGE(PRIV(ucp_typerange)[(int)cc[1] * 2], PRIV(ucp_typerange)[(int)cc[1] * 2 + 1]); + break; + case PT_PC: + items = UCPCAT(cc[1]); + break; + + case PT_WORD: + items = UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N; + break; + case PT_ALNUM: - unicode_status |= XCLASS_HAS_TYPE; + items = UCPCAT_L | UCPCAT_N; break; case PT_SCX: @@ -7613,7 +7772,6 @@ while (*cc != XCL_END) case PT_SPACE: case PT_PXSPACE: - case PT_WORD: case PT_PXGRAPH: case PT_PXPRINT: case PT_PXPUNCT: @@ -7622,6 +7780,7 @@ while (*cc != XCL_END) case PT_CLIST: case PT_UCNC: + case PT_PXXDIGIT: unicode_status |= XCLASS_SAVE_CHAR; break; @@ -7637,11 +7796,42 @@ while (*cc != XCL_END) SLJIT_UNREACHABLE(); break; } + + if (items > 0) + { + if (cc[-1] == XCL_NOTPROP) + items ^= UCPCAT_ALL; + category_list |= items; + unicode_status |= XCLASS_HAS_TYPE; + compares--; + } + cc += 2; } #endif /* SUPPORT_UNICODE */ } + +#ifdef SUPPORT_UNICODE +if (category_list == UCPCAT_ALL) + { + /* All characters are accepted, same as dotall. */ + compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); + if (list == backtracks) + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + return; + } + +if (compares == 0 && category_list == 0) + { + /* No characters are accepted, same as (*F) or dotall. */ + compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); + if (list != backtracks) + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + return; + } +#else /* !SUPPORT_UNICODE */ SLJIT_ASSERT(compares > 0); +#endif /* SUPPORT_UNICODE */ /* We are not necessary in utf mode even in 8 bit mode. */ cc = ccbegin; @@ -7742,6 +7932,9 @@ if (unicode_status & XCLASS_NEEDS_UCD) ccbegin = cc; + if (category_list != 0) + compares++; + if (unicode_status & XCLASS_HAS_BIDICL) { OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass)); @@ -7946,7 +8139,16 @@ if (unicode_status & XCLASS_NEEDS_UCD) if (unicode_status & XCLASS_SAVE_CHAR) typereg = RETURN_ADDR; - OP1(SLJIT_MOV_U8, typereg, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + OP2(SLJIT_SHL, typereg, 0, SLJIT_IMM, 1, TMP2, 0); + + if (category_list > 0) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, category_list); + add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); + } } } #endif /* SUPPORT_UNICODE */ @@ -7954,9 +8156,6 @@ if (unicode_status & XCLASS_NEEDS_UCD) /* Generating code. */ charoffset = 0; numberofcmps = 0; -#ifdef SUPPORT_UNICODE -typeoffset = 0; -#endif /* SUPPORT_UNICODE */ while (*cc != XCL_END) { @@ -8024,36 +8223,17 @@ while (*cc != XCL_END) switch(*cc) { case PT_ANY: - if (!invertcmp) - jump = JUMP(SLJIT_JUMP); - break; - case PT_LAMP: - OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - case PT_GC: - c = PRIV(ucp_typerange)[(int)cc[1] * 2]; - SET_TYPE_OFFSET(c); - jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c); - break; - case PT_PC: - jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset); - break; - case PT_SC: case PT_SCX: case PT_BOOL: case PT_BIDICL: + case PT_WORD: + case PT_ALNUM: compares++; - /* Do nothing. */ + /* Already handled. */ break; case PT_SPACE: @@ -8068,24 +8248,8 @@ while (*cc != XCL_END) OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - SET_TYPE_OFFSET(ucp_Zl); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_WORD: - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - /* Fall through. */ - - case PT_ALNUM: - SET_TYPE_OFFSET(ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - SET_TYPE_OFFSET(ucp_Nd); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Zl, ucp_Zs)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); break; @@ -8160,13 +8324,13 @@ while (*cc != XCL_END) break; case PT_PXGRAPH: - /* C and Z groups are the farthest two groups. */ - SET_TYPE_OFFSET(ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_GREATER, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT_RANGE(ucp_Zl, ucp_Zs)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); - jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); + jump = JUMP(SLJIT_ZERO); + c = charoffset; /* In case of ucp_Cf, we overwrite the result. */ SET_CHAR_OFFSET(0x2066); OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); @@ -8178,21 +8342,21 @@ while (*cc != XCL_END) OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + /* Restore charoffset. */ + SET_CHAR_OFFSET(c); + JUMPHERE(jump); jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); break; case PT_PXPRINT: - /* C and Z groups are the farthest two groups. */ - SET_TYPE_OFFSET(ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_GREATER, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT2(ucp_Zl, ucp_Zp)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); - OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll); - OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_NOT_EQUAL); - - jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); + jump = JUMP(SLJIT_ZERO); + c = charoffset; /* In case of ucp_Cf, we overwrite the result. */ SET_CHAR_OFFSET(0x2066); OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); @@ -8201,22 +8365,54 @@ while (*cc != XCL_END) OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + /* Restore charoffset. */ + SET_CHAR_OFFSET(c); + JUMPHERE(jump); jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); break; case PT_PXPUNCT: - SET_TYPE_OFFSET(ucp_Sc); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Sc, ucp_So)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); SET_CHAR_OFFSET(0); OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x7f); OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_LESS_EQUAL); - SET_TYPE_OFFSET(ucp_Pc); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Pc, ucp_Ps)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_PXXDIGIT: + SET_CHAR_OFFSET(CHAR_A); + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, ~0x20); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP2, 0, SLJIT_IMM, CHAR_F - CHAR_A); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(CHAR_0); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_9 - CHAR_0); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff10); + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff10); + + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff19 - 0xff10); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff21); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff26 - 0xff21); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff41); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff41); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff10); + + JUMPHERE(jump); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0); jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); break; @@ -8232,6 +8428,7 @@ while (*cc != XCL_END) add_jump(compiler, compares > 0 ? list : backtracks, jump); } +SLJIT_ASSERT(compares == 0); if (found != NULL) set_jumps(found, LABEL()); } @@ -8244,11 +8441,7 @@ if (found != NULL) static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks) { DEFINE_COMPILER; -int length; struct sljit_jump *jump[4]; -#ifdef SUPPORT_UNICODE -struct sljit_label *label; -#endif /* SUPPORT_UNICODE */ switch(type) { @@ -8276,16 +8469,18 @@ switch(type) case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: - add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + add_jump(compiler, (type == OP_NOT_WORD_BOUNDARY || type == OP_WORD_BOUNDARY) ? &common->wordboundary : &common->ucp_wordboundary, JUMP(SLJIT_FAST_CALL)); #ifdef SUPPORT_UNICODE if (common->invalid_utf) { - add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0)); return cc; } #endif /* SUPPORT_UNICODE */ sljit_set_current_flags(compiler, SLJIT_SET_Z); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + add_jump(compiler, backtracks, JUMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_ZERO : SLJIT_ZERO)); return cc; case OP_EODN: @@ -8481,36 +8676,6 @@ switch(type) } JUMPHERE(jump[0]); return cc; - - case OP_REVERSE: - length = GET(cc, 0); - if (length == 0) - return cc + LINK_SIZE; - if (HAS_VIRTUAL_REGISTERS) - { - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - } - else - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); -#ifdef SUPPORT_UNICODE - if (common->utf) - { - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, length); - label = LABEL(); - add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0)); - move_back(common, backtracks, FALSE); - OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - else -#endif - { - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0)); - } - check_start_used_ptr(common); - return cc + LINK_SIZE; } SLJIT_UNREACHABLE(); return cc; @@ -8667,7 +8832,7 @@ c = *cc++; #if PCRE2_CODE_UNIT_WIDTH == 32 if (c >= 0x110000) - return NULL; + return cc; #endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ lgb = UCD_GRAPHBREAK(c); @@ -8809,35 +8974,14 @@ switch(type) if (check_str_ptr) detect_partial_match(common, backtracks); #ifdef SUPPORT_UNICODE - if (common->utf) + if (common->utf && common->invalid_utf) { - if (common->invalid_utf) - { - read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR); - return cc; - } - -#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if PCRE2_CODE_UNIT_WIDTH == 8 - jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -#elif PCRE2_CODE_UNIT_WIDTH == 16 - jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xd800); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - JUMPHERE(jump[0]); + read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR); return cc; -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ } #endif /* SUPPORT_UNICODE */ - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + + skip_valid_char(common); return cc; case OP_ANYBYTE: @@ -8928,7 +9072,7 @@ switch(type) #else sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_no_utf)); - if (!common->utf || common->invalid_utf) + if (common->invalid_utf) add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); #endif @@ -8990,7 +9134,7 @@ switch(type) if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) { OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, oc); - CMOV(SLJIT_EQUAL, TMP1, SLJIT_IMM, c); + SELECT(SLJIT_EQUAL, TMP1, SLJIT_IMM, c, TMP1); add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); } else @@ -9509,14 +9653,16 @@ if (!minimize) if (ref) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + if (ref) { - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); + if (!common->unset_backref) + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); } else { - compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); + compile_dnref_search(common, ccbegin, &backtrack->own_backtracks); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); @@ -9529,7 +9675,7 @@ if (!minimize) label = LABEL(); if (!ref) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); - compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); + compile_ref_matchingpath(common, ccbegin, &backtrack->own_backtracks, FALSE, FALSE); if (min > 1 || max > 1) { @@ -9591,12 +9737,13 @@ else { if (ref) { - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); + if (!common->unset_backref) + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); } else { - compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); + compile_dnref_search(common, ccbegin, &backtrack->own_backtracks); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); @@ -9605,11 +9752,11 @@ else BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL(); if (max > 0) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); if (!ref) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); -compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); +compile_ref_matchingpath(common, ccbegin, &backtrack->own_backtracks, TRUE, TRUE); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); if (min > 1) @@ -9684,12 +9831,12 @@ if (entry->entry_label == NULL) else JUMPTO(SLJIT_FAST_CALL, entry->entry_label); /* Leave if the match is failed. */ -add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0)); +add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0)); BACKTRACK_AS(recurse_backtrack)->matchingpath = LABEL(); return cc + 1 + LINK_SIZE; } -static sljit_s32 SLJIT_FUNC do_callout_jit(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector) +static sljit_s32 SLJIT_FUNC SLJIT_FUNC_ATTRIBUTE do_callout_jit(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector) { PCRE2_SPTR begin; PCRE2_SIZE *ovector; @@ -9812,7 +9959,7 @@ free_stack(common, callout_arg_size); /* Check return value. */ OP2U(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); -add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER)); +add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_SIG_GREATER)); if (common->abort_label == NULL) add_jump(compiler, &common->abort, JUMP(SLJIT_NOT_EQUAL) /* SIG_LESS */); else @@ -9823,6 +9970,106 @@ return cc + callout_length; #undef CALLOUT_ARG_SIZE #undef CALLOUT_ARG_OFFSET +static PCRE2_SPTR compile_reverse_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack = NULL; +jump_list **reverse_failed; +unsigned int lmin, lmax; +#ifdef SUPPORT_UNICODE +struct sljit_jump *jump; +struct sljit_label *label; +#endif + +SLJIT_ASSERT(parent->top == NULL); + +if (*cc == OP_REVERSE) + { + reverse_failed = &parent->own_backtracks; + lmin = GET2(cc, 1); + lmax = lmin; + cc += 1 + IMM2_SIZE; + + SLJIT_ASSERT(lmin > 0); + } +else + { + SLJIT_ASSERT(*cc == OP_VREVERSE); + PUSH_BACKTRACK(sizeof(vreverse_backtrack), cc, NULL); + + reverse_failed = &backtrack->own_backtracks; + lmin = GET2(cc, 1); + lmax = GET2(cc, 1 + IMM2_SIZE); + cc += 1 + 2 * IMM2_SIZE; + + SLJIT_ASSERT(lmin < lmax); + } + +if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + } +else + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + +#ifdef SUPPORT_UNICODE +if (common->utf) + { + if (lmin > 0) + { + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, lmin); + label = LABEL(); + add_jump(compiler, reverse_failed, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0)); + move_back(common, reverse_failed, FALSE); + OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + + if (lmin < lmax) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0); + + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, lmax - lmin); + label = LABEL(); + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); + move_back(common, reverse_failed, FALSE); + OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + + JUMPHERE(jump); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0); + } + } +else +#endif + { + if (lmin > 0) + { + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(lmin)); + add_jump(compiler, reverse_failed, CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0)); + } + + if (lmin < lmax) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0); + + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(lmax - lmin)); + OP2U(SLJIT_SUB | SLJIT_SET_LESS, STR_PTR, 0, TMP2, 0); + SELECT(SLJIT_LESS, STR_PTR, TMP2, 0, STR_PTR); + + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0); + } + } + +check_start_used_ptr(common); + +if (lmin < lmax) + BACKTRACK_AS(vreverse_backtrack)->matchingpath = LABEL(); + +return cc; +} + static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(PCRE2_SPTR cc) { while (TRUE) @@ -9841,6 +10088,8 @@ while (TRUE) case OP_DOLLM: case OP_CALLOUT: case OP_ALT: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: cc += PRIV(OP_lengths)[*cc]; break; @@ -9860,13 +10109,15 @@ int framesize; int extrasize; BOOL local_quit_available = FALSE; BOOL needs_control_head; +BOOL end_block_size = 0; +BOOL has_vreverse; int private_data_ptr; backtrack_common altbacktrack; PCRE2_SPTR ccbegin; PCRE2_UCHAR opcode; PCRE2_UCHAR bra = OP_BRA; jump_list *tmp = NULL; -jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; +jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.own_backtracks; jump_list **found; /* Saving previous accept variables. */ BOOL save_local_quit_available = common->local_quit_available; @@ -9889,6 +10140,7 @@ if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) bra = *cc; cc++; } + private_data_ptr = PRIVATE_DATA(cc); SLJIT_ASSERT(private_data_ptr != 0); framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); @@ -9908,12 +10160,17 @@ if (bra == OP_BRAMINZERO) brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); } +if ((opcode == OP_ASSERTBACK || opcode == OP_ASSERTBACK_NOT) && find_vreverse(ccbegin)) + end_block_size = 3; + if (framesize < 0) { extrasize = 1; if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE)) extrasize = 0; + extrasize += end_block_size; + if (needs_control_head) extrasize++; @@ -9931,18 +10188,19 @@ if (framesize < 0) if (needs_control_head) { - SLJIT_ASSERT(extrasize == 2); + SLJIT_ASSERT(extrasize == end_block_size + 2); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1), TMP1, 0); } } else { - extrasize = needs_control_head ? 3 : 2; + extrasize = (needs_control_head ? 3 : 2) + end_block_size; + + OP1(SLJIT_MOV, TMP2, 0, STACK_TOP, 0); allocate_stack(common, framesize + extrasize); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP2(SLJIT_ADD, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); if (needs_control_head) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); @@ -9950,16 +10208,22 @@ else if (needs_control_head) { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 2), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1), TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); } else - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1), TMP1, 0); init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize); } +if (end_block_size > 0) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, STR_PTR, 0); + } + memset(&altbacktrack, 0, sizeof(backtrack_common)); if (conditional || (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)) { @@ -9978,13 +10242,19 @@ while (1) common->accept_label = NULL; common->accept = NULL; altbacktrack.top = NULL; - altbacktrack.topbacktracks = NULL; + altbacktrack.own_backtracks = NULL; if (*ccbegin == OP_ALT && extrasize > 0) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); altbacktrack.cc = ccbegin; - compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); + ccbegin += 1 + LINK_SIZE; + + has_vreverse = (*ccbegin == OP_VREVERSE); + if (*ccbegin == OP_REVERSE || has_vreverse) + ccbegin = compile_reverse_matchingpath(common, ccbegin, &altbacktrack); + + compile_matchingpath(common, ccbegin, cc, &altbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { if (local_quit_available) @@ -10000,6 +10270,13 @@ while (1) common->accept = save_accept; return NULL; } + + if (has_vreverse) + { + SLJIT_ASSERT(altbacktrack.top != NULL); + add_jump(compiler, &altbacktrack.top->simple_backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + } + common->accept_label = LABEL(); if (common->accept != NULL) set_jumps(common->accept, common->accept_label); @@ -10012,6 +10289,9 @@ while (1) else if (extrasize > 0) free_stack(common, extrasize); + if (end_block_size > 0) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize + 1)); + if (needs_control_head) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1)); } @@ -10021,12 +10301,20 @@ while (1) { /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); + + if (end_block_size > 0) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize + 2)); + if (needs_control_head) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1)); } else { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + + if (end_block_size > 0) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(-framesize - extrasize + 1)); + if (needs_control_head) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 2)); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); @@ -10040,7 +10328,7 @@ while (1) if (conditional) { if (extrasize > 0) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? STACK(-2) : STACK(-1)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-end_block_size - (needs_control_head ? 2 : 1))); } else if (bra == OP_BRAZERO) { @@ -10079,7 +10367,7 @@ while (1) common->accept = save_accept; return NULL; } - set_jumps(altbacktrack.topbacktracks, LABEL()); + set_jumps(altbacktrack.own_backtracks, LABEL()); if (*cc != OP_ALT) break; @@ -10112,8 +10400,11 @@ if (common->positive_assertion_quit != NULL) JUMPHERE(jump); } +if (end_block_size > 0) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1)); if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) { @@ -10126,8 +10417,8 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) /* The topmost item should be 0. */ if (bra == OP_BRAZERO) { - if (extrasize == 2) - free_stack(common, 1); + if (extrasize >= 2) + free_stack(common, extrasize - 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } else if (extrasize > 0) @@ -10161,8 +10452,9 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) /* Keep the STR_PTR on the top of the stack. */ if (bra == OP_BRAZERO) { + /* This allocation is always successful. */ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); - if (extrasize == 2) + if (extrasize >= 2) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); } else if (bra == OP_BRAMINZERO) @@ -10182,8 +10474,9 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) else { /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ - OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw)); - if (extrasize == 2) + OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + end_block_size + 2) * sizeof(sljit_sw)); + + if (extrasize == 2 + end_block_size) { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); if (bra == OP_BRAMINZERO) @@ -10191,7 +10484,7 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) } else { - SLJIT_ASSERT(extrasize == 3); + SLJIT_ASSERT(extrasize == 3 + end_block_size); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-1)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); } @@ -10215,7 +10508,7 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); } - set_jumps(backtrack->common.topbacktracks, LABEL()); + set_jumps(backtrack->common.own_backtracks, LABEL()); } } else @@ -10228,8 +10521,8 @@ else if (bra != OP_BRA) { - if (extrasize == 2) - free_stack(common, 1); + if (extrasize >= 2) + free_stack(common, extrasize - 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } else if (extrasize > 0) @@ -10260,9 +10553,9 @@ else if (bra != OP_BRA) { - SLJIT_ASSERT(found == &backtrack->common.topbacktracks); - set_jumps(backtrack->common.topbacktracks, LABEL()); - backtrack->common.topbacktracks = NULL; + SLJIT_ASSERT(found == &backtrack->common.own_backtracks); + set_jumps(backtrack->common.own_backtracks, LABEL()); + backtrack->common.own_backtracks = NULL; } } @@ -10371,7 +10664,7 @@ static PCRE2_SPTR SLJIT_FUNC do_script_run_utf(PCRE2_SPTR ptr, PCRE2_SPTR endptr #endif /* SUPPORT_UNICODE */ -static SLJIT_INLINE void match_script_run_common(compiler_common *common, int private_data_ptr, backtrack_common *parent) +static void match_script_run_common(compiler_common *common, int private_data_ptr, backtrack_common *parent) { DEFINE_COMPILER; @@ -10386,7 +10679,7 @@ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FU #endif OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); -add_jump(compiler, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); +add_jump(compiler, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); } /* @@ -10460,6 +10753,7 @@ PCRE2_UCHAR ket; assert_backtrack *assert; BOOL has_alternatives; BOOL needs_control_head = FALSE; +BOOL has_vreverse = FALSE; struct sljit_jump *jump; struct sljit_jump *skip; struct sljit_label *rmax_label = NULL; @@ -10709,6 +11003,21 @@ else if (opcode == OP_CBRA || opcode == OP_SCBRA) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); } } +else if (opcode == OP_ASSERTBACK_NA && PRIVATE_DATA(ccbegin + 1)) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + allocate_stack(common, 4); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), STR_END, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + OP1(SLJIT_MOV, STR_END, 0, STR_PTR, 0); + + has_vreverse = (*matchingpath == OP_VREVERSE); + if (*matchingpath == OP_REVERSE || has_vreverse) + matchingpath = compile_reverse_matchingpath(common, matchingpath, backtrack); + } else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) { /* Saving the previous value. */ @@ -10716,6 +11025,9 @@ else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SC allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + + if (*matchingpath == OP_REVERSE) + matchingpath = compile_reverse_matchingpath(common, matchingpath, backtrack); } else if (has_alternatives) { @@ -10835,14 +11147,28 @@ compile_matchingpath(common, matchingpath, cc, backtrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; -if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); +switch (opcode) + { + case OP_ASSERTBACK_NA: + if (has_vreverse) + { + SLJIT_ASSERT(backtrack->top != NULL && PRIVATE_DATA(ccbegin + 1)); + add_jump(compiler, &backtrack->top->simple_backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + } -if (opcode == OP_ONCE) - match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); - -if (opcode == OP_SCRIPT_RUN) - match_script_run_common(common, private_data_ptr, backtrack); + if (PRIVATE_DATA(ccbegin + 1)) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + break; + case OP_ASSERT_NA: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + break; + case OP_ONCE: + match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); + break; + case OP_SCRIPT_RUN: + match_script_run_common(common, private_data_ptr, backtrack); + break; + } stacksize = 0; if (repeat_type == OP_MINUPTO) @@ -11041,7 +11367,7 @@ switch(opcode) case OP_CBRAPOS: case OP_SCBRAPOS: offset = GET2(cc, 1 + LINK_SIZE); - /* This case cannot be optimized in the same was as + /* This case cannot be optimized in the same way as normal capturing brackets. */ SLJIT_ASSERT(common->optimized_cbracket[offset] == 0); cbraprivptr = OVECTOR_PRIV(offset); @@ -11158,7 +11484,7 @@ loop = LABEL(); while (*cc != OP_KETRPOS) { backtrack->top = NULL; - backtrack->topbacktracks = NULL; + backtrack->own_backtracks = NULL; cc += GET(cc, 1); compile_matchingpath(common, ccbegin, cc, backtrack); @@ -11239,7 +11565,7 @@ while (*cc != OP_KETRPOS) compile_backtrackingpath(common, backtrack->top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; - set_jumps(backtrack->topbacktracks, LABEL()); + set_jumps(backtrack->own_backtracks, LABEL()); if (framesize < 0) { @@ -11271,13 +11597,13 @@ while (*cc != OP_KETRPOS) /* We don't have to restore the control head in case of a failed match. */ -backtrack->topbacktracks = NULL; +backtrack->own_backtracks = NULL; if (!zero) { if (framesize < 0) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); else /* TMP2 is set to [private_data_ptr] above. */ - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), STACK(-stacksize), SLJIT_IMM, 0)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), STACK(-stacksize), SLJIT_IMM, 0)); } /* None of them matched. */ @@ -11473,7 +11799,7 @@ SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || early_fail_ptr == 0 || (early_fail_ptr >= common->early_fail_start_ptr && early_fail_ptr <= common->early_fail_end_ptr)); if (early_fail_type == type_fail) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr)); cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end); @@ -11500,10 +11826,10 @@ if (exact > 1) && type != OP_ANYNL && type != OP_EXTUNI) { OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact)); - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0)); OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, FALSE); OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); JUMPTO(SLJIT_NOT_ZERO, label); } @@ -11511,13 +11837,13 @@ if (exact > 1) { OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); JUMPTO(SLJIT_NOT_ZERO, label); } } else if (exact == 1) - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); if (early_fail_type == type_fail_range) { @@ -11526,7 +11852,7 @@ if (early_fail_type == type_fail_range) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0); OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0); - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw), STR_PTR, 0); @@ -11606,7 +11932,7 @@ switch(opcode) if (common->mode == PCRE2_JIT_COMPLETE) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); - CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); } else { @@ -11674,14 +12000,14 @@ switch(opcode) if (opcode == OP_UPTO) { OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO)); + add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_ZERO)); } - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, FALSE); if (early_fail_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); JUMPHERE(jump); - detect_partial_match(common, &backtrack->topbacktracks); + detect_partial_match(common, &backtrack->own_backtracks); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); if (charpos_othercasebit != 0) OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); @@ -11835,7 +12161,7 @@ switch(opcode) } #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) + if (type == OP_EXTUNI || common->utf) { OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); detect_partial_match(common, &no_match); @@ -11899,7 +12225,7 @@ switch(opcode) if (common->mode == PCRE2_JIT_COMPLETE) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); - CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); } else { @@ -11952,12 +12278,12 @@ PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); if (*cc == OP_FAIL) { - add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); + add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_JUMP)); return cc + 1; } if (*cc == OP_ACCEPT && common->currententry == NULL && (common->re->overall_options & PCRE2_ENDANCHORED) != 0) - add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); + add_jump(compiler, &common->restart_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty) { @@ -11983,7 +12309,7 @@ else OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options)); OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY); -add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO)); +add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_NOT_ZERO)); OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART); if (common->accept_label == NULL) add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO)); @@ -11995,7 +12321,7 @@ if (common->accept_label == NULL) add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); else CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label); -add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); +add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_JUMP)); return cc + 1; } @@ -12115,8 +12441,9 @@ while (cc < ccend) case OP_DOLLM: case OP_CIRC: case OP_CIRCM: - case OP_REVERSE: - cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); break; case OP_NOT_DIGIT: @@ -12138,7 +12465,7 @@ while (cc < ccend) case OP_EXTUNI: case OP_NOT: case OP_NOTI: - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; case OP_SET_SOM: @@ -12153,9 +12480,9 @@ while (cc < ccend) case OP_CHAR: case OP_CHARI: if (common->mode == PCRE2_JIT_COMPLETE) - cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; case OP_STAR: @@ -12231,7 +12558,7 @@ while (cc < ccend) if (cc[1 + (32 / sizeof(PCRE2_UCHAR))] >= OP_CRSTAR && cc[1 + (32 / sizeof(PCRE2_UCHAR))] <= OP_CRPOSRANGE) cc = compile_iterator_matchingpath(common, cc, parent); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 @@ -12239,7 +12566,7 @@ while (cc < ccend) if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE) cc = compile_iterator_matchingpath(common, cc, parent); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; #endif @@ -12249,7 +12576,7 @@ while (cc < ccend) cc = compile_ref_iterator_matchingpath(common, cc, parent); else { - compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE, FALSE); cc += 1 + IMM2_SIZE; } break; @@ -12260,8 +12587,8 @@ while (cc < ccend) cc = compile_ref_iterator_matchingpath(common, cc, parent); else { - compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); - compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); + compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE, FALSE); cc += 1 + 2 * IMM2_SIZE; } break; @@ -12539,7 +12866,7 @@ switch(opcode) break; } -set_jumps(current->topbacktracks, LABEL()); +set_jumps(current->own_backtracks, LABEL()); } static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) @@ -12554,7 +12881,7 @@ type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE]; if ((type & 0x1) == 0) { /* Maximize case. */ - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath); @@ -12563,7 +12890,7 @@ if ((type & 0x1) == 0) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath); -set_jumps(current->topbacktracks, LABEL()); +set_jumps(current->own_backtracks, LABEL()); free_stack(common, ref ? 2 : 3); } @@ -12584,7 +12911,7 @@ if (!CURRENT_AS(recurse_backtrack)->inlined_pattern) else compile_backtrackingpath(common, current->top); -set_jumps(current->topbacktracks, LABEL()); +set_jumps(current->own_backtracks, LABEL()); } static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current) @@ -12603,13 +12930,13 @@ if (*cc == OP_BRAZERO) if (bra == OP_BRAZERO) { - SLJIT_ASSERT(current->topbacktracks == NULL); + SLJIT_ASSERT(current->own_backtracks == NULL); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); } if (CURRENT_AS(assert_backtrack)->framesize < 0) { - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); if (bra == OP_BRAZERO) { @@ -12641,10 +12968,10 @@ if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(assert_backtrack)->framesize - 1) * sizeof(sljit_sw)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, TMP1, 0); - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); } else - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); if (bra == OP_BRAZERO) { @@ -12671,6 +12998,7 @@ PCRE2_UCHAR ket; assert_backtrack *assert; BOOL has_alternatives; BOOL needs_control_head = FALSE; +BOOL has_vreverse; struct sljit_jump *brazero = NULL; struct sljit_jump *next_alt = NULL; struct sljit_jump *once = NULL; @@ -12847,8 +13175,8 @@ else if (has_alternatives) } COMPILE_BACKTRACKINGPATH(current->top); -if (current->topbacktracks) - set_jumps(current->topbacktracks, LABEL()); +if (current->own_backtracks) + set_jumps(current->own_backtracks, LABEL()); if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) { @@ -12884,14 +13212,25 @@ if (has_alternatives) do { current->top = NULL; - current->topbacktracks = NULL; - current->nextbacktracks = NULL; + current->own_backtracks = NULL; + current->simple_backtracks = NULL; /* Conditional blocks always have an additional alternative, even if it is empty. */ if (*cc == OP_ALT) { ccprev = cc + 1 + LINK_SIZE; cc += GET(cc, 1); - if (opcode != OP_COND && opcode != OP_SCOND) + + has_vreverse = FALSE; + if (opcode == OP_ASSERTBACK || opcode == OP_ASSERTBACK_NA) + { + SLJIT_ASSERT(private_data_ptr != 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + + has_vreverse = (*ccprev == OP_VREVERSE); + if (*ccprev == OP_REVERSE || has_vreverse) + ccprev = compile_reverse_matchingpath(common, ccprev, current); + } + else if (opcode != OP_COND && opcode != OP_SCOND) { if (opcode != OP_ONCE) { @@ -12903,15 +13242,30 @@ if (has_alternatives) else OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0)); } + compile_matchingpath(common, ccprev, cc, current); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return; - if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + switch (opcode) + { + case OP_ASSERTBACK_NA: + if (has_vreverse) + { + SLJIT_ASSERT(current->top != NULL && PRIVATE_DATA(ccbegin + 1)); + add_jump(compiler, ¤t->top->simple_backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + } - if (opcode == OP_SCRIPT_RUN) - match_script_run_common(common, private_data_ptr, current); + if (PRIVATE_DATA(ccbegin + 1)) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + break; + case OP_ASSERT_NA: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + break; + case OP_SCRIPT_RUN: + match_script_run_common(common, private_data_ptr, current); + break; + } } /* Instructions after the current alternative is successfully matched. */ @@ -12998,9 +13352,9 @@ if (has_alternatives) } COMPILE_BACKTRACKINGPATH(current->top); - if (current->topbacktracks) - set_jumps(current->topbacktracks, LABEL()); - SLJIT_ASSERT(!current->nextbacktracks); + if (current->own_backtracks) + set_jumps(current->own_backtracks, LABEL()); + SLJIT_ASSERT(!current->simple_backtracks); } while (*cc == OP_ALT); @@ -13042,6 +13396,15 @@ if (offset != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); } } +else if (opcode == OP_ASSERTBACK_NA && PRIVATE_DATA(ccbegin + 1)) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP2, 0); + free_stack(common, 4); + } else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0)); @@ -13128,12 +13491,19 @@ static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *co DEFINE_COMPILER; int offset; struct sljit_jump *jump; +PCRE2_SPTR cc; +/* No retry on backtrack, just drop everything. */ if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) { - if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS) + cc = current->cc; + + if (*cc == OP_BRAPOSZERO) + cc++; + + if (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS) { - offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1; + offset = (GET2(cc, 1 + LINK_SIZE)) << 1; OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); @@ -13143,7 +13513,7 @@ if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) if (common->capture_last_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0); } - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); return; } @@ -13152,10 +13522,10 @@ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtra add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(bracketpos_backtrack)->framesize - 1) * sizeof(sljit_sw)); -if (current->topbacktracks) +if (current->own_backtracks) { jump = JUMP(SLJIT_JUMP); - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); /* Drop the stack frame. */ free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); JUMPHERE(jump); @@ -13168,8 +13538,8 @@ static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *co assert_backtrack backtrack; current->top = NULL; -current->topbacktracks = NULL; -current->nextbacktracks = NULL; +current->own_backtracks = NULL; +current->simple_backtracks = NULL; if (current->cc[1] > OP_ASSERTBACK_NOT) { /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */ @@ -13184,7 +13554,7 @@ else /* Manual call of compile_assert_matchingpath. */ compile_assert_matchingpath(common, current->cc, &backtrack, FALSE); } -SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); +SLJIT_ASSERT(!current->simple_backtracks && !current->own_backtracks); } static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current) @@ -13249,6 +13619,23 @@ else add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP)); } +static SLJIT_INLINE void compile_vreverse_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_label *label; + +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); +jump = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(3)); +skip_valid_char(common); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0); +JUMPTO(SLJIT_JUMP, CURRENT_AS(vreverse_backtrack)->matchingpath); + +label = LABEL(); +sljit_set_label(jump, label); +set_jumps(current->own_backtracks, label); +} + static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; @@ -13289,8 +13676,8 @@ then_trap_backtrack *save_then_trap = common->then_trap; while (current) { - if (current->nextbacktracks != NULL) - set_jumps(current->nextbacktracks, LABEL()); + if (current->simple_backtracks != NULL) + set_jumps(current->simple_backtracks, LABEL()); switch(*current->cc) { case OP_SET_SOM: @@ -13456,7 +13843,11 @@ while (current) case OP_FAIL: case OP_ACCEPT: case OP_ASSERT_ACCEPT: - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); + break; + + case OP_VREVERSE: + compile_vreverse_backtrackingpath(common, current); break; case OP_THEN_TRAP: @@ -13502,7 +13893,7 @@ SLJIT_ASSERT(common->currententry->entry_label == NULL && common->recursive_head common->currententry->entry_label = LABEL(); set_jumps(common->currententry->entry_calls, common->currententry->entry_label); -sljit_emit_fast_enter(compiler, TMP2, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, TMP2, 0); count_match(common); local_size = (alt_max > 1) ? 2 : 1; @@ -13535,7 +13926,7 @@ cc += GET(cc, 1); while (1) { altbacktrack.top = NULL; - altbacktrack.topbacktracks = NULL; + altbacktrack.own_backtracks = NULL; if (altbacktrack.cc != ccbegin) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); @@ -13564,7 +13955,7 @@ while (1) common->currententry->backtrack_label = LABEL(); set_jumps(common->currententry->backtrack_calls, common->currententry->backtrack_label); - sljit_emit_fast_enter(compiler, TMP1, 0); + sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, TMP1, 0); if (recurse_flags & recurse_flag_accept_found) accept_exit = CMP(SLJIT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, -1); @@ -13612,7 +14003,7 @@ while (1) compile_backtrackingpath(common, altbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return; - set_jumps(altbacktrack.topbacktracks, LABEL()); + set_jumps(altbacktrack.own_backtracks, LABEL()); if (*cc != OP_ALT) break; @@ -13718,9 +14109,9 @@ jump_list *reqcu_not_found = NULL; SLJIT_ASSERT(tables); #if HAS_VIRTUAL_REGISTERS == 1 -SLJIT_ASSERT(sljit_get_register_index(TMP3) < 0 && sljit_get_register_index(ARGUMENTS) < 0 && sljit_get_register_index(RETURN_ADDR) < 0); +SLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, TMP3) < 0 && sljit_get_register_index(SLJIT_GP_REGISTER, ARGUMENTS) < 0 && sljit_get_register_index(SLJIT_GP_REGISTER, RETURN_ADDR) < 0); #elif HAS_VIRTUAL_REGISTERS == 0 -SLJIT_ASSERT(sljit_get_register_index(TMP3) >= 0 && sljit_get_register_index(ARGUMENTS) >= 0 && sljit_get_register_index(RETURN_ADDR) >= 0); +SLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, TMP3) >= 0 && sljit_get_register_index(SLJIT_GP_REGISTER, ARGUMENTS) >= 0 && sljit_get_register_index(SLJIT_GP_REGISTER, RETURN_ADDR) >= 0); #else #error "Invalid value for HAS_VIRTUAL_REGISTERS" #endif @@ -13892,13 +14283,13 @@ memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32)); private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && !common->has_skip_in_assert_back) - detect_early_fail(common, common->start, &private_data_size, 0, 0, TRUE); + detect_early_fail(common, common->start, &private_data_size, 0, 0); set_private_data_ptrs(common, &private_data_size, ccend); SLJIT_ASSERT(common->early_fail_start_ptr <= common->early_fail_end_ptr); -if (private_data_size > SLJIT_MAX_LOCAL_SIZE) +if (private_data_size > 65536) { SLJIT_FREE(common->private_data_ptrs, allocator_data); SLJIT_FREE(common->optimized_cbracket, allocator_data); @@ -13923,7 +14314,7 @@ common->compiler = compiler; /* Main pcre2_jit_exec entry. */ SLJIT_ASSERT((private_data_size & (sizeof(sljit_sw) - 1)) == 0); -sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, W), 5, 5, 0, 0, private_data_size); +sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, W), 5, 5, SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS, 0, private_data_size); /* Register init. */ reset_ovector(common, (re->top_bracket + 1) * 2); @@ -14187,7 +14578,7 @@ common->quit_label = quit_label; /* This is a (really) rare case. */ set_jumps(common->stackalloc, LABEL()); /* RETURN_ADDR is not a saved register. */ -sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); @@ -14225,7 +14616,12 @@ if (common->revertframes != NULL) if (common->wordboundary != NULL) { set_jumps(common->wordboundary, LABEL()); - check_wordboundary(common); + check_wordboundary(common, FALSE); + } +if (common->ucp_wordboundary != NULL) + { + set_jumps(common->ucp_wordboundary, LABEL()); + check_wordboundary(common, TRUE); } if (common->anynewline != NULL) { @@ -14252,10 +14648,17 @@ if (common->caselesscmp != NULL) set_jumps(common->caselesscmp, LABEL()); do_caselesscmp(common); } -if (common->reset_match != NULL) +if (common->reset_match != NULL || common->restart_match != NULL) { + if (common->restart_match != NULL) + { + set_jumps(common->restart_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); + } + set_jumps(common->reset_match, LABEL()); do_reset_match(common, (re->top_bracket + 1) * 2); + /* The value of restart_match is in TMP1. */ CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label); OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); JUMPTO(SLJIT_JUMP, reset_match_label); diff --git a/src/3rdparty/pcre2/src/pcre2_jit_match.c b/src/3rdparty/pcre2/src/pcre2_jit_match.c index 1ab3af073e6..ae5903e202b 100644 --- a/src/3rdparty/pcre2/src/pcre2_jit_match.c +++ b/src/3rdparty/pcre2/src/pcre2_jit_match.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2018 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -42,6 +42,12 @@ POSSIBILITY OF SUCH DAMAGE. #error This file must be included from pcre2_jit_compile.c. #endif +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#include +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ + #ifdef SUPPORT_JIT static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func) @@ -171,6 +177,7 @@ if (rc > (int)oveccount) rc = 0; match_data->code = re; match_data->subject = (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)? subject : NULL; +match_data->subject_length = length; match_data->rc = rc; match_data->startchar = arguments.startchar_ptr - subject; match_data->leftchar = 0; @@ -178,6 +185,13 @@ match_data->rightchar = 0; match_data->mark = arguments.mark_ptr; match_data->matchedby = PCRE2_MATCHEDBY_JIT; +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +if (rc > 0) + __msan_unpoison(match_data->ovector, 2 * rc * sizeof(match_data->ovector[0])); +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ + return match_data->rc; #endif /* SUPPORT_JIT */ diff --git a/src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h b/src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h index 165602edc0c..4a718b67b7e 100644 --- a/src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h +++ b/src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h @@ -82,7 +82,12 @@ POSSIBILITY OF SUCH DAMAGE. # endif # endif -static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 *str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars) +#if (defined(__GNUC__) && __SANITIZE_ADDRESS__) \ + || (defined(__clang__) \ + && ((__clang_major__ == 3 && __clang_minor__ >= 3) || (__clang_major__ > 3))) +__attribute__((no_sanitize_address)) +#endif +static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 **str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars) #undef FF_FUN { quad_word qw; @@ -171,7 +176,7 @@ else } # endif -str_ptr += IN_UCHARS(offs1); +*str_ptr += IN_UCHARS(offs1); #endif #if PCRE2_CODE_UNIT_WIDTH != 8 @@ -183,13 +188,13 @@ restart:; #endif #if defined(FFCPS) -if (str_ptr >= str_end) +if (*str_ptr >= str_end) return NULL; -sljit_u8 *p1 = str_ptr - diff; +sljit_u8 *p1 = *str_ptr - diff; #endif -sljit_s32 align_offset = ((uint64_t)str_ptr & 0xf); -str_ptr = (sljit_u8 *) ((uint64_t)str_ptr & ~0xf); -vect_t data = VLD1Q(str_ptr); +sljit_s32 align_offset = ((uint64_t)*str_ptr & 0xf); +*str_ptr = (sljit_u8 *) ((uint64_t)*str_ptr & ~0xf); +vect_t data = VLD1Q(*str_ptr); #if PCRE2_CODE_UNIT_WIDTH != 8 data = VANDQ(data, char_mask); #endif @@ -212,9 +217,9 @@ vect_t prev_data = data; # endif vect_t data2; -if (p1 < str_ptr) +if (p1 < *str_ptr) { - data2 = VLD1Q(str_ptr - diff); + data2 = VLD1Q(*str_ptr - diff); #if PCRE2_CODE_UNIT_WIDTH != 8 data2 = VANDQ(data2, char_mask); #endif @@ -242,12 +247,12 @@ if (align_offset < 8) qw.dw[0] >>= align_offset * 8; if (qw.dw[0]) { - str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8; + *str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8; goto match; } if (qw.dw[1]) { - str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; + *str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; goto match; } } @@ -256,15 +261,15 @@ else qw.dw[1] >>= (align_offset - 8) * 8; if (qw.dw[1]) { - str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8; + *str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8; goto match; } } -str_ptr += 16; +*str_ptr += 16; -while (str_ptr < str_end) +while (*str_ptr < str_end) { - vect_t orig_data = VLD1Q(str_ptr); + vect_t orig_data = VLD1Q(*str_ptr); #if PCRE2_CODE_UNIT_WIDTH != 8 orig_data = VANDQ(orig_data, char_mask); #endif @@ -287,7 +292,7 @@ while (str_ptr < str_end) # if defined (FFCPS_DIFF1) data2 = VEXTQ(prev_data, data, VECTOR_FACTOR - 1); # else - data2 = VLD1Q(str_ptr - diff); + data2 = VLD1Q(*str_ptr - diff); # if PCRE2_CODE_UNIT_WIDTH != 8 data2 = VANDQ(data2, char_mask); # endif @@ -312,11 +317,11 @@ while (str_ptr < str_end) VST1Q(qw.mem, eq); if (qw.dw[0]) - str_ptr += __builtin_ctzll(qw.dw[0]) / 8; + *str_ptr += __builtin_ctzll(qw.dw[0]) / 8; else if (qw.dw[1]) - str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; + *str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; else { - str_ptr += 16; + *str_ptr += 16; #if defined (FFCPS_DIFF1) prev_data = orig_data; #endif @@ -324,24 +329,24 @@ while (str_ptr < str_end) } match:; - if (str_ptr >= str_end) + if (*str_ptr >= str_end) /* Failed match. */ return NULL; #if defined(FF_UTF) - if (utf_continue((PCRE2_SPTR)str_ptr - offs1)) + if (utf_continue((PCRE2_SPTR)*str_ptr - offs1)) { /* Not a match. */ - str_ptr += IN_UCHARS(1); + *str_ptr += IN_UCHARS(1); goto restart; } #endif /* Match. */ #if defined (FFCPS) - str_ptr -= IN_UCHARS(offs1); + *str_ptr -= IN_UCHARS(offs1); #endif - return str_ptr; + return *str_ptr; } /* Failed match. */ diff --git a/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h b/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h index 1a5ce4ed09f..783a85f50e2 100644 --- a/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h +++ b/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h @@ -42,7 +42,8 @@ POSSIBILITY OF SUCH DAMAGE. #if !(defined SUPPORT_VALGRIND) #if ((defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ - || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)) + || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + || (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64)) typedef enum { vector_compare_match1, @@ -50,7 +51,27 @@ typedef enum { vector_compare_match2, } vector_compare_type; -static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void) +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) +static SLJIT_INLINE sljit_s32 max_fast_forward_char_pair_offset(void) +{ +#if PCRE2_CODE_UNIT_WIDTH == 8 +/* The AVX2 code path is currently disabled. */ +/* return sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? 31 : 15; */ +return 15; +#elif PCRE2_CODE_UNIT_WIDTH == 16 +/* The AVX2 code path is currently disabled. */ +/* return sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? 15 : 7; */ +return 7; +#elif PCRE2_CODE_UNIT_WIDTH == 32 +/* The AVX2 code path is currently disabled. */ +/* return sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? 7 : 3; */ +return 3; +#else +#error "Unsupported unit width" +#endif +} +#else /* !SLJIT_CONFIG_X86 */ +static SLJIT_INLINE sljit_s32 max_fast_forward_char_pair_offset(void) { #if PCRE2_CODE_UNIT_WIDTH == 8 return 15; @@ -62,6 +83,7 @@ return 3; #error "Unsupported unit width" #endif } +#endif /* SLJIT_CONFIG_X86 */ #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 static struct sljit_jump *jump_if_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg) @@ -86,49 +108,35 @@ static sljit_s32 character_to_int32(PCRE2_UCHAR chr) { sljit_u32 value = chr; #if PCRE2_CODE_UNIT_WIDTH == 8 -#define SSE2_COMPARE_TYPE_INDEX 0 +#define SIMD_COMPARE_TYPE_INDEX 0 return (sljit_s32)((value << 24) | (value << 16) | (value << 8) | value); #elif PCRE2_CODE_UNIT_WIDTH == 16 -#define SSE2_COMPARE_TYPE_INDEX 1 +#define SIMD_COMPARE_TYPE_INDEX 1 return (sljit_s32)((value << 16) | value); #elif PCRE2_CODE_UNIT_WIDTH == 32 -#define SSE2_COMPARE_TYPE_INDEX 2 +#define SIMD_COMPARE_TYPE_INDEX 2 return (sljit_s32)(value); #else #error "Unsupported unit width" #endif } -static void load_from_mem_sse2(struct sljit_compiler *compiler, sljit_s32 dst_xmm_reg, sljit_s32 src_general_reg, sljit_s8 offset) -{ -sljit_u8 instruction[5]; - -SLJIT_ASSERT(dst_xmm_reg < 8); -SLJIT_ASSERT(src_general_reg < 8); - -/* MOVDQA xmm1, xmm2/m128 */ -instruction[0] = ((sljit_u8)offset & 0xf) == 0 ? 0x66 : 0xf3; -instruction[1] = 0x0f; -instruction[2] = 0x6f; - -if (offset == 0) - { - instruction[3] = (dst_xmm_reg << 3) | src_general_reg; - sljit_emit_op_custom(compiler, instruction, 4); - return; - } - -instruction[3] = 0x40 | (dst_xmm_reg << 3) | src_general_reg; -instruction[4] = (sljit_u8)offset; -sljit_emit_op_custom(compiler, instruction, 5); -} - static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, vector_compare_type compare_type, - int step, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind) + sljit_s32 reg_type, int step, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind) { sljit_u8 instruction[4]; -instruction[0] = 0x66; -instruction[1] = 0x0f; + +if (reg_type == SLJIT_SIMD_REG_128) + { + instruction[0] = 0x66; + instruction[1] = 0x0f; + } +else + { + /* Two byte VEX prefix. */ + instruction[0] = 0xc5; + instruction[1] = 0xfd; + } SLJIT_ASSERT(step >= 0 && step <= 3); @@ -139,8 +147,10 @@ if (compare_type != vector_compare_match2) if (compare_type == vector_compare_match1i) { /* POR xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ + if (reg_type == SLJIT_SIMD_REG_256) + instruction[1] ^= (dst_ind << 3); + + /* Prefix is filled. */ instruction[2] = 0xeb; instruction[3] = 0xc0 | (dst_ind << 3) | cmp2_ind; sljit_emit_op_custom(compiler, instruction, 4); @@ -152,20 +162,35 @@ if (compare_type != vector_compare_match2) return; /* PCMPEQB/W/D xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ - instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; + if (reg_type == SLJIT_SIMD_REG_256) + instruction[1] ^= (dst_ind << 3); + + /* Prefix is filled. */ + instruction[2] = 0x74 + SIMD_COMPARE_TYPE_INDEX; instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind; sljit_emit_op_custom(compiler, instruction, 4); return; } +if (reg_type == SLJIT_SIMD_REG_256) + { + if (step == 2) + return; + + if (step == 0) + { + step = 2; + instruction[1] ^= (dst_ind << 3); + } + } + switch (step) { case 0: + SLJIT_ASSERT(reg_type == SLJIT_SIMD_REG_128); + /* MOVDQA xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ + /* Prefix is filled. */ instruction[2] = 0x6f; instruction[3] = 0xc0 | (tmp_ind << 3) | dst_ind; sljit_emit_op_custom(compiler, instruction, 4); @@ -173,26 +198,29 @@ switch (step) case 1: /* PCMPEQB/W/D xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ - instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; + if (reg_type == SLJIT_SIMD_REG_256) + instruction[1] ^= (dst_ind << 3); + + /* Prefix is filled. */ + instruction[2] = 0x74 + SIMD_COMPARE_TYPE_INDEX; instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind; sljit_emit_op_custom(compiler, instruction, 4); return; case 2: /* PCMPEQB/W/D xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ - instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; + /* Prefix is filled. */ + instruction[2] = 0x74 + SIMD_COMPARE_TYPE_INDEX; instruction[3] = 0xc0 | (tmp_ind << 3) | cmp2_ind; sljit_emit_op_custom(compiler, instruction, 4); return; case 3: /* POR xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ + if (reg_type == SLJIT_SIMD_REG_256) + instruction[1] ^= (dst_ind << 3); + + /* Prefix is filled. */ instruction[2] = 0xeb; instruction[3] = 0xc0 | (dst_ind << 3) | tmp_ind; sljit_emit_op_custom(compiler, instruction, 4); @@ -200,12 +228,16 @@ switch (step) } } -#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2)) +#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD)) static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset) { DEFINE_COMPILER; sljit_u8 instruction[8]; +/* The AVX2 code path is currently disabled. */ +/* sljit_s32 reg_type = sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? SLJIT_SIMD_REG_256 : SLJIT_SIMD_REG_128; */ +sljit_s32 reg_type = SLJIT_SIMD_REG_128; +sljit_s32 value; struct sljit_label *start; #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 struct sljit_label *restart; @@ -213,12 +245,11 @@ struct sljit_label *restart; struct sljit_jump *quit; struct sljit_jump *partial_quit[2]; vector_compare_type compare_type = vector_compare_match1; -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); -sljit_s32 data_ind = 0; -sljit_s32 tmp_ind = 1; -sljit_s32 cmp1_ind = 2; -sljit_s32 cmp2_ind = 3; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 data_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); +sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); +sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); +sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); sljit_u32 bit = 0; int i; @@ -241,61 +272,34 @@ if (common->mode == PCRE2_JIT_COMPLETE) add_jump(compiler, &common->failed_match, partial_quit[0]); /* First part (unaligned start) */ - -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); - -SLJIT_ASSERT(tmp1_reg_ind < 8); - -/* MOVD xmm, r/m32 */ -instruction[0] = 0x66; -instruction[1] = 0x0f; -instruction[2] = 0x6e; -instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind; -sljit_emit_op_custom(compiler, instruction, 4); +value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); if (char1 != char2) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); - - /* MOVD xmm, r/m32 */ - instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); -/* PSHUFD xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x70; -instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind; -instruction[4] = 0; -sljit_emit_op_custom(compiler, instruction, 5); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR1, SLJIT_FR1, 0); if (char1 != char2) - { - /* PSHUFD xmm1, xmm2/m128, imm8 */ - instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 restart = LABEL(); #endif -OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); -load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); +value = (reg_type == SLJIT_SIMD_REG_256) ? 0x1f : 0xf; +OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~value); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value); + +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); + for (i = 0; i < 4; i++) - fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; -sljit_emit_op_custom(compiler, instruction, 4); + fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); @@ -306,27 +310,24 @@ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); /* Second part (aligned) */ start = LABEL(); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); +value = (reg_type == SLJIT_SIMD_REG_256) ? 32 : 16; +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); if (common->mode == PCRE2_JIT_COMPLETE) add_jump(compiler, &common->failed_match, partial_quit[1]); -load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); for (i = 0; i < 4; i++) - fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; -sljit_emit_op_custom(compiler, instruction, 4); + fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); JUMPHERE(quit); +SLJIT_ASSERT(tmp1_reg_ind < 8); /* BSF r32, r/m32 */ instruction[0] = 0x0f; instruction[1] = 0xbc; @@ -340,7 +341,7 @@ if (common->mode != PCRE2_JIT_COMPLETE) JUMPHERE(partial_quit[0]); JUMPHERE(partial_quit[1]); OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); - CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); } else add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); @@ -364,22 +365,25 @@ if (common->utf && offset > 0) #endif } -#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2)) +#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD)) static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2) { DEFINE_COMPILER; sljit_u8 instruction[8]; +/* The AVX2 code path is currently disabled. */ +/* sljit_s32 reg_type = sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? SLJIT_SIMD_REG_256 : SLJIT_SIMD_REG_128; */ +sljit_s32 reg_type = SLJIT_SIMD_REG_128; +sljit_s32 value; struct sljit_label *start; struct sljit_jump *quit; jump_list *not_found = NULL; vector_compare_type compare_type = vector_compare_match1; -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); -sljit_s32 data_ind = 0; -sljit_s32 tmp_ind = 1; -sljit_s32 cmp1_ind = 2; -sljit_s32 cmp2_ind = 3; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 data_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); +sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); +sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); +sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); sljit_u32 bit = 0; int i; @@ -401,57 +405,30 @@ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); /* First part (unaligned start) */ -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); - -SLJIT_ASSERT(tmp1_reg_ind < 8); - -/* MOVD xmm, r/m32 */ -instruction[0] = 0x66; -instruction[1] = 0x0f; -instruction[2] = 0x6e; -instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind; -sljit_emit_op_custom(compiler, instruction, 4); +value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); if (char1 != char2) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); - - /* MOVD xmm, r/m32 */ - instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0); -/* PSHUFD xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x70; -instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind; -instruction[4] = 0; -sljit_emit_op_custom(compiler, instruction, 5); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR1, SLJIT_FR1, 0); if (char1 != char2) - { - /* PSHUFD xmm1, xmm2/m128, imm8 */ - instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); -OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); +value = (reg_type == SLJIT_SIMD_REG_256) ? 0x1f : 0xf; +OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~value); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value); + +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); -load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); for (i = 0; i < 4; i++) - fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; -sljit_emit_op_custom(compiler, instruction, 4); + fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); @@ -462,25 +439,23 @@ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); /* Second part (aligned) */ start = LABEL(); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); +value = (reg_type == SLJIT_SIMD_REG_256) ? 32 : 16; +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); -load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); + for (i = 0; i < 4; i++) - fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; -sljit_emit_op_custom(compiler, instruction, 4); + fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); JUMPHERE(quit); +SLJIT_ASSERT(tmp1_reg_ind < 8); /* BSF r32, r/m32 */ instruction[0] = 0x0f; instruction[1] = 0xbc; @@ -496,29 +471,31 @@ return not_found; #ifndef _WIN64 -#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2)) +#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD)) static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1, PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b) { DEFINE_COMPILER; sljit_u8 instruction[8]; +/* The AVX2 code path is currently disabled. */ +/* sljit_s32 reg_type = sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? SLJIT_SIMD_REG_256 : SLJIT_SIMD_REG_128; */ +sljit_s32 reg_type = SLJIT_SIMD_REG_128; +sljit_s32 value; vector_compare_type compare1_type = vector_compare_match1; vector_compare_type compare2_type = vector_compare_match1; sljit_u32 bit1 = 0; sljit_u32 bit2 = 0; sljit_u32 diff = IN_UCHARS(offs1 - offs2); -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 tmp2_reg_ind = sljit_get_register_index(TMP2); -sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); -sljit_s32 data1_ind = 0; -sljit_s32 data2_ind = 1; -sljit_s32 tmp1_ind = 2; -sljit_s32 tmp2_ind = 3; -sljit_s32 cmp1a_ind = 4; -sljit_s32 cmp1b_ind = 5; -sljit_s32 cmp2a_ind = 6; -sljit_s32 cmp2b_ind = 7; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 data1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); +sljit_s32 data2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); +sljit_s32 cmp1a_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); +sljit_s32 cmp2a_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); +sljit_s32 cmp1b_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR4); +sljit_s32 cmp2b_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR5); +sljit_s32 tmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR6); +sljit_s32 tmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_TMP_FR0); struct sljit_label *start; #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 struct sljit_label *restart; @@ -526,9 +503,8 @@ struct sljit_label *restart; struct sljit_jump *jump[2]; int i; -SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2); -SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset())); -SLJIT_ASSERT(tmp1_reg_ind < 8 && tmp2_reg_ind == 1); +SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2 && offs2 >= 0); +SLJIT_ASSERT(diff <= (unsigned)IN_UCHARS(max_fast_forward_char_pair_offset())); /* Initialize. */ if (common->match_end_ptr != 0) @@ -538,17 +514,12 @@ if (common->match_end_ptr != 0) OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0); - CMOV(SLJIT_LESS, STR_END, TMP1, 0); + SELECT(SLJIT_LESS, STR_END, TMP1, 0, STR_END); } OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); -/* MOVD xmm, r/m32 */ -instruction[0] = 0x66; -instruction[1] = 0x0f; -instruction[2] = 0x6e; - if (char1a == char1b) OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a)); else @@ -569,14 +540,11 @@ else } } -instruction[3] = 0xc0 | (cmp1a_ind << 3) | tmp1_reg_ind; -sljit_emit_op_custom(compiler, instruction, 4); +value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, TMP1, 0); if (char1a != char1b) - { - instruction[3] = 0xc0 | (cmp1b_ind << 3) | tmp2_reg_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR4, 0, TMP2, 0); if (char2a == char2b) OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a)); @@ -598,38 +566,18 @@ else } } -instruction[3] = 0xc0 | (cmp2a_ind << 3) | tmp1_reg_ind; -sljit_emit_op_custom(compiler, instruction, 4); +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR3, 0, TMP1, 0); if (char2a != char2b) - { - instruction[3] = 0xc0 | (cmp2b_ind << 3) | tmp2_reg_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } - -/* PSHUFD xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x70; -instruction[4] = 0; - -instruction[3] = 0xc0 | (cmp1a_ind << 3) | cmp1a_ind; -sljit_emit_op_custom(compiler, instruction, 5); + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR5, 0, TMP2, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); if (char1a != char1b) - { - instruction[3] = 0xc0 | (cmp1b_ind << 3) | cmp1b_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } - -instruction[3] = 0xc0 | (cmp2a_ind << 3) | cmp2a_ind; -sljit_emit_op_custom(compiler, instruction, 5); + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR4, SLJIT_FR4, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR3, SLJIT_FR3, 0); if (char2a != char2b) - { - instruction[3] = 0xc0 | (cmp2b_ind << 3) | cmp2b_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR5, SLJIT_FR5, 0); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 restart = LABEL(); @@ -637,55 +585,91 @@ restart = LABEL(); OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, diff); OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); -OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); +value = (reg_type == SLJIT_SIMD_REG_256) ? ~0x1f : ~0xf; +OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); -load_from_mem_sse2(compiler, data1_ind, str_ptr_reg_ind, 0); +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0); -load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff); +sljit_emit_simd_mov(compiler, reg_type, SLJIT_FR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); jump[1] = JUMP(SLJIT_JUMP); JUMPHERE(jump[0]); -/* MOVDQA xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x6f; -instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind; -sljit_emit_op_custom(compiler, instruction, 4); +if (reg_type == SLJIT_SIMD_REG_256) + { + if (diff != 16) + { + /* PSLLDQ ymm1, ymm2, imm8 */ + instruction[0] = 0xc5; + instruction[1] = (sljit_u8)(0xf9 ^ (data2_ind << 3)); + instruction[2] = 0x73; + instruction[3] = 0xc0 | (7 << 3) | data1_ind; + instruction[4] = diff & 0xf; + sljit_emit_op_custom(compiler, instruction, 5); + } -/* PSLLDQ xmm1, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x73; -instruction[3] = 0xc0 | (7 << 3) | data2_ind; -instruction[4] = diff; -sljit_emit_op_custom(compiler, instruction, 5); + instruction[0] = 0xc4; + instruction[1] = 0xe3; + if (diff < 16) + { + /* VINSERTI128 xmm1, xmm2, xmm3/m128 */ + /* instruction[0] = 0xc4; */ + /* instruction[1] = 0xe3; */ + instruction[2] = (sljit_u8)(0x7d ^ (data2_ind << 3)); + instruction[3] = 0x38; + SLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR) <= 7); + instruction[4] = 0x40 | (data2_ind << 3) | sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); + instruction[5] = (sljit_u8)(16 - diff); + instruction[6] = 1; + sljit_emit_op_custom(compiler, instruction, 7); + } + else + { + /* VPERM2I128 xmm1, xmm2, xmm3/m128 */ + /* instruction[0] = 0xc4; */ + /* instruction[1] = 0xe3; */ + value = (diff == 16) ? data1_ind : data2_ind; + instruction[2] = (sljit_u8)(0x7d ^ (value << 3)); + instruction[3] = 0x46; + instruction[4] = 0xc0 | (data2_ind << 3) | value; + instruction[5] = 0x08; + sljit_emit_op_custom(compiler, instruction, 6); + } + } +else + { + /* MOVDQA xmm1, xmm2/m128 */ + instruction[0] = 0x66; + instruction[1] = 0x0f; + instruction[2] = 0x6f; + instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind; + sljit_emit_op_custom(compiler, instruction, 4); + + /* PSLLDQ xmm1, imm8 */ + /* instruction[0] = 0x66; */ + /* instruction[1] = 0x0f; */ + instruction[2] = 0x73; + instruction[3] = 0xc0 | (7 << 3) | data2_ind; + instruction[4] = diff; + sljit_emit_op_custom(compiler, instruction, 5); + } JUMPHERE(jump[1]); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); +value = (reg_type == SLJIT_SIMD_REG_256) ? 0x1f : 0xf; +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value); for (i = 0; i < 4; i++) { - fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind); - fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind); + fast_forward_char_pair_sse2_compare(compiler, compare2_type, reg_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind); + fast_forward_char_pair_sse2_compare(compiler, compare1_type, reg_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind); } -/* PAND xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xdb; -instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | 0; -sljit_emit_op_custom(compiler, instruction, 4); +sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_FR0, SLJIT_FR0, SLJIT_FR1); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); /* Ignore matches before the first STR_PTR. */ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); @@ -698,36 +682,28 @@ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); /* Main loop. */ start = LABEL(); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); +value = (reg_type == SLJIT_SIMD_REG_256) ? 32 : 16; +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); -load_from_mem_sse2(compiler, data1_ind, str_ptr_reg_ind, 0); -load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff); +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type, SLJIT_FR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); for (i = 0; i < 4; i++) { - fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind); - fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind); + fast_forward_char_pair_sse2_compare(compiler, compare1_type, reg_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind); + fast_forward_char_pair_sse2_compare(compiler, compare2_type, reg_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind); } -/* PAND xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xdb; -instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | 0; -sljit_emit_op_custom(compiler, instruction, 4); +sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_FR0, SLJIT_FR0, SLJIT_FR1); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); JUMPHERE(jump[0]); +SLJIT_ASSERT(tmp1_reg_ind < 8); /* BSF r32, r/m32 */ instruction[0] = 0x0f; instruction[1] = 0xbc; @@ -762,7 +738,7 @@ if (common->match_end_ptr != 0) #endif /* !_WIN64 */ -#undef SSE2_COMPARE_TYPE_INDEX +#undef SIMD_COMPARE_TYPE_INDEX #endif /* SLJIT_CONFIG_X86 */ @@ -865,14 +841,14 @@ static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, P { DEFINE_COMPILER; int_char ic; -struct sljit_jump *partial_quit; +struct sljit_jump *partial_quit, *quit; /* Save temporary registers. */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP3, 0); /* Prepare function arguments */ OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0); -OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0); +GET_LOCAL_BASE(SLJIT_R1, 0, LOCALS0); OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, offset); if (char1 == char2) @@ -944,9 +920,14 @@ if (common->mode == PCRE2_JIT_COMPLETE) /* Fast forward STR_PTR to the result of memchr. */ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); - if (common->mode != PCRE2_JIT_COMPLETE) + { + quit = CMP(SLJIT_NOT_ZERO, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); JUMPHERE(partial_quit); + OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); + JUMPHERE(quit); + } } typedef enum { @@ -1068,10 +1049,10 @@ else OP2(SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, SLJIT_R0, 0); - CMOV(SLJIT_LESS, SLJIT_R0, STR_END, 0); + SELECT(SLJIT_LESS, SLJIT_R0, STR_END, 0, SLJIT_R0); } -OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0); +GET_LOCAL_BASE(SLJIT_R1, 0, LOCALS0); OP1(SLJIT_MOV_S32, SLJIT_R2, 0, SLJIT_IMM, offs1); OP1(SLJIT_MOV_S32, SLJIT_R3, 0, SLJIT_IMM, offs2); ic.c.c1 = char1a; @@ -1177,7 +1158,7 @@ if (step == 0) OP1(SLJIT_MOV, tmp_general_reg, 0, SLJIT_IMM, chr); /* VLVG */ - instruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4) | sljit_get_register_index(tmp_general_reg)); + instruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4) | sljit_get_register_index(SLJIT_GP_REGISTER, tmp_general_reg)); instruction[1] = 0; instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x22); sljit_emit_op_custom(compiler, instruction, 6); @@ -1256,8 +1237,8 @@ struct sljit_label *restart; struct sljit_jump *quit; struct sljit_jump *partial_quit[2]; vector_compare_type compare_type = vector_compare_match1; -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); sljit_s32 data_ind = 0; sljit_s32 tmp_ind = 1; sljit_s32 cmp1_ind = 2; @@ -1419,7 +1400,7 @@ if (common->mode != PCRE2_JIT_COMPLETE) JUMPHERE(partial_quit[0]); JUMPHERE(partial_quit[1]); OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); - CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); } else add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); @@ -1454,8 +1435,8 @@ struct sljit_label *start; struct sljit_jump *quit; jump_list *not_found = NULL; vector_compare_type compare_type = vector_compare_match1; -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 tmp3_reg_ind = sljit_get_register_index(TMP3); +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 tmp3_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP3); sljit_s32 data_ind = 0; sljit_s32 tmp_ind = 1; sljit_s32 cmp1_ind = 2; @@ -1624,9 +1605,9 @@ vector_compare_type compare2_type = vector_compare_match1; sljit_u32 bit1 = 0; sljit_u32 bit2 = 0; sljit_s32 diff = IN_UCHARS(offs2 - offs1); -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 tmp2_reg_ind = sljit_get_register_index(TMP2); -sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 tmp2_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP2); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); sljit_s32 data1_ind = 0; sljit_s32 data2_ind = 1; sljit_s32 tmp1_ind = 2; @@ -1674,7 +1655,7 @@ if (common->match_end_ptr != 0) OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0); - CMOV(SLJIT_LESS, STR_END, TMP1, 0); + SELECT(SLJIT_LESS, STR_END, TMP1, 0, STR_END); } OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); @@ -1855,4 +1836,520 @@ if (common->match_end_ptr != 0) #endif /* SLJIT_CONFIG_S390X */ +#if (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) + +#ifdef __linux__ +/* Using getauxval(AT_HWCAP) under Linux for detecting whether LSX is available */ +#include +#define LOONGARCH_HWCAP_LSX (1 << 4) +#define HAS_LSX_SUPPORT ((getauxval(AT_HWCAP) & LOONGARCH_HWCAP_LSX) != 0) +#else +#define HAS_LSX_SUPPORT 0 +#endif + +typedef sljit_ins sljit_u32; + +#define SI12_IMM_MASK 0x003ffc00 +#define UI5_IMM_MASK 0x00007c00 +#define UI2_IMM_MASK 0x00000c00 + +#define VD(vd) ((sljit_ins)vd << 0) +#define VJ(vj) ((sljit_ins)vj << 5) +#define VK(vk) ((sljit_ins)vk << 10) +#define RD_V(rd) ((sljit_ins)rd << 0) +#define RJ_V(rj) ((sljit_ins)rj << 5) + +#define IMM_SI12(imm) (((sljit_ins)(imm) << 10) & SI12_IMM_MASK) +#define IMM_UI5(imm) (((sljit_ins)(imm) << 10) & UI5_IMM_MASK) +#define IMM_UI2(imm) (((sljit_ins)(imm) << 10) & UI2_IMM_MASK) + +// LSX OPCODES: +#define VLD 0x2c000000 +#define VOR_V 0x71268000 +#define VAND_V 0x71260000 +#define VBSLL_V 0x728e0000 +#define VMSKLTZ_B 0x729c4000 +#define VPICKVE2GR_WU 0x72f3e000 + +#if PCRE2_CODE_UNIT_WIDTH == 8 +#define VREPLGR2VR 0x729f0000 +#define VSEQ 0x70000000 +#elif PCRE2_CODE_UNIT_WIDTH == 16 +#define VREPLGR2VR 0x729f0400 +#define VSEQ 0x70008000 +#else +#define VREPLGR2VR 0x729f0800 +#define VSEQ 0x70010000 +#endif + +static void fast_forward_char_pair_lsx_compare(struct sljit_compiler *compiler, vector_compare_type compare_type, + sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind) +{ +if (compare_type != vector_compare_match2) + { + if (compare_type == vector_compare_match1i) + { + /* VOR.V vd, vj, vk */ + push_inst(compiler, VOR_V | VD(dst_ind) | VJ(cmp2_ind) | VK(dst_ind)); + } + + /* VSEQ.B/H/W vd, vj, vk */ + push_inst(compiler, VSEQ | VD(dst_ind) | VJ(dst_ind) | VK(cmp1_ind)); + return; + } + +/* VBSLL.V vd, vj, ui5 */ +push_inst(compiler, VBSLL_V | VD(tmp_ind) | VJ(dst_ind) | IMM_UI5(0)); + +/* VSEQ.B/H/W vd, vj, vk */ +push_inst(compiler, VSEQ | VD(dst_ind) | VJ(dst_ind) | VK(cmp1_ind)); + +/* VSEQ.B/H/W vd, vj, vk */ +push_inst(compiler, VSEQ | VD(tmp_ind) | VJ(tmp_ind) | VK(cmp2_ind)); + +/* VOR vd, vj, vk */ +push_inst(compiler, VOR_V | VD(dst_ind) | VJ(tmp_ind) | VK(dst_ind)); +return; +} + +#define JIT_HAS_FAST_FORWARD_CHAR_SIMD HAS_LSX_SUPPORT + +static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset) +{ +DEFINE_COMPILER; +struct sljit_label *start; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_label *restart; +#endif +struct sljit_jump *quit; +struct sljit_jump *partial_quit[2]; +vector_compare_type compare_type = vector_compare_match1; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); +sljit_s32 data_ind = 0; +sljit_s32 tmp_ind = 1; +sljit_s32 cmp1_ind = 2; +sljit_s32 cmp2_ind = 3; +sljit_u32 bit = 0; + +SLJIT_UNUSED_ARG(offset); + +if (char1 != char2) + { + bit = char1 ^ char2; + compare_type = vector_compare_match1i; + + if (!is_powerof2(bit)) + { + bit = 0; + compare_type = vector_compare_match2; + } + } + +partial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, &common->failed_match, partial_quit[0]); + +/* First part (unaligned start) */ + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1 | bit); + +/* VREPLGR2VR.B/H/W vd, rj */ +push_inst(compiler, VREPLGR2VR | VD(cmp1_ind) | RJ_V(tmp1_reg_ind)); + +if (char1 != char2) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, bit != 0 ? bit : char2); + + /* VREPLGR2VR.B/H/W vd, rj */ + push_inst(compiler, VREPLGR2VR | VD(cmp2_ind) | RJ_V(tmp1_reg_ind)); + } + +OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +restart = LABEL(); +#endif + +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); +fast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0)); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); + +quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0); + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* Second part (aligned) */ +start = LABEL(); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); + +partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, &common->failed_match, partial_quit[1]); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); +fast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0)); + +CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); + +JUMPHERE(quit); + +/* CTZ.W rd, rj */ +push_inst(compiler, CTZ_W | RD_V(tmp1_reg_ind) | RJ_V(tmp1_reg_ind)); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + +if (common->mode != PCRE2_JIT_COMPLETE) + { + JUMPHERE(partial_quit[0]); + JUMPHERE(partial_quit[1]); + OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); + } +else + add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +if (common->utf && offset > 0) + { + SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE); + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset)); + + quit = jump_if_utf_char_start(compiler, TMP1); + + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, restart); + + JUMPHERE(quit); + } +#endif +} + +#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD HAS_LSX_SUPPORT + +static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *quit; +jump_list *not_found = NULL; +vector_compare_type compare_type = vector_compare_match1; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); +sljit_s32 data_ind = 0; +sljit_s32 tmp_ind = 1; +sljit_s32 cmp1_ind = 2; +sljit_s32 cmp2_ind = 3; +sljit_u32 bit = 0; + +if (char1 != char2) + { + bit = char1 ^ char2; + compare_type = vector_compare_match1i; + + if (!is_powerof2(bit)) + { + bit = 0; + compare_type = vector_compare_match2; + } + } + +add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0)); +OP1(SLJIT_MOV, TMP2, 0, TMP1, 0); +OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + +/* First part (unaligned start) */ + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1 | bit); + +/* VREPLGR2VR vd, rj */ +push_inst(compiler, VREPLGR2VR | VD(cmp1_ind) | RJ_V(tmp1_reg_ind)); + +if (char1 != char2) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, bit != 0 ? bit : char2); + /* VREPLGR2VR vd, rj */ + push_inst(compiler, VREPLGR2VR | VD(cmp2_ind) | RJ_V(tmp1_reg_ind)); + } + +OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); +fast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0)); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); + +quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0); + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* Second part (aligned) */ +start = LABEL(); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); + +add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); +fast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0)); + +CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); + +JUMPHERE(quit); + +/* CTZ.W rd, rj */ +push_inst(compiler, CTZ_W | RD_V(tmp1_reg_ind) | RJ_V(tmp1_reg_ind)); + +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, STR_PTR, 0); +add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0)); + +OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); +return not_found; +} + +#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD HAS_LSX_SUPPORT + +static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1, + PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b) +{ +DEFINE_COMPILER; +vector_compare_type compare1_type = vector_compare_match1; +vector_compare_type compare2_type = vector_compare_match1; +sljit_u32 bit1 = 0; +sljit_u32 bit2 = 0; +sljit_u32 diff = IN_UCHARS(offs1 - offs2); +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 tmp2_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP2); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); +sljit_s32 data1_ind = 0; +sljit_s32 data2_ind = 1; +sljit_s32 tmp1_ind = 2; +sljit_s32 tmp2_ind = 3; +sljit_s32 cmp1a_ind = 4; +sljit_s32 cmp1b_ind = 5; +sljit_s32 cmp2a_ind = 6; +sljit_s32 cmp2b_ind = 7; +struct sljit_label *start; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_label *restart; +#endif +struct sljit_jump *jump[2]; + +SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2); +SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset())); + +/* Initialize. */ +if (common->match_end_ptr != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1)); + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + + OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0); + SELECT(SLJIT_LESS, STR_END, TMP1, 0, STR_END); + } + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); +add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +if (char1a == char1b) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1a); +else + { + bit1 = char1a ^ char1b; + if (is_powerof2(bit1)) + { + compare1_type = vector_compare_match1i; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1a | bit1); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, bit1); + } + else + { + compare1_type = vector_compare_match2; + bit1 = 0; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1a); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, char1b); + } + } + +/* VREPLGR2VR vd, rj */ +push_inst(compiler, VREPLGR2VR | VD(cmp1a_ind) | RJ_V(tmp1_reg_ind)); + +if (char1a != char1b) + { + /* VREPLGR2VR vd, rj */ + push_inst(compiler, VREPLGR2VR | VD(cmp1b_ind) | RJ_V(tmp2_reg_ind)); + } + +if (char2a == char2b) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char2a); +else + { + bit2 = char2a ^ char2b; + if (is_powerof2(bit2)) + { + compare2_type = vector_compare_match1i; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char2a | bit2); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, bit2); + } + else + { + compare2_type = vector_compare_match2; + bit2 = 0; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char2a); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, char2b); + } + } + +/* VREPLGR2VR vd, rj */ +push_inst(compiler, VREPLGR2VR | VD(cmp2a_ind) | RJ_V(tmp1_reg_ind)); + +if (char2a != char2b) + { + /* VREPLGR2VR vd, rj */ + push_inst(compiler, VREPLGR2VR | VD(cmp2b_ind) | RJ_V(tmp2_reg_ind)); + } + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +restart = LABEL(); +#endif + +OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, diff); +OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data1_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); + +jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data2_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(-(sljit_s8)diff)); +jump[1] = JUMP(SLJIT_JUMP); + +JUMPHERE(jump[0]); + +/* VBSLL.V vd, vj, ui5 */ +push_inst(compiler, VBSLL_V | VD(data2_ind) | VJ(data1_ind) | IMM_UI5(diff)); + +JUMPHERE(jump[1]); + +fast_forward_char_pair_lsx_compare(compiler, compare2_type, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind); +fast_forward_char_pair_lsx_compare(compiler, compare1_type, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind); + +/* VAND vd, vj, vk */ +push_inst(compiler, VOR_V | VD(data1_ind) | VJ(data1_ind) | VK(data2_ind)); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp1_ind) | VJ(data1_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp1_ind) | IMM_UI2(0)); + +/* Ignore matches before the first STR_PTR. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); + +jump[0] = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0); + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* Main loop. */ +start = LABEL(); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); +add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data1_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); +push_inst(compiler, VLD | VD(data2_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(-(sljit_s8)diff)); + +fast_forward_char_pair_lsx_compare(compiler, compare1_type, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind); +fast_forward_char_pair_lsx_compare(compiler, compare2_type, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind); + +/* VAND.V vd, vj, vk */ +push_inst(compiler, VAND_V | VD(data1_ind) | VJ(data1_ind) | VK(data2_ind)); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp1_ind) | VJ(data1_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp1_ind) | IMM_UI2(0)); + +CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); + +JUMPHERE(jump[0]); + +/* CTZ.W rd, rj */ +push_inst(compiler, CTZ_W | RD_V(tmp1_reg_ind) | RJ_V(tmp1_reg_ind)); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + +add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +if (common->utf) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1)); + + jump[0] = jump_if_utf_char_start(compiler, TMP1); + + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart); + + add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP)); + + JUMPHERE(jump[0]); + } +#endif + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); + +if (common->match_end_ptr != 0) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); +} + +#endif /* SLJIT_CONFIG_LOONGARCH_64 */ + #endif /* !SUPPORT_VALGRIND */ diff --git a/src/3rdparty/pcre2/src/pcre2_maketables.c b/src/3rdparty/pcre2/src/pcre2_maketables.c index 56d24940232..ac8b63b8097 100644 --- a/src/3rdparty/pcre2/src/pcre2_maketables.c +++ b/src/3rdparty/pcre2/src/pcre2_maketables.c @@ -52,8 +52,6 @@ PCRE2_DFTABLES is defined. */ # include "pcre2_internal.h" #endif - - /************************************************* * Create PCRE2 character tables * *************************************************/ @@ -98,7 +96,11 @@ for (i = 0; i < 256; i++) *p++ = tolower(i); /* Next the case-flipping table */ -for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i); +for (i = 0; i < 256; i++) + { + int c = islower(i)? toupper(i) : tolower(i); + *p++ = (c < 256)? c : i; + } /* Then the character class tables. Don't try to be clever and save effort on exclusive ones - in some locales things may be different. diff --git a/src/3rdparty/pcre2/src/pcre2_match.c b/src/3rdparty/pcre2/src/pcre2_match.c index 168b9fad019..b4a970313d7 100644 --- a/src/3rdparty/pcre2/src/pcre2_match.c +++ b/src/3rdparty/pcre2/src/pcre2_match.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2015-2022 University of Cambridge + New API code Copyright (c) 2015-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -43,6 +43,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "config.h" #endif +#include "pcre2_internal.h" + /* These defines enable debugging code */ /* #define DEBUG_FRAMES_DISPLAY */ @@ -53,6 +55,10 @@ POSSIBILITY OF SUCH DAMAGE. #include #endif +#ifdef DEBUG_SHOW_OPS +static const char *OP_names[] = { OP_NAME_LIST }; +#endif + /* These defines identify the name of the block containing "static" information, and fields within it. */ @@ -60,8 +66,6 @@ information, and fields within it. */ #define PSSTART start_subject /* Field containing processed string start */ #define PSEND end_subject /* Field containing processed string end */ -#include "pcre2_internal.h" - #define RECURSE_UNSET 0xffffffffu /* Bigger than max group number */ /* Masks for identifying the public options that are permitted at match time. */ @@ -69,7 +73,8 @@ information, and fields within it. */ #define PUBLIC_MATCH_OPTIONS \ (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \ PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \ - PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT|PCRE2_COPY_MATCHED_SUBJECT) + PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT|PCRE2_COPY_MATCHED_SUBJECT| \ + PCRE2_DISABLE_RECURSELOOP_CHECK) #define PUBLIC_JIT_MATCH_OPTIONS \ (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\ @@ -150,7 +155,7 @@ changed, the code at RETURN_SWITCH below must be updated in sync. */ enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, - RM31, RM32, RM33, RM34, RM35, RM36 }; + RM31, RM32, RM33, RM34, RM35, RM36, RM37 }; #ifdef SUPPORT_WIDE_CHARS enum { RM100=100, RM101 }; @@ -597,11 +602,12 @@ heapframe *P = NULL; heapframe *frames_top; /* End of frames vector */ heapframe *assert_accept_frame = NULL; /* For passing back a frame with captures */ -PCRE2_SIZE heapframes_size; /* Usable size of frames vector */ PCRE2_SIZE frame_copy_size; /* Amount to copy when creating a new frame */ /* Local variables that do not need to be preserved over calls to RRMATCH(). */ +PCRE2_SPTR branch_end = NULL; +PCRE2_SPTR branch_start; PCRE2_SPTR bracode; /* Temp pointer to start of group */ PCRE2_SIZE offset; /* Used for group offsets */ PCRE2_SIZE length; /* Used for various length calculations */ @@ -635,13 +641,10 @@ copied when a new frame is created. */ frame_copy_size = frame_size - offsetof(heapframe, eptr); -/* Set up the first frame and the end of the frames vector. We set the local -heapframes_size to the usuable amount of the vector, that is, a whole number of -frames. */ +/* Set up the first frame and the end of the frames vector. */ F = match_data->heapframes; -heapframes_size = (match_data->heapframes_size / frame_size) * frame_size; -frames_top = (heapframe *)((char *)F + heapframes_size); +frames_top = (heapframe *)((char *)F + match_data->heapframes_size); Frdepth = 0; /* "Recursion" depth */ Fcapture_last = 0; /* Number of most recent capture */ @@ -662,35 +665,54 @@ MATCH_RECURSE: doubling the size, but constrained by the heap limit (which is in KiB). */ N = (heapframe *)((char *)F + frame_size); -if (N >= frames_top) +if ((heapframe *)((char *)N + frame_size) >= frames_top) { heapframe *new; - PCRE2_SIZE newsize = match_data->heapframes_size * 2; + PCRE2_SIZE newsize; + PCRE2_SIZE usedsize = (char *)N - (char *)(match_data->heapframes); - if (newsize > mb->heap_limit) + if (match_data->heapframes_size >= PCRE2_SIZE_MAX / 2) { - PCRE2_SIZE maxsize = (mb->heap_limit/frame_size) * frame_size; - if (match_data->heapframes_size >= maxsize) return PCRE2_ERROR_HEAPLIMIT; - newsize = maxsize; + if (match_data->heapframes_size == PCRE2_SIZE_MAX - 1) + return PCRE2_ERROR_NOMEMORY; + newsize = PCRE2_SIZE_MAX - 1; + } + else + newsize = match_data->heapframes_size * 2; + + if (newsize / 1024 >= mb->heap_limit) + { + PCRE2_SIZE old_size = match_data->heapframes_size / 1024; + if (mb->heap_limit <= old_size) + return PCRE2_ERROR_HEAPLIMIT; + else + { + PCRE2_SIZE max_delta = 1024 * (mb->heap_limit - old_size); + int over_bytes = match_data->heapframes_size % 1024; + if (over_bytes) max_delta -= (1024 - over_bytes); + newsize = match_data->heapframes_size + max_delta; + } } + /* With a heap limit set, the permitted additional size may not be enough for + another frame, so do a final check. */ + + if (newsize - usedsize < frame_size) return PCRE2_ERROR_HEAPLIMIT; new = match_data->memctl.malloc(newsize, match_data->memctl.memory_data); if (new == NULL) return PCRE2_ERROR_NOMEMORY; - memcpy(new, match_data->heapframes, heapframes_size); + memcpy(new, match_data->heapframes, usedsize); - F = (heapframe *)((char *)new + ((char *)F - (char *)match_data->heapframes)); - N = (heapframe *)((char *)F + frame_size); + N = (heapframe *)((char *)new + usedsize); + F = (heapframe *)((char *)N - frame_size); match_data->memctl.free(match_data->heapframes, match_data->memctl.memory_data); match_data->heapframes = new; match_data->heapframes_size = newsize; - - heapframes_size = (newsize / frame_size) * frame_size; - frames_top = (heapframe *)((char *)new + heapframes_size); + frames_top = (heapframe *)((char *)new + newsize); } #ifdef DEBUG_SHOW_RMATCH -fprintf(stderr, "++ RMATCH %2d frame=%d", Freturn_id, Frdepth + 1); +fprintf(stderr, "++ RMATCH %d frame=%d", Freturn_id, Frdepth + 1); if (group_frame_type != 0) { fprintf(stderr, " type=%x ", group_frame_type); @@ -760,10 +782,16 @@ opcodes. */ if (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT; if (Frdepth >= mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT; +#ifdef DEBUG_SHOW_OPS +fprintf(stderr, "\n++ New frame: type=0x%x subject offset %ld\n", + GF_IDMASK(Fgroup_frame_type), Feptr - mb->start_subject); +#endif + for (;;) { #ifdef DEBUG_SHOW_OPS -fprintf(stderr, "++ op=%d\n", *Fecode); +fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, + OP_names[*Fecode]); #endif Fop = (uint8_t)(*Fecode); /* Cast needed for 16-bit and 32-bit modes */ @@ -811,15 +839,16 @@ fprintf(stderr, "++ op=%d\n", *Fecode); assert_accept_frame = F; RRETURN(MATCH_ACCEPT); - /* If recursing, we have to find the most recent recursion. */ + /* For ACCEPT within a recursion, we have to find the most recent + recursion. If not in a recursion, fall through to code that is common with + OP_END. */ case OP_ACCEPT: - case OP_END: - - /* Handle end of a recursion. */ - if (Fcurrent_recurse != RECURSE_UNSET) { +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ Accept within recursion\n"); +#endif offset = Flast_group_offset; for(;;) { @@ -842,27 +871,49 @@ fprintf(stderr, "++ op=%d\n", *Fecode); Fecode += 1 + LINK_SIZE; continue; } + /* Fall through */ - /* Not a recursion. Fail for an empty string match if either PCRE2_NOTEMPTY - is set, or if PCRE2_NOTEMPTY_ATSTART is set and we have matched at the - start of the subject. In both cases, backtracking will then try other - alternatives, if any. */ + /* OP_END itself can never be reached within a recursion because that is + picked up when the OP_KET that always precedes OP_END is reached. */ + + case OP_END: + + /* Fail for an empty string match if either PCRE2_NOTEMPTY is set, or if + PCRE2_NOTEMPTY_ATSTART is set and we have matched at the start of the + subject. In both cases, backtracking will then try other alternatives, if + any. */ if (Feptr == Fstart_match && ((mb->moptions & PCRE2_NOTEMPTY) != 0 || ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) != 0 && Fstart_match == mb->start_subject + mb->start_offset))) + { +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ Backtrack because empty string\n"); +#endif RRETURN(MATCH_NOMATCH); + } - /* Also fail if PCRE2_ENDANCHORED is set and the end of the match is not + /* Fail if PCRE2_ENDANCHORED is set and the end of the match is not the end of the subject. After (*ACCEPT) we fail the entire match (at this - position) but backtrack on reaching the end of the pattern. */ + position) but backtrack if we've reached the end of the pattern. This + applies whether or not we are in a recursion. */ if (Feptr < mb->end_subject && ((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0) { - if (Fop == OP_END) RRETURN(MATCH_NOMATCH); - return MATCH_NOMATCH; + if (Fop == OP_END) + { +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ Backtrack because not at end (endanchored set)\n"); +#endif + RRETURN(MATCH_NOMATCH); + } + +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ Failed ACCEPT not at end (endanchnored set)\n"); +#endif + return MATCH_NOMATCH; /* (*ACCEPT) */ } /* We have a successful match of the whole pattern. Record the result and @@ -2435,6 +2486,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); GETCHARINCTEST(fc, Feptr); { const uint32_t *cp; + uint32_t chartype; const ucd_record *prop = GET_UCD(fc); BOOL notmatch = Fop == OP_NOTPROP; @@ -2445,9 +2497,10 @@ fprintf(stderr, "++ op=%d\n", *Fecode); break; case PT_LAMP: - if ((prop->chartype == ucp_Lu || - prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt) == notmatch) + chartype = prop->chartype; + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == notmatch) RRETURN(MATCH_NOMATCH); break; @@ -2477,8 +2530,9 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* These are specials */ case PT_ALNUM: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N) == notmatch) + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N) == notmatch) RRETURN(MATCH_NOMATCH); break; @@ -2503,13 +2557,22 @@ fprintf(stderr, "++ op=%d\n", *Fecode); break; case PT_WORD: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - fc == CHAR_UNDERSCORE) == notmatch) + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || + chartype == ucp_Pc) == notmatch) RRETURN(MATCH_NOMATCH); break; case PT_CLIST: +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (fc > MAX_UTF_CODE_POINT) + { + if (notmatch) break;; + RRETURN(MATCH_NOMATCH); + } +#endif cp = PRIV(ucd_caseless_sets) + Fecode[2]; for (;;) { @@ -2805,16 +2868,17 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case PT_WORD: for (i = 1; i <= Lmin; i++) { - int category; + int chartype, category; if (Feptr >= mb->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); - category = UCD_CATEGORY(fc); + chartype = UCD_CHARTYPE(fc); + category = PRIV(ucp_gentype)[chartype]; if ((category == ucp_L || category == ucp_N || - fc == CHAR_UNDERSCORE) == notmatch) + chartype == ucp_Mn || chartype == ucp_Pc) == notmatch) RRETURN(MATCH_NOMATCH); } break; @@ -2829,6 +2893,13 @@ fprintf(stderr, "++ op=%d\n", *Fecode); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (fc > MAX_UTF_CODE_POINT) + { + if (notmatch) continue; + RRETURN(MATCH_NOMATCH); + } +#endif cp = PRIV(ucd_caseless_sets) + Lpropvalue; for (;;) { @@ -3609,7 +3680,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case PT_WORD: for (;;) { - int category; + int chartype, category; RMATCH(Fecode, RM215); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); @@ -3619,10 +3690,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); - category = UCD_CATEGORY(fc); + chartype = UCD_CHARTYPE(fc); + category = PRIV(ucp_gentype)[chartype]; if ((category == ucp_L || category == ucp_N || - fc == CHAR_UNDERSCORE) == (Lctype == OP_NOTPROP)) + chartype == ucp_Mn || + chartype == ucp_Pc) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ @@ -3640,6 +3713,13 @@ fprintf(stderr, "++ op=%d\n", *Fecode); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (fc > MAX_UTF_CODE_POINT) + { + if (Lctype == OP_NOTPROP) continue; + RRETURN(MATCH_NOMATCH); + } +#endif cp = PRIV(ucd_caseless_sets) + Lpropvalue; for (;;) { @@ -4190,7 +4270,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case PT_WORD: for (i = Lmin; i < Lmax; i++) { - int category; + int chartype, category; int len = 1; if (Feptr >= mb->end_subject) { @@ -4198,9 +4278,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode); break; } GETCHARLENTEST(fc, Feptr, len); - category = UCD_CATEGORY(fc); - if ((category == ucp_L || category == ucp_N || - fc == CHAR_UNDERSCORE) == notmatch) + chartype = UCD_CHARTYPE(fc); + category = PRIV(ucp_gentype)[chartype]; + if ((category == ucp_L || + category == ucp_N || + chartype == ucp_Mn || + chartype == ucp_Pc) == notmatch) break; Feptr+= len; } @@ -4217,14 +4300,24 @@ fprintf(stderr, "++ op=%d\n", *Fecode); break; } GETCHARLENTEST(fc, Feptr, len); - cp = PRIV(ucd_caseless_sets) + Lpropvalue; - for (;;) +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (fc > MAX_UTF_CODE_POINT) { - if (fc < *cp) - { if (notmatch) break; else goto GOT_MAX; } - if (fc == *cp++) - { if (notmatch) goto GOT_MAX; else break; } + if (!notmatch) goto GOT_MAX; } + else +#endif + { + cp = PRIV(ucd_caseless_sets) + Lpropvalue; + for (;;) + { + if (fc < *cp) + { if (notmatch) break; else goto GOT_MAX; } + if (fc == *cp++) + { if (notmatch) goto GOT_MAX; else break; } + } + } + Feptr += len; } GOT_MAX: @@ -5322,9 +5415,11 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* ===================================================================== */ - /* Recursion either matches the current regex, or some subexpression. The - offset data is the offset to the starting bracket from the start of the - whole pattern. (This is so that it works from duplicated subpatterns.) */ + /* Pattern recursion either matches the current regex, or some + subexpression. The offset data is the offset to the starting bracket from + the start of the whole pattern. This is so that it works from duplicated + subpatterns. For a whole-pattern recursion, we have to infer the number + zero. */ #define Lframe_type F->temp_32[0] #define Lstart_branch F->temp_sptr[0] @@ -5333,9 +5428,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode); bracode = mb->start_code + GET(Fecode, 1); number = (bracode == mb->start_code)? 0 : GET2(bracode, 1 + LINK_SIZE); - /* If we are already in a recursion, check for repeating the same one - without advancing the subject pointer. This should catch convoluted mutual - recursions. (Some simple cases are caught at compile time.) */ + /* If we are already in a pattern recursion, check for repeating the same + one without changing the subject pointer or the last referenced character + in the subject. This should catch convoluted mutual recursions; some + simple cases are caught at compile time. However, there are rare cases when + this check needs to be turned off. In this case, actual recursion loops + will be caught by the match or heap limits. */ if (Fcurrent_recurse != RECURSE_UNSET) { @@ -5346,15 +5444,19 @@ fprintf(stderr, "++ op=%d\n", *Fecode); P = (heapframe *)((char *)N - frame_size); if (N->group_frame_type == (GF_RECURSE | number)) { - if (Feptr == P->eptr) return PCRE2_ERROR_RECURSELOOP; + if (Feptr == P->eptr && mb->last_used_ptr == P->recurse_last_used && + (mb->moptions & PCRE2_DISABLE_RECURSELOOP_CHECK) == 0) + return PCRE2_ERROR_RECURSELOOP; break; } offset = P->last_group_offset; } } - /* Now run the recursion, branch by branch. */ + /* Remember the current last referenced character and then run the + recursion branch by branch. */ + F->recurse_last_used = mb->last_used_ptr; Lstart_branch = bracode; Lframe_type = GF_RECURSE | number; @@ -5683,13 +5785,13 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* ===================================================================== */ - /* Move the subject pointer back. This occurs only at the start of each - branch of a lookbehind assertion. If we are too close to the start to move - back, fail. When working with UTF-8 we move back a number of characters, - not bytes. */ + /* Move the subject pointer back by one fixed amount. This occurs at the + start of each branch that has a fixed length in a lookbehind assertion. If + we are too close to the start to move back, fail. When working with UTF-8 + we move back a number of characters, not bytes. */ case OP_REVERSE: - number = GET(Fecode, 1); + number = GET2(Fecode, 1); #ifdef SUPPORT_UNICODE if (utf) { @@ -5703,7 +5805,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); else #endif - /* No UTF-8 support, or not in UTF-8 mode: count is code unit count */ + /* No UTF support, or not in UTF mode: count is code unit count */ { if ((ptrdiff_t)number > Feptr - mb->start_subject) RRETURN(MATCH_NOMATCH); @@ -5713,15 +5815,84 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* Save the earliest consulted character, then skip to next opcode */ if (Feptr < mb->start_used_ptr) mb->start_used_ptr = Feptr; - Fecode += 1 + LINK_SIZE; + Fecode += 1 + IMM2_SIZE; break; + /* ===================================================================== */ + /* Move the subject pointer back by a variable amount. This occurs at the + start of each branch of a lookbehind assertion when the branch has a + variable, but limited, length. A loop is needed to try matching the branch + after moving back different numbers of characters. If we are too close to + the start to move back even the minimum amount, fail. When working with + UTF-8 we move back a number of characters, not bytes. */ + +#define Lmin F->temp_32[0] +#define Lmax F->temp_32[1] +#define Leptr F->temp_sptr[0] + + case OP_VREVERSE: + Lmin = GET2(Fecode, 1); + Lmax = GET2(Fecode, 1 + IMM2_SIZE); + Leptr = Feptr; + + /* Move back by the maximum branch length and then work forwards. This + ensures that items such as \d{3,5} get the maximum length, which is + relevant for captures, and makes for Perl compatibility. */ + +#ifdef SUPPORT_UNICODE + if (utf) + { + for (i = 0; i < Lmax; i++) + { + if (Feptr == mb->start_subject) + { + if (i < Lmin) RRETURN(MATCH_NOMATCH); + Lmax = i; + break; + } + Feptr--; + BACKCHAR(Feptr); + } + } + else +#endif + + /* No UTF support or not in UTF mode */ + + { + ptrdiff_t diff = Feptr - mb->start_subject; + uint32_t available = (diff > 65535)? 65535 : ((diff > 0)? diff : 0); + if (Lmin > available) RRETURN(MATCH_NOMATCH); + if (Lmax > available) Lmax = available; + Feptr -= Lmax; + } + + /* Now try matching, moving forward one character on failure, until we + reach the mimimum back length. */ + + for (;;) + { + RMATCH(Fecode + 1 + 2 * IMM2_SIZE, RM37); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (Lmax-- <= Lmin) RRETURN(MATCH_NOMATCH); + Feptr++; +#ifdef SUPPORT_UNICODE + if (utf) { FORWARDCHARTEST(Feptr, mb->end_subject); } +#endif + } + /* Control never reaches here */ + +#undef Lmin +#undef Lmax +#undef Leptr + /* ===================================================================== */ /* An alternation is the end of a branch; scan along to find the end of the bracketed group. */ case OP_ALT: + branch_end = Fecode; do Fecode += GET(Fecode,1); while (*Fecode == OP_ALT); break; @@ -5729,7 +5900,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* ===================================================================== */ /* The end of a parenthesized group. For all but OP_BRA and OP_COND, the starting frame was added to the chained frames in order to remember the - starting subject position for the group. */ + starting subject position for the group. (Not true for OP_BRA when it's a + whole pattern recursion, but that is handled separately below.)*/ case OP_KET: case OP_KETRMIN: @@ -5738,8 +5910,14 @@ fprintf(stderr, "++ op=%d\n", *Fecode); bracode = Fecode - GET(Fecode, 1); - /* Point N to the frame at the start of the most recent group. - Remember the subject pointer at the start of the group. */ + if (branch_end == NULL) branch_end = Fecode; + branch_start = bracode; + while (branch_start + GET(branch_start, 1) != branch_end) + branch_start += GET(branch_start, 1); + branch_end = NULL; + + /* Point N to the frame at the start of the most recent group, and P to its + predecessor. Remember the subject pointer at the start of the group. */ if (*bracode != OP_BRA && *bracode != OP_COND) { @@ -5775,27 +5953,64 @@ fprintf(stderr, "++ op=%d\n", *Fecode); switch (*bracode) { - case OP_BRA: /* No need to do anything for these */ - case OP_COND: + /* Whole pattern recursion is handled as a recursion into group 0, but + the entire pattern is wrapped in OP_BRA/OP_KET rather than a capturing + group - a design mistake: it should perhaps have been capture group 0. + Anyway, that means the end of such recursion must be handled here. It is + detected by checking for an immediately following OP_END when we are + recursing in group 0. If this is not the end of a whole-pattern + recursion, there is nothing to be done. */ + + case OP_BRA: + if (Fcurrent_recurse != 0 || Fecode[1+LINK_SIZE] != OP_END) break; + + /* It is the end of whole-pattern recursion. */ + + offset = Flast_group_offset; + if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL; + N = (heapframe *)((char *)match_data->heapframes + offset); + P = (heapframe *)((char *)N - frame_size); + Flast_group_offset = P->last_group_offset; + + /* Reinstate the previous set of captures and then carry on after the + recursion call. */ + + memcpy((char *)F + offsetof(heapframe, ovector), P->ovector, + Foffset_top * sizeof(PCRE2_SIZE)); + Foffset_top = P->offset_top; + Fcapture_last = P->capture_last; + Fcurrent_recurse = P->current_recurse; + Fecode = P->ecode + 1 + LINK_SIZE; + continue; /* With next opcode */ + + case OP_COND: /* No need to do anything for these */ case OP_SCOND: break; /* Non-atomic positive assertions are like OP_BRA, except that the subject pointer must be put back to where it was at the start of the - assertion. */ + assertion. For a variable lookbehind, check its end point. */ + + case OP_ASSERTBACK_NA: + if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) + RRETURN(MATCH_NOMATCH); + /* Fall through */ case OP_ASSERT_NA: - case OP_ASSERTBACK_NA: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; Feptr = P->eptr; break; /* Atomic positive assertions are like OP_ONCE, except that in addition the subject pointer must be put back to where it was at the start of the - assertion. */ + assertion. For a variable lookbehind, check its end point. */ + + case OP_ASSERTBACK: + if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) + RRETURN(MATCH_NOMATCH); + /* Fall through */ case OP_ASSERT: - case OP_ASSERTBACK: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; Feptr = P->eptr; /* Fall through */ @@ -5816,10 +6031,15 @@ fprintf(stderr, "++ op=%d\n", *Fecode); break; /* A matching negative assertion returns MATCH, which is turned into - NOMATCH at the assertion level. */ + NOMATCH at the assertion level. For a variable lookbehind, check its end + point. */ + + case OP_ASSERTBACK_NOT: + if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) + RRETURN(MATCH_NOMATCH); + /* Fall through */ case OP_ASSERT_NOT: - case OP_ASSERTBACK_NOT: RRETURN(MATCH_MATCH); /* At the end of a script run, apply the script-checking rules. This code @@ -5830,9 +6050,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (!PRIV(script_run)(P->eptr, Feptr, utf)) RRETURN(MATCH_NOMATCH); break; - /* Whole-pattern recursion is coded as a recurse into group 0, so it - won't be picked up here. Instead, we catch it when the OP_END is reached. - Other recursion is handled here. */ + /* Whole-pattern recursion is coded as a recurse into group 0, and is + handled with OP_BRA above. Other recursion is handled here. */ case OP_CBRA: case OP_CBRAPOS: @@ -5847,7 +6066,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); { P = (heapframe *)((char *)N - frame_size); memcpy((char *)F + offsetof(heapframe, ovector), P->ovector, - P->offset_top * sizeof(PCRE2_SIZE)); + Foffset_top * sizeof(PCRE2_SIZE)); Foffset_top = P->offset_top; Fcapture_last = P->capture_last; Fcurrent_recurse = P->current_recurse; @@ -5930,10 +6149,10 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS; /* Fall through */ - /* Unconditional end of subject assertion (\z) */ + /* Unconditional end of subject assertion (\z). */ case OP_EOD: - if (Feptr < mb->end_subject) RRETURN(MATCH_NOMATCH); + if (Feptr < mb->true_end_subject) RRETURN(MATCH_NOMATCH); if (mb->partial != 0) { mb->hitend = TRUE; @@ -6045,6 +6264,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: if (Feptr == mb->check_subject) prev_is_word = FALSE; else { PCRE2_SPTR lastptr = Feptr - 1; @@ -6059,13 +6280,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode); fc = *lastptr; if (lastptr < mb->start_used_ptr) mb->start_used_ptr = lastptr; #ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) + if (Fop == OP_UCP_WORD_BOUNDARY || Fop == OP_NOT_UCP_WORD_BOUNDARY) { - if (fc == '_') prev_is_word = TRUE; else - { - int cat = UCD_CATEGORY(fc); - prev_is_word = (cat == ucp_L || cat == ucp_N); - } + int chartype = UCD_CHARTYPE(fc); + int category = PRIV(ucp_gentype)[chartype]; + prev_is_word = (category == ucp_L || category == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc); } else #endif /* SUPPORT_UNICODE */ @@ -6093,13 +6313,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode); fc = *Feptr; if (nextptr > mb->last_used_ptr) mb->last_used_ptr = nextptr; #ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) + if (Fop == OP_UCP_WORD_BOUNDARY || Fop == OP_NOT_UCP_WORD_BOUNDARY) { - if (fc == '_') cur_is_word = TRUE; else - { - int cat = UCD_CATEGORY(fc); - cur_is_word = (cat == ucp_L || cat == ucp_N); - } + int chartype = UCD_CHARTYPE(fc); + int category = PRIV(ucp_gentype)[chartype]; + cur_is_word = (category == ucp_L || category == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc); } else #endif /* SUPPORT_UNICODE */ @@ -6108,7 +6327,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* Now see if the situation is what we want */ - if ((*Fecode++ == OP_WORD_BOUNDARY)? + if ((*Fecode++ == OP_WORD_BOUNDARY || Fop == OP_UCP_WORD_BOUNDARY)? cur_is_word == prev_is_word : cur_is_word != prev_is_word) RRETURN(MATCH_NOMATCH); break; @@ -6254,7 +6473,7 @@ F = (heapframe *)((char *)F - Fback_frame); /* Backtrack */ mb->cb->callout_flags |= PCRE2_CALLOUT_BACKTRACK; /* Note for callouts */ #ifdef DEBUG_SHOW_RMATCH -fprintf(stderr, "++ RETURN %d to %d\n", rrc, Freturn_id); +fprintf(stderr, "++ RETURN %d to RM%d\n", rrc, Freturn_id); #endif switch (Freturn_id) @@ -6263,7 +6482,7 @@ switch (Freturn_id) LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16) LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24) LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32) - LBL(33) LBL(34) LBL(35) LBL(36) + LBL(33) LBL(34) LBL(35) LBL(36) LBL(37) #ifdef SUPPORT_WIDE_CHARS LBL(100) LBL(101) @@ -6551,6 +6770,7 @@ if (use_jit) match_data, mcontext); if (rc != PCRE2_ERROR_JIT_BADOPTION) { + match_data->subject_length = length; if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0) { length = CU2BYTES(length + was_zero_terminated); @@ -6719,7 +6939,7 @@ if (mcontext == NULL) else mb->memctl = mcontext->memctl; anchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0; -firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0; +firstline = !anchored && (re->overall_options & PCRE2_FIRSTLINE) != 0; startline = (re->flags & PCRE2_STARTLINE) != 0; bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)? true_end_subject : subject + mcontext->offset_limit; @@ -6742,6 +6962,7 @@ mb->callout_data = mcontext->callout_data; mb->start_subject = subject; mb->start_offset = start_offset; mb->end_subject = end_subject; +mb->true_end_subject = true_end_subject; mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0; mb->allowemptypartial = (re->max_lookbehind > 0) || (re->flags & PCRE2_MATCH_EMPTY) != 0; @@ -6801,7 +7022,7 @@ the pattern. It is not used at all if there are no capturing parentheses. frame_size is the total size of each frame match_data->heapframes is the pointer to the frames vector - match_data->heapframes_size is the total size of the vector + match_data->heapframes_size is the allocated size of the vector We must pad the frame_size for alignment to ensure subsequent frames are as aligned as heapframe. Whilst ovector is word-aligned due to being a PCRE2_SIZE @@ -6816,7 +7037,7 @@ frame_size = (offsetof(heapframe, ovector) + smaller. */ mb->heap_limit = ((mcontext->heap_limit < re->limit_heap)? - mcontext->heap_limit : re->limit_heap) * 1024; + mcontext->heap_limit : re->limit_heap); mb->match_limit = (mcontext->match_limit < re->limit_match)? mcontext->match_limit : re->limit_match; @@ -6827,19 +7048,19 @@ mb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)? /* If a pattern has very many capturing parentheses, the frame size may be very large. Set the initial frame vector size to ensure that there are at least 10 available frames, but enforce a minimum of START_FRAMES_SIZE. If this is -greater than the heap limit, get as large a vector as possible. Always round -the size to a multiple of the frame size. */ +greater than the heap limit, get as large a vector as possible. */ heapframes_size = frame_size * 10; if (heapframes_size < START_FRAMES_SIZE) heapframes_size = START_FRAMES_SIZE; -if (heapframes_size > mb->heap_limit) +if (heapframes_size / 1024 > mb->heap_limit) { - if (frame_size > mb->heap_limit ) return PCRE2_ERROR_HEAPLIMIT; - heapframes_size = mb->heap_limit; + PCRE2_SIZE max_size = 1024 * mb->heap_limit; + if (max_size < frame_size) return PCRE2_ERROR_HEAPLIMIT; + heapframes_size = max_size; } /* If an existing frame vector in the match_data block is large enough, we can -use it.Otherwise, free any pre-existing vector and get a new one. */ +use it. Otherwise, free any pre-existing vector and get a new one. */ if (match_data->heapframes_size < heapframes_size) { @@ -7286,9 +7507,17 @@ for(;;) mb->end_offset_top = 0; mb->skip_arg_count = 0; +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ Calling match()\n"); +#endif + rc = match(start_match, mb->start_code, re->top_bracket, frame_size, match_data, mb); +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ match() returned %d\n\n", rc); +#endif + if (mb->hitend && start_partial == NULL) { start_partial = mb->start_used_ptr; @@ -7436,6 +7665,7 @@ if (utf && end_subject != true_end_subject && if (start_match >= true_end_subject) { rc = MATCH_NOMATCH; /* In case it was partial */ + match_partial = NULL; break; } @@ -7485,6 +7715,7 @@ if (rc == MATCH_MATCH) { match_data->rc = ((int)mb->end_offset_top >= 2 * match_data->oveccount)? 0 : (int)mb->end_offset_top/2 + 1; + match_data->subject_length = length; match_data->startchar = start_match - subject; match_data->leftchar = mb->start_used_ptr - subject; match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)? @@ -7499,6 +7730,7 @@ if (rc == MATCH_MATCH) match_data->flags |= PCRE2_MD_COPIED_SUBJECT; } else match_data->subject = subject; + return match_data->rc; } @@ -7520,6 +7752,7 @@ PCRE2_ERROR_PARTIAL. */ else if (match_partial != NULL) { match_data->subject = subject; + match_data->subject_length = length; match_data->ovector[0] = match_partial - subject; match_data->ovector[1] = end_subject - subject; match_data->startchar = match_partial - subject; diff --git a/src/3rdparty/pcre2/src/pcre2_match_data.c b/src/3rdparty/pcre2/src/pcre2_match_data.c index fa129b8bc5e..757dab9df51 100644 --- a/src/3rdparty/pcre2/src/pcre2_match_data.c +++ b/src/3rdparty/pcre2/src/pcre2_match_data.c @@ -170,4 +170,16 @@ return offsetof(pcre2_match_data, ovector) + 2 * (match_data->oveccount) * sizeof(PCRE2_SIZE); } + + +/************************************************* +* Get heapframes size * +*************************************************/ + +PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION +pcre2_get_match_data_heapframes_size(pcre2_match_data *match_data) +{ +return match_data->heapframes_size; +} + /* End of pcre2_match_data.c */ diff --git a/src/3rdparty/pcre2/src/pcre2_study.c b/src/3rdparty/pcre2/src/pcre2_study.c index 4db3ad11842..792e696dad7 100644 --- a/src/3rdparty/pcre2/src/pcre2_study.c +++ b/src/3rdparty/pcre2/src/pcre2_study.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2021 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -256,6 +256,7 @@ for (;;) /* Skip over things that don't match chars */ case OP_REVERSE: + case OP_VREVERSE: case OP_CREF: case OP_DNCREF: case OP_RREF: @@ -273,6 +274,8 @@ for (;;) case OP_DOLLM: case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: cc += PRIV(OP_lengths)[*cc]; break; @@ -976,6 +979,7 @@ do while (try_next) /* Loop for items in this branch */ { int rc; + PCRE2_SPTR ncode; uint8_t *classmap = NULL; #ifdef SUPPORT_WIDE_CHARS PCRE2_UCHAR xclassflags; @@ -1054,6 +1058,7 @@ do case OP_REF: case OP_REFI: case OP_REVERSE: + case OP_VREVERSE: case OP_RREF: case OP_SCOND: case OP_SET_SOM: @@ -1101,13 +1106,100 @@ do case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: tcode++; break; - /* If we hit a bracket or a positive lookahead assertion, recurse to set - bits from within the subpattern. If it can't find anything, we have to - give up. If it finds some mandatory character(s), we are done for this - branch. Otherwise, carry on scanning after the subpattern. */ + /* For a positive lookahead assertion, inspect what immediately follows, + ignoring intermediate assertions and callouts. If the next item is one + that sets a mandatory character, skip this assertion. Otherwise, treat it + the same as other bracket groups. */ + + case OP_ASSERT: + case OP_ASSERT_NA: + ncode = tcode + GET(tcode, 1); + while (*ncode == OP_ALT) ncode += GET(ncode, 1); + ncode += 1 + LINK_SIZE; + + /* Skip irrelevant items */ + + for (BOOL done = FALSE; !done;) + { + switch (*ncode) + { + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: + ncode += GET(ncode, 1); + while (*ncode == OP_ALT) ncode += GET(ncode, 1); + ncode += 1 + LINK_SIZE; + break; + + case OP_WORD_BOUNDARY: + case OP_NOT_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: + ncode++; + break; + + case OP_CALLOUT: + ncode += PRIV(OP_lengths)[OP_CALLOUT]; + break; + + case OP_CALLOUT_STR: + ncode += GET(ncode, 1 + 2*LINK_SIZE); + break; + + default: + done = TRUE; + break; + } + } + + /* Now check the next significant item. */ + + switch(*ncode) + { + default: + break; + + case OP_PROP: + if (ncode[1] != PT_CLIST) break; + /* Fall through */ + case OP_ANYNL: + case OP_CHAR: + case OP_CHARI: + case OP_EXACT: + case OP_EXACTI: + case OP_HSPACE: + case OP_MINPLUS: + case OP_MINPLUSI: + case OP_PLUS: + case OP_PLUSI: + case OP_POSPLUS: + case OP_POSPLUSI: + case OP_VSPACE: + /* Note that these types will only be present in non-UCP mode. */ + case OP_DIGIT: + case OP_NOT_DIGIT: + case OP_WORDCHAR: + case OP_NOT_WORDCHAR: + case OP_WHITESPACE: + case OP_NOT_WHITESPACE: + tcode = ncode; + continue; /* With the following significant opcode */ + } + /* Fall through */ + + /* For a group bracket or a positive assertion without an immediately + following mandatory setting, recurse to set bits from within the + subpattern. If it can't find anything, we have to give up. If it finds + some mandatory character(s), we are done for this branch. Otherwise, + carry on scanning after the subpattern. */ case OP_BRA: case OP_SBRA: @@ -1119,8 +1211,6 @@ do case OP_SCBRAPOS: case OP_ONCE: case OP_SCRIPT_RUN: - case OP_ASSERT: - case OP_ASSERT_NA: rc = set_start_bits(re, tcode, utf, ucp, depthptr); if (rc == SSB_DONE) { diff --git a/src/3rdparty/pcre2/src/pcre2_substring.c b/src/3rdparty/pcre2/src/pcre2_substring.c index ddf5774e150..14e919dce93 100644 --- a/src/3rdparty/pcre2/src/pcre2_substring.c +++ b/src/3rdparty/pcre2/src/pcre2_substring.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2018 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -309,6 +309,7 @@ Returns: if successful: 0 PCRE2_ERROR_NOSUBSTRING: no such substring PCRE2_ERROR_UNAVAILABLE: ovector is too small PCRE2_ERROR_UNSET: substring is not set + PCRE2_ERROR_INVALIDOFFSET: internal error, should not occur */ PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION @@ -341,6 +342,8 @@ else /* Matched using pcre2_dfa_match() */ left = match_data->ovector[stringnumber*2]; right = match_data->ovector[stringnumber*2+1]; +if (left > match_data->subject_length || right > match_data->subject_length) + return PCRE2_ERROR_INVALIDOFFSET; if (sizeptr != NULL) *sizeptr = (left > right)? 0 : right - left; return 0; } @@ -442,7 +445,7 @@ Returns: nothing */ PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_substring_list_free(PCRE2_SPTR *list) +pcre2_substring_list_free(PCRE2_UCHAR **list) { if (list != NULL) { diff --git a/src/3rdparty/pcre2/src/pcre2_ucd.c b/src/3rdparty/pcre2/src/pcre2_ucd.c index 5e0fc37c359..97dbc8b26f3 100644 --- a/src/3rdparty/pcre2/src/pcre2_ucd.c +++ b/src/3rdparty/pcre2/src/pcre2_ucd.c @@ -68,15 +68,15 @@ the tables when not needed. But don't leave a totally empty module because some compilers barf at that. Instead, just supply some small dummy tables. */ #ifndef SUPPORT_UNICODE -const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0 }}; +const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0}}; const uint16_t PRIV(ucd_stage1)[] = {0}; const uint16_t PRIV(ucd_stage2)[] = {0}; const uint32_t PRIV(ucd_caseless_sets)[] = {0}; #else -/* Total size: 111116 bytes, block size: 128. */ +/* Total size: 112564 bytes, block size: 128. */ -const char *PRIV(unicode_version) = "14.0.0"; +const char *PRIV(unicode_version) = "15.0.0"; /* When recompiling tables with a new Unicode version, please check the types in this structure definition with those in pcre2_internal.h (the actual field @@ -152,16 +152,16 @@ decimal digits. It is used to ensure that all the digits in a script run come from the same set. */ const uint32_t PRIV(ucd_digit_sets)[] = { - 66, /* Number of subsequent values */ + 68, /* Number of subsequent values */ 0x00039, 0x00669, 0x006f9, 0x007c9, 0x0096f, 0x009ef, 0x00a6f, 0x00aef, 0x00b6f, 0x00bef, 0x00c6f, 0x00cef, 0x00d6f, 0x00def, 0x00e59, 0x00ed9, 0x00f29, 0x01049, 0x01099, 0x017e9, 0x01819, 0x0194f, 0x019d9, 0x01a89, 0x01a99, 0x01b59, 0x01bb9, 0x01c49, 0x01c59, 0x0a629, 0x0a8d9, 0x0a909, 0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x1106f, 0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, 0x116c9, - 0x11739, 0x118e9, 0x11959, 0x11c59, 0x11d59, 0x11da9, 0x16a69, 0x16ac9, - 0x16b59, 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9, - 0x1e959, 0x1fbf9, + 0x11739, 0x118e9, 0x11959, 0x11c59, 0x11d59, 0x11da9, 0x11f59, 0x16a69, + 0x16ac9, 0x16b59, 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, + 0x1e2f9, 0x1e4f9, 0x1e959, 0x1fbf9, }; /* This vector is a list of script bitsets for the Script Extension property. @@ -323,6 +323,7 @@ const uint32_t PRIV(ucd_boolprop_sets)[] = { 0x21004024u, 0x00040000u, 0x20808004u, 0x00040000u, 0x60800944u, 0x000c0004u, + 0x60800064u, 0x000c0004u, 0x60802004u, 0x000c0000u, 0x60800344u, 0x000c8000u, 0x22808000u, 0x00040000u, @@ -334,7 +335,6 @@ const uint32_t PRIV(ucd_boolprop_sets)[] = { 0x01008020u, 0x00000000u, 0x21408024u, 0x00040000u, 0x00808000u, 0x00000000u, - 0x60800064u, 0x000c0004u, 0x60800044u, 0x000c1004u, 0x60800064u, 0x000c1004u, 0x01002020u, 0x00000001u, @@ -424,7 +424,7 @@ offset to multichar other cases or zero (8 bits), offset to other case or zero (32 bits, signed), bidi class (5 bits) and script extension (11 bits) packed into a 16-bit field, and offset in binary properties table (16 bits). */ -const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ +const ucd_record PRIV(ucd_records)[] = { /* 17076 bytes, record size 12 */ { 69, 0, 2, 0, 0, 6144, 2, }, /* 0 */ { 69, 0, 2, 0, 0, 43008, 4, }, /* 1 */ { 69, 0, 1, 0, 0, 4096, 4, }, /* 2 */ @@ -498,7 +498,7 @@ const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ { 0, 5, 12, 0, 0, 18432, 60, }, /* 70 */ { 0, 5, 12, 0, 0, 18432, 80, }, /* 71 */ { 0, 9, 12, 0, -121, 18432, 74, }, /* 72 */ - { 0, 5, 12, 1, -268, 18432, 70, }, /* 73 */ + { 0, 5, 12, 1, 0, 18432, 70, }, /* 73 */ { 0, 5, 12, 0, 195, 18432, 76, }, /* 74 */ { 0, 9, 12, 0, 210, 18432, 74, }, /* 75 */ { 0, 9, 12, 0, 206, 18432, 74, }, /* 76 */ @@ -819,57 +819,57 @@ const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ { 11, 23, 12, 0, 0, 14336, 68, }, /* 391 */ { 12, 12, 3, 0, 0, 26624, 130, }, /* 392 */ { 12, 10, 5, 0, 0, 18432, 144, }, /* 393 */ - { 12, 12, 3, 0, 0, 26624, 102, }, /* 394 */ - { 12, 7, 12, 0, 0, 18432, 82, }, /* 395 */ - { 12, 12, 3, 0, 0, 26624, 96, }, /* 396 */ - { 12, 12, 3, 0, 0, 26624, 146, }, /* 397 */ - { 12, 13, 12, 0, 0, 18432, 138, }, /* 398 */ - { 12, 21, 12, 0, 0, 18432, 68, }, /* 399 */ - { 12, 15, 12, 0, 0, 28672, 68, }, /* 400 */ - { 12, 26, 12, 0, 0, 18432, 68, }, /* 401 */ - { 13, 7, 12, 0, 0, 18432, 82, }, /* 402 */ - { 13, 12, 3, 0, 0, 26624, 130, }, /* 403 */ - { 13, 10, 5, 0, 0, 18432, 144, }, /* 404 */ - { 13, 21, 12, 0, 0, 18432, 68, }, /* 405 */ - { 13, 12, 3, 0, 0, 26624, 96, }, /* 406 */ - { 13, 12, 3, 0, 0, 18432, 130, }, /* 407 */ - { 13, 10, 3, 0, 0, 18432, 148, }, /* 408 */ - { 13, 12, 3, 0, 0, 26624, 146, }, /* 409 */ - { 13, 13, 12, 0, 0, 18528, 138, }, /* 410 */ - { 14, 12, 3, 0, 0, 26624, 130, }, /* 411 */ - { 14, 10, 5, 0, 0, 18432, 144, }, /* 412 */ - { 14, 7, 12, 0, 0, 18432, 82, }, /* 413 */ - { 14, 12, 3, 0, 0, 26624, 146, }, /* 414 */ - { 14, 10, 3, 0, 0, 18432, 148, }, /* 415 */ - { 14, 7, 4, 0, 0, 18432, 82, }, /* 416 */ - { 14, 26, 12, 0, 0, 18432, 68, }, /* 417 */ - { 14, 15, 12, 0, 0, 18432, 68, }, /* 418 */ - { 14, 13, 12, 0, 0, 18432, 138, }, /* 419 */ - { 15, 12, 3, 0, 0, 26624, 130, }, /* 420 */ - { 15, 10, 5, 0, 0, 18432, 144, }, /* 421 */ - { 15, 7, 12, 0, 0, 18432, 82, }, /* 422 */ - { 15, 12, 3, 0, 0, 26624, 146, }, /* 423 */ - { 15, 10, 3, 0, 0, 18432, 148, }, /* 424 */ - { 15, 13, 12, 0, 0, 18432, 138, }, /* 425 */ - { 15, 21, 12, 0, 0, 18432, 68, }, /* 426 */ - { 72, 7, 12, 0, 0, 18432, 82, }, /* 427 */ - { 72, 12, 3, 0, 0, 26624, 130, }, /* 428 */ - { 72, 7, 5, 0, 0, 18432, 152, }, /* 429 */ - { 72, 12, 3, 0, 0, 26624, 154, }, /* 430 */ - { 69, 23, 12, 0, 0, 14336, 68, }, /* 431 */ - { 72, 7, 12, 0, 0, 18432, 156, }, /* 432 */ - { 72, 6, 12, 0, 0, 18432, 136, }, /* 433 */ - { 72, 12, 3, 0, 0, 26624, 96, }, /* 434 */ - { 72, 21, 12, 0, 0, 18432, 68, }, /* 435 */ - { 72, 13, 12, 0, 0, 18432, 138, }, /* 436 */ - { 72, 21, 12, 0, 0, 18432, 106, }, /* 437 */ - { 73, 7, 12, 0, 0, 18432, 82, }, /* 438 */ - { 73, 12, 3, 0, 0, 26624, 130, }, /* 439 */ - { 73, 7, 5, 0, 0, 18432, 152, }, /* 440 */ - { 73, 12, 3, 0, 0, 26624, 146, }, /* 441 */ - { 73, 7, 12, 0, 0, 18432, 156, }, /* 442 */ - { 73, 6, 12, 0, 0, 18432, 136, }, /* 443 */ - { 73, 12, 3, 0, 0, 26624, 96, }, /* 444 */ + { 12, 7, 12, 0, 0, 18432, 82, }, /* 394 */ + { 12, 12, 3, 0, 0, 26624, 96, }, /* 395 */ + { 12, 12, 3, 0, 0, 26624, 146, }, /* 396 */ + { 12, 13, 12, 0, 0, 18432, 138, }, /* 397 */ + { 12, 21, 12, 0, 0, 18432, 68, }, /* 398 */ + { 12, 15, 12, 0, 0, 28672, 68, }, /* 399 */ + { 12, 26, 12, 0, 0, 18432, 68, }, /* 400 */ + { 13, 7, 12, 0, 0, 18432, 82, }, /* 401 */ + { 13, 12, 3, 0, 0, 26624, 130, }, /* 402 */ + { 13, 10, 5, 0, 0, 18432, 144, }, /* 403 */ + { 13, 21, 12, 0, 0, 18432, 68, }, /* 404 */ + { 13, 12, 3, 0, 0, 26624, 96, }, /* 405 */ + { 13, 12, 3, 0, 0, 18432, 130, }, /* 406 */ + { 13, 10, 3, 0, 0, 18432, 148, }, /* 407 */ + { 13, 12, 3, 0, 0, 26624, 146, }, /* 408 */ + { 13, 13, 12, 0, 0, 18528, 138, }, /* 409 */ + { 14, 12, 3, 0, 0, 26624, 130, }, /* 410 */ + { 14, 10, 5, 0, 0, 18432, 144, }, /* 411 */ + { 14, 7, 12, 0, 0, 18432, 82, }, /* 412 */ + { 14, 12, 3, 0, 0, 26624, 146, }, /* 413 */ + { 14, 10, 3, 0, 0, 18432, 148, }, /* 414 */ + { 14, 7, 4, 0, 0, 18432, 82, }, /* 415 */ + { 14, 26, 12, 0, 0, 18432, 68, }, /* 416 */ + { 14, 15, 12, 0, 0, 18432, 68, }, /* 417 */ + { 14, 13, 12, 0, 0, 18432, 138, }, /* 418 */ + { 15, 12, 3, 0, 0, 26624, 130, }, /* 419 */ + { 15, 10, 5, 0, 0, 18432, 144, }, /* 420 */ + { 15, 7, 12, 0, 0, 18432, 82, }, /* 421 */ + { 15, 12, 3, 0, 0, 26624, 146, }, /* 422 */ + { 15, 10, 3, 0, 0, 18432, 148, }, /* 423 */ + { 15, 13, 12, 0, 0, 18432, 138, }, /* 424 */ + { 15, 21, 12, 0, 0, 18432, 68, }, /* 425 */ + { 72, 7, 12, 0, 0, 18432, 82, }, /* 426 */ + { 72, 12, 3, 0, 0, 26624, 130, }, /* 427 */ + { 72, 7, 5, 0, 0, 18432, 152, }, /* 428 */ + { 72, 12, 3, 0, 0, 26624, 154, }, /* 429 */ + { 69, 23, 12, 0, 0, 14336, 68, }, /* 430 */ + { 72, 7, 12, 0, 0, 18432, 156, }, /* 431 */ + { 72, 6, 12, 0, 0, 18432, 136, }, /* 432 */ + { 72, 12, 3, 0, 0, 26624, 96, }, /* 433 */ + { 72, 21, 12, 0, 0, 18432, 68, }, /* 434 */ + { 72, 13, 12, 0, 0, 18432, 138, }, /* 435 */ + { 72, 21, 12, 0, 0, 18432, 106, }, /* 436 */ + { 73, 7, 12, 0, 0, 18432, 82, }, /* 437 */ + { 73, 12, 3, 0, 0, 26624, 130, }, /* 438 */ + { 73, 7, 5, 0, 0, 18432, 152, }, /* 439 */ + { 73, 12, 3, 0, 0, 26624, 146, }, /* 440 */ + { 73, 7, 12, 0, 0, 18432, 156, }, /* 441 */ + { 73, 6, 12, 0, 0, 18432, 136, }, /* 442 */ + { 73, 12, 3, 0, 0, 26624, 96, }, /* 443 */ + { 73, 12, 3, 0, 0, 26624, 102, }, /* 444 */ { 73, 13, 12, 0, 0, 18432, 138, }, /* 445 */ { 74, 7, 12, 0, 0, 18432, 82, }, /* 446 */ { 74, 26, 12, 0, 0, 18432, 68, }, /* 447 */ @@ -884,431 +884,431 @@ const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ { 74, 12, 3, 0, 0, 26624, 130, }, /* 456 */ { 74, 12, 3, 0, 0, 26624, 162, }, /* 457 */ { 74, 10, 5, 0, 0, 18432, 144, }, /* 458 */ - { 74, 12, 3, 0, 0, 26624, 146, }, /* 459 */ - { 69, 26, 12, 0, 0, 18432, 68, }, /* 460 */ - { 16, 7, 12, 0, 0, 18432, 82, }, /* 461 */ - { 16, 10, 12, 0, 0, 18432, 144, }, /* 462 */ - { 16, 12, 3, 0, 0, 26624, 130, }, /* 463 */ - { 16, 10, 5, 0, 0, 18432, 144, }, /* 464 */ - { 16, 12, 3, 0, 0, 26624, 96, }, /* 465 */ - { 16, 12, 3, 0, 0, 26624, 146, }, /* 466 */ - { 16, 13, 12, 0, 0, 18549, 138, }, /* 467 */ - { 16, 21, 12, 0, 0, 18432, 124, }, /* 468 */ - { 16, 21, 12, 0, 0, 18432, 68, }, /* 469 */ - { 16, 10, 12, 0, 0, 18432, 164, }, /* 470 */ - { 16, 12, 3, 0, 0, 26624, 128, }, /* 471 */ - { 16, 13, 12, 0, 0, 18432, 138, }, /* 472 */ - { 16, 26, 12, 0, 0, 18432, 68, }, /* 473 */ - { 17, 9, 12, 0, 7264, 18432, 74, }, /* 474 */ - { 17, 5, 12, 0, 3008, 18432, 166, }, /* 475 */ - { 69, 21, 12, 0, 0, 18510, 68, }, /* 476 */ - { 17, 6, 12, 0, 0, 18432, 142, }, /* 477 */ - { 18, 7, 6, 0, 0, 18432, 82, }, /* 478 */ - { 18, 7, 6, 0, 0, 18432, 168, }, /* 479 */ - { 18, 7, 7, 0, 0, 18432, 168, }, /* 480 */ - { 18, 7, 7, 0, 0, 18432, 82, }, /* 481 */ - { 18, 7, 8, 0, 0, 18432, 82, }, /* 482 */ - { 75, 7, 12, 0, 0, 18432, 82, }, /* 483 */ - { 75, 12, 3, 0, 0, 26624, 96, }, /* 484 */ - { 75, 21, 12, 0, 0, 18432, 68, }, /* 485 */ - { 75, 21, 12, 0, 0, 18432, 106, }, /* 486 */ - { 75, 21, 12, 0, 0, 18432, 124, }, /* 487 */ - { 75, 15, 12, 0, 0, 18432, 138, }, /* 488 */ - { 75, 15, 12, 0, 0, 18432, 68, }, /* 489 */ - { 75, 26, 12, 0, 0, 28672, 68, }, /* 490 */ - { 76, 9, 12, 0, 38864, 18432, 170, }, /* 491 */ - { 76, 9, 12, 0, 8, 18432, 170, }, /* 492 */ - { 76, 5, 12, 0, -8, 18432, 70, }, /* 493 */ - { 77, 17, 12, 0, 0, 28672, 126, }, /* 494 */ - { 77, 7, 12, 0, 0, 18432, 82, }, /* 495 */ - { 77, 26, 12, 0, 0, 18432, 68, }, /* 496 */ - { 77, 21, 12, 0, 0, 18432, 124, }, /* 497 */ - { 78, 29, 12, 0, 0, 45056, 52, }, /* 498 */ - { 78, 7, 12, 0, 0, 18432, 82, }, /* 499 */ - { 78, 22, 12, 0, 0, 28672, 158, }, /* 500 */ - { 78, 18, 12, 0, 0, 28672, 158, }, /* 501 */ - { 79, 7, 12, 0, 0, 18432, 82, }, /* 502 */ - { 69, 21, 12, 0, 0, 18432, 106, }, /* 503 */ - { 79, 14, 12, 0, 0, 18432, 82, }, /* 504 */ - { 25, 7, 12, 0, 0, 18432, 82, }, /* 505 */ - { 25, 12, 3, 0, 0, 26624, 130, }, /* 506 */ - { 25, 12, 3, 0, 0, 26624, 146, }, /* 507 */ - { 25, 10, 5, 0, 0, 18432, 172, }, /* 508 */ - { 26, 7, 12, 0, 0, 18432, 82, }, /* 509 */ - { 26, 12, 3, 0, 0, 26624, 130, }, /* 510 */ - { 26, 10, 5, 0, 0, 18432, 174, }, /* 511 */ - { 69, 21, 12, 0, 0, 18573, 124, }, /* 512 */ - { 27, 7, 12, 0, 0, 18432, 82, }, /* 513 */ - { 27, 12, 3, 0, 0, 26624, 130, }, /* 514 */ - { 28, 7, 12, 0, 0, 18432, 82, }, /* 515 */ - { 28, 12, 3, 0, 0, 26624, 130, }, /* 516 */ - { 80, 7, 12, 0, 0, 18432, 82, }, /* 517 */ - { 80, 7, 12, 0, 0, 18432, 140, }, /* 518 */ - { 80, 12, 3, 0, 0, 26624, 100, }, /* 519 */ - { 80, 10, 5, 0, 0, 18432, 144, }, /* 520 */ - { 80, 12, 3, 0, 0, 26624, 130, }, /* 521 */ - { 80, 12, 3, 0, 0, 26624, 96, }, /* 522 */ - { 80, 12, 3, 0, 0, 26624, 146, }, /* 523 */ - { 80, 21, 12, 0, 0, 18432, 106, }, /* 524 */ - { 80, 6, 12, 0, 0, 18432, 142, }, /* 525 */ - { 80, 21, 12, 0, 0, 18432, 68, }, /* 526 */ - { 80, 23, 12, 0, 0, 14336, 68, }, /* 527 */ - { 80, 13, 12, 0, 0, 18432, 138, }, /* 528 */ - { 80, 15, 12, 0, 0, 28672, 68, }, /* 529 */ - { 19, 21, 12, 0, 0, 28672, 68, }, /* 530 */ - { 69, 21, 12, 0, 0, 28777, 106, }, /* 531 */ - { 69, 21, 12, 0, 0, 28777, 124, }, /* 532 */ - { 19, 21, 12, 0, 0, 28672, 106, }, /* 533 */ - { 19, 17, 12, 0, 0, 28672, 126, }, /* 534 */ - { 19, 21, 12, 0, 0, 28672, 124, }, /* 535 */ - { 19, 21, 12, 0, 0, 28672, 176, }, /* 536 */ - { 19, 12, 3, 0, 0, 26624, 178, }, /* 537 */ - { 19, 1, 2, 0, 0, 6144, 66, }, /* 538 */ - { 19, 13, 12, 0, 0, 18432, 138, }, /* 539 */ - { 19, 7, 12, 0, 0, 18432, 82, }, /* 540 */ - { 19, 6, 12, 0, 0, 18432, 136, }, /* 541 */ - { 19, 12, 3, 0, 0, 26624, 180, }, /* 542 */ - { 19, 12, 3, 0, 0, 26624, 130, }, /* 543 */ - { 29, 7, 12, 0, 0, 18432, 82, }, /* 544 */ - { 29, 12, 3, 0, 0, 26624, 130, }, /* 545 */ - { 29, 10, 5, 0, 0, 18432, 144, }, /* 546 */ - { 29, 12, 3, 0, 0, 26624, 96, }, /* 547 */ - { 29, 26, 12, 0, 0, 28672, 68, }, /* 548 */ - { 29, 21, 12, 0, 0, 28672, 124, }, /* 549 */ - { 29, 13, 12, 0, 0, 18432, 138, }, /* 550 */ - { 30, 7, 12, 0, 0, 18432, 82, }, /* 551 */ - { 89, 7, 12, 0, 0, 18432, 82, }, /* 552 */ - { 89, 7, 12, 0, 0, 18432, 156, }, /* 553 */ - { 89, 13, 12, 0, 0, 18432, 138, }, /* 554 */ - { 89, 15, 12, 0, 0, 18432, 138, }, /* 555 */ - { 89, 26, 12, 0, 0, 28672, 68, }, /* 556 */ - { 80, 26, 12, 0, 0, 28672, 68, }, /* 557 */ - { 33, 7, 12, 0, 0, 18432, 82, }, /* 558 */ - { 33, 12, 3, 0, 0, 26624, 130, }, /* 559 */ - { 33, 10, 5, 0, 0, 18432, 144, }, /* 560 */ - { 33, 21, 12, 0, 0, 18432, 68, }, /* 561 */ - { 106, 7, 12, 0, 0, 18432, 82, }, /* 562 */ - { 106, 10, 5, 0, 0, 18432, 144, }, /* 563 */ - { 106, 12, 3, 0, 0, 26624, 130, }, /* 564 */ - { 106, 12, 3, 0, 0, 26624, 182, }, /* 565 */ - { 106, 10, 12, 0, 0, 18432, 144, }, /* 566 */ - { 106, 12, 3, 0, 0, 26624, 96, }, /* 567 */ - { 106, 13, 12, 0, 0, 18432, 138, }, /* 568 */ - { 106, 21, 12, 0, 0, 18432, 68, }, /* 569 */ - { 106, 6, 12, 0, 0, 18432, 136, }, /* 570 */ - { 106, 21, 12, 0, 0, 18432, 124, }, /* 571 */ - { 84, 11, 3, 0, 0, 26624, 184, }, /* 572 */ - { 84, 12, 3, 0, 0, 26624, 130, }, /* 573 */ - { 93, 12, 3, 0, 0, 26624, 130, }, /* 574 */ - { 93, 10, 5, 0, 0, 18432, 144, }, /* 575 */ - { 93, 7, 12, 0, 0, 18432, 82, }, /* 576 */ - { 93, 12, 3, 0, 0, 26624, 96, }, /* 577 */ - { 93, 10, 3, 0, 0, 18432, 148, }, /* 578 */ - { 93, 10, 5, 0, 0, 18432, 172, }, /* 579 */ - { 93, 13, 12, 0, 0, 18432, 138, }, /* 580 */ - { 93, 21, 12, 0, 0, 18432, 124, }, /* 581 */ - { 93, 21, 12, 0, 0, 18432, 68, }, /* 582 */ - { 93, 21, 12, 0, 0, 18432, 106, }, /* 583 */ - { 93, 26, 12, 0, 0, 18432, 68, }, /* 584 */ - { 96, 12, 3, 0, 0, 26624, 130, }, /* 585 */ - { 96, 10, 5, 0, 0, 18432, 144, }, /* 586 */ - { 96, 7, 12, 0, 0, 18432, 82, }, /* 587 */ - { 96, 10, 5, 0, 0, 18432, 172, }, /* 588 */ - { 96, 12, 3, 0, 0, 26624, 146, }, /* 589 */ - { 96, 13, 12, 0, 0, 18432, 138, }, /* 590 */ - { 119, 7, 12, 0, 0, 18432, 82, }, /* 591 */ - { 119, 12, 3, 0, 0, 26624, 102, }, /* 592 */ - { 119, 10, 5, 0, 0, 18432, 144, }, /* 593 */ - { 119, 12, 3, 0, 0, 26624, 130, }, /* 594 */ - { 119, 10, 5, 0, 0, 18432, 174, }, /* 595 */ - { 119, 21, 12, 0, 0, 18432, 68, }, /* 596 */ - { 97, 7, 12, 0, 0, 18432, 82, }, /* 597 */ - { 97, 10, 5, 0, 0, 18432, 144, }, /* 598 */ - { 97, 12, 3, 0, 0, 26624, 130, }, /* 599 */ - { 97, 12, 3, 0, 0, 26624, 186, }, /* 600 */ - { 97, 12, 3, 0, 0, 26624, 96, }, /* 601 */ - { 97, 21, 12, 0, 0, 18432, 124, }, /* 602 */ - { 97, 21, 12, 0, 0, 18432, 106, }, /* 603 */ - { 97, 13, 12, 0, 0, 18432, 138, }, /* 604 */ - { 98, 13, 12, 0, 0, 18432, 138, }, /* 605 */ - { 98, 7, 12, 0, 0, 18432, 82, }, /* 606 */ - { 98, 6, 12, 0, 0, 18432, 92, }, /* 607 */ - { 98, 6, 12, 0, 0, 18432, 94, }, /* 608 */ - { 98, 21, 12, 0, 0, 18432, 124, }, /* 609 */ - { 2, 5, 12, 63, -6222, 18432, 70, }, /* 610 */ - { 2, 5, 12, 67, -6221, 18432, 70, }, /* 611 */ - { 2, 5, 12, 71, -6212, 18432, 70, }, /* 612 */ - { 2, 5, 12, 75, -6210, 18432, 70, }, /* 613 */ - { 2, 5, 12, 79, -6210, 18432, 70, }, /* 614 */ - { 2, 5, 12, 79, -6211, 18432, 70, }, /* 615 */ - { 2, 5, 12, 84, -6204, 18432, 70, }, /* 616 */ - { 2, 5, 12, 88, -6180, 18432, 70, }, /* 617 */ - { 2, 5, 12, 108, 35267, 18432, 70, }, /* 618 */ - { 17, 9, 12, 0, -3008, 18432, 74, }, /* 619 */ - { 96, 21, 12, 0, 0, 18432, 68, }, /* 620 */ - { 84, 12, 3, 0, 0, 26762, 96, }, /* 621 */ - { 84, 12, 3, 0, 0, 26630, 96, }, /* 622 */ - { 69, 21, 12, 0, 0, 18498, 188, }, /* 623 */ - { 84, 12, 3, 0, 0, 26666, 96, }, /* 624 */ - { 84, 12, 3, 0, 0, 26696, 96, }, /* 625 */ - { 84, 12, 3, 0, 0, 26780, 96, }, /* 626 */ - { 69, 10, 5, 0, 0, 18474, 160, }, /* 627 */ - { 69, 7, 12, 0, 0, 18501, 82, }, /* 628 */ - { 69, 7, 12, 0, 0, 18474, 82, }, /* 629 */ - { 69, 7, 12, 0, 0, 18438, 82, }, /* 630 */ - { 69, 7, 12, 0, 0, 18594, 82, }, /* 631 */ - { 69, 7, 12, 0, 0, 18498, 82, }, /* 632 */ - { 84, 12, 3, 0, 0, 26750, 96, }, /* 633 */ - { 69, 10, 5, 0, 0, 18435, 160, }, /* 634 */ - { 84, 12, 3, 0, 0, 26690, 96, }, /* 635 */ - { 69, 7, 12, 0, 0, 18453, 82, }, /* 636 */ - { 2, 5, 12, 0, 0, 18432, 60, }, /* 637 */ - { 1, 6, 12, 0, 0, 18432, 88, }, /* 638 */ - { 2, 6, 12, 0, 0, 18432, 190, }, /* 639 */ - { 0, 5, 12, 0, 35332, 18432, 76, }, /* 640 */ - { 0, 5, 12, 0, 3814, 18432, 76, }, /* 641 */ - { 0, 5, 12, 0, 35384, 18432, 76, }, /* 642 */ - { 0, 5, 12, 0, 0, 18432, 192, }, /* 643 */ - { 0, 6, 12, 0, 0, 18432, 190, }, /* 644 */ - { 0, 6, 12, 0, 0, 18432, 194, }, /* 645 */ - { 1, 6, 12, 0, 0, 18432, 190, }, /* 646 */ - { 84, 12, 3, 0, 0, 26636, 102, }, /* 647 */ - { 84, 12, 3, 0, 0, 26687, 96, }, /* 648 */ - { 84, 12, 3, 0, 0, 26648, 96, }, /* 649 */ - { 0, 9, 12, 92, 1, 18432, 74, }, /* 650 */ - { 0, 5, 12, 92, -1, 18432, 76, }, /* 651 */ - { 0, 5, 12, 0, 0, 18432, 70, }, /* 652 */ - { 0, 5, 12, 92, -58, 18432, 70, }, /* 653 */ - { 0, 9, 12, 0, -7615, 18432, 74, }, /* 654 */ - { 1, 5, 12, 0, 8, 18432, 76, }, /* 655 */ - { 1, 9, 12, 0, -8, 18432, 74, }, /* 656 */ - { 1, 5, 12, 0, 74, 18432, 76, }, /* 657 */ - { 1, 5, 12, 0, 86, 18432, 76, }, /* 658 */ - { 1, 5, 12, 0, 100, 18432, 76, }, /* 659 */ - { 1, 5, 12, 0, 128, 18432, 76, }, /* 660 */ - { 1, 5, 12, 0, 112, 18432, 76, }, /* 661 */ - { 1, 5, 12, 0, 126, 18432, 76, }, /* 662 */ - { 1, 5, 12, 0, 8, 18432, 70, }, /* 663 */ - { 1, 8, 12, 0, -8, 18432, 86, }, /* 664 */ - { 1, 5, 12, 0, 0, 18432, 70, }, /* 665 */ - { 1, 5, 12, 0, 9, 18432, 70, }, /* 666 */ - { 1, 9, 12, 0, -74, 18432, 74, }, /* 667 */ - { 1, 8, 12, 0, -9, 18432, 86, }, /* 668 */ - { 1, 5, 12, 21, -7173, 18432, 76, }, /* 669 */ - { 1, 9, 12, 0, -86, 18432, 74, }, /* 670 */ - { 1, 9, 12, 0, -100, 18432, 74, }, /* 671 */ - { 1, 9, 12, 0, -112, 18432, 74, }, /* 672 */ - { 1, 9, 12, 0, -128, 18432, 74, }, /* 673 */ - { 1, 9, 12, 0, -126, 18432, 74, }, /* 674 */ - { 69, 29, 12, 0, 0, 45056, 52, }, /* 675 */ - { 84, 1, 3, 0, 0, 6144, 196, }, /* 676 */ - { 84, 1, 13, 0, 0, 6144, 198, }, /* 677 */ - { 69, 1, 2, 0, 0, 18432, 200, }, /* 678 */ - { 69, 1, 2, 0, 0, 34816, 200, }, /* 679 */ - { 69, 17, 12, 0, 0, 28672, 202, }, /* 680 */ - { 69, 21, 12, 0, 0, 28672, 64, }, /* 681 */ - { 69, 20, 12, 0, 0, 28672, 204, }, /* 682 */ - { 69, 19, 12, 0, 0, 28672, 204, }, /* 683 */ - { 69, 22, 12, 0, 0, 28672, 206, }, /* 684 */ - { 69, 20, 12, 0, 0, 28672, 206, }, /* 685 */ - { 69, 19, 12, 0, 0, 28672, 206, }, /* 686 */ - { 69, 21, 12, 0, 0, 28672, 208, }, /* 687 */ - { 69, 27, 2, 0, 0, 45056, 50, }, /* 688 */ - { 69, 28, 2, 0, 0, 4096, 50, }, /* 689 */ - { 69, 1, 2, 0, 0, 20480, 134, }, /* 690 */ - { 69, 1, 2, 0, 0, 36864, 134, }, /* 691 */ - { 69, 1, 2, 0, 0, 30720, 134, }, /* 692 */ - { 69, 1, 2, 0, 0, 24576, 134, }, /* 693 */ - { 69, 1, 2, 0, 0, 40960, 134, }, /* 694 */ - { 69, 29, 12, 0, 0, 8291, 52, }, /* 695 */ - { 69, 21, 12, 0, 0, 14336, 54, }, /* 696 */ - { 69, 21, 12, 0, 0, 14336, 64, }, /* 697 */ - { 69, 21, 14, 0, 0, 28672, 210, }, /* 698 */ - { 69, 21, 12, 0, 0, 28672, 212, }, /* 699 */ - { 69, 16, 12, 0, 0, 28672, 138, }, /* 700 */ - { 69, 16, 12, 0, 0, 28672, 214, }, /* 701 */ - { 69, 25, 12, 0, 0, 8192, 64, }, /* 702 */ - { 69, 22, 12, 0, 0, 28672, 216, }, /* 703 */ - { 69, 18, 12, 0, 0, 28672, 216, }, /* 704 */ - { 69, 21, 12, 0, 0, 28672, 202, }, /* 705 */ - { 69, 1, 2, 0, 0, 6144, 218, }, /* 706 */ - { 68, 2, 2, 0, 0, 6144, 220, }, /* 707 */ - { 69, 1, 2, 0, 0, 22528, 134, }, /* 708 */ - { 69, 1, 2, 0, 0, 38912, 134, }, /* 709 */ - { 69, 1, 2, 0, 0, 16384, 134, }, /* 710 */ - { 69, 1, 2, 0, 0, 32768, 134, }, /* 711 */ - { 69, 1, 2, 0, 0, 6144, 222, }, /* 712 */ - { 69, 25, 12, 0, 0, 12288, 118, }, /* 713 */ - { 69, 25, 12, 0, 0, 12288, 224, }, /* 714 */ - { 69, 25, 12, 0, 0, 28672, 118, }, /* 715 */ - { 69, 22, 12, 0, 0, 28672, 226, }, /* 716 */ - { 69, 18, 12, 0, 0, 28672, 226, }, /* 717 */ - { 68, 2, 12, 0, 0, 14336, 0, }, /* 718 */ - { 84, 12, 3, 0, 0, 26624, 228, }, /* 719 */ - { 84, 11, 3, 0, 0, 26624, 120, }, /* 720 */ - { 84, 11, 3, 0, 0, 26624, 230, }, /* 721 */ - { 84, 12, 3, 0, 0, 26753, 102, }, /* 722 */ - { 69, 26, 12, 0, 0, 28672, 68, }, /* 723 */ - { 69, 9, 12, 0, 0, 18432, 112, }, /* 724 */ - { 69, 5, 12, 0, 0, 18432, 232, }, /* 725 */ - { 69, 25, 12, 0, 0, 28672, 234, }, /* 726 */ - { 69, 26, 14, 0, 0, 28672, 236, }, /* 727 */ - { 1, 9, 12, 96, -7517, 18432, 74, }, /* 728 */ - { 69, 26, 12, 0, 0, 28672, 118, }, /* 729 */ - { 0, 9, 12, 100, -8383, 18432, 74, }, /* 730 */ - { 0, 9, 12, 104, -8262, 18432, 74, }, /* 731 */ - { 69, 26, 12, 0, 0, 14336, 238, }, /* 732 */ - { 0, 9, 12, 0, 28, 18432, 74, }, /* 733 */ - { 69, 7, 12, 0, 0, 18432, 240, }, /* 734 */ - { 69, 5, 14, 0, 0, 18432, 242, }, /* 735 */ - { 69, 5, 12, 0, 0, 18432, 244, }, /* 736 */ - { 0, 5, 12, 0, -28, 18432, 76, }, /* 737 */ - { 0, 14, 12, 0, 16, 18432, 74, }, /* 738 */ - { 0, 14, 12, 0, -16, 18432, 76, }, /* 739 */ - { 0, 14, 12, 0, 0, 18432, 82, }, /* 740 */ - { 69, 25, 14, 0, 0, 28672, 246, }, /* 741 */ - { 69, 26, 14, 0, 0, 28672, 246, }, /* 742 */ - { 69, 26, 12, 0, 0, 28672, 64, }, /* 743 */ - { 69, 25, 12, 0, 0, 28672, 248, }, /* 744 */ - { 69, 25, 12, 0, 0, 12288, 250, }, /* 745 */ - { 69, 22, 12, 0, 0, 28672, 248, }, /* 746 */ - { 69, 18, 12, 0, 0, 28672, 248, }, /* 747 */ - { 69, 26, 14, 0, 0, 28672, 252, }, /* 748 */ - { 69, 22, 12, 0, 0, 28672, 254, }, /* 749 */ - { 69, 18, 12, 0, 0, 28672, 254, }, /* 750 */ - { 69, 26, 12, 0, 0, 18432, 54, }, /* 751 */ - { 69, 26, 14, 0, 0, 28672, 256, }, /* 752 */ - { 68, 2, 12, 0, 0, 18432, 258, }, /* 753 */ - { 69, 26, 12, 0, 26, 18432, 260, }, /* 754 */ - { 69, 26, 14, 0, 26, 18432, 262, }, /* 755 */ - { 69, 26, 12, 0, -26, 18432, 264, }, /* 756 */ - { 69, 25, 14, 0, 0, 28672, 266, }, /* 757 */ - { 69, 26, 14, 0, 0, 28672, 268, }, /* 758 */ - { 69, 26, 14, 0, 0, 28672, 270, }, /* 759 */ - { 69, 25, 14, 0, 0, 28672, 268, }, /* 760 */ - { 69, 26, 14, 0, 0, 18432, 256, }, /* 761 */ - { 69, 26, 14, 0, 0, 28672, 272, }, /* 762 */ - { 88, 26, 12, 0, 0, 18432, 54, }, /* 763 */ - { 69, 26, 12, 0, 0, 28672, 216, }, /* 764 */ - { 35, 9, 12, 0, 48, 18432, 74, }, /* 765 */ - { 35, 5, 12, 0, -48, 18432, 76, }, /* 766 */ - { 0, 9, 12, 0, -10743, 18432, 74, }, /* 767 */ - { 0, 9, 12, 0, -3814, 18432, 74, }, /* 768 */ - { 0, 9, 12, 0, -10727, 18432, 74, }, /* 769 */ - { 0, 5, 12, 0, -10795, 18432, 76, }, /* 770 */ - { 0, 5, 12, 0, -10792, 18432, 76, }, /* 771 */ - { 0, 9, 12, 0, -10780, 18432, 74, }, /* 772 */ - { 0, 9, 12, 0, -10749, 18432, 74, }, /* 773 */ - { 0, 9, 12, 0, -10783, 18432, 74, }, /* 774 */ - { 0, 9, 12, 0, -10782, 18432, 74, }, /* 775 */ - { 0, 9, 12, 0, -10815, 18432, 74, }, /* 776 */ - { 34, 5, 12, 0, 0, 18432, 60, }, /* 777 */ - { 34, 26, 12, 0, 0, 28672, 68, }, /* 778 */ - { 34, 12, 3, 0, 0, 26624, 96, }, /* 779 */ - { 34, 21, 12, 0, 0, 28672, 68, }, /* 780 */ - { 34, 15, 12, 0, 0, 28672, 68, }, /* 781 */ - { 17, 5, 12, 0, -7264, 18432, 76, }, /* 782 */ - { 90, 7, 12, 0, 0, 18432, 82, }, /* 783 */ - { 90, 6, 12, 0, 0, 18432, 142, }, /* 784 */ - { 90, 21, 12, 0, 0, 18432, 68, }, /* 785 */ - { 90, 12, 3, 0, 0, 26624, 182, }, /* 786 */ - { 2, 12, 3, 0, 0, 26624, 130, }, /* 787 */ - { 69, 20, 12, 0, 0, 28672, 216, }, /* 788 */ - { 69, 19, 12, 0, 0, 28672, 216, }, /* 789 */ - { 69, 6, 12, 0, 0, 28672, 274, }, /* 790 */ - { 69, 21, 12, 0, 0, 28672, 276, }, /* 791 */ - { 69, 21, 12, 0, 0, 28726, 54, }, /* 792 */ - { 23, 26, 12, 0, 0, 28672, 278, }, /* 793 */ - { 69, 26, 12, 0, 0, 28672, 280, }, /* 794 */ - { 69, 26, 12, 0, 0, 28672, 282, }, /* 795 */ - { 69, 21, 12, 0, 0, 28825, 276, }, /* 796 */ - { 69, 21, 12, 0, 0, 28825, 212, }, /* 797 */ - { 69, 21, 12, 0, 0, 28819, 54, }, /* 798 */ - { 23, 6, 12, 0, 0, 18432, 136, }, /* 799 */ - { 69, 7, 12, 0, 0, 18447, 284, }, /* 800 */ - { 23, 14, 12, 0, 0, 18432, 284, }, /* 801 */ - { 69, 22, 12, 0, 0, 28825, 216, }, /* 802 */ - { 69, 18, 12, 0, 0, 28825, 216, }, /* 803 */ - { 69, 22, 12, 0, 0, 28825, 62, }, /* 804 */ - { 69, 18, 12, 0, 0, 28825, 62, }, /* 805 */ - { 69, 26, 12, 0, 0, 28819, 54, }, /* 806 */ - { 69, 17, 12, 0, 0, 28819, 202, }, /* 807 */ - { 69, 22, 12, 0, 0, 28819, 206, }, /* 808 */ - { 69, 18, 12, 0, 0, 28819, 206, }, /* 809 */ - { 84, 12, 3, 0, 0, 26669, 96, }, /* 810 */ - { 18, 10, 3, 0, 0, 18432, 286, }, /* 811 */ - { 69, 17, 14, 0, 0, 28819, 288, }, /* 812 */ - { 69, 6, 12, 0, 0, 18525, 136, }, /* 813 */ - { 69, 26, 12, 0, 0, 28819, 68, }, /* 814 */ - { 23, 6, 12, 0, 0, 18432, 142, }, /* 815 */ - { 69, 7, 12, 0, 0, 18564, 82, }, /* 816 */ - { 69, 21, 14, 0, 0, 28804, 236, }, /* 817 */ - { 69, 26, 12, 0, 0, 28687, 68, }, /* 818 */ - { 20, 7, 12, 0, 0, 18432, 82, }, /* 819 */ - { 84, 12, 3, 0, 0, 26717, 96, }, /* 820 */ - { 69, 24, 12, 0, 0, 28765, 290, }, /* 821 */ - { 20, 6, 12, 0, 0, 18432, 136, }, /* 822 */ - { 69, 17, 12, 0, 0, 28765, 126, }, /* 823 */ - { 21, 7, 12, 0, 0, 18432, 82, }, /* 824 */ - { 69, 21, 12, 0, 0, 28825, 68, }, /* 825 */ - { 69, 6, 12, 0, 0, 18525, 94, }, /* 826 */ - { 21, 6, 12, 0, 0, 18432, 136, }, /* 827 */ - { 22, 7, 12, 0, 0, 18432, 82, }, /* 828 */ - { 18, 7, 12, 0, 0, 18432, 82, }, /* 829 */ - { 18, 7, 12, 0, 0, 18432, 168, }, /* 830 */ - { 69, 26, 12, 0, 0, 18447, 68, }, /* 831 */ - { 69, 15, 12, 0, 0, 18447, 68, }, /* 832 */ - { 18, 26, 12, 0, 0, 18432, 68, }, /* 833 */ - { 18, 26, 12, 0, 0, 28672, 68, }, /* 834 */ - { 69, 15, 12, 0, 0, 18432, 68, }, /* 835 */ - { 69, 26, 14, 0, 0, 18447, 236, }, /* 836 */ - { 21, 26, 12, 0, 0, 18432, 68, }, /* 837 */ - { 23, 7, 12, 0, 0, 18432, 292, }, /* 838 */ - { 24, 7, 12, 0, 0, 18432, 82, }, /* 839 */ - { 24, 6, 12, 0, 0, 18432, 136, }, /* 840 */ - { 24, 26, 12, 0, 0, 28672, 68, }, /* 841 */ - { 111, 7, 12, 0, 0, 18432, 82, }, /* 842 */ - { 111, 6, 12, 0, 0, 18432, 142, }, /* 843 */ - { 111, 21, 12, 0, 0, 18432, 106, }, /* 844 */ - { 111, 21, 12, 0, 0, 18432, 124, }, /* 845 */ - { 99, 7, 12, 0, 0, 18432, 82, }, /* 846 */ - { 99, 6, 12, 0, 0, 18432, 136, }, /* 847 */ - { 99, 21, 12, 0, 0, 28672, 106, }, /* 848 */ - { 99, 21, 12, 0, 0, 28672, 124, }, /* 849 */ - { 99, 13, 12, 0, 0, 18432, 138, }, /* 850 */ - { 2, 9, 12, 108, 1, 18432, 74, }, /* 851 */ - { 2, 5, 12, 108, -35267, 18432, 76, }, /* 852 */ - { 2, 7, 12, 0, 0, 18432, 82, }, /* 853 */ - { 2, 21, 12, 0, 0, 28672, 68, }, /* 854 */ - { 2, 12, 3, 0, 0, 26624, 96, }, /* 855 */ - { 2, 6, 12, 0, 0, 28672, 92, }, /* 856 */ - { 2, 6, 12, 0, 0, 18432, 88, }, /* 857 */ - { 112, 7, 12, 0, 0, 18432, 82, }, /* 858 */ - { 112, 14, 12, 0, 0, 18432, 82, }, /* 859 */ - { 112, 12, 3, 0, 0, 26624, 96, }, /* 860 */ - { 112, 21, 12, 0, 0, 18432, 68, }, /* 861 */ - { 112, 21, 12, 0, 0, 18432, 124, }, /* 862 */ - { 112, 21, 12, 0, 0, 18432, 106, }, /* 863 */ - { 69, 24, 12, 0, 0, 28762, 56, }, /* 864 */ - { 0, 9, 12, 0, -35332, 18432, 74, }, /* 865 */ - { 69, 24, 12, 0, 0, 18432, 56, }, /* 866 */ - { 0, 9, 12, 0, -42280, 18432, 74, }, /* 867 */ - { 0, 5, 12, 0, 48, 18432, 76, }, /* 868 */ - { 0, 9, 12, 0, -42308, 18432, 74, }, /* 869 */ - { 0, 9, 12, 0, -42319, 18432, 74, }, /* 870 */ - { 0, 9, 12, 0, -42315, 18432, 74, }, /* 871 */ - { 0, 9, 12, 0, -42305, 18432, 74, }, /* 872 */ - { 0, 9, 12, 0, -42258, 18432, 74, }, /* 873 */ - { 0, 9, 12, 0, -42282, 18432, 74, }, /* 874 */ - { 0, 9, 12, 0, -42261, 18432, 74, }, /* 875 */ - { 0, 9, 12, 0, 928, 18432, 74, }, /* 876 */ - { 0, 9, 12, 0, -48, 18432, 74, }, /* 877 */ - { 0, 9, 12, 0, -42307, 18432, 74, }, /* 878 */ - { 0, 9, 12, 0, -35384, 18432, 74, }, /* 879 */ - { 0, 6, 12, 0, 0, 18432, 142, }, /* 880 */ + { 74, 12, 3, 0, 0, 26624, 128, }, /* 459 */ + { 74, 12, 3, 0, 0, 26624, 146, }, /* 460 */ + { 69, 26, 12, 0, 0, 18432, 68, }, /* 461 */ + { 16, 7, 12, 0, 0, 18432, 82, }, /* 462 */ + { 16, 10, 12, 0, 0, 18432, 144, }, /* 463 */ + { 16, 12, 3, 0, 0, 26624, 130, }, /* 464 */ + { 16, 10, 5, 0, 0, 18432, 144, }, /* 465 */ + { 16, 12, 3, 0, 0, 26624, 96, }, /* 466 */ + { 16, 12, 3, 0, 0, 26624, 146, }, /* 467 */ + { 16, 13, 12, 0, 0, 18549, 138, }, /* 468 */ + { 16, 21, 12, 0, 0, 18432, 124, }, /* 469 */ + { 16, 21, 12, 0, 0, 18432, 68, }, /* 470 */ + { 16, 10, 12, 0, 0, 18432, 164, }, /* 471 */ + { 16, 12, 3, 0, 0, 26624, 128, }, /* 472 */ + { 16, 13, 12, 0, 0, 18432, 138, }, /* 473 */ + { 16, 26, 12, 0, 0, 18432, 68, }, /* 474 */ + { 17, 9, 12, 0, 7264, 18432, 74, }, /* 475 */ + { 17, 5, 12, 0, 3008, 18432, 166, }, /* 476 */ + { 69, 21, 12, 0, 0, 18510, 68, }, /* 477 */ + { 17, 6, 12, 0, 0, 18432, 168, }, /* 478 */ + { 18, 7, 6, 0, 0, 18432, 82, }, /* 479 */ + { 18, 7, 6, 0, 0, 18432, 170, }, /* 480 */ + { 18, 7, 7, 0, 0, 18432, 170, }, /* 481 */ + { 18, 7, 7, 0, 0, 18432, 82, }, /* 482 */ + { 18, 7, 8, 0, 0, 18432, 82, }, /* 483 */ + { 75, 7, 12, 0, 0, 18432, 82, }, /* 484 */ + { 75, 12, 3, 0, 0, 26624, 96, }, /* 485 */ + { 75, 21, 12, 0, 0, 18432, 68, }, /* 486 */ + { 75, 21, 12, 0, 0, 18432, 106, }, /* 487 */ + { 75, 21, 12, 0, 0, 18432, 124, }, /* 488 */ + { 75, 15, 12, 0, 0, 18432, 138, }, /* 489 */ + { 75, 15, 12, 0, 0, 18432, 68, }, /* 490 */ + { 75, 26, 12, 0, 0, 28672, 68, }, /* 491 */ + { 76, 9, 12, 0, 38864, 18432, 172, }, /* 492 */ + { 76, 9, 12, 0, 8, 18432, 172, }, /* 493 */ + { 76, 5, 12, 0, -8, 18432, 70, }, /* 494 */ + { 77, 17, 12, 0, 0, 28672, 126, }, /* 495 */ + { 77, 7, 12, 0, 0, 18432, 82, }, /* 496 */ + { 77, 26, 12, 0, 0, 18432, 68, }, /* 497 */ + { 77, 21, 12, 0, 0, 18432, 124, }, /* 498 */ + { 78, 29, 12, 0, 0, 45056, 52, }, /* 499 */ + { 78, 7, 12, 0, 0, 18432, 82, }, /* 500 */ + { 78, 22, 12, 0, 0, 28672, 158, }, /* 501 */ + { 78, 18, 12, 0, 0, 28672, 158, }, /* 502 */ + { 79, 7, 12, 0, 0, 18432, 82, }, /* 503 */ + { 69, 21, 12, 0, 0, 18432, 106, }, /* 504 */ + { 79, 14, 12, 0, 0, 18432, 82, }, /* 505 */ + { 25, 7, 12, 0, 0, 18432, 82, }, /* 506 */ + { 25, 12, 3, 0, 0, 26624, 130, }, /* 507 */ + { 25, 12, 3, 0, 0, 26624, 146, }, /* 508 */ + { 25, 10, 5, 0, 0, 18432, 174, }, /* 509 */ + { 26, 7, 12, 0, 0, 18432, 82, }, /* 510 */ + { 26, 12, 3, 0, 0, 26624, 130, }, /* 511 */ + { 26, 10, 5, 0, 0, 18432, 176, }, /* 512 */ + { 69, 21, 12, 0, 0, 18573, 124, }, /* 513 */ + { 27, 7, 12, 0, 0, 18432, 82, }, /* 514 */ + { 27, 12, 3, 0, 0, 26624, 130, }, /* 515 */ + { 28, 7, 12, 0, 0, 18432, 82, }, /* 516 */ + { 28, 12, 3, 0, 0, 26624, 130, }, /* 517 */ + { 80, 7, 12, 0, 0, 18432, 82, }, /* 518 */ + { 80, 7, 12, 0, 0, 18432, 140, }, /* 519 */ + { 80, 12, 3, 0, 0, 26624, 100, }, /* 520 */ + { 80, 10, 5, 0, 0, 18432, 144, }, /* 521 */ + { 80, 12, 3, 0, 0, 26624, 130, }, /* 522 */ + { 80, 12, 3, 0, 0, 26624, 96, }, /* 523 */ + { 80, 12, 3, 0, 0, 26624, 146, }, /* 524 */ + { 80, 21, 12, 0, 0, 18432, 106, }, /* 525 */ + { 80, 6, 12, 0, 0, 18432, 142, }, /* 526 */ + { 80, 21, 12, 0, 0, 18432, 68, }, /* 527 */ + { 80, 23, 12, 0, 0, 14336, 68, }, /* 528 */ + { 80, 13, 12, 0, 0, 18432, 138, }, /* 529 */ + { 80, 15, 12, 0, 0, 28672, 68, }, /* 530 */ + { 19, 21, 12, 0, 0, 28672, 68, }, /* 531 */ + { 69, 21, 12, 0, 0, 28777, 106, }, /* 532 */ + { 69, 21, 12, 0, 0, 28777, 124, }, /* 533 */ + { 19, 21, 12, 0, 0, 28672, 106, }, /* 534 */ + { 19, 17, 12, 0, 0, 28672, 126, }, /* 535 */ + { 19, 21, 12, 0, 0, 28672, 124, }, /* 536 */ + { 19, 21, 12, 0, 0, 28672, 178, }, /* 537 */ + { 19, 12, 3, 0, 0, 26624, 180, }, /* 538 */ + { 19, 1, 2, 0, 0, 6144, 66, }, /* 539 */ + { 19, 13, 12, 0, 0, 18432, 138, }, /* 540 */ + { 19, 7, 12, 0, 0, 18432, 82, }, /* 541 */ + { 19, 6, 12, 0, 0, 18432, 136, }, /* 542 */ + { 19, 12, 3, 0, 0, 26624, 182, }, /* 543 */ + { 19, 12, 3, 0, 0, 26624, 130, }, /* 544 */ + { 29, 7, 12, 0, 0, 18432, 82, }, /* 545 */ + { 29, 12, 3, 0, 0, 26624, 130, }, /* 546 */ + { 29, 10, 5, 0, 0, 18432, 144, }, /* 547 */ + { 29, 12, 3, 0, 0, 26624, 96, }, /* 548 */ + { 29, 26, 12, 0, 0, 28672, 68, }, /* 549 */ + { 29, 21, 12, 0, 0, 28672, 124, }, /* 550 */ + { 29, 13, 12, 0, 0, 18432, 138, }, /* 551 */ + { 30, 7, 12, 0, 0, 18432, 82, }, /* 552 */ + { 89, 7, 12, 0, 0, 18432, 82, }, /* 553 */ + { 89, 7, 12, 0, 0, 18432, 156, }, /* 554 */ + { 89, 13, 12, 0, 0, 18432, 138, }, /* 555 */ + { 89, 15, 12, 0, 0, 18432, 138, }, /* 556 */ + { 89, 26, 12, 0, 0, 28672, 68, }, /* 557 */ + { 80, 26, 12, 0, 0, 28672, 68, }, /* 558 */ + { 33, 7, 12, 0, 0, 18432, 82, }, /* 559 */ + { 33, 12, 3, 0, 0, 26624, 130, }, /* 560 */ + { 33, 10, 5, 0, 0, 18432, 144, }, /* 561 */ + { 33, 21, 12, 0, 0, 18432, 68, }, /* 562 */ + { 106, 7, 12, 0, 0, 18432, 82, }, /* 563 */ + { 106, 10, 5, 0, 0, 18432, 144, }, /* 564 */ + { 106, 12, 3, 0, 0, 26624, 130, }, /* 565 */ + { 106, 12, 3, 0, 0, 26624, 184, }, /* 566 */ + { 106, 10, 12, 0, 0, 18432, 144, }, /* 567 */ + { 106, 12, 3, 0, 0, 26624, 96, }, /* 568 */ + { 106, 13, 12, 0, 0, 18432, 138, }, /* 569 */ + { 106, 21, 12, 0, 0, 18432, 68, }, /* 570 */ + { 106, 6, 12, 0, 0, 18432, 136, }, /* 571 */ + { 106, 21, 12, 0, 0, 18432, 124, }, /* 572 */ + { 84, 11, 3, 0, 0, 26624, 186, }, /* 573 */ + { 84, 12, 3, 0, 0, 26624, 130, }, /* 574 */ + { 93, 12, 3, 0, 0, 26624, 130, }, /* 575 */ + { 93, 10, 5, 0, 0, 18432, 144, }, /* 576 */ + { 93, 7, 12, 0, 0, 18432, 82, }, /* 577 */ + { 93, 12, 3, 0, 0, 26624, 96, }, /* 578 */ + { 93, 10, 3, 0, 0, 18432, 148, }, /* 579 */ + { 93, 10, 5, 0, 0, 18432, 174, }, /* 580 */ + { 93, 13, 12, 0, 0, 18432, 138, }, /* 581 */ + { 93, 21, 12, 0, 0, 18432, 124, }, /* 582 */ + { 93, 21, 12, 0, 0, 18432, 68, }, /* 583 */ + { 93, 21, 12, 0, 0, 18432, 106, }, /* 584 */ + { 93, 26, 12, 0, 0, 18432, 68, }, /* 585 */ + { 96, 12, 3, 0, 0, 26624, 130, }, /* 586 */ + { 96, 10, 5, 0, 0, 18432, 144, }, /* 587 */ + { 96, 7, 12, 0, 0, 18432, 82, }, /* 588 */ + { 96, 10, 5, 0, 0, 18432, 174, }, /* 589 */ + { 96, 12, 3, 0, 0, 26624, 146, }, /* 590 */ + { 96, 13, 12, 0, 0, 18432, 138, }, /* 591 */ + { 119, 7, 12, 0, 0, 18432, 82, }, /* 592 */ + { 119, 12, 3, 0, 0, 26624, 102, }, /* 593 */ + { 119, 10, 5, 0, 0, 18432, 144, }, /* 594 */ + { 119, 12, 3, 0, 0, 26624, 130, }, /* 595 */ + { 119, 10, 5, 0, 0, 18432, 176, }, /* 596 */ + { 119, 21, 12, 0, 0, 18432, 68, }, /* 597 */ + { 97, 7, 12, 0, 0, 18432, 82, }, /* 598 */ + { 97, 10, 5, 0, 0, 18432, 144, }, /* 599 */ + { 97, 12, 3, 0, 0, 26624, 130, }, /* 600 */ + { 97, 12, 3, 0, 0, 26624, 188, }, /* 601 */ + { 97, 12, 3, 0, 0, 26624, 96, }, /* 602 */ + { 97, 21, 12, 0, 0, 18432, 124, }, /* 603 */ + { 97, 21, 12, 0, 0, 18432, 106, }, /* 604 */ + { 97, 13, 12, 0, 0, 18432, 138, }, /* 605 */ + { 98, 13, 12, 0, 0, 18432, 138, }, /* 606 */ + { 98, 7, 12, 0, 0, 18432, 82, }, /* 607 */ + { 98, 6, 12, 0, 0, 18432, 92, }, /* 608 */ + { 98, 6, 12, 0, 0, 18432, 94, }, /* 609 */ + { 98, 21, 12, 0, 0, 18432, 124, }, /* 610 */ + { 2, 5, 12, 63, -6222, 18432, 70, }, /* 611 */ + { 2, 5, 12, 67, -6221, 18432, 70, }, /* 612 */ + { 2, 5, 12, 71, -6212, 18432, 70, }, /* 613 */ + { 2, 5, 12, 75, -6210, 18432, 70, }, /* 614 */ + { 2, 5, 12, 79, -6210, 18432, 70, }, /* 615 */ + { 2, 5, 12, 79, -6211, 18432, 70, }, /* 616 */ + { 2, 5, 12, 84, -6204, 18432, 70, }, /* 617 */ + { 2, 5, 12, 88, -6180, 18432, 70, }, /* 618 */ + { 2, 5, 12, 108, 35267, 18432, 70, }, /* 619 */ + { 17, 9, 12, 0, -3008, 18432, 74, }, /* 620 */ + { 96, 21, 12, 0, 0, 18432, 68, }, /* 621 */ + { 84, 12, 3, 0, 0, 26762, 96, }, /* 622 */ + { 84, 12, 3, 0, 0, 26630, 96, }, /* 623 */ + { 69, 21, 12, 0, 0, 18498, 190, }, /* 624 */ + { 84, 12, 3, 0, 0, 26666, 96, }, /* 625 */ + { 84, 12, 3, 0, 0, 26696, 96, }, /* 626 */ + { 84, 12, 3, 0, 0, 26780, 96, }, /* 627 */ + { 69, 10, 5, 0, 0, 18474, 160, }, /* 628 */ + { 69, 7, 12, 0, 0, 18501, 82, }, /* 629 */ + { 69, 7, 12, 0, 0, 18474, 82, }, /* 630 */ + { 69, 7, 12, 0, 0, 18438, 82, }, /* 631 */ + { 69, 7, 12, 0, 0, 18594, 82, }, /* 632 */ + { 69, 7, 12, 0, 0, 18498, 82, }, /* 633 */ + { 84, 12, 3, 0, 0, 26750, 96, }, /* 634 */ + { 69, 10, 5, 0, 0, 18435, 160, }, /* 635 */ + { 84, 12, 3, 0, 0, 26690, 96, }, /* 636 */ + { 69, 7, 12, 0, 0, 18453, 82, }, /* 637 */ + { 2, 5, 12, 0, 0, 18432, 60, }, /* 638 */ + { 1, 6, 12, 0, 0, 18432, 88, }, /* 639 */ + { 2, 6, 12, 0, 0, 18432, 168, }, /* 640 */ + { 0, 5, 12, 0, 35332, 18432, 76, }, /* 641 */ + { 0, 5, 12, 0, 3814, 18432, 76, }, /* 642 */ + { 0, 5, 12, 0, 35384, 18432, 76, }, /* 643 */ + { 0, 5, 12, 0, 0, 18432, 192, }, /* 644 */ + { 0, 6, 12, 0, 0, 18432, 168, }, /* 645 */ + { 0, 6, 12, 0, 0, 18432, 194, }, /* 646 */ + { 1, 6, 12, 0, 0, 18432, 168, }, /* 647 */ + { 84, 12, 3, 0, 0, 26636, 102, }, /* 648 */ + { 84, 12, 3, 0, 0, 26687, 96, }, /* 649 */ + { 84, 12, 3, 0, 0, 26648, 96, }, /* 650 */ + { 0, 9, 12, 92, 1, 18432, 74, }, /* 651 */ + { 0, 5, 12, 92, -1, 18432, 76, }, /* 652 */ + { 0, 5, 12, 0, 0, 18432, 70, }, /* 653 */ + { 0, 5, 12, 92, -58, 18432, 70, }, /* 654 */ + { 0, 9, 12, 0, -7615, 18432, 74, }, /* 655 */ + { 1, 5, 12, 0, 8, 18432, 76, }, /* 656 */ + { 1, 9, 12, 0, -8, 18432, 74, }, /* 657 */ + { 1, 5, 12, 0, 74, 18432, 76, }, /* 658 */ + { 1, 5, 12, 0, 86, 18432, 76, }, /* 659 */ + { 1, 5, 12, 0, 100, 18432, 76, }, /* 660 */ + { 1, 5, 12, 0, 128, 18432, 76, }, /* 661 */ + { 1, 5, 12, 0, 112, 18432, 76, }, /* 662 */ + { 1, 5, 12, 0, 126, 18432, 76, }, /* 663 */ + { 1, 5, 12, 0, 8, 18432, 70, }, /* 664 */ + { 1, 8, 12, 0, -8, 18432, 86, }, /* 665 */ + { 1, 5, 12, 0, 0, 18432, 70, }, /* 666 */ + { 1, 5, 12, 0, 9, 18432, 70, }, /* 667 */ + { 1, 9, 12, 0, -74, 18432, 74, }, /* 668 */ + { 1, 8, 12, 0, -9, 18432, 86, }, /* 669 */ + { 1, 5, 12, 21, -7173, 18432, 76, }, /* 670 */ + { 1, 9, 12, 0, -86, 18432, 74, }, /* 671 */ + { 1, 9, 12, 0, -100, 18432, 74, }, /* 672 */ + { 1, 9, 12, 0, -112, 18432, 74, }, /* 673 */ + { 1, 9, 12, 0, -128, 18432, 74, }, /* 674 */ + { 1, 9, 12, 0, -126, 18432, 74, }, /* 675 */ + { 69, 29, 12, 0, 0, 45056, 52, }, /* 676 */ + { 84, 1, 3, 0, 0, 6144, 196, }, /* 677 */ + { 84, 1, 13, 0, 0, 6144, 198, }, /* 678 */ + { 69, 1, 2, 0, 0, 18432, 200, }, /* 679 */ + { 69, 1, 2, 0, 0, 34816, 200, }, /* 680 */ + { 69, 17, 12, 0, 0, 28672, 202, }, /* 681 */ + { 69, 21, 12, 0, 0, 28672, 64, }, /* 682 */ + { 69, 20, 12, 0, 0, 28672, 204, }, /* 683 */ + { 69, 19, 12, 0, 0, 28672, 204, }, /* 684 */ + { 69, 22, 12, 0, 0, 28672, 206, }, /* 685 */ + { 69, 20, 12, 0, 0, 28672, 206, }, /* 686 */ + { 69, 19, 12, 0, 0, 28672, 206, }, /* 687 */ + { 69, 21, 12, 0, 0, 28672, 208, }, /* 688 */ + { 69, 27, 2, 0, 0, 45056, 50, }, /* 689 */ + { 69, 28, 2, 0, 0, 4096, 50, }, /* 690 */ + { 69, 1, 2, 0, 0, 20480, 134, }, /* 691 */ + { 69, 1, 2, 0, 0, 36864, 134, }, /* 692 */ + { 69, 1, 2, 0, 0, 30720, 134, }, /* 693 */ + { 69, 1, 2, 0, 0, 24576, 134, }, /* 694 */ + { 69, 1, 2, 0, 0, 40960, 134, }, /* 695 */ + { 69, 29, 12, 0, 0, 8291, 52, }, /* 696 */ + { 69, 21, 12, 0, 0, 14336, 54, }, /* 697 */ + { 69, 21, 12, 0, 0, 14336, 64, }, /* 698 */ + { 69, 21, 14, 0, 0, 28672, 210, }, /* 699 */ + { 69, 21, 12, 0, 0, 28672, 212, }, /* 700 */ + { 69, 16, 12, 0, 0, 28672, 138, }, /* 701 */ + { 69, 16, 12, 0, 0, 28672, 214, }, /* 702 */ + { 69, 25, 12, 0, 0, 8192, 64, }, /* 703 */ + { 69, 22, 12, 0, 0, 28672, 216, }, /* 704 */ + { 69, 18, 12, 0, 0, 28672, 216, }, /* 705 */ + { 69, 21, 12, 0, 0, 28672, 202, }, /* 706 */ + { 69, 1, 2, 0, 0, 6144, 218, }, /* 707 */ + { 68, 2, 2, 0, 0, 6144, 220, }, /* 708 */ + { 69, 1, 2, 0, 0, 22528, 134, }, /* 709 */ + { 69, 1, 2, 0, 0, 38912, 134, }, /* 710 */ + { 69, 1, 2, 0, 0, 16384, 134, }, /* 711 */ + { 69, 1, 2, 0, 0, 32768, 134, }, /* 712 */ + { 69, 1, 2, 0, 0, 6144, 222, }, /* 713 */ + { 69, 25, 12, 0, 0, 12288, 118, }, /* 714 */ + { 69, 25, 12, 0, 0, 12288, 224, }, /* 715 */ + { 69, 25, 12, 0, 0, 28672, 118, }, /* 716 */ + { 69, 22, 12, 0, 0, 28672, 226, }, /* 717 */ + { 69, 18, 12, 0, 0, 28672, 226, }, /* 718 */ + { 68, 2, 12, 0, 0, 14336, 0, }, /* 719 */ + { 84, 12, 3, 0, 0, 26624, 228, }, /* 720 */ + { 84, 11, 3, 0, 0, 26624, 120, }, /* 721 */ + { 84, 11, 3, 0, 0, 26624, 230, }, /* 722 */ + { 84, 12, 3, 0, 0, 26753, 102, }, /* 723 */ + { 69, 26, 12, 0, 0, 28672, 68, }, /* 724 */ + { 69, 9, 12, 0, 0, 18432, 112, }, /* 725 */ + { 69, 5, 12, 0, 0, 18432, 232, }, /* 726 */ + { 69, 25, 12, 0, 0, 28672, 234, }, /* 727 */ + { 69, 26, 14, 0, 0, 28672, 236, }, /* 728 */ + { 1, 9, 12, 96, -7517, 18432, 74, }, /* 729 */ + { 69, 26, 12, 0, 0, 28672, 118, }, /* 730 */ + { 0, 9, 12, 100, 0, 18432, 74, }, /* 731 */ + { 0, 9, 12, 104, -8262, 18432, 74, }, /* 732 */ + { 69, 26, 12, 0, 0, 14336, 238, }, /* 733 */ + { 0, 9, 12, 0, 28, 18432, 74, }, /* 734 */ + { 69, 7, 12, 0, 0, 18432, 240, }, /* 735 */ + { 69, 5, 14, 0, 0, 18432, 242, }, /* 736 */ + { 69, 5, 12, 0, 0, 18432, 244, }, /* 737 */ + { 0, 5, 12, 0, -28, 18432, 76, }, /* 738 */ + { 0, 14, 12, 0, 16, 18432, 74, }, /* 739 */ + { 0, 14, 12, 0, -16, 18432, 76, }, /* 740 */ + { 0, 14, 12, 0, 0, 18432, 82, }, /* 741 */ + { 69, 25, 14, 0, 0, 28672, 246, }, /* 742 */ + { 69, 26, 14, 0, 0, 28672, 246, }, /* 743 */ + { 69, 26, 12, 0, 0, 28672, 64, }, /* 744 */ + { 69, 25, 12, 0, 0, 28672, 248, }, /* 745 */ + { 69, 25, 12, 0, 0, 12288, 250, }, /* 746 */ + { 69, 22, 12, 0, 0, 28672, 248, }, /* 747 */ + { 69, 18, 12, 0, 0, 28672, 248, }, /* 748 */ + { 69, 26, 14, 0, 0, 28672, 252, }, /* 749 */ + { 69, 22, 12, 0, 0, 28672, 254, }, /* 750 */ + { 69, 18, 12, 0, 0, 28672, 254, }, /* 751 */ + { 69, 26, 12, 0, 0, 18432, 54, }, /* 752 */ + { 69, 26, 14, 0, 0, 28672, 256, }, /* 753 */ + { 68, 2, 12, 0, 0, 18432, 258, }, /* 754 */ + { 69, 26, 12, 0, 26, 18432, 260, }, /* 755 */ + { 69, 26, 14, 0, 26, 18432, 262, }, /* 756 */ + { 69, 26, 12, 0, -26, 18432, 264, }, /* 757 */ + { 69, 25, 14, 0, 0, 28672, 266, }, /* 758 */ + { 69, 26, 14, 0, 0, 28672, 268, }, /* 759 */ + { 69, 26, 14, 0, 0, 28672, 270, }, /* 760 */ + { 69, 25, 14, 0, 0, 28672, 268, }, /* 761 */ + { 69, 26, 14, 0, 0, 18432, 256, }, /* 762 */ + { 69, 26, 14, 0, 0, 28672, 272, }, /* 763 */ + { 88, 26, 12, 0, 0, 18432, 54, }, /* 764 */ + { 69, 26, 12, 0, 0, 28672, 216, }, /* 765 */ + { 35, 9, 12, 0, 48, 18432, 74, }, /* 766 */ + { 35, 5, 12, 0, -48, 18432, 76, }, /* 767 */ + { 0, 9, 12, 0, -10743, 18432, 74, }, /* 768 */ + { 0, 9, 12, 0, -3814, 18432, 74, }, /* 769 */ + { 0, 9, 12, 0, -10727, 18432, 74, }, /* 770 */ + { 0, 5, 12, 0, -10795, 18432, 76, }, /* 771 */ + { 0, 5, 12, 0, -10792, 18432, 76, }, /* 772 */ + { 0, 9, 12, 0, -10780, 18432, 74, }, /* 773 */ + { 0, 9, 12, 0, -10749, 18432, 74, }, /* 774 */ + { 0, 9, 12, 0, -10783, 18432, 74, }, /* 775 */ + { 0, 9, 12, 0, -10782, 18432, 74, }, /* 776 */ + { 0, 9, 12, 0, -10815, 18432, 74, }, /* 777 */ + { 34, 5, 12, 0, 0, 18432, 60, }, /* 778 */ + { 34, 26, 12, 0, 0, 28672, 68, }, /* 779 */ + { 34, 12, 3, 0, 0, 26624, 96, }, /* 780 */ + { 34, 21, 12, 0, 0, 28672, 68, }, /* 781 */ + { 34, 15, 12, 0, 0, 28672, 68, }, /* 782 */ + { 17, 5, 12, 0, -7264, 18432, 76, }, /* 783 */ + { 90, 7, 12, 0, 0, 18432, 82, }, /* 784 */ + { 90, 6, 12, 0, 0, 18432, 142, }, /* 785 */ + { 90, 21, 12, 0, 0, 18432, 68, }, /* 786 */ + { 90, 12, 3, 0, 0, 26624, 184, }, /* 787 */ + { 2, 12, 3, 0, 0, 26624, 130, }, /* 788 */ + { 69, 20, 12, 0, 0, 28672, 216, }, /* 789 */ + { 69, 19, 12, 0, 0, 28672, 216, }, /* 790 */ + { 69, 6, 12, 0, 0, 28672, 274, }, /* 791 */ + { 69, 21, 12, 0, 0, 28672, 276, }, /* 792 */ + { 69, 21, 12, 0, 0, 28726, 54, }, /* 793 */ + { 23, 26, 12, 0, 0, 28672, 278, }, /* 794 */ + { 69, 26, 12, 0, 0, 28672, 280, }, /* 795 */ + { 69, 26, 12, 0, 0, 28672, 282, }, /* 796 */ + { 69, 21, 12, 0, 0, 28825, 276, }, /* 797 */ + { 69, 21, 12, 0, 0, 28825, 212, }, /* 798 */ + { 69, 21, 12, 0, 0, 28819, 54, }, /* 799 */ + { 23, 6, 12, 0, 0, 18432, 136, }, /* 800 */ + { 69, 7, 12, 0, 0, 18447, 284, }, /* 801 */ + { 23, 14, 12, 0, 0, 18432, 284, }, /* 802 */ + { 69, 22, 12, 0, 0, 28825, 216, }, /* 803 */ + { 69, 18, 12, 0, 0, 28825, 216, }, /* 804 */ + { 69, 22, 12, 0, 0, 28825, 62, }, /* 805 */ + { 69, 18, 12, 0, 0, 28825, 62, }, /* 806 */ + { 69, 26, 12, 0, 0, 28819, 54, }, /* 807 */ + { 69, 17, 12, 0, 0, 28819, 202, }, /* 808 */ + { 69, 22, 12, 0, 0, 28819, 206, }, /* 809 */ + { 69, 18, 12, 0, 0, 28819, 206, }, /* 810 */ + { 84, 12, 3, 0, 0, 26669, 96, }, /* 811 */ + { 18, 10, 3, 0, 0, 18432, 286, }, /* 812 */ + { 69, 17, 14, 0, 0, 28819, 288, }, /* 813 */ + { 69, 6, 12, 0, 0, 18525, 136, }, /* 814 */ + { 69, 26, 12, 0, 0, 28819, 68, }, /* 815 */ + { 23, 6, 12, 0, 0, 18432, 142, }, /* 816 */ + { 69, 7, 12, 0, 0, 18564, 82, }, /* 817 */ + { 69, 21, 14, 0, 0, 28804, 236, }, /* 818 */ + { 69, 26, 12, 0, 0, 28687, 68, }, /* 819 */ + { 20, 7, 12, 0, 0, 18432, 82, }, /* 820 */ + { 84, 12, 3, 0, 0, 26717, 96, }, /* 821 */ + { 69, 24, 12, 0, 0, 28765, 290, }, /* 822 */ + { 20, 6, 12, 0, 0, 18432, 136, }, /* 823 */ + { 69, 17, 12, 0, 0, 28765, 126, }, /* 824 */ + { 21, 7, 12, 0, 0, 18432, 82, }, /* 825 */ + { 69, 21, 12, 0, 0, 28825, 68, }, /* 826 */ + { 69, 6, 12, 0, 0, 18525, 94, }, /* 827 */ + { 21, 6, 12, 0, 0, 18432, 136, }, /* 828 */ + { 22, 7, 12, 0, 0, 18432, 82, }, /* 829 */ + { 18, 7, 12, 0, 0, 18432, 82, }, /* 830 */ + { 18, 7, 12, 0, 0, 18432, 170, }, /* 831 */ + { 69, 26, 12, 0, 0, 18447, 68, }, /* 832 */ + { 69, 15, 12, 0, 0, 18447, 68, }, /* 833 */ + { 18, 26, 12, 0, 0, 18432, 68, }, /* 834 */ + { 18, 26, 12, 0, 0, 28672, 68, }, /* 835 */ + { 69, 15, 12, 0, 0, 18432, 68, }, /* 836 */ + { 69, 26, 14, 0, 0, 18447, 236, }, /* 837 */ + { 21, 26, 12, 0, 0, 18432, 68, }, /* 838 */ + { 23, 7, 12, 0, 0, 18432, 292, }, /* 839 */ + { 24, 7, 12, 0, 0, 18432, 82, }, /* 840 */ + { 24, 6, 12, 0, 0, 18432, 136, }, /* 841 */ + { 24, 26, 12, 0, 0, 28672, 68, }, /* 842 */ + { 111, 7, 12, 0, 0, 18432, 82, }, /* 843 */ + { 111, 6, 12, 0, 0, 18432, 142, }, /* 844 */ + { 111, 21, 12, 0, 0, 18432, 106, }, /* 845 */ + { 111, 21, 12, 0, 0, 18432, 124, }, /* 846 */ + { 99, 7, 12, 0, 0, 18432, 82, }, /* 847 */ + { 99, 6, 12, 0, 0, 18432, 136, }, /* 848 */ + { 99, 21, 12, 0, 0, 28672, 106, }, /* 849 */ + { 99, 21, 12, 0, 0, 28672, 124, }, /* 850 */ + { 99, 13, 12, 0, 0, 18432, 138, }, /* 851 */ + { 2, 9, 12, 108, 1, 18432, 74, }, /* 852 */ + { 2, 5, 12, 108, -35267, 18432, 76, }, /* 853 */ + { 2, 7, 12, 0, 0, 18432, 82, }, /* 854 */ + { 2, 21, 12, 0, 0, 28672, 68, }, /* 855 */ + { 2, 12, 3, 0, 0, 26624, 96, }, /* 856 */ + { 2, 6, 12, 0, 0, 28672, 92, }, /* 857 */ + { 2, 6, 12, 0, 0, 18432, 88, }, /* 858 */ + { 112, 7, 12, 0, 0, 18432, 82, }, /* 859 */ + { 112, 14, 12, 0, 0, 18432, 82, }, /* 860 */ + { 112, 12, 3, 0, 0, 26624, 96, }, /* 861 */ + { 112, 21, 12, 0, 0, 18432, 68, }, /* 862 */ + { 112, 21, 12, 0, 0, 18432, 124, }, /* 863 */ + { 112, 21, 12, 0, 0, 18432, 106, }, /* 864 */ + { 69, 24, 12, 0, 0, 28762, 56, }, /* 865 */ + { 0, 9, 12, 0, -35332, 18432, 74, }, /* 866 */ + { 69, 24, 12, 0, 0, 18432, 56, }, /* 867 */ + { 0, 9, 12, 0, -42280, 18432, 74, }, /* 868 */ + { 0, 5, 12, 0, 48, 18432, 76, }, /* 869 */ + { 0, 9, 12, 0, -42308, 18432, 74, }, /* 870 */ + { 0, 9, 12, 0, -42319, 18432, 74, }, /* 871 */ + { 0, 9, 12, 0, -42315, 18432, 74, }, /* 872 */ + { 0, 9, 12, 0, -42305, 18432, 74, }, /* 873 */ + { 0, 9, 12, 0, -42258, 18432, 74, }, /* 874 */ + { 0, 9, 12, 0, -42282, 18432, 74, }, /* 875 */ + { 0, 9, 12, 0, -42261, 18432, 74, }, /* 876 */ + { 0, 9, 12, 0, 928, 18432, 74, }, /* 877 */ + { 0, 9, 12, 0, -48, 18432, 74, }, /* 878 */ + { 0, 9, 12, 0, -42307, 18432, 74, }, /* 879 */ + { 0, 9, 12, 0, -35384, 18432, 74, }, /* 880 */ { 36, 7, 12, 0, 0, 18432, 82, }, /* 881 */ { 36, 12, 3, 0, 0, 26624, 130, }, /* 882 */ - { 36, 12, 3, 0, 0, 26624, 182, }, /* 883 */ + { 36, 12, 3, 0, 0, 26624, 184, }, /* 883 */ { 36, 10, 5, 0, 0, 18432, 144, }, /* 884 */ { 36, 26, 12, 0, 0, 28672, 68, }, /* 885 */ { 69, 15, 12, 0, 0, 18612, 68, }, /* 886 */ @@ -1331,18 +1331,18 @@ const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ { 39, 7, 12, 0, 0, 18432, 82, }, /* 903 */ { 39, 12, 3, 0, 0, 26624, 130, }, /* 904 */ { 39, 12, 3, 0, 0, 26624, 96, }, /* 905 */ - { 69, 21, 12, 0, 0, 18567, 188, }, /* 906 */ + { 69, 21, 12, 0, 0, 18567, 190, }, /* 906 */ { 39, 21, 12, 0, 0, 18432, 124, }, /* 907 */ { 101, 7, 12, 0, 0, 18432, 82, }, /* 908 */ { 101, 12, 3, 0, 0, 26624, 130, }, /* 909 */ { 101, 10, 5, 0, 0, 18432, 144, }, /* 910 */ - { 101, 10, 5, 0, 0, 18432, 172, }, /* 911 */ + { 101, 10, 5, 0, 0, 18432, 174, }, /* 911 */ { 101, 21, 12, 0, 0, 18432, 68, }, /* 912 */ { 40, 12, 3, 0, 0, 26624, 130, }, /* 913 */ { 40, 10, 5, 0, 0, 18432, 144, }, /* 914 */ { 40, 7, 12, 0, 0, 18432, 82, }, /* 915 */ { 40, 12, 3, 0, 0, 26624, 96, }, /* 916 */ - { 40, 10, 5, 0, 0, 18432, 172, }, /* 917 */ + { 40, 10, 5, 0, 0, 18432, 174, }, /* 917 */ { 40, 21, 12, 0, 0, 18432, 68, }, /* 918 */ { 40, 21, 12, 0, 0, 18432, 106, }, /* 919 */ { 40, 21, 12, 0, 0, 18432, 124, }, /* 920 */ @@ -1370,470 +1370,484 @@ const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ { 113, 6, 12, 0, 0, 18432, 136, }, /* 942 */ { 113, 12, 3, 0, 0, 26624, 146, }, /* 943 */ { 0, 5, 12, 0, -928, 18432, 76, }, /* 944 */ - { 0, 6, 12, 0, 0, 18432, 92, }, /* 945 */ - { 76, 5, 12, 0, -38864, 18432, 70, }, /* 946 */ - { 113, 10, 5, 0, 0, 18432, 160, }, /* 947 */ - { 113, 13, 12, 0, 0, 18432, 138, }, /* 948 */ - { 18, 7, 9, 0, 0, 18432, 82, }, /* 949 */ - { 18, 7, 10, 0, 0, 18432, 82, }, /* 950 */ - { 68, 4, 12, 0, 0, 18432, 0, }, /* 951 */ - { 68, 3, 12, 0, 0, 18432, 0, }, /* 952 */ - { 23, 7, 12, 0, 0, 18432, 284, }, /* 953 */ - { 71, 25, 12, 0, 0, 12288, 118, }, /* 954 */ - { 3, 7, 12, 0, 0, 0, 296, }, /* 955 */ - { 69, 18, 12, 0, 0, 28705, 54, }, /* 956 */ - { 69, 22, 12, 0, 0, 28705, 54, }, /* 957 */ - { 68, 2, 12, 0, 0, 6144, 298, }, /* 958 */ - { 3, 7, 12, 0, 0, 39, 82, }, /* 959 */ - { 3, 26, 12, 0, 0, 28711, 68, }, /* 960 */ - { 84, 12, 3, 0, 0, 26624, 178, }, /* 961 */ - { 84, 12, 3, 0, 0, 26624, 300, }, /* 962 */ - { 69, 21, 12, 0, 0, 28672, 68, }, /* 963 */ - { 69, 21, 12, 0, 0, 28672, 122, }, /* 964 */ - { 69, 22, 12, 0, 0, 28672, 68, }, /* 965 */ - { 69, 18, 12, 0, 0, 28672, 68, }, /* 966 */ - { 69, 17, 12, 0, 0, 28672, 126, }, /* 967 */ - { 69, 22, 12, 0, 0, 28672, 302, }, /* 968 */ - { 69, 18, 12, 0, 0, 28672, 302, }, /* 969 */ - { 69, 21, 12, 0, 0, 8192, 106, }, /* 970 */ - { 69, 21, 12, 0, 0, 8192, 304, }, /* 971 */ - { 69, 21, 12, 0, 0, 8192, 306, }, /* 972 */ - { 69, 21, 12, 0, 0, 28672, 124, }, /* 973 */ - { 69, 22, 12, 0, 0, 28672, 158, }, /* 974 */ - { 69, 18, 12, 0, 0, 28672, 158, }, /* 975 */ - { 69, 21, 12, 0, 0, 14336, 68, }, /* 976 */ - { 69, 21, 12, 0, 0, 28672, 118, }, /* 977 */ - { 69, 17, 12, 0, 0, 12288, 224, }, /* 978 */ - { 69, 25, 12, 0, 0, 28672, 226, }, /* 979 */ - { 69, 21, 12, 0, 0, 28672, 302, }, /* 980 */ - { 69, 21, 12, 0, 0, 28672, 308, }, /* 981 */ - { 69, 17, 12, 0, 0, 12288, 126, }, /* 982 */ - { 69, 21, 12, 0, 0, 8192, 68, }, /* 983 */ - { 69, 13, 12, 0, 0, 10240, 310, }, /* 984 */ - { 0, 9, 12, 0, 32, 18432, 312, }, /* 985 */ - { 69, 24, 12, 0, 0, 28672, 314, }, /* 986 */ - { 0, 5, 12, 0, -32, 18432, 316, }, /* 987 */ - { 69, 21, 12, 0, 0, 28825, 124, }, /* 988 */ - { 69, 22, 12, 0, 0, 28825, 318, }, /* 989 */ - { 69, 18, 12, 0, 0, 28825, 318, }, /* 990 */ - { 69, 21, 12, 0, 0, 28825, 106, }, /* 991 */ - { 69, 6, 3, 0, 0, 18525, 320, }, /* 992 */ - { 69, 1, 2, 0, 0, 28672, 322, }, /* 993 */ - { 31, 7, 12, 0, 0, 18432, 82, }, /* 994 */ - { 69, 21, 12, 0, 0, 18552, 68, }, /* 995 */ - { 69, 21, 12, 0, 0, 28792, 68, }, /* 996 */ - { 69, 21, 12, 0, 0, 18483, 68, }, /* 997 */ - { 69, 15, 12, 0, 0, 18555, 68, }, /* 998 */ - { 69, 26, 12, 0, 0, 18483, 68, }, /* 999 */ - { 1, 14, 12, 0, 0, 28672, 82, }, /* 1000 */ - { 1, 15, 12, 0, 0, 28672, 68, }, /* 1001 */ - { 1, 26, 12, 0, 0, 28672, 68, }, /* 1002 */ - { 1, 26, 12, 0, 0, 18432, 68, }, /* 1003 */ - { 102, 7, 12, 0, 0, 18432, 82, }, /* 1004 */ - { 103, 7, 12, 0, 0, 18432, 82, }, /* 1005 */ - { 84, 12, 3, 0, 0, 26651, 96, }, /* 1006 */ - { 69, 15, 12, 0, 0, 10267, 68, }, /* 1007 */ - { 81, 7, 12, 0, 0, 18432, 82, }, /* 1008 */ - { 81, 15, 12, 0, 0, 18432, 68, }, /* 1009 */ - { 82, 7, 12, 0, 0, 18432, 82, }, /* 1010 */ - { 82, 14, 12, 0, 0, 18432, 82, }, /* 1011 */ - { 53, 7, 12, 0, 0, 18432, 82, }, /* 1012 */ - { 53, 12, 3, 0, 0, 26624, 130, }, /* 1013 */ - { 85, 7, 12, 0, 0, 18432, 82, }, /* 1014 */ - { 85, 21, 12, 0, 0, 18432, 106, }, /* 1015 */ - { 91, 7, 12, 0, 0, 18432, 82, }, /* 1016 */ - { 91, 21, 12, 0, 0, 18432, 106, }, /* 1017 */ - { 91, 14, 12, 0, 0, 18432, 82, }, /* 1018 */ - { 83, 9, 12, 0, 40, 18432, 74, }, /* 1019 */ - { 83, 5, 12, 0, -40, 18432, 76, }, /* 1020 */ - { 86, 7, 12, 0, 0, 18432, 82, }, /* 1021 */ - { 87, 7, 12, 0, 0, 18432, 82, }, /* 1022 */ - { 87, 13, 12, 0, 0, 18432, 138, }, /* 1023 */ - { 145, 9, 12, 0, 40, 18432, 74, }, /* 1024 */ - { 145, 5, 12, 0, -40, 18432, 76, }, /* 1025 */ - { 127, 7, 12, 0, 0, 18432, 82, }, /* 1026 */ - { 125, 7, 12, 0, 0, 18432, 82, }, /* 1027 */ - { 125, 21, 12, 0, 0, 18432, 68, }, /* 1028 */ - { 161, 9, 12, 0, 39, 18432, 74, }, /* 1029 */ - { 161, 5, 12, 0, -39, 18432, 76, }, /* 1030 */ - { 49, 7, 12, 0, 0, 18432, 82, }, /* 1031 */ - { 0, 6, 12, 0, 0, 18432, 94, }, /* 1032 */ - { 32, 7, 12, 0, 0, 34816, 82, }, /* 1033 */ - { 114, 7, 12, 0, 0, 34816, 82, }, /* 1034 */ - { 114, 21, 12, 0, 0, 34816, 106, }, /* 1035 */ - { 114, 15, 12, 0, 0, 34816, 68, }, /* 1036 */ - { 133, 7, 12, 0, 0, 34816, 82, }, /* 1037 */ - { 133, 26, 12, 0, 0, 34816, 68, }, /* 1038 */ - { 133, 15, 12, 0, 0, 34816, 68, }, /* 1039 */ - { 132, 7, 12, 0, 0, 34816, 82, }, /* 1040 */ - { 132, 15, 12, 0, 0, 34816, 68, }, /* 1041 */ - { 139, 7, 12, 0, 0, 34816, 82, }, /* 1042 */ - { 139, 15, 12, 0, 0, 34816, 68, }, /* 1043 */ - { 95, 7, 12, 0, 0, 34816, 82, }, /* 1044 */ - { 95, 15, 12, 0, 0, 34816, 68, }, /* 1045 */ - { 95, 21, 12, 0, 0, 28672, 106, }, /* 1046 */ - { 104, 7, 12, 0, 0, 34816, 82, }, /* 1047 */ - { 104, 21, 12, 0, 0, 34816, 68, }, /* 1048 */ - { 122, 7, 12, 0, 0, 34816, 82, }, /* 1049 */ - { 121, 7, 12, 0, 0, 34816, 82, }, /* 1050 */ - { 121, 15, 12, 0, 0, 34816, 68, }, /* 1051 */ - { 92, 7, 12, 0, 0, 34816, 82, }, /* 1052 */ - { 92, 12, 3, 0, 0, 26624, 130, }, /* 1053 */ - { 92, 12, 3, 0, 0, 26624, 102, }, /* 1054 */ - { 92, 12, 3, 0, 0, 26624, 182, }, /* 1055 */ - { 92, 15, 12, 0, 0, 34816, 68, }, /* 1056 */ - { 92, 21, 12, 0, 0, 34816, 68, }, /* 1057 */ - { 92, 21, 12, 0, 0, 34816, 124, }, /* 1058 */ - { 115, 7, 12, 0, 0, 34816, 82, }, /* 1059 */ - { 115, 15, 12, 0, 0, 34816, 68, }, /* 1060 */ - { 115, 21, 12, 0, 0, 34816, 68, }, /* 1061 */ - { 131, 7, 12, 0, 0, 34816, 82, }, /* 1062 */ - { 131, 15, 12, 0, 0, 34816, 68, }, /* 1063 */ - { 51, 7, 12, 0, 0, 34816, 82, }, /* 1064 */ - { 51, 26, 12, 0, 0, 34816, 68, }, /* 1065 */ - { 51, 12, 3, 0, 0, 26624, 96, }, /* 1066 */ - { 51, 15, 12, 0, 0, 34816, 68, }, /* 1067 */ - { 51, 21, 12, 0, 0, 34816, 106, }, /* 1068 */ - { 51, 21, 12, 0, 0, 34918, 106, }, /* 1069 */ - { 51, 21, 12, 0, 0, 34816, 68, }, /* 1070 */ - { 108, 7, 12, 0, 0, 34816, 82, }, /* 1071 */ - { 108, 21, 12, 0, 0, 28672, 68, }, /* 1072 */ - { 108, 21, 12, 0, 0, 28672, 106, }, /* 1073 */ - { 116, 7, 12, 0, 0, 34816, 82, }, /* 1074 */ - { 116, 15, 12, 0, 0, 34816, 68, }, /* 1075 */ - { 117, 7, 12, 0, 0, 34816, 82, }, /* 1076 */ - { 117, 15, 12, 0, 0, 34816, 68, }, /* 1077 */ - { 54, 7, 12, 0, 0, 34816, 82, }, /* 1078 */ - { 54, 21, 12, 0, 0, 34816, 106, }, /* 1079 */ - { 54, 15, 12, 0, 0, 34816, 68, }, /* 1080 */ - { 118, 7, 12, 0, 0, 34816, 82, }, /* 1081 */ - { 140, 9, 12, 0, 64, 34816, 74, }, /* 1082 */ - { 140, 5, 12, 0, -64, 34816, 76, }, /* 1083 */ - { 140, 15, 12, 0, 0, 34816, 68, }, /* 1084 */ - { 62, 7, 12, 0, 0, 0, 82, }, /* 1085 */ - { 62, 7, 12, 0, 0, 0, 294, }, /* 1086 */ - { 62, 12, 3, 0, 0, 26624, 128, }, /* 1087 */ - { 62, 13, 12, 0, 0, 2048, 138, }, /* 1088 */ - { 3, 15, 12, 0, 0, 2048, 68, }, /* 1089 */ - { 65, 7, 12, 0, 0, 34816, 82, }, /* 1090 */ - { 65, 12, 3, 0, 0, 26624, 130, }, /* 1091 */ - { 65, 17, 12, 0, 0, 34816, 126, }, /* 1092 */ - { 152, 7, 12, 0, 0, 34816, 82, }, /* 1093 */ - { 152, 15, 12, 0, 0, 34816, 68, }, /* 1094 */ - { 63, 7, 12, 0, 0, 0, 82, }, /* 1095 */ - { 63, 12, 3, 0, 0, 26624, 96, }, /* 1096 */ - { 63, 15, 12, 0, 0, 0, 68, }, /* 1097 */ - { 63, 21, 12, 0, 0, 0, 124, }, /* 1098 */ - { 67, 7, 12, 0, 0, 34816, 82, }, /* 1099 */ - { 67, 12, 3, 0, 0, 26624, 96, }, /* 1100 */ - { 67, 21, 12, 0, 0, 34816, 124, }, /* 1101 */ - { 156, 7, 12, 0, 0, 34816, 82, }, /* 1102 */ - { 156, 15, 12, 0, 0, 34816, 68, }, /* 1103 */ - { 153, 7, 12, 0, 0, 34816, 82, }, /* 1104 */ - { 120, 10, 5, 0, 0, 18432, 144, }, /* 1105 */ - { 120, 12, 3, 0, 0, 26624, 130, }, /* 1106 */ - { 120, 7, 12, 0, 0, 18432, 82, }, /* 1107 */ - { 120, 12, 3, 0, 0, 26624, 146, }, /* 1108 */ - { 120, 21, 12, 0, 0, 18432, 124, }, /* 1109 */ - { 120, 21, 12, 0, 0, 18432, 106, }, /* 1110 */ - { 120, 15, 12, 0, 0, 28672, 68, }, /* 1111 */ - { 120, 13, 12, 0, 0, 18432, 138, }, /* 1112 */ - { 120, 12, 3, 0, 0, 26624, 182, }, /* 1113 */ - { 41, 12, 3, 0, 0, 26624, 102, }, /* 1114 */ - { 41, 10, 5, 0, 0, 18432, 144, }, /* 1115 */ - { 41, 7, 12, 0, 0, 18432, 82, }, /* 1116 */ - { 41, 12, 3, 0, 0, 26624, 130, }, /* 1117 */ - { 41, 12, 3, 0, 0, 26624, 146, }, /* 1118 */ - { 41, 12, 3, 0, 0, 26624, 96, }, /* 1119 */ - { 41, 21, 12, 0, 0, 18432, 68, }, /* 1120 */ - { 41, 1, 4, 0, 0, 18432, 132, }, /* 1121 */ - { 41, 21, 12, 0, 0, 18432, 124, }, /* 1122 */ - { 124, 7, 12, 0, 0, 18432, 82, }, /* 1123 */ - { 124, 13, 12, 0, 0, 18432, 138, }, /* 1124 */ - { 43, 12, 3, 0, 0, 26624, 130, }, /* 1125 */ - { 43, 7, 12, 0, 0, 18432, 82, }, /* 1126 */ - { 43, 10, 5, 0, 0, 18432, 144, }, /* 1127 */ - { 43, 12, 3, 0, 0, 26624, 146, }, /* 1128 */ - { 43, 13, 12, 0, 0, 18432, 138, }, /* 1129 */ - { 43, 21, 12, 0, 0, 18432, 68, }, /* 1130 */ - { 43, 21, 12, 0, 0, 18432, 124, }, /* 1131 */ - { 50, 7, 12, 0, 0, 18432, 82, }, /* 1132 */ - { 50, 12, 3, 0, 0, 26624, 96, }, /* 1133 */ - { 50, 21, 12, 0, 0, 18432, 68, }, /* 1134 */ - { 44, 12, 3, 0, 0, 26624, 130, }, /* 1135 */ - { 44, 10, 5, 0, 0, 18432, 144, }, /* 1136 */ - { 44, 7, 12, 0, 0, 18432, 82, }, /* 1137 */ - { 44, 10, 5, 0, 0, 18432, 172, }, /* 1138 */ - { 44, 7, 4, 0, 0, 18432, 82, }, /* 1139 */ - { 44, 21, 12, 0, 0, 18432, 124, }, /* 1140 */ - { 44, 21, 12, 0, 0, 18432, 68, }, /* 1141 */ - { 44, 12, 3, 0, 0, 26624, 102, }, /* 1142 */ - { 44, 12, 3, 0, 0, 26624, 96, }, /* 1143 */ - { 44, 13, 12, 0, 0, 18432, 138, }, /* 1144 */ - { 15, 15, 12, 0, 0, 18432, 68, }, /* 1145 */ - { 48, 7, 12, 0, 0, 18432, 82, }, /* 1146 */ - { 48, 10, 5, 0, 0, 18432, 144, }, /* 1147 */ - { 48, 12, 3, 0, 0, 26624, 130, }, /* 1148 */ - { 48, 10, 5, 0, 0, 18432, 172, }, /* 1149 */ - { 48, 12, 3, 0, 0, 26624, 96, }, /* 1150 */ - { 48, 21, 12, 0, 0, 18432, 124, }, /* 1151 */ - { 48, 21, 12, 0, 0, 18432, 106, }, /* 1152 */ - { 48, 21, 12, 0, 0, 18432, 68, }, /* 1153 */ - { 57, 7, 12, 0, 0, 18432, 82, }, /* 1154 */ - { 57, 21, 12, 0, 0, 18432, 124, }, /* 1155 */ - { 55, 7, 12, 0, 0, 18432, 82, }, /* 1156 */ - { 55, 12, 3, 0, 0, 26624, 130, }, /* 1157 */ - { 55, 10, 5, 0, 0, 18432, 144, }, /* 1158 */ - { 55, 12, 3, 0, 0, 26624, 96, }, /* 1159 */ - { 55, 12, 3, 0, 0, 26624, 146, }, /* 1160 */ - { 55, 13, 12, 0, 0, 18432, 138, }, /* 1161 */ - { 47, 12, 3, 0, 0, 26624, 130, }, /* 1162 */ - { 47, 12, 3, 0, 0, 26705, 130, }, /* 1163 */ - { 47, 10, 5, 0, 0, 18432, 144, }, /* 1164 */ - { 47, 10, 5, 0, 0, 18513, 144, }, /* 1165 */ - { 47, 7, 12, 0, 0, 18432, 82, }, /* 1166 */ - { 84, 12, 3, 0, 0, 26705, 102, }, /* 1167 */ - { 47, 12, 3, 0, 0, 26705, 96, }, /* 1168 */ - { 47, 10, 3, 0, 0, 18432, 148, }, /* 1169 */ - { 47, 10, 5, 0, 0, 18432, 172, }, /* 1170 */ - { 47, 7, 12, 0, 0, 18432, 324, }, /* 1171 */ - { 47, 12, 3, 0, 0, 26624, 96, }, /* 1172 */ - { 144, 7, 12, 0, 0, 18432, 82, }, /* 1173 */ - { 144, 10, 5, 0, 0, 18432, 144, }, /* 1174 */ - { 144, 12, 3, 0, 0, 26624, 130, }, /* 1175 */ - { 144, 12, 3, 0, 0, 26624, 146, }, /* 1176 */ - { 144, 12, 3, 0, 0, 26624, 96, }, /* 1177 */ - { 144, 21, 12, 0, 0, 18432, 124, }, /* 1178 */ - { 144, 21, 12, 0, 0, 18432, 106, }, /* 1179 */ - { 144, 21, 12, 0, 0, 18432, 68, }, /* 1180 */ - { 144, 13, 12, 0, 0, 18432, 138, }, /* 1181 */ - { 144, 12, 3, 0, 0, 26624, 102, }, /* 1182 */ - { 56, 7, 12, 0, 0, 18432, 82, }, /* 1183 */ - { 56, 10, 3, 0, 0, 18432, 148, }, /* 1184 */ - { 56, 10, 5, 0, 0, 18432, 144, }, /* 1185 */ - { 56, 12, 3, 0, 0, 26624, 130, }, /* 1186 */ - { 56, 12, 3, 0, 0, 26624, 146, }, /* 1187 */ - { 56, 12, 3, 0, 0, 26624, 96, }, /* 1188 */ - { 56, 21, 12, 0, 0, 18432, 68, }, /* 1189 */ - { 56, 13, 12, 0, 0, 18432, 138, }, /* 1190 */ - { 135, 7, 12, 0, 0, 18432, 82, }, /* 1191 */ - { 135, 10, 3, 0, 0, 18432, 148, }, /* 1192 */ - { 135, 10, 5, 0, 0, 18432, 144, }, /* 1193 */ - { 135, 12, 3, 0, 0, 26624, 130, }, /* 1194 */ - { 135, 12, 3, 0, 0, 26624, 146, }, /* 1195 */ - { 135, 12, 3, 0, 0, 26624, 96, }, /* 1196 */ - { 135, 21, 12, 0, 0, 18432, 68, }, /* 1197 */ - { 135, 21, 12, 0, 0, 18432, 124, }, /* 1198 */ - { 135, 21, 12, 0, 0, 18432, 106, }, /* 1199 */ - { 135, 21, 12, 0, 0, 18432, 176, }, /* 1200 */ - { 52, 7, 12, 0, 0, 18432, 82, }, /* 1201 */ - { 52, 10, 5, 0, 0, 18432, 144, }, /* 1202 */ - { 52, 12, 3, 0, 0, 26624, 130, }, /* 1203 */ - { 52, 12, 3, 0, 0, 26624, 146, }, /* 1204 */ - { 52, 21, 12, 0, 0, 18432, 124, }, /* 1205 */ - { 52, 21, 12, 0, 0, 18432, 68, }, /* 1206 */ - { 52, 13, 12, 0, 0, 18432, 138, }, /* 1207 */ - { 45, 7, 12, 0, 0, 18432, 82, }, /* 1208 */ - { 45, 12, 3, 0, 0, 26624, 130, }, /* 1209 */ - { 45, 10, 5, 0, 0, 18432, 144, }, /* 1210 */ - { 45, 10, 5, 0, 0, 18432, 172, }, /* 1211 */ - { 45, 12, 3, 0, 0, 26624, 96, }, /* 1212 */ - { 45, 21, 12, 0, 0, 18432, 68, }, /* 1213 */ - { 45, 13, 12, 0, 0, 18432, 138, }, /* 1214 */ - { 137, 7, 12, 0, 0, 18432, 82, }, /* 1215 */ - { 137, 12, 3, 0, 0, 26624, 130, }, /* 1216 */ - { 137, 10, 12, 0, 0, 18432, 144, }, /* 1217 */ - { 137, 10, 5, 0, 0, 18432, 144, }, /* 1218 */ - { 137, 12, 3, 0, 0, 26624, 146, }, /* 1219 */ - { 137, 13, 12, 0, 0, 18432, 138, }, /* 1220 */ - { 137, 15, 12, 0, 0, 18432, 68, }, /* 1221 */ - { 137, 21, 12, 0, 0, 18432, 124, }, /* 1222 */ - { 137, 26, 12, 0, 0, 18432, 68, }, /* 1223 */ - { 60, 7, 12, 0, 0, 18432, 82, }, /* 1224 */ - { 60, 10, 5, 0, 0, 18432, 144, }, /* 1225 */ - { 60, 12, 3, 0, 0, 26624, 130, }, /* 1226 */ - { 60, 12, 3, 0, 0, 26624, 146, }, /* 1227 */ - { 60, 12, 3, 0, 0, 26624, 96, }, /* 1228 */ - { 60, 21, 12, 0, 0, 18432, 68, }, /* 1229 */ - { 136, 9, 12, 0, 32, 18432, 74, }, /* 1230 */ - { 136, 5, 12, 0, -32, 18432, 76, }, /* 1231 */ - { 136, 13, 12, 0, 0, 18432, 138, }, /* 1232 */ - { 136, 15, 12, 0, 0, 18432, 68, }, /* 1233 */ - { 136, 7, 12, 0, 0, 18432, 82, }, /* 1234 */ - { 157, 7, 12, 0, 0, 18432, 82, }, /* 1235 */ - { 157, 10, 3, 0, 0, 18432, 148, }, /* 1236 */ - { 157, 10, 5, 0, 0, 18432, 144, }, /* 1237 */ - { 157, 12, 3, 0, 0, 26624, 130, }, /* 1238 */ - { 157, 10, 5, 0, 0, 18432, 172, }, /* 1239 */ - { 157, 12, 3, 0, 0, 26624, 146, }, /* 1240 */ - { 157, 7, 4, 0, 0, 18432, 82, }, /* 1241 */ - { 157, 12, 3, 0, 0, 26624, 96, }, /* 1242 */ - { 157, 21, 12, 0, 0, 18432, 124, }, /* 1243 */ - { 157, 21, 12, 0, 0, 18432, 68, }, /* 1244 */ - { 157, 13, 12, 0, 0, 18432, 138, }, /* 1245 */ - { 64, 7, 12, 0, 0, 18432, 82, }, /* 1246 */ - { 64, 10, 5, 0, 0, 18432, 144, }, /* 1247 */ - { 64, 12, 3, 0, 0, 26624, 130, }, /* 1248 */ - { 64, 12, 3, 0, 0, 26624, 146, }, /* 1249 */ - { 64, 21, 12, 0, 0, 18432, 68, }, /* 1250 */ - { 149, 7, 12, 0, 0, 18432, 82, }, /* 1251 */ - { 149, 12, 3, 0, 0, 26624, 130, }, /* 1252 */ - { 149, 12, 3, 0, 0, 18432, 130, }, /* 1253 */ - { 149, 12, 3, 0, 0, 26624, 102, }, /* 1254 */ - { 149, 12, 3, 0, 0, 26624, 146, }, /* 1255 */ - { 149, 10, 5, 0, 0, 18432, 144, }, /* 1256 */ - { 149, 7, 4, 0, 0, 18432, 82, }, /* 1257 */ - { 149, 21, 12, 0, 0, 18432, 68, }, /* 1258 */ - { 149, 21, 12, 0, 0, 18432, 124, }, /* 1259 */ - { 148, 7, 12, 0, 0, 18432, 82, }, /* 1260 */ - { 148, 12, 3, 0, 0, 26624, 130, }, /* 1261 */ - { 148, 10, 5, 0, 0, 18432, 144, }, /* 1262 */ - { 148, 7, 4, 0, 0, 18432, 82, }, /* 1263 */ - { 148, 12, 3, 0, 0, 26624, 326, }, /* 1264 */ - { 148, 12, 3, 0, 0, 26624, 146, }, /* 1265 */ - { 148, 21, 12, 0, 0, 18432, 68, }, /* 1266 */ - { 148, 21, 12, 0, 0, 18432, 124, }, /* 1267 */ - { 148, 21, 12, 0, 0, 18432, 106, }, /* 1268 */ - { 134, 7, 12, 0, 0, 18432, 82, }, /* 1269 */ - { 142, 7, 12, 0, 0, 18432, 82, }, /* 1270 */ - { 142, 10, 5, 0, 0, 18432, 144, }, /* 1271 */ - { 142, 12, 3, 0, 0, 26624, 130, }, /* 1272 */ - { 142, 12, 3, 0, 0, 18432, 146, }, /* 1273 */ - { 142, 21, 12, 0, 0, 18432, 124, }, /* 1274 */ - { 142, 21, 12, 0, 0, 18432, 106, }, /* 1275 */ - { 142, 21, 12, 0, 0, 18432, 68, }, /* 1276 */ - { 142, 13, 12, 0, 0, 18432, 138, }, /* 1277 */ - { 142, 15, 12, 0, 0, 18432, 68, }, /* 1278 */ - { 143, 21, 12, 0, 0, 18432, 68, }, /* 1279 */ - { 143, 21, 12, 0, 0, 18432, 106, }, /* 1280 */ - { 143, 7, 12, 0, 0, 18432, 82, }, /* 1281 */ - { 143, 12, 3, 0, 0, 26624, 130, }, /* 1282 */ - { 143, 10, 5, 0, 0, 18432, 144, }, /* 1283 */ - { 59, 7, 12, 0, 0, 18432, 82, }, /* 1284 */ - { 59, 12, 3, 0, 0, 26624, 130, }, /* 1285 */ - { 59, 12, 3, 0, 0, 26624, 96, }, /* 1286 */ - { 59, 12, 3, 0, 0, 26624, 146, }, /* 1287 */ - { 59, 7, 4, 0, 0, 18432, 82, }, /* 1288 */ - { 59, 13, 12, 0, 0, 18432, 138, }, /* 1289 */ - { 61, 7, 12, 0, 0, 18432, 82, }, /* 1290 */ - { 61, 10, 5, 0, 0, 18432, 144, }, /* 1291 */ - { 61, 12, 3, 0, 0, 26624, 130, }, /* 1292 */ - { 61, 12, 3, 0, 0, 26624, 146, }, /* 1293 */ - { 61, 13, 12, 0, 0, 18432, 138, }, /* 1294 */ - { 150, 7, 12, 0, 0, 18432, 82, }, /* 1295 */ - { 150, 12, 3, 0, 0, 26624, 130, }, /* 1296 */ - { 150, 10, 5, 0, 0, 18432, 144, }, /* 1297 */ - { 150, 21, 12, 0, 0, 18432, 124, }, /* 1298 */ - { 11, 15, 12, 0, 0, 18432, 68, }, /* 1299 */ - { 11, 21, 12, 0, 0, 18432, 68, }, /* 1300 */ - { 94, 7, 12, 0, 0, 18432, 82, }, /* 1301 */ - { 94, 14, 12, 0, 0, 18432, 82, }, /* 1302 */ - { 94, 21, 12, 0, 0, 18432, 106, }, /* 1303 */ - { 66, 7, 12, 0, 0, 18432, 82, }, /* 1304 */ - { 66, 21, 12, 0, 0, 18432, 68, }, /* 1305 */ - { 109, 7, 12, 0, 0, 18432, 82, }, /* 1306 */ - { 109, 1, 2, 0, 0, 18432, 322, }, /* 1307 */ - { 138, 7, 12, 0, 0, 18432, 82, }, /* 1308 */ - { 130, 7, 12, 0, 0, 18432, 82, }, /* 1309 */ - { 130, 13, 12, 0, 0, 18432, 138, }, /* 1310 */ - { 130, 21, 12, 0, 0, 18432, 124, }, /* 1311 */ - { 159, 7, 12, 0, 0, 18432, 82, }, /* 1312 */ - { 159, 13, 12, 0, 0, 18432, 138, }, /* 1313 */ - { 126, 7, 12, 0, 0, 18432, 82, }, /* 1314 */ - { 126, 12, 3, 0, 0, 26624, 96, }, /* 1315 */ - { 126, 21, 12, 0, 0, 18432, 124, }, /* 1316 */ - { 128, 7, 12, 0, 0, 18432, 82, }, /* 1317 */ - { 128, 12, 3, 0, 0, 26624, 96, }, /* 1318 */ - { 128, 21, 12, 0, 0, 18432, 124, }, /* 1319 */ - { 128, 21, 12, 0, 0, 18432, 106, }, /* 1320 */ - { 128, 21, 12, 0, 0, 18432, 68, }, /* 1321 */ - { 128, 26, 12, 0, 0, 18432, 68, }, /* 1322 */ - { 128, 6, 12, 0, 0, 18432, 142, }, /* 1323 */ - { 128, 6, 12, 0, 0, 18432, 136, }, /* 1324 */ - { 128, 13, 12, 0, 0, 18432, 138, }, /* 1325 */ - { 128, 15, 12, 0, 0, 18432, 68, }, /* 1326 */ - { 151, 9, 12, 0, 32, 18432, 74, }, /* 1327 */ - { 151, 5, 12, 0, -32, 18432, 76, }, /* 1328 */ - { 151, 15, 12, 0, 0, 18432, 68, }, /* 1329 */ - { 151, 21, 12, 0, 0, 18432, 106, }, /* 1330 */ - { 151, 21, 12, 0, 0, 18432, 124, }, /* 1331 */ - { 151, 21, 12, 0, 0, 18432, 68, }, /* 1332 */ - { 123, 7, 12, 0, 0, 18432, 82, }, /* 1333 */ - { 123, 12, 3, 0, 0, 26624, 130, }, /* 1334 */ - { 123, 10, 5, 0, 0, 18432, 144, }, /* 1335 */ - { 123, 12, 3, 0, 0, 26624, 128, }, /* 1336 */ - { 123, 6, 12, 0, 0, 18432, 92, }, /* 1337 */ - { 146, 6, 12, 0, 0, 18432, 136, }, /* 1338 */ - { 147, 6, 12, 0, 0, 18432, 136, }, /* 1339 */ - { 23, 21, 12, 0, 0, 28672, 68, }, /* 1340 */ - { 158, 12, 3, 0, 0, 26624, 328, }, /* 1341 */ - { 23, 10, 5, 0, 0, 18432, 164, }, /* 1342 */ - { 146, 7, 12, 0, 0, 18432, 284, }, /* 1343 */ - { 158, 7, 12, 0, 0, 18432, 284, }, /* 1344 */ - { 21, 6, 12, 0, 0, 18432, 92, }, /* 1345 */ - { 147, 7, 12, 0, 0, 18432, 284, }, /* 1346 */ - { 46, 7, 12, 0, 0, 18432, 82, }, /* 1347 */ - { 46, 26, 12, 0, 0, 18432, 68, }, /* 1348 */ - { 46, 12, 3, 0, 0, 26624, 102, }, /* 1349 */ - { 46, 12, 3, 0, 0, 26624, 130, }, /* 1350 */ - { 46, 21, 12, 0, 0, 18432, 124, }, /* 1351 */ - { 69, 1, 2, 0, 0, 6153, 66, }, /* 1352 */ - { 69, 10, 3, 0, 0, 18432, 330, }, /* 1353 */ - { 69, 10, 5, 0, 0, 18432, 138, }, /* 1354 */ - { 69, 10, 5, 0, 0, 18432, 160, }, /* 1355 */ - { 69, 10, 3, 0, 0, 18432, 286, }, /* 1356 */ - { 1, 12, 3, 0, 0, 26624, 102, }, /* 1357 */ - { 69, 25, 12, 0, 0, 18432, 118, }, /* 1358 */ - { 69, 13, 12, 0, 0, 10240, 214, }, /* 1359 */ - { 141, 26, 12, 0, 0, 18432, 68, }, /* 1360 */ - { 141, 12, 3, 0, 0, 26624, 102, }, /* 1361 */ - { 141, 21, 12, 0, 0, 18432, 106, }, /* 1362 */ - { 141, 21, 12, 0, 0, 18432, 124, }, /* 1363 */ - { 141, 21, 12, 0, 0, 18432, 68, }, /* 1364 */ - { 35, 12, 3, 0, 0, 26624, 130, }, /* 1365 */ - { 154, 7, 12, 0, 0, 18432, 82, }, /* 1366 */ - { 154, 12, 3, 0, 0, 26624, 96, }, /* 1367 */ - { 154, 6, 12, 0, 0, 18432, 142, }, /* 1368 */ - { 154, 6, 12, 0, 0, 18432, 136, }, /* 1369 */ - { 154, 13, 12, 0, 0, 18432, 138, }, /* 1370 */ - { 154, 26, 12, 0, 0, 18432, 68, }, /* 1371 */ - { 160, 7, 12, 0, 0, 18432, 82, }, /* 1372 */ - { 160, 12, 3, 0, 0, 26624, 96, }, /* 1373 */ - { 155, 7, 12, 0, 0, 18432, 82, }, /* 1374 */ - { 155, 12, 3, 0, 0, 26624, 96, }, /* 1375 */ - { 155, 13, 12, 0, 0, 18432, 138, }, /* 1376 */ - { 155, 23, 12, 0, 0, 14336, 68, }, /* 1377 */ - { 129, 7, 12, 0, 0, 34816, 82, }, /* 1378 */ - { 129, 15, 12, 0, 0, 34816, 68, }, /* 1379 */ - { 129, 12, 3, 0, 0, 26624, 96, }, /* 1380 */ - { 58, 9, 12, 0, 34, 34816, 74, }, /* 1381 */ - { 58, 5, 12, 0, -34, 34816, 76, }, /* 1382 */ - { 58, 12, 3, 0, 0, 26624, 150, }, /* 1383 */ - { 58, 12, 3, 0, 0, 26624, 130, }, /* 1384 */ - { 58, 12, 3, 0, 0, 26624, 96, }, /* 1385 */ - { 58, 6, 12, 0, 0, 34816, 142, }, /* 1386 */ - { 58, 13, 12, 0, 0, 34816, 138, }, /* 1387 */ - { 58, 21, 12, 0, 0, 34816, 68, }, /* 1388 */ - { 69, 15, 12, 0, 0, 0, 68, }, /* 1389 */ - { 69, 26, 12, 0, 0, 0, 68, }, /* 1390 */ - { 69, 23, 12, 0, 0, 0, 68, }, /* 1391 */ - { 3, 7, 12, 0, 0, 0, 240, }, /* 1392 */ - { 69, 26, 14, 0, 0, 28672, 332, }, /* 1393 */ - { 69, 26, 14, 0, 0, 28672, 334, }, /* 1394 */ - { 68, 2, 14, 0, 0, 18432, 336, }, /* 1395 */ - { 69, 26, 12, 0, 0, 18432, 338, }, /* 1396 */ - { 69, 26, 14, 0, 0, 18432, 340, }, /* 1397 */ - { 69, 26, 14, 0, 0, 18432, 334, }, /* 1398 */ - { 69, 26, 11, 0, 0, 18432, 342, }, /* 1399 */ - { 20, 26, 12, 0, 0, 18432, 68, }, /* 1400 */ - { 69, 26, 14, 0, 0, 18432, 236, }, /* 1401 */ - { 69, 26, 14, 0, 0, 18447, 334, }, /* 1402 */ - { 69, 26, 14, 0, 0, 28672, 344, }, /* 1403 */ - { 69, 26, 14, 0, 0, 28672, 346, }, /* 1404 */ - { 69, 24, 3, 0, 0, 28672, 348, }, /* 1405 */ - { 69, 26, 14, 0, 0, 28672, 350, }, /* 1406 */ - { 69, 13, 12, 0, 0, 10240, 138, }, /* 1407 */ - { 69, 1, 3, 0, 0, 6144, 352, }, /* 1408 */ + { 76, 5, 12, 0, -38864, 18432, 70, }, /* 945 */ + { 113, 10, 5, 0, 0, 18432, 160, }, /* 946 */ + { 113, 13, 12, 0, 0, 18432, 138, }, /* 947 */ + { 18, 7, 9, 0, 0, 18432, 82, }, /* 948 */ + { 18, 7, 10, 0, 0, 18432, 82, }, /* 949 */ + { 68, 4, 12, 0, 0, 18432, 0, }, /* 950 */ + { 68, 3, 12, 0, 0, 18432, 0, }, /* 951 */ + { 23, 7, 12, 0, 0, 18432, 284, }, /* 952 */ + { 71, 25, 12, 0, 0, 12288, 118, }, /* 953 */ + { 3, 7, 12, 0, 0, 0, 296, }, /* 954 */ + { 69, 18, 12, 0, 0, 28705, 54, }, /* 955 */ + { 69, 22, 12, 0, 0, 28705, 54, }, /* 956 */ + { 68, 2, 12, 0, 0, 6144, 298, }, /* 957 */ + { 3, 7, 12, 0, 0, 39, 82, }, /* 958 */ + { 3, 26, 12, 0, 0, 28711, 68, }, /* 959 */ + { 84, 12, 3, 0, 0, 26624, 180, }, /* 960 */ + { 84, 12, 3, 0, 0, 26624, 300, }, /* 961 */ + { 69, 21, 12, 0, 0, 28672, 68, }, /* 962 */ + { 69, 21, 12, 0, 0, 28672, 122, }, /* 963 */ + { 69, 22, 12, 0, 0, 28672, 68, }, /* 964 */ + { 69, 18, 12, 0, 0, 28672, 68, }, /* 965 */ + { 69, 17, 12, 0, 0, 28672, 126, }, /* 966 */ + { 69, 22, 12, 0, 0, 28672, 302, }, /* 967 */ + { 69, 18, 12, 0, 0, 28672, 302, }, /* 968 */ + { 69, 21, 12, 0, 0, 8192, 106, }, /* 969 */ + { 69, 21, 12, 0, 0, 8192, 304, }, /* 970 */ + { 69, 21, 12, 0, 0, 8192, 306, }, /* 971 */ + { 69, 21, 12, 0, 0, 28672, 124, }, /* 972 */ + { 69, 22, 12, 0, 0, 28672, 158, }, /* 973 */ + { 69, 18, 12, 0, 0, 28672, 158, }, /* 974 */ + { 69, 21, 12, 0, 0, 14336, 68, }, /* 975 */ + { 69, 21, 12, 0, 0, 28672, 118, }, /* 976 */ + { 69, 17, 12, 0, 0, 12288, 224, }, /* 977 */ + { 69, 25, 12, 0, 0, 28672, 226, }, /* 978 */ + { 69, 21, 12, 0, 0, 28672, 302, }, /* 979 */ + { 69, 21, 12, 0, 0, 28672, 308, }, /* 980 */ + { 69, 17, 12, 0, 0, 12288, 126, }, /* 981 */ + { 69, 21, 12, 0, 0, 8192, 68, }, /* 982 */ + { 69, 13, 12, 0, 0, 10240, 310, }, /* 983 */ + { 0, 9, 12, 0, 32, 18432, 312, }, /* 984 */ + { 69, 24, 12, 0, 0, 28672, 314, }, /* 985 */ + { 0, 5, 12, 0, -32, 18432, 316, }, /* 986 */ + { 69, 21, 12, 0, 0, 28825, 124, }, /* 987 */ + { 69, 22, 12, 0, 0, 28825, 318, }, /* 988 */ + { 69, 18, 12, 0, 0, 28825, 318, }, /* 989 */ + { 69, 21, 12, 0, 0, 28825, 106, }, /* 990 */ + { 69, 6, 3, 0, 0, 18525, 320, }, /* 991 */ + { 69, 1, 2, 0, 0, 28672, 322, }, /* 992 */ + { 31, 7, 12, 0, 0, 18432, 82, }, /* 993 */ + { 69, 21, 12, 0, 0, 18552, 68, }, /* 994 */ + { 69, 21, 12, 0, 0, 28792, 68, }, /* 995 */ + { 69, 21, 12, 0, 0, 18483, 68, }, /* 996 */ + { 69, 15, 12, 0, 0, 18555, 68, }, /* 997 */ + { 69, 26, 12, 0, 0, 18483, 68, }, /* 998 */ + { 1, 14, 12, 0, 0, 28672, 82, }, /* 999 */ + { 1, 15, 12, 0, 0, 28672, 68, }, /* 1000 */ + { 1, 26, 12, 0, 0, 28672, 68, }, /* 1001 */ + { 1, 26, 12, 0, 0, 18432, 68, }, /* 1002 */ + { 102, 7, 12, 0, 0, 18432, 82, }, /* 1003 */ + { 103, 7, 12, 0, 0, 18432, 82, }, /* 1004 */ + { 84, 12, 3, 0, 0, 26651, 96, }, /* 1005 */ + { 69, 15, 12, 0, 0, 10267, 68, }, /* 1006 */ + { 81, 7, 12, 0, 0, 18432, 82, }, /* 1007 */ + { 81, 15, 12, 0, 0, 18432, 68, }, /* 1008 */ + { 82, 7, 12, 0, 0, 18432, 82, }, /* 1009 */ + { 82, 14, 12, 0, 0, 18432, 82, }, /* 1010 */ + { 53, 7, 12, 0, 0, 18432, 82, }, /* 1011 */ + { 53, 12, 3, 0, 0, 26624, 130, }, /* 1012 */ + { 85, 7, 12, 0, 0, 18432, 82, }, /* 1013 */ + { 85, 21, 12, 0, 0, 18432, 106, }, /* 1014 */ + { 91, 7, 12, 0, 0, 18432, 82, }, /* 1015 */ + { 91, 21, 12, 0, 0, 18432, 106, }, /* 1016 */ + { 91, 14, 12, 0, 0, 18432, 82, }, /* 1017 */ + { 83, 9, 12, 0, 40, 18432, 74, }, /* 1018 */ + { 83, 5, 12, 0, -40, 18432, 76, }, /* 1019 */ + { 86, 7, 12, 0, 0, 18432, 82, }, /* 1020 */ + { 87, 7, 12, 0, 0, 18432, 82, }, /* 1021 */ + { 87, 13, 12, 0, 0, 18432, 138, }, /* 1022 */ + { 145, 9, 12, 0, 40, 18432, 74, }, /* 1023 */ + { 145, 5, 12, 0, -40, 18432, 76, }, /* 1024 */ + { 127, 7, 12, 0, 0, 18432, 82, }, /* 1025 */ + { 125, 7, 12, 0, 0, 18432, 82, }, /* 1026 */ + { 125, 21, 12, 0, 0, 18432, 68, }, /* 1027 */ + { 161, 9, 12, 0, 39, 18432, 74, }, /* 1028 */ + { 161, 5, 12, 0, -39, 18432, 76, }, /* 1029 */ + { 49, 7, 12, 0, 0, 18432, 82, }, /* 1030 */ + { 0, 6, 12, 0, 0, 18432, 94, }, /* 1031 */ + { 32, 7, 12, 0, 0, 34816, 82, }, /* 1032 */ + { 114, 7, 12, 0, 0, 34816, 82, }, /* 1033 */ + { 114, 21, 12, 0, 0, 34816, 106, }, /* 1034 */ + { 114, 15, 12, 0, 0, 34816, 68, }, /* 1035 */ + { 133, 7, 12, 0, 0, 34816, 82, }, /* 1036 */ + { 133, 26, 12, 0, 0, 34816, 68, }, /* 1037 */ + { 133, 15, 12, 0, 0, 34816, 68, }, /* 1038 */ + { 132, 7, 12, 0, 0, 34816, 82, }, /* 1039 */ + { 132, 15, 12, 0, 0, 34816, 68, }, /* 1040 */ + { 139, 7, 12, 0, 0, 34816, 82, }, /* 1041 */ + { 139, 15, 12, 0, 0, 34816, 68, }, /* 1042 */ + { 95, 7, 12, 0, 0, 34816, 82, }, /* 1043 */ + { 95, 15, 12, 0, 0, 34816, 68, }, /* 1044 */ + { 95, 21, 12, 0, 0, 28672, 106, }, /* 1045 */ + { 104, 7, 12, 0, 0, 34816, 82, }, /* 1046 */ + { 104, 21, 12, 0, 0, 34816, 68, }, /* 1047 */ + { 122, 7, 12, 0, 0, 34816, 82, }, /* 1048 */ + { 121, 7, 12, 0, 0, 34816, 82, }, /* 1049 */ + { 121, 15, 12, 0, 0, 34816, 68, }, /* 1050 */ + { 92, 7, 12, 0, 0, 34816, 82, }, /* 1051 */ + { 92, 12, 3, 0, 0, 26624, 130, }, /* 1052 */ + { 92, 12, 3, 0, 0, 26624, 102, }, /* 1053 */ + { 92, 12, 3, 0, 0, 26624, 184, }, /* 1054 */ + { 92, 15, 12, 0, 0, 34816, 68, }, /* 1055 */ + { 92, 21, 12, 0, 0, 34816, 68, }, /* 1056 */ + { 92, 21, 12, 0, 0, 34816, 124, }, /* 1057 */ + { 115, 7, 12, 0, 0, 34816, 82, }, /* 1058 */ + { 115, 15, 12, 0, 0, 34816, 68, }, /* 1059 */ + { 115, 21, 12, 0, 0, 34816, 68, }, /* 1060 */ + { 131, 7, 12, 0, 0, 34816, 82, }, /* 1061 */ + { 131, 15, 12, 0, 0, 34816, 68, }, /* 1062 */ + { 51, 7, 12, 0, 0, 34816, 82, }, /* 1063 */ + { 51, 26, 12, 0, 0, 34816, 68, }, /* 1064 */ + { 51, 12, 3, 0, 0, 26624, 96, }, /* 1065 */ + { 51, 15, 12, 0, 0, 34816, 68, }, /* 1066 */ + { 51, 21, 12, 0, 0, 34816, 106, }, /* 1067 */ + { 51, 21, 12, 0, 0, 34918, 106, }, /* 1068 */ + { 51, 21, 12, 0, 0, 34816, 68, }, /* 1069 */ + { 108, 7, 12, 0, 0, 34816, 82, }, /* 1070 */ + { 108, 21, 12, 0, 0, 28672, 68, }, /* 1071 */ + { 108, 21, 12, 0, 0, 28672, 106, }, /* 1072 */ + { 116, 7, 12, 0, 0, 34816, 82, }, /* 1073 */ + { 116, 15, 12, 0, 0, 34816, 68, }, /* 1074 */ + { 117, 7, 12, 0, 0, 34816, 82, }, /* 1075 */ + { 117, 15, 12, 0, 0, 34816, 68, }, /* 1076 */ + { 54, 7, 12, 0, 0, 34816, 82, }, /* 1077 */ + { 54, 21, 12, 0, 0, 34816, 106, }, /* 1078 */ + { 54, 15, 12, 0, 0, 34816, 68, }, /* 1079 */ + { 118, 7, 12, 0, 0, 34816, 82, }, /* 1080 */ + { 140, 9, 12, 0, 64, 34816, 74, }, /* 1081 */ + { 140, 5, 12, 0, -64, 34816, 76, }, /* 1082 */ + { 140, 15, 12, 0, 0, 34816, 68, }, /* 1083 */ + { 62, 7, 12, 0, 0, 0, 82, }, /* 1084 */ + { 62, 7, 12, 0, 0, 0, 294, }, /* 1085 */ + { 62, 12, 3, 0, 0, 26624, 128, }, /* 1086 */ + { 62, 13, 12, 0, 0, 2048, 138, }, /* 1087 */ + { 3, 15, 12, 0, 0, 2048, 68, }, /* 1088 */ + { 65, 7, 12, 0, 0, 34816, 82, }, /* 1089 */ + { 65, 12, 3, 0, 0, 26624, 130, }, /* 1090 */ + { 65, 17, 12, 0, 0, 34816, 126, }, /* 1091 */ + { 152, 7, 12, 0, 0, 34816, 82, }, /* 1092 */ + { 152, 15, 12, 0, 0, 34816, 68, }, /* 1093 */ + { 63, 7, 12, 0, 0, 0, 82, }, /* 1094 */ + { 63, 12, 3, 0, 0, 26624, 96, }, /* 1095 */ + { 63, 15, 12, 0, 0, 0, 68, }, /* 1096 */ + { 63, 21, 12, 0, 0, 0, 124, }, /* 1097 */ + { 67, 7, 12, 0, 0, 34816, 82, }, /* 1098 */ + { 67, 12, 3, 0, 0, 26624, 96, }, /* 1099 */ + { 67, 21, 12, 0, 0, 34816, 124, }, /* 1100 */ + { 156, 7, 12, 0, 0, 34816, 82, }, /* 1101 */ + { 156, 15, 12, 0, 0, 34816, 68, }, /* 1102 */ + { 153, 7, 12, 0, 0, 34816, 82, }, /* 1103 */ + { 120, 10, 5, 0, 0, 18432, 144, }, /* 1104 */ + { 120, 12, 3, 0, 0, 26624, 130, }, /* 1105 */ + { 120, 7, 12, 0, 0, 18432, 82, }, /* 1106 */ + { 120, 12, 3, 0, 0, 26624, 146, }, /* 1107 */ + { 120, 21, 12, 0, 0, 18432, 124, }, /* 1108 */ + { 120, 21, 12, 0, 0, 18432, 106, }, /* 1109 */ + { 120, 15, 12, 0, 0, 28672, 68, }, /* 1110 */ + { 120, 13, 12, 0, 0, 18432, 138, }, /* 1111 */ + { 120, 12, 3, 0, 0, 26624, 184, }, /* 1112 */ + { 41, 12, 3, 0, 0, 26624, 130, }, /* 1113 */ + { 41, 10, 5, 0, 0, 18432, 144, }, /* 1114 */ + { 41, 7, 12, 0, 0, 18432, 82, }, /* 1115 */ + { 41, 12, 3, 0, 0, 26624, 146, }, /* 1116 */ + { 41, 12, 3, 0, 0, 26624, 96, }, /* 1117 */ + { 41, 21, 12, 0, 0, 18432, 68, }, /* 1118 */ + { 41, 1, 4, 0, 0, 18432, 132, }, /* 1119 */ + { 41, 21, 12, 0, 0, 18432, 124, }, /* 1120 */ + { 124, 7, 12, 0, 0, 18432, 82, }, /* 1121 */ + { 124, 13, 12, 0, 0, 18432, 138, }, /* 1122 */ + { 43, 12, 3, 0, 0, 26624, 130, }, /* 1123 */ + { 43, 7, 12, 0, 0, 18432, 82, }, /* 1124 */ + { 43, 10, 5, 0, 0, 18432, 144, }, /* 1125 */ + { 43, 12, 3, 0, 0, 26624, 146, }, /* 1126 */ + { 43, 13, 12, 0, 0, 18432, 138, }, /* 1127 */ + { 43, 21, 12, 0, 0, 18432, 68, }, /* 1128 */ + { 43, 21, 12, 0, 0, 18432, 124, }, /* 1129 */ + { 50, 7, 12, 0, 0, 18432, 82, }, /* 1130 */ + { 50, 12, 3, 0, 0, 26624, 96, }, /* 1131 */ + { 50, 21, 12, 0, 0, 18432, 68, }, /* 1132 */ + { 44, 12, 3, 0, 0, 26624, 130, }, /* 1133 */ + { 44, 10, 5, 0, 0, 18432, 144, }, /* 1134 */ + { 44, 7, 12, 0, 0, 18432, 82, }, /* 1135 */ + { 44, 10, 5, 0, 0, 18432, 174, }, /* 1136 */ + { 44, 7, 4, 0, 0, 18432, 82, }, /* 1137 */ + { 44, 21, 12, 0, 0, 18432, 124, }, /* 1138 */ + { 44, 21, 12, 0, 0, 18432, 68, }, /* 1139 */ + { 44, 12, 3, 0, 0, 26624, 102, }, /* 1140 */ + { 44, 12, 3, 0, 0, 26624, 96, }, /* 1141 */ + { 44, 13, 12, 0, 0, 18432, 138, }, /* 1142 */ + { 15, 15, 12, 0, 0, 18432, 68, }, /* 1143 */ + { 48, 7, 12, 0, 0, 18432, 82, }, /* 1144 */ + { 48, 10, 5, 0, 0, 18432, 144, }, /* 1145 */ + { 48, 12, 3, 0, 0, 26624, 130, }, /* 1146 */ + { 48, 10, 5, 0, 0, 18432, 174, }, /* 1147 */ + { 48, 12, 3, 0, 0, 26624, 96, }, /* 1148 */ + { 48, 21, 12, 0, 0, 18432, 124, }, /* 1149 */ + { 48, 21, 12, 0, 0, 18432, 106, }, /* 1150 */ + { 48, 21, 12, 0, 0, 18432, 68, }, /* 1151 */ + { 57, 7, 12, 0, 0, 18432, 82, }, /* 1152 */ + { 57, 21, 12, 0, 0, 18432, 124, }, /* 1153 */ + { 55, 7, 12, 0, 0, 18432, 82, }, /* 1154 */ + { 55, 12, 3, 0, 0, 26624, 130, }, /* 1155 */ + { 55, 10, 5, 0, 0, 18432, 144, }, /* 1156 */ + { 55, 12, 3, 0, 0, 26624, 96, }, /* 1157 */ + { 55, 12, 3, 0, 0, 26624, 146, }, /* 1158 */ + { 55, 13, 12, 0, 0, 18432, 138, }, /* 1159 */ + { 47, 12, 3, 0, 0, 26624, 130, }, /* 1160 */ + { 47, 12, 3, 0, 0, 26705, 130, }, /* 1161 */ + { 47, 10, 5, 0, 0, 18432, 144, }, /* 1162 */ + { 47, 10, 5, 0, 0, 18513, 144, }, /* 1163 */ + { 47, 7, 12, 0, 0, 18432, 82, }, /* 1164 */ + { 84, 12, 3, 0, 0, 26705, 102, }, /* 1165 */ + { 47, 12, 3, 0, 0, 26705, 96, }, /* 1166 */ + { 47, 10, 3, 0, 0, 18432, 148, }, /* 1167 */ + { 47, 10, 5, 0, 0, 18432, 174, }, /* 1168 */ + { 47, 7, 12, 0, 0, 18432, 324, }, /* 1169 */ + { 47, 12, 3, 0, 0, 26624, 96, }, /* 1170 */ + { 144, 7, 12, 0, 0, 18432, 82, }, /* 1171 */ + { 144, 10, 5, 0, 0, 18432, 144, }, /* 1172 */ + { 144, 12, 3, 0, 0, 26624, 130, }, /* 1173 */ + { 144, 12, 3, 0, 0, 26624, 146, }, /* 1174 */ + { 144, 12, 3, 0, 0, 26624, 96, }, /* 1175 */ + { 144, 21, 12, 0, 0, 18432, 124, }, /* 1176 */ + { 144, 21, 12, 0, 0, 18432, 106, }, /* 1177 */ + { 144, 21, 12, 0, 0, 18432, 68, }, /* 1178 */ + { 144, 13, 12, 0, 0, 18432, 138, }, /* 1179 */ + { 144, 12, 3, 0, 0, 26624, 102, }, /* 1180 */ + { 56, 7, 12, 0, 0, 18432, 82, }, /* 1181 */ + { 56, 10, 3, 0, 0, 18432, 148, }, /* 1182 */ + { 56, 10, 5, 0, 0, 18432, 144, }, /* 1183 */ + { 56, 12, 3, 0, 0, 26624, 130, }, /* 1184 */ + { 56, 12, 3, 0, 0, 26624, 146, }, /* 1185 */ + { 56, 12, 3, 0, 0, 26624, 96, }, /* 1186 */ + { 56, 21, 12, 0, 0, 18432, 68, }, /* 1187 */ + { 56, 13, 12, 0, 0, 18432, 138, }, /* 1188 */ + { 135, 7, 12, 0, 0, 18432, 82, }, /* 1189 */ + { 135, 10, 3, 0, 0, 18432, 148, }, /* 1190 */ + { 135, 10, 5, 0, 0, 18432, 144, }, /* 1191 */ + { 135, 12, 3, 0, 0, 26624, 130, }, /* 1192 */ + { 135, 12, 3, 0, 0, 26624, 146, }, /* 1193 */ + { 135, 12, 3, 0, 0, 26624, 96, }, /* 1194 */ + { 135, 21, 12, 0, 0, 18432, 68, }, /* 1195 */ + { 135, 21, 12, 0, 0, 18432, 124, }, /* 1196 */ + { 135, 21, 12, 0, 0, 18432, 106, }, /* 1197 */ + { 135, 21, 12, 0, 0, 18432, 178, }, /* 1198 */ + { 52, 7, 12, 0, 0, 18432, 82, }, /* 1199 */ + { 52, 10, 5, 0, 0, 18432, 144, }, /* 1200 */ + { 52, 12, 3, 0, 0, 26624, 130, }, /* 1201 */ + { 52, 12, 3, 0, 0, 26624, 146, }, /* 1202 */ + { 52, 21, 12, 0, 0, 18432, 124, }, /* 1203 */ + { 52, 21, 12, 0, 0, 18432, 68, }, /* 1204 */ + { 52, 13, 12, 0, 0, 18432, 138, }, /* 1205 */ + { 45, 7, 12, 0, 0, 18432, 82, }, /* 1206 */ + { 45, 12, 3, 0, 0, 26624, 130, }, /* 1207 */ + { 45, 10, 5, 0, 0, 18432, 144, }, /* 1208 */ + { 45, 10, 5, 0, 0, 18432, 174, }, /* 1209 */ + { 45, 12, 3, 0, 0, 26624, 96, }, /* 1210 */ + { 45, 21, 12, 0, 0, 18432, 68, }, /* 1211 */ + { 45, 13, 12, 0, 0, 18432, 138, }, /* 1212 */ + { 137, 7, 12, 0, 0, 18432, 82, }, /* 1213 */ + { 137, 12, 3, 0, 0, 26624, 130, }, /* 1214 */ + { 137, 10, 12, 0, 0, 18432, 144, }, /* 1215 */ + { 137, 10, 5, 0, 0, 18432, 144, }, /* 1216 */ + { 137, 12, 3, 0, 0, 26624, 146, }, /* 1217 */ + { 137, 13, 12, 0, 0, 18432, 138, }, /* 1218 */ + { 137, 15, 12, 0, 0, 18432, 68, }, /* 1219 */ + { 137, 21, 12, 0, 0, 18432, 124, }, /* 1220 */ + { 137, 26, 12, 0, 0, 18432, 68, }, /* 1221 */ + { 60, 7, 12, 0, 0, 18432, 82, }, /* 1222 */ + { 60, 10, 5, 0, 0, 18432, 144, }, /* 1223 */ + { 60, 12, 3, 0, 0, 26624, 130, }, /* 1224 */ + { 60, 12, 3, 0, 0, 26624, 146, }, /* 1225 */ + { 60, 12, 3, 0, 0, 26624, 96, }, /* 1226 */ + { 60, 21, 12, 0, 0, 18432, 68, }, /* 1227 */ + { 136, 9, 12, 0, 32, 18432, 74, }, /* 1228 */ + { 136, 5, 12, 0, -32, 18432, 76, }, /* 1229 */ + { 136, 13, 12, 0, 0, 18432, 138, }, /* 1230 */ + { 136, 15, 12, 0, 0, 18432, 68, }, /* 1231 */ + { 136, 7, 12, 0, 0, 18432, 82, }, /* 1232 */ + { 157, 7, 12, 0, 0, 18432, 82, }, /* 1233 */ + { 157, 10, 3, 0, 0, 18432, 148, }, /* 1234 */ + { 157, 10, 5, 0, 0, 18432, 144, }, /* 1235 */ + { 157, 12, 3, 0, 0, 26624, 130, }, /* 1236 */ + { 157, 10, 5, 0, 0, 18432, 174, }, /* 1237 */ + { 157, 12, 3, 0, 0, 26624, 146, }, /* 1238 */ + { 157, 7, 4, 0, 0, 18432, 82, }, /* 1239 */ + { 157, 12, 3, 0, 0, 26624, 96, }, /* 1240 */ + { 157, 21, 12, 0, 0, 18432, 124, }, /* 1241 */ + { 157, 21, 12, 0, 0, 18432, 68, }, /* 1242 */ + { 157, 13, 12, 0, 0, 18432, 138, }, /* 1243 */ + { 64, 7, 12, 0, 0, 18432, 82, }, /* 1244 */ + { 64, 10, 5, 0, 0, 18432, 144, }, /* 1245 */ + { 64, 12, 3, 0, 0, 26624, 130, }, /* 1246 */ + { 64, 12, 3, 0, 0, 26624, 146, }, /* 1247 */ + { 64, 21, 12, 0, 0, 18432, 68, }, /* 1248 */ + { 149, 7, 12, 0, 0, 18432, 82, }, /* 1249 */ + { 149, 12, 3, 0, 0, 26624, 130, }, /* 1250 */ + { 149, 12, 3, 0, 0, 18432, 130, }, /* 1251 */ + { 149, 12, 3, 0, 0, 26624, 102, }, /* 1252 */ + { 149, 12, 3, 0, 0, 26624, 146, }, /* 1253 */ + { 149, 10, 5, 0, 0, 18432, 144, }, /* 1254 */ + { 149, 7, 4, 0, 0, 18432, 82, }, /* 1255 */ + { 149, 21, 12, 0, 0, 18432, 68, }, /* 1256 */ + { 149, 21, 12, 0, 0, 18432, 124, }, /* 1257 */ + { 148, 7, 12, 0, 0, 18432, 82, }, /* 1258 */ + { 148, 12, 3, 0, 0, 26624, 130, }, /* 1259 */ + { 148, 10, 5, 0, 0, 18432, 144, }, /* 1260 */ + { 148, 7, 4, 0, 0, 18432, 82, }, /* 1261 */ + { 148, 12, 3, 0, 0, 26624, 326, }, /* 1262 */ + { 148, 12, 3, 0, 0, 26624, 146, }, /* 1263 */ + { 148, 21, 12, 0, 0, 18432, 68, }, /* 1264 */ + { 148, 21, 12, 0, 0, 18432, 124, }, /* 1265 */ + { 148, 21, 12, 0, 0, 18432, 106, }, /* 1266 */ + { 134, 7, 12, 0, 0, 18432, 82, }, /* 1267 */ + { 142, 7, 12, 0, 0, 18432, 82, }, /* 1268 */ + { 142, 10, 5, 0, 0, 18432, 144, }, /* 1269 */ + { 142, 12, 3, 0, 0, 26624, 130, }, /* 1270 */ + { 142, 12, 3, 0, 0, 18432, 146, }, /* 1271 */ + { 142, 21, 12, 0, 0, 18432, 124, }, /* 1272 */ + { 142, 21, 12, 0, 0, 18432, 106, }, /* 1273 */ + { 142, 21, 12, 0, 0, 18432, 68, }, /* 1274 */ + { 142, 13, 12, 0, 0, 18432, 138, }, /* 1275 */ + { 142, 15, 12, 0, 0, 18432, 68, }, /* 1276 */ + { 143, 21, 12, 0, 0, 18432, 68, }, /* 1277 */ + { 143, 21, 12, 0, 0, 18432, 106, }, /* 1278 */ + { 143, 7, 12, 0, 0, 18432, 82, }, /* 1279 */ + { 143, 12, 3, 0, 0, 26624, 130, }, /* 1280 */ + { 143, 10, 5, 0, 0, 18432, 144, }, /* 1281 */ + { 59, 7, 12, 0, 0, 18432, 82, }, /* 1282 */ + { 59, 12, 3, 0, 0, 26624, 130, }, /* 1283 */ + { 59, 12, 3, 0, 0, 26624, 96, }, /* 1284 */ + { 59, 12, 3, 0, 0, 26624, 146, }, /* 1285 */ + { 59, 7, 4, 0, 0, 18432, 82, }, /* 1286 */ + { 59, 13, 12, 0, 0, 18432, 138, }, /* 1287 */ + { 61, 7, 12, 0, 0, 18432, 82, }, /* 1288 */ + { 61, 10, 5, 0, 0, 18432, 144, }, /* 1289 */ + { 61, 12, 3, 0, 0, 26624, 130, }, /* 1290 */ + { 61, 12, 3, 0, 0, 26624, 146, }, /* 1291 */ + { 61, 13, 12, 0, 0, 18432, 138, }, /* 1292 */ + { 150, 7, 12, 0, 0, 18432, 82, }, /* 1293 */ + { 150, 12, 3, 0, 0, 26624, 130, }, /* 1294 */ + { 150, 10, 5, 0, 0, 18432, 144, }, /* 1295 */ + { 150, 21, 12, 0, 0, 18432, 124, }, /* 1296 */ + { 162, 12, 3, 0, 0, 26624, 130, }, /* 1297 */ + { 162, 7, 4, 0, 0, 18432, 82, }, /* 1298 */ + { 162, 10, 5, 0, 0, 18432, 144, }, /* 1299 */ + { 162, 7, 12, 0, 0, 18432, 82, }, /* 1300 */ + { 162, 10, 5, 0, 0, 18432, 176, }, /* 1301 */ + { 162, 12, 3, 0, 0, 26624, 184, }, /* 1302 */ + { 162, 21, 12, 0, 0, 18432, 124, }, /* 1303 */ + { 162, 21, 12, 0, 0, 18432, 68, }, /* 1304 */ + { 162, 13, 12, 0, 0, 18432, 138, }, /* 1305 */ + { 11, 15, 12, 0, 0, 18432, 68, }, /* 1306 */ + { 11, 21, 12, 0, 0, 18432, 68, }, /* 1307 */ + { 94, 7, 12, 0, 0, 18432, 82, }, /* 1308 */ + { 94, 14, 12, 0, 0, 18432, 82, }, /* 1309 */ + { 94, 21, 12, 0, 0, 18432, 106, }, /* 1310 */ + { 66, 7, 12, 0, 0, 18432, 82, }, /* 1311 */ + { 66, 21, 12, 0, 0, 18432, 68, }, /* 1312 */ + { 109, 7, 12, 0, 0, 18432, 82, }, /* 1313 */ + { 109, 1, 2, 0, 0, 18432, 322, }, /* 1314 */ + { 109, 12, 3, 0, 0, 26624, 102, }, /* 1315 */ + { 109, 12, 3, 0, 0, 26624, 96, }, /* 1316 */ + { 138, 7, 12, 0, 0, 18432, 82, }, /* 1317 */ + { 130, 7, 12, 0, 0, 18432, 82, }, /* 1318 */ + { 130, 13, 12, 0, 0, 18432, 138, }, /* 1319 */ + { 130, 21, 12, 0, 0, 18432, 124, }, /* 1320 */ + { 159, 7, 12, 0, 0, 18432, 82, }, /* 1321 */ + { 159, 13, 12, 0, 0, 18432, 138, }, /* 1322 */ + { 126, 7, 12, 0, 0, 18432, 82, }, /* 1323 */ + { 126, 12, 3, 0, 0, 26624, 96, }, /* 1324 */ + { 126, 21, 12, 0, 0, 18432, 124, }, /* 1325 */ + { 128, 7, 12, 0, 0, 18432, 82, }, /* 1326 */ + { 128, 12, 3, 0, 0, 26624, 96, }, /* 1327 */ + { 128, 21, 12, 0, 0, 18432, 124, }, /* 1328 */ + { 128, 21, 12, 0, 0, 18432, 106, }, /* 1329 */ + { 128, 21, 12, 0, 0, 18432, 68, }, /* 1330 */ + { 128, 26, 12, 0, 0, 18432, 68, }, /* 1331 */ + { 128, 6, 12, 0, 0, 18432, 142, }, /* 1332 */ + { 128, 6, 12, 0, 0, 18432, 136, }, /* 1333 */ + { 128, 13, 12, 0, 0, 18432, 138, }, /* 1334 */ + { 128, 15, 12, 0, 0, 18432, 68, }, /* 1335 */ + { 151, 9, 12, 0, 32, 18432, 74, }, /* 1336 */ + { 151, 5, 12, 0, -32, 18432, 76, }, /* 1337 */ + { 151, 15, 12, 0, 0, 18432, 68, }, /* 1338 */ + { 151, 21, 12, 0, 0, 18432, 106, }, /* 1339 */ + { 151, 21, 12, 0, 0, 18432, 124, }, /* 1340 */ + { 151, 21, 12, 0, 0, 18432, 68, }, /* 1341 */ + { 123, 7, 12, 0, 0, 18432, 82, }, /* 1342 */ + { 123, 12, 3, 0, 0, 26624, 130, }, /* 1343 */ + { 123, 10, 5, 0, 0, 18432, 144, }, /* 1344 */ + { 123, 12, 3, 0, 0, 26624, 128, }, /* 1345 */ + { 123, 6, 12, 0, 0, 18432, 92, }, /* 1346 */ + { 146, 6, 12, 0, 0, 18432, 136, }, /* 1347 */ + { 147, 6, 12, 0, 0, 18432, 136, }, /* 1348 */ + { 23, 21, 12, 0, 0, 28672, 68, }, /* 1349 */ + { 158, 12, 3, 0, 0, 26624, 328, }, /* 1350 */ + { 23, 10, 5, 0, 0, 18432, 164, }, /* 1351 */ + { 146, 7, 12, 0, 0, 18432, 284, }, /* 1352 */ + { 158, 7, 12, 0, 0, 18432, 284, }, /* 1353 */ + { 21, 6, 12, 0, 0, 18432, 92, }, /* 1354 */ + { 147, 7, 12, 0, 0, 18432, 284, }, /* 1355 */ + { 46, 7, 12, 0, 0, 18432, 82, }, /* 1356 */ + { 46, 26, 12, 0, 0, 18432, 68, }, /* 1357 */ + { 46, 12, 3, 0, 0, 26624, 102, }, /* 1358 */ + { 46, 12, 3, 0, 0, 26624, 130, }, /* 1359 */ + { 46, 21, 12, 0, 0, 18432, 124, }, /* 1360 */ + { 69, 1, 2, 0, 0, 6153, 66, }, /* 1361 */ + { 69, 10, 3, 0, 0, 18432, 330, }, /* 1362 */ + { 69, 10, 5, 0, 0, 18432, 138, }, /* 1363 */ + { 69, 10, 5, 0, 0, 18432, 160, }, /* 1364 */ + { 69, 10, 3, 0, 0, 18432, 286, }, /* 1365 */ + { 1, 12, 3, 0, 0, 26624, 102, }, /* 1366 */ + { 69, 25, 12, 0, 0, 18432, 118, }, /* 1367 */ + { 69, 13, 12, 0, 0, 10240, 214, }, /* 1368 */ + { 141, 26, 12, 0, 0, 18432, 68, }, /* 1369 */ + { 141, 12, 3, 0, 0, 26624, 102, }, /* 1370 */ + { 141, 21, 12, 0, 0, 18432, 106, }, /* 1371 */ + { 141, 21, 12, 0, 0, 18432, 124, }, /* 1372 */ + { 141, 21, 12, 0, 0, 18432, 68, }, /* 1373 */ + { 35, 12, 3, 0, 0, 26624, 130, }, /* 1374 */ + { 2, 6, 12, 0, 0, 18432, 90, }, /* 1375 */ + { 154, 7, 12, 0, 0, 18432, 82, }, /* 1376 */ + { 154, 12, 3, 0, 0, 26624, 96, }, /* 1377 */ + { 154, 6, 12, 0, 0, 18432, 142, }, /* 1378 */ + { 154, 6, 12, 0, 0, 18432, 136, }, /* 1379 */ + { 154, 13, 12, 0, 0, 18432, 138, }, /* 1380 */ + { 154, 26, 12, 0, 0, 18432, 68, }, /* 1381 */ + { 160, 7, 12, 0, 0, 18432, 82, }, /* 1382 */ + { 160, 12, 3, 0, 0, 26624, 96, }, /* 1383 */ + { 155, 7, 12, 0, 0, 18432, 82, }, /* 1384 */ + { 155, 12, 3, 0, 0, 26624, 96, }, /* 1385 */ + { 155, 13, 12, 0, 0, 18432, 138, }, /* 1386 */ + { 155, 23, 12, 0, 0, 14336, 68, }, /* 1387 */ + { 163, 7, 12, 0, 0, 18432, 82, }, /* 1388 */ + { 163, 6, 12, 0, 0, 18432, 142, }, /* 1389 */ + { 163, 12, 3, 0, 0, 26624, 102, }, /* 1390 */ + { 163, 13, 12, 0, 0, 18432, 138, }, /* 1391 */ + { 129, 7, 12, 0, 0, 34816, 82, }, /* 1392 */ + { 129, 15, 12, 0, 0, 34816, 68, }, /* 1393 */ + { 129, 12, 3, 0, 0, 26624, 96, }, /* 1394 */ + { 58, 9, 12, 0, 34, 34816, 74, }, /* 1395 */ + { 58, 5, 12, 0, -34, 34816, 76, }, /* 1396 */ + { 58, 12, 3, 0, 0, 26624, 150, }, /* 1397 */ + { 58, 12, 3, 0, 0, 26624, 130, }, /* 1398 */ + { 58, 12, 3, 0, 0, 26624, 96, }, /* 1399 */ + { 58, 6, 12, 0, 0, 34816, 142, }, /* 1400 */ + { 58, 13, 12, 0, 0, 34816, 138, }, /* 1401 */ + { 58, 21, 12, 0, 0, 34816, 68, }, /* 1402 */ + { 69, 15, 12, 0, 0, 0, 68, }, /* 1403 */ + { 69, 26, 12, 0, 0, 0, 68, }, /* 1404 */ + { 69, 23, 12, 0, 0, 0, 68, }, /* 1405 */ + { 3, 7, 12, 0, 0, 0, 240, }, /* 1406 */ + { 69, 26, 14, 0, 0, 28672, 332, }, /* 1407 */ + { 69, 26, 14, 0, 0, 28672, 334, }, /* 1408 */ + { 68, 2, 14, 0, 0, 18432, 336, }, /* 1409 */ + { 69, 26, 12, 0, 0, 18432, 338, }, /* 1410 */ + { 69, 26, 14, 0, 0, 18432, 340, }, /* 1411 */ + { 69, 26, 14, 0, 0, 18432, 334, }, /* 1412 */ + { 69, 26, 11, 0, 0, 18432, 342, }, /* 1413 */ + { 20, 26, 12, 0, 0, 18432, 68, }, /* 1414 */ + { 69, 26, 14, 0, 0, 18432, 236, }, /* 1415 */ + { 69, 26, 14, 0, 0, 18447, 334, }, /* 1416 */ + { 69, 26, 14, 0, 0, 28672, 344, }, /* 1417 */ + { 69, 26, 14, 0, 0, 28672, 346, }, /* 1418 */ + { 69, 24, 3, 0, 0, 28672, 348, }, /* 1419 */ + { 69, 26, 14, 0, 0, 28672, 350, }, /* 1420 */ + { 69, 13, 12, 0, 0, 10240, 138, }, /* 1421 */ + { 69, 1, 3, 0, 0, 6144, 352, }, /* 1422 */ }; const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ @@ -1872,35 +1886,35 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 142,143,144,145,146,147,148,149,150,151,152,153,154,154,155,156, /* U+10000 */ 157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172, /* U+10800 */ 173,174,175,176,177,178,179,146,180,181,146,182,183,184,185,146, /* U+11000 */ -186,187,188,189,190,191,146,146,192,193,194,195,146,196,146,197, /* U+11800 */ -198,198,198,198,198,198,198,199,200,198,201,146,146,146,146,146, /* U+12000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,202, /* U+12800 */ -203,203,203,203,203,203,203,203,204,146,146,146,146,146,146,146, /* U+13000 */ +186,187,188,189,190,191,192,146,193,194,195,196,146,197,198,199, /* U+11800 */ +200,200,200,200,200,200,200,201,202,200,203,146,146,146,146,146, /* U+12000 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,204, /* U+12800 */ +205,205,205,205,205,205,205,205,206,146,146,146,146,146,146,146, /* U+13000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+13800 */ -146,146,146,146,146,146,146,146,205,205,205,205,206,146,146,146, /* U+14000 */ +146,146,146,146,146,146,146,146,207,207,207,207,208,146,146,146, /* U+14000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+14800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+16000 */ -207,207,207,207,208,209,210,211,146,146,146,146,212,213,214,215, /* U+16800 */ -216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, /* U+17000 */ -216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, /* U+17800 */ -216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,217, /* U+18000 */ -216,216,216,216,216,216,218,218,218,219,220,146,146,146,146,146, /* U+18800 */ +209,209,209,209,210,211,212,213,146,146,146,146,214,215,216,217, /* U+16800 */ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, /* U+17000 */ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, /* U+17800 */ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,219, /* U+18000 */ +218,218,218,218,218,218,220,220,220,221,222,146,146,146,146,146, /* U+18800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1A000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,221, /* U+1A800 */ -222,223,224,225,225,226,146,146,146,146,146,146,146,146,146,146, /* U+1B000 */ -146,146,146,146,146,146,146,146,227,228,146,146,146,146,146,146, /* U+1B800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,223, /* U+1A800 */ +224,225,226,227,227,228,146,146,146,146,146,146,146,146,146,146, /* U+1B000 */ +146,146,146,146,146,146,146,146,229,230,146,146,146,146,146,146, /* U+1B800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1C000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,229,230, /* U+1C800 */ -231,232,233,234,235,236,237,146,238,239,240,241,242,243,244,245, /* U+1D000 */ -246,246,246,246,247,248,146,146,146,146,146,146,146,146,249,146, /* U+1D800 */ -250,146,251,146,146,252,146,146,146,146,146,146,146,146,146,253, /* U+1E000 */ -254,255,256,168,168,168,168,168,257,258,259,168,260,261,168,168, /* U+1E800 */ -262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277, /* U+1F000 */ -278,279,280,281,282,283,284,285,267,267,267,267,267,267,267,286, /* U+1F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,231,232, /* U+1C800 */ +233,234,235,236,237,238,239,146,240,241,242,243,244,245,246,247, /* U+1D000 */ +248,248,248,248,249,250,146,146,146,146,146,146,146,146,251,146, /* U+1D800 */ +252,253,254,146,146,255,146,146,146,256,146,146,146,146,146,257, /* U+1E000 */ +258,259,260,168,168,168,168,168,261,262,263,168,264,265,168,168, /* U+1E800 */ +266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281, /* U+1F000 */ +282,283,284,285,286,287,288,289,271,271,271,271,271,271,271,290, /* U+1F800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+21000 */ @@ -1921,23 +1935,23 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+28800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29800 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,287,101,101, /* U+2A000 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,291,101,101, /* U+2A000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2A800 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,101,288,101, /* U+2B000 */ -289,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2B800 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,101,292,101, /* U+2B000 */ +293,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2B800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2C000 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,290,101,101, /* U+2C800 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,294,101,101, /* U+2C800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2E000 */ -101,101,101,101,101,101,101,291,146,146,146,146,146,146,146,146, /* U+2E800 */ +101,101,101,101,101,101,101,295,146,146,146,146,146,146,146,146, /* U+2E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+2F000 */ -129,129,129,129,292,146,146,146,146,146,146,146,146,146,146,293, /* U+2F800 */ +129,129,129,129,296,146,146,146,146,146,146,146,146,146,146,297, /* U+2F800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30800 */ -101,101,101,101,101,101,294,146,146,146,146,146,146,146,146,146, /* U+31000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+31800 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+32000 */ +101,101,101,101,101,101,298,101,101,101,101,101,101,101,101,101, /* U+31000 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+31800 */ +101,101,101,101,101,101,101,299,146,146,146,146,146,146,146,146, /* U+32000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+32800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33800 */ @@ -1964,7 +1978,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+3F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+3F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+41000 */ @@ -1996,7 +2010,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+4F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+4F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+51000 */ @@ -2028,7 +2042,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+5F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+5F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+61000 */ @@ -2060,7 +2074,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+6F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+6F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+71000 */ @@ -2092,7 +2106,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+7F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+7F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+81000 */ @@ -2124,7 +2138,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+8F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+8F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+91000 */ @@ -2156,7 +2170,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+9F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+9F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A1000 */ @@ -2188,7 +2202,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+AF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+AF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B1000 */ @@ -2220,7 +2234,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+BF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+BF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C1000 */ @@ -2252,7 +2266,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+CF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+CF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D1000 */ @@ -2284,9 +2298,9 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+DF800 */ -295,296,297,298,296,296,296,296,296,296,296,296,296,296,296,296, /* U+E0000 */ -296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296, /* U+E0800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+DF800 */ +300,301,302,303,301,301,301,301,301,301,301,301,301,301,301,301, /* U+E0000 */ +301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301, /* U+E0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E2000 */ @@ -2316,7 +2330,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+EF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+EF800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F1000 */ @@ -2348,7 +2362,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FF000 */ -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,299, /* U+FF800 */ +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,304, /* U+FF800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+101000 */ @@ -2380,10 +2394,10 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10F000 */ -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,299, /* U+10F800 */ +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,304, /* U+10F800 */ }; -const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ +const uint16_t PRIV(ucd_stage2)[] = { /* 78080 bytes, block = 128 */ /* block 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 3, 4, 0, 0, @@ -2626,62 +2640,62 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 388,388,388,389,390,390,390,390,390,391,390,163,163,163,163,163, /* block 24 */ -392,393,393,393,394,395,395,395,395,395,395,395,395,163,395,395, -395,163,395,395,395,395,395,395,395,395,395,395,395,395,395,395, -395,395,395,395,395,395,395,395,395,163,395,395,395,395,395,395, -395,395,395,395,395,395,395,395,395,395,163,163,396,395,392,392, -392,393,393,393,393,163,392,392,392,163,392,392,392,397,163,163, -163,163,163,163,163,392,392,163,395,395,395,163,163,395,163,163, -395,395,392,392,163,163,398,398,398,398,398,398,398,398,398,398, -163,163,163,163,163,163,163,399,400,400,400,400,400,400,400,401, +392,393,393,393,392,394,394,394,394,394,394,394,394,163,394,394, +394,163,394,394,394,394,394,394,394,394,394,394,394,394,394,394, +394,394,394,394,394,394,394,394,394,163,394,394,394,394,394,394, +394,394,394,394,394,394,394,394,394,394,163,163,395,394,392,392, +392,393,393,393,393,163,392,392,392,163,392,392,392,396,163,163, +163,163,163,163,163,392,392,163,394,394,394,163,163,394,163,163, +394,394,392,392,163,163,397,397,397,397,397,397,397,397,397,397, +163,163,163,163,163,163,163,398,399,399,399,399,399,399,399,400, /* block 25 */ -402,403,404,404,405,402,402,402,402,402,402,402,402,163,402,402, -402,163,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,163,402,402,402,402,402,402, -402,402,402,402,163,402,402,402,402,402,163,163,406,402,404,407, -404,404,408,404,404,163,407,404,404,163,404,404,403,409,163,163, -163,163,163,163,163,408,408,163,163,163,163,163,163,402,402,163, -402,402,403,403,163,163,410,410,410,410,410,410,410,410,410,410, -163,402,402,163,163,163,163,163,163,163,163,163,163,163,163,163, +401,402,403,403,404,401,401,401,401,401,401,401,401,163,401,401, +401,163,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +401,401,401,401,401,401,401,401,401,163,401,401,401,401,401,401, +401,401,401,401,163,401,401,401,401,401,163,163,405,401,403,406, +403,403,407,403,403,163,406,403,403,163,403,403,402,408,163,163, +163,163,163,163,163,407,407,163,163,163,163,163,163,401,401,163, +401,401,402,402,163,163,409,409,409,409,409,409,409,409,409,409, +163,401,401,403,163,163,163,163,163,163,163,163,163,163,163,163, /* block 26 */ -411,411,412,412,413,413,413,413,413,413,413,413,413,163,413,413, -413,163,413,413,413,413,413,413,413,413,413,413,413,413,413,413, -413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, -413,413,413,413,413,413,413,413,413,413,413,414,414,413,415,412, -412,411,411,411,411,163,412,412,412,163,412,412,412,414,416,417, -163,163,163,163,413,413,413,415,418,418,418,418,418,418,418,413, -413,413,411,411,163,163,419,419,419,419,419,419,419,419,419,419, -418,418,418,418,418,418,418,418,418,417,413,413,413,413,413,413, +410,410,411,411,412,412,412,412,412,412,412,412,412,163,412,412, +412,163,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,413,413,412,414,411, +411,410,410,410,410,163,411,411,411,163,411,411,411,413,415,416, +163,163,163,163,412,412,412,414,417,417,417,417,417,417,417,412, +412,412,410,410,163,163,418,418,418,418,418,418,418,418,418,418, +417,417,417,417,417,417,417,417,417,416,412,412,412,412,412,412, /* block 27 */ -163,420,421,421,163,422,422,422,422,422,422,422,422,422,422,422, -422,422,422,422,422,422,422,163,163,163,422,422,422,422,422,422, -422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, -422,422,163,422,422,422,422,422,422,422,422,422,163,422,163,163, -422,422,422,422,422,422,422,163,163,163,423,163,163,163,163,424, -421,421,420,420,420,163,420,163,421,421,421,421,421,421,421,424, -163,163,163,163,163,163,425,425,425,425,425,425,425,425,425,425, -163,163,421,421,426,163,163,163,163,163,163,163,163,163,163,163, +163,419,420,420,163,421,421,421,421,421,421,421,421,421,421,421, +421,421,421,421,421,421,421,163,163,163,421,421,421,421,421,421, +421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421, +421,421,163,421,421,421,421,421,421,421,421,421,163,421,163,163, +421,421,421,421,421,421,421,163,163,163,422,163,163,163,163,423, +420,420,419,419,419,163,419,163,420,420,420,420,420,420,420,423, +163,163,163,163,163,163,424,424,424,424,424,424,424,424,424,424, +163,163,420,420,425,163,163,163,163,163,163,163,163,163,163,163, /* block 28 */ -163,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427, -427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427, -427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427, -427,428,427,429,428,428,428,428,428,428,430,163,163,163,163,431, -432,432,432,432,432,427,433,434,434,434,434,434,434,428,434,435, -436,436,436,436,436,436,436,436,436,436,437,437,163,163,163,163, +163,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,427,426,428,427,427,427,427,427,427,429,163,163,163,163,430, +431,431,431,431,431,426,432,433,433,433,433,433,433,427,433,434, +435,435,435,435,435,435,435,435,435,435,436,436,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 29 */ -163,438,438,163,438,163,438,438,438,438,438,163,438,438,438,438, -438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438, -438,438,438,438,163,438,163,438,438,438,438,438,438,438,438,438, -438,439,438,440,439,439,439,439,439,439,441,439,439,438,163,163, -442,442,442,442,442,163,443,163,444,444,444,444,444,439,163,163, -445,445,445,445,445,445,445,445,445,445,163,163,438,438,438,438, +163,437,437,163,437,163,437,437,437,437,437,163,437,437,437,437, +437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437, +437,437,437,437,163,437,163,437,437,437,437,437,437,437,437,437, +437,438,437,439,438,438,438,438,438,438,440,438,438,437,163,163, +441,441,441,441,441,163,442,163,443,443,443,443,443,438,444,163, +445,445,445,445,445,445,445,445,445,445,163,163,437,437,437,437, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, @@ -2696,274 +2710,274 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 163,456,456,456,456,456,456,457,456,457,456,456,456,456,456,458, /* block 31 */ -456,456,450,450,459,448,450,450,446,446,446,446,446,456,456,456, +456,456,459,459,460,448,450,450,446,446,446,446,446,456,456,456, 456,456,456,456,456,456,456,456,163,456,456,456,456,456,456,456, 456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456, 456,456,456,456,456,456,456,456,456,456,456,456,456,163,447,447, 447,447,447,447,447,447,450,447,447,447,447,447,447,163,447,447, -448,448,448,448,448,460,460,460,460,448,448,163,163,163,163,163, +448,448,448,448,448,461,461,461,461,448,448,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 32 */ -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,462,462,463,463,463, -463,464,463,463,463,463,463,465,462,466,466,464,464,463,463,461, -467,467,467,467,467,467,467,467,467,467,468,468,469,469,469,469, -461,461,461,461,461,461,464,464,463,463,461,461,461,461,463,463, -463,461,462,470,470,461,461,462,462,470,470,470,470,470,461,461, -461,463,463,463,463,461,461,461,461,461,461,461,461,461,461,461, +462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, +462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, +462,462,462,462,462,462,462,462,462,462,462,463,463,464,464,464, +464,465,464,464,464,464,464,466,463,467,467,465,465,464,464,462, +468,468,468,468,468,468,468,468,468,468,469,469,470,470,470,470, +462,462,462,462,462,462,465,465,464,464,462,462,462,462,464,464, +464,462,463,471,471,462,462,463,463,471,471,471,471,471,462,462, +462,464,464,464,464,462,462,462,462,462,462,462,462,462,462,462, /* block 33 */ -461,461,463,462,464,463,463,470,470,470,470,470,470,471,461,470, -472,472,472,472,472,472,472,472,472,472,470,470,462,463,473,473, -474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474, -474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474, -474,474,474,474,474,474,163,474,163,163,163,163,163,474,163,163, +462,462,464,463,465,464,464,471,471,471,471,471,471,472,462,471, +473,473,473,473,473,473,473,473,473,473,471,471,463,464,474,474, 475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, 475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, -475,475,475,475,475,475,475,475,475,475,475,476,477,475,475,475, +475,475,475,475,475,475,163,475,163,163,163,163,163,475,163,163, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,477,478,476,476,476, /* block 34 */ -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,479, -480,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, -481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,480, +481,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, /* block 35 */ -481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, -481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, -481,481,481,481,481,481,481,481,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, 482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, 482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,482,482,482,482,482,482,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, /* block 36 */ -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,163,483,483,483,483,163,163, -483,483,483,483,483,483,483,163,483,163,483,483,483,483,163,163, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,163,484,484,484,484,163,163, +484,484,484,484,484,484,484,163,484,163,484,484,484,484,163,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, /* block 37 */ -483,483,483,483,483,483,483,483,483,163,483,483,483,483,163,163, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,163,483,483,483,483,163,163,483,483,483,483,483,483,483,163, -483,163,483,483,483,483,163,163,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +484,484,484,484,484,484,484,484,484,163,484,484,484,484,163,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,163, +484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, /* block 38 */ -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,163,483,483,483,483,163,163,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,163,163,484,484,484, -485,486,487,486,486,486,486,487,487,488,488,488,488,488,488,488, -488,488,489,489,489,489,489,489,489,489,489,489,489,163,163,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,163,163,485,485,485, +486,487,488,487,487,487,487,488,488,489,489,489,489,489,489,489, +489,489,490,490,490,490,490,490,490,490,490,490,490,163,163,163, /* block 39 */ -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -490,490,490,490,490,490,490,490,490,490,163,163,163,163,163,163, -491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, -491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, -491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, -491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, -491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, -492,492,492,492,492,492,163,163,493,493,493,493,493,493,163,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +491,491,491,491,491,491,491,491,491,491,163,163,163,163,163,163, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +493,493,493,493,493,493,163,163,494,494,494,494,494,494,163,163, /* block 40 */ -494,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, +495,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, /* block 41 */ -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, /* block 42 */ -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,496,497,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,497,498,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, /* block 43 */ -498,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, -499,499,499,499,499,499,499,499,499,499,499,500,501,163,163,163, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,503,503,503,504,504, -504,502,502,502,502,502,502,502,502,163,163,163,163,163,163,163, +499,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500, +500,500,500,500,500,500,500,500,500,500,500,501,502,163,163,163, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,504,504,504,505,505, +505,503,503,503,503,503,503,503,503,163,163,163,163,163,163,163, /* block 44 */ -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,506,506,507,508,163,163,163,163,163,163,163,163,163,505, -509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509, -509,509,510,510,511,512,512,163,163,163,163,163,163,163,163,163, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,514,514,163,163,163,163,163,163,163,163,163,163,163,163, -515,515,515,515,515,515,515,515,515,515,515,515,515,163,515,515, -515,163,516,516,163,163,163,163,163,163,163,163,163,163,163,163, +506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, +506,506,507,507,508,509,163,163,163,163,163,163,163,163,163,506, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,511,511,512,513,513,163,163,163,163,163,163,163,163,163, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,515,515,163,163,163,163,163,163,163,163,163,163,163,163, +516,516,516,516,516,516,516,516,516,516,516,516,516,163,516,516, +516,163,517,517,163,163,163,163,163,163,163,163,163,163,163,163, /* block 45 */ -517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,518,518,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,517,519,519,520,521,521,521,521,521,521,521,520,520, -520,520,520,520,520,520,521,520,520,522,522,522,522,522,522,522, -522,522,523,522,524,524,524,525,526,526,524,527,517,522,163,163, -528,528,528,528,528,528,528,528,528,528,163,163,163,163,163,163, +518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518, +518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518, +518,518,518,519,519,518,518,518,518,518,518,518,518,518,518,518, +518,518,518,518,520,520,521,522,522,522,522,522,522,522,521,521, +521,521,521,521,521,521,522,521,521,523,523,523,523,523,523,523, +523,523,524,523,525,525,525,526,527,527,525,528,518,523,163,163, 529,529,529,529,529,529,529,529,529,529,163,163,163,163,163,163, +530,530,530,530,530,530,530,530,530,530,163,163,163,163,163,163, /* block 46 */ -530,530,531,532,533,531,534,530,533,535,536,537,537,537,538,537, -539,539,539,539,539,539,539,539,539,539,163,163,163,163,163,163, -540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,541,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,163,163,163,163,163,163,163, +531,531,532,533,534,532,535,531,534,536,537,538,538,538,539,538, +540,540,540,540,540,540,540,540,540,540,163,163,163,163,163,163, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,542,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,163,163,163,163,163,163,163, /* block 47 */ -540,540,540,540,540,542,542,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,543,540,163,163,163,163,163, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,163,163,163,163,163,163,163,163,163,163, +541,541,541,541,541,543,543,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,544,541,163,163,163,163,163, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,163,163,163,163,163,163,163,163,163,163, /* block 48 */ -544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, -544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,163, -545,545,545,546,546,546,546,545,545,546,546,546,163,163,163,163, -546,546,545,546,546,546,546,546,546,547,547,547,163,163,163,163, -548,163,163,163,549,549,550,550,550,550,550,550,550,550,550,550, -551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551, -551,551,551,551,551,551,551,551,551,551,551,551,551,551,163,163, -551,551,551,551,551,163,163,163,163,163,163,163,163,163,163,163, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,163, +546,546,546,547,547,547,547,546,546,547,547,547,163,163,163,163, +547,547,546,547,547,547,547,547,547,548,548,548,163,163,163,163, +549,163,163,163,550,550,551,551,551,551,551,551,551,551,551,551, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,163,163, +552,552,552,552,552,163,163,163,163,163,163,163,163,163,163,163, /* block 49 */ -552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,552,552,163,163,163,163, -552,552,552,552,552,553,553,553,552,552,553,552,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,163,163,163,163,163,163, -554,554,554,554,554,554,554,554,554,554,555,163,163,163,556,556, -557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, -557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,553,553,163,163,163,163, +553,553,553,553,553,554,554,554,553,553,554,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,163,163,163,163,163,163, +555,555,555,555,555,555,555,555,555,555,556,163,163,163,557,557, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, /* block 50 */ -558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, -558,558,558,558,558,558,558,559,559,560,560,559,163,163,561,561, -562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, -562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, -562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, -562,562,562,562,562,563,564,563,564,564,564,564,564,564,564,163, -565,566,564,566,566,564,564,564,564,564,564,564,564,563,563,563, -563,563,563,564,564,567,567,567,567,567,567,567,567,163,163,567, +559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559, +559,559,559,559,559,559,559,560,560,561,561,560,163,163,562,562, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,564,565,564,565,565,565,565,565,565,565,163, +566,567,565,567,567,565,565,565,565,565,565,565,565,564,564,564, +564,564,564,565,565,568,568,568,568,568,568,568,568,163,163,568, /* block 51 */ -568,568,568,568,568,568,568,568,568,568,163,163,163,163,163,163, -568,568,568,568,568,568,568,568,568,568,163,163,163,163,163,163, -569,569,569,569,569,569,569,570,571,571,571,571,569,569,163,163, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,572,573, -573,154,154,154,154,154,154,154,154,154,154,154,573,573,573,163, +569,569,569,569,569,569,569,569,569,569,163,163,163,163,163,163, +569,569,569,569,569,569,569,569,569,569,163,163,163,163,163,163, +570,570,570,570,570,570,570,571,572,572,572,572,570,570,163,163, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,573,574, +574,154,154,154,154,154,154,154,154,154,154,154,574,574,574,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 52 */ -574,574,574,574,575,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,577,578,574,574,574,574,574,575,574,575,575,575, -575,575,574,575,579,576,576,576,576,576,576,576,576,163,163,163, -580,580,580,580,580,580,580,580,580,580,581,581,582,583,581,581, -582,584,584,584,584,584,584,584,584,584,584,577,577,577,577,577, -577,577,577,577,584,584,584,584,584,584,584,584,584,581,581,163, +575,575,575,575,576,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,578,579,575,575,575,575,575,576,575,576,576,576, +576,576,575,576,580,577,577,577,577,577,577,577,577,163,163,163, +581,581,581,581,581,581,581,581,581,581,582,582,583,584,582,582, +583,585,585,585,585,585,585,585,585,585,585,578,578,578,578,578, +578,578,578,578,585,585,585,585,585,585,585,585,585,582,582,163, /* block 53 */ -585,585,586,587,587,587,587,587,587,587,587,587,587,587,587,587, -587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, -587,586,585,585,585,585,586,586,585,585,588,589,585,585,587,587, -590,590,590,590,590,590,590,590,590,590,587,587,587,587,587,587, -591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,592,593,594,594,593,593,593,594,593,594, -594,594,595,595,163,163,163,163,163,163,163,163,596,596,596,596, +586,586,587,588,588,588,588,588,588,588,588,588,588,588,588,588, +588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588, +588,587,586,586,586,586,587,587,586,586,589,590,586,586,588,588, +591,591,591,591,591,591,591,591,591,591,588,588,588,588,588,588, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,593,594,595,595,594,594,594,595,594,595, +595,595,596,596,163,163,163,163,163,163,163,163,597,597,597,597, /* block 54 */ -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,598,598,598,598,598,598,598,598,599,599,599,599, -599,599,599,599,598,598,600,601,163,163,163,602,602,603,603,603, -604,604,604,604,604,604,604,604,604,604,163,163,163,597,597,597, -605,605,605,605,605,605,605,605,605,605,606,606,606,606,606,606, -606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606, -606,606,606,606,606,606,606,606,607,607,607,608,607,607,609,609, +598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598, +598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598, +598,598,598,598,599,599,599,599,599,599,599,599,600,600,600,600, +600,600,600,600,599,599,601,602,163,163,163,603,603,604,604,604, +605,605,605,605,605,605,605,605,605,605,163,163,163,598,598,598, +606,606,606,606,606,606,606,606,606,606,607,607,607,607,607,607, +607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607, +607,607,607,607,607,607,607,607,608,608,608,609,608,608,610,610, /* block 55 */ -610,611,612,613,614,615,616,617,618,163,163,163,163,163,163,163, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,163,163,619,619,619, -620,620,620,620,620,620,620,620,163,163,163,163,163,163,163,163, -621,622,621,623,622,624,624,625,624,625,626,622,625,625,622,622, -625,627,622,622,622,622,622,622,622,628,629,630,630,624,630,630, -630,630,631,632,633,629,629,634,635,635,636,163,163,163,163,163, +611,612,613,614,615,616,617,618,619,163,163,163,163,163,163,163, +620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, +620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, +620,620,620,620,620,620,620,620,620,620,620,163,163,620,620,620, +621,621,621,621,621,621,621,621,163,163,163,163,163,163,163,163, +622,623,622,624,623,625,625,626,625,626,627,623,626,626,623,623, +626,628,623,623,623,623,623,623,623,629,630,631,631,625,631,631, +631,631,632,633,634,630,630,635,636,636,637,163,163,163,163,163, /* block 56 */ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70,221,221,221,221,221,637,147,147,147,147, + 70, 70, 70, 70, 70, 70,221,221,221,221,221,638,147,147,147,147, 147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, 147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,638,638,638, -638,638,148,147,147,147,638,638,638,638,638, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70,639,640, 70, 70, 70,641, 70, 70, +147,147,147,147,147,147,147,147,147,147,147,147,147,639,639,639, +639,639,148,147,147,147,639,639,639,639,639, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70,640,641, 70, 70, 70,642, 70, 70, /* block 57 */ - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,642, 70, - 70, 70, 70, 70, 70, 70,643, 70, 70, 70, 70,644,644,644,644,644, -644,644,644,644,645,644,644,644,645,644,644,644,644,644,644,644, -644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,646, -647,647,158,158,154,154,154,154,154,154,154,154,154,154,154,154, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,643, 70, + 70, 70, 70, 70, 70, 70,644, 70, 70, 70, 70,645,645,645,645,645, +645,645,645,645,646,645,645,645,646,645,645,645,645,645,645,645, +645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,647, +648,648,158,158,154,154,154,154,154,154,154,154,154,154,154,154, 158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, -158,158,158,158,158,158,158,573,573,573,573,573,573,573,573,573, -573,573,573,573,573,154,154,154,648,154,649,154,154,154,154,154, +158,158,158,158,158,158,158,574,574,574,574,574,574,574,574,574, +574,574,574,574,574,154,154,154,649,154,650,154,154,154,154,154, /* block 58 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, @@ -2972,12 +2986,12 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, -650,651, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, +651,652, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, /* block 59 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 69, 69, 69, 69,652,653, 70, 70,654, 70, + 65, 66, 65, 66, 65, 66, 69, 69, 69, 69,653,654, 70, 70,655, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 67, 65, 66, 65, 66, @@ -2986,123 +3000,123 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, /* block 60 */ -655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656, -655,655,655,655,655,655,163,163,656,656,656,656,656,656,163,163, -655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656, -655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656, -655,655,655,655,655,655,163,163,656,656,656,656,656,656,163,163, -173,655,173,655,173,655,173,655,163,656,163,656,163,656,163,656, -655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656, -657,657,658,658,658,658,659,659,660,660,661,661,662,662,163,163, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +656,656,656,656,656,656,163,163,657,657,657,657,657,657,163,163, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +656,656,656,656,656,656,163,163,657,657,657,657,657,657,163,163, +173,656,173,656,173,656,173,656,163,657,163,657,163,657,163,657, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +658,658,659,659,659,659,660,660,661,661,662,662,663,663,163,163, /* block 61 */ -663,663,663,663,663,663,663,663,664,664,664,664,664,664,664,664, -663,663,663,663,663,663,663,663,664,664,664,664,664,664,664,664, -663,663,663,663,663,663,663,663,664,664,664,664,664,664,664,664, -655,655,665,666,665,163,173,665,656,656,667,667,668,162,669,162, -162,162,665,666,665,163,173,665,670,670,670,670,668,162,162,162, -655,655,173,173,163,163,173,173,656,656,671,671,163,162,162,162, -655,655,173,173,173,215,173,173,656,656,672,672,220,162,162,162, -163,163,665,666,665,163,173,665,673,673,674,674,668,162,162,163, +664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, +664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, +664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, +656,656,666,667,666,163,173,666,657,657,668,668,669,162,670,162, +162,162,666,667,666,163,173,666,671,671,671,671,669,162,162,162, +656,656,173,173,163,163,173,173,657,657,672,672,163,162,162,162, +656,656,173,173,173,215,173,173,657,657,673,673,220,162,162,162, +163,163,666,667,666,163,173,666,674,674,675,675,669,162,162,163, /* block 62 */ -675,675,675,675,675,675,675,675,675,675,675, 51,676,677,678,679, -680,680,680,680,680,680,681, 43,682,683,684,685,685,686,684,685, - 43, 43, 43, 43,687, 43, 43,687,688,689,690,691,692,693,694,695, -696,696,697,697,697, 43, 43, 43, 43, 49, 57, 43,698,699, 43,700, -701, 43, 43, 43,702,703,704,699,699,698, 43, 43, 43, 43, 43, 43, - 43, 43, 50,705,700, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,675, - 51,706,706,706,706,707,708,709,710,711,712,712,712,712,712,712, - 54,645,163,163, 54, 54, 54, 54, 54, 54,713,714,715,716,717,644, +676,676,676,676,676,676,676,676,676,676,676, 51,677,678,679,680, +681,681,681,681,681,681,682, 43,683,684,685,686,686,687,685,686, + 43, 43, 43, 43,688, 43, 43,688,689,690,691,692,693,694,695,696, +697,697,698,698,698, 43, 43, 43, 43, 49, 57, 43,699,700, 43,701, +702, 43, 43, 43,703,704,705,700,700,699, 43, 43, 43, 43, 43, 43, + 43, 43, 50,706,701, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,676, + 51,707,707,707,707,708,709,710,711,712,713,713,713,713,713,713, + 54,646,163,163, 54, 54, 54, 54, 54, 54,714,715,716,717,718,645, /* block 63 */ - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,713,714,715,716,717,163, -644,644,644,644,644,644,644,644,644,644,644,644,644,163,163,163, -431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431, -431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431, -431,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718, -719,719,719,719,719,719,719,719,719,719,719,719,719,720,720,720, -720,719,720,721,720,719,719,158,158,158,158,719,719,719,719,719, -722,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,714,715,716,717,718,163, +645,645,645,645,645,645,645,645,645,645,645,645,645,163,163,163, +430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, +430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, +430,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719, +720,720,720,720,720,720,720,720,720,720,720,720,720,721,721,721, +721,720,721,722,721,720,720,158,158,158,158,720,720,720,720,720, +723,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 64 */ -723,723,724,723,723,723,723,724,723,723,725,724,724,724,725,725, -724,724,724,725,723,724,723,723,726,724,724,724,724,724,723,723, -723,723,727,723,724,723,728,723,724,729,730,731,724,724,732,725, -724,724,733,724,725,734,734,734,734,735,723,723,725,725,724,724, -715,715,715,715,715,724,725,725,736,736,723,715,723,723,737,460, +724,724,725,724,724,724,724,725,724,724,726,725,725,725,726,726, +725,725,725,726,724,725,724,724,727,725,725,725,725,725,724,724, +724,724,728,724,725,724,729,724,725,730,731,732,725,725,733,726, +725,725,734,725,726,735,735,735,735,736,724,724,726,726,725,725, +716,716,716,716,716,725,726,726,737,737,724,716,724,724,738,461, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738, 739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739, +740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740, /* block 65 */ -740,740,740, 65, 66,740,740,740,740, 58,723,723,163,163,163,163, - 50, 50, 50, 50,741,742,742,742,742,742, 50, 50,743,743,743,743, - 50,743,743, 50,743,743, 50,743, 45,742,742,743,743,743, 50, 45, -743,743, 45, 45, 45, 45,743,743, 45, 45, 45, 45,743,743,743,743, -743,743,743,743,743,743,743,743,743,743,743,743,743,743, 50, 50, -743,743, 50,743, 50,743,743,743,743,743,743,743, 45,743, 45, 45, - 45, 45, 45, 45,743,743, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +741,741,741, 65, 66,741,741,741,741, 58,724,724,163,163,163,163, + 50, 50, 50, 50,742,743,743,743,743,743, 50, 50,744,744,744,744, + 50,744,744, 50,744,744, 50,744, 45,743,743,744,744,744, 50, 45, +744,744, 45, 45, 45, 45,744,744, 45, 45, 45, 45,744,744,744,744, +744,744,744,744,744,744,744,744,744,744,744,744,744,744, 50, 50, +744,744, 50,744, 50,744,744,744,744,744,744,744, 45,744, 45, 45, + 45, 45, 45, 45,744,744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 66 */ - 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744,744,744, 50, 50, - 50, 50,745, 53, 50,744, 50, 50, 50, 50, 50, 50, 50, 50, 50,744, -744,744,744, 50,744, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744, 50, 50, - 50, 50, 50,744, 50,744, 50, 50, 50, 50, 50, 50,744, 50, 50, 50, - 50, 50,744,744,744,744, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,744,744,744,744,744,744,744,744, 50, 50,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, + 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745,745, 50, 50, + 50, 50,746, 53, 50,745, 50, 50, 50, 50, 50, 50, 50, 50, 50,745, +745,745,745, 50,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745, 50, 50, + 50, 50, 50,745, 50,745, 50, 50, 50, 50, 50, 50,745, 50, 50, 50, + 50, 50,745,745,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50,745,745,745,745,745,745,745,745, 50, 50,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, /* block 67 */ -744,744,744,744,744,744,744,744,744,744,744,744, 50, 50, 50,744, -744,744,744, 50, 50, 50, 50, 50,744, 50, 50, 50, 50, 50, 50, 50, - 50, 50,744,744, 50, 50,744, 50,744,744, 50,744, 50, 50, 50, 50, -744,744,744,744,744,744,744,744,744, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744,744, 50, 50, -744,744, 50, 50, 50, 50,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744, 50, 50, -744,744,744,744,744, 50,744,744, 50, 50,744,744,744,744,744, 50, +745,745,745,745,745,745,745,745,745,745,745,745, 50, 50, 50,745, +745,745,745, 50, 50, 50, 50, 50,745, 50, 50, 50, 50, 50, 50, 50, + 50, 50,745,745, 50, 50,745, 50,745,745, 50,745, 50, 50, 50, 50, +745,745,745,745,745,745,745,745,745, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745, 50, 50, +745,745, 50, 50, 50, 50,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745, 50, 50, +745,745,745,745,745, 50,745,745, 50, 50,745,745,745,745,745, 50, /* block 68 */ - 45, 45, 45, 45, 45, 45, 45, 45,746,747,746,747, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,748,748, 45, 45, 45, 45, - 50, 50, 45, 45, 45, 45, 45, 45, 47,749,750, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45,751,751,751,751,751,751,751,751,751,751, -751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751, -751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751, -751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751, -751,751,751,751,751,751,751,751,751,751,751, 45, 50, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45,747,748,747,748, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749,749, 45, 45, 45, 45, + 50, 50, 45, 45, 45, 45, 45, 45, 47,750,751, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752, 45, 50, 45, 45, 45, /* block 69 */ - 45, 45, 45, 45, 45, 45, 45, 45,752, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45,751, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, + 45, 45, 45, 45, 45, 45, 45, 45,753, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45,752, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,743,743, 45,743, 45, 45, 45, 45, 45, 45, 45, 45, + 50, 50, 50, 50,744,744, 45,744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, -743, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, - 50, 50,743, 45, 45, 45, 45, 45, 45,748,748,748,748, 47, 47, 47, -748, 47, 47,748, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, +744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, + 50, 50,744, 45, 45, 45, 45, 45, 45,749,749,749,749, 47, 47, 47, +749, 47, 47,749, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, /* block 70 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45,753,753,753,753,753,753,753,753,753, -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,753,753,753,753,753, -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, + 45, 45, 45, 45, 45, 45, 45,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 71 */ 58, 58, 58, 58, 58, 58, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,754,754,754,754,754,754,754,754,754,754, -754,754,755,754,754,754,754,754,754,754,754,754,754,754,754,754, -756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756, -756,756,756,756,756,756,756,756,756,756, 58, 58, 58, 58, 58, 58, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,755,755,755,755,755,755,755,755,755,755, +755,755,756,755,755,755,755,755,755,755,755,755,755,755,755,755, +757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757, +757,757,757,757,757,757,757,757,757,757, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 72 */ @@ -3118,132 +3132,132 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ /* block 73 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -743,743, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45,743,743, -743,743,743,743,743,743,742, 50, 45, 45, 45, 45,743,743,743,743, -742, 50, 45, 45, 45, 45,743,743, 45, 45,743,743, 45, 45, 45,743, -743,743,743,743, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45,743, 45,743, 45, 45,743,743,743,743,743,743, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50,741,741,757,757, 50, +744,744, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45,744,744, +744,744,744,744,744,744,743, 50, 45, 45, 45, 45,744,744,744,744, +743, 50, 45, 45, 45, 45,744,744, 45, 45,744,744, 45, 45, 45,744, +744,744,744,744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45,744, 45,744, 45, 45,744,744,744,744,744,744, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50,742,742,758,758, 50, /* block 74 */ - 47, 47, 47, 47, 47,758,743,752,752,752,752,752,752,752, 47,752, -752, 47,752, 45,748,748,752,752, 47,752,752,752,752,759,752,752, - 47,752, 47, 47,752,752, 47,752,752,752, 47,752,752,752, 47, 47, -752,752,752,752,752,752,752,752, 47, 47, 47,752,752,752,752,752, -742,752,742,752,752,752,752,752,748,748,748,748,748,748,748,748, -748,748,748,748,752,752,752,752,752,752,752,752,752,752,752, 47, -742,758,758,742,752, 47, 47,752, 47,752,752,752,752,758,758,760, -752,752,752,752,752,752,752,752,752,752,752, 47,752,752, 47,748, + 47, 47, 47, 47, 47,759,744,753,753,753,753,753,753,753, 47,753, +753, 47,753, 45,749,749,753,753, 47,753,753,753,753,760,753,753, + 47,753, 47, 47,753,753, 47,753,753,753, 47,753,753,753, 47, 47, +753,753,753,753,753,753,753,753, 47, 47, 47,753,753,753,753,753, +743,753,743,753,753,753,753,753,749,749,749,749,749,749,749,749, +749,749,749,749,753,753,753,753,753,753,753,753,753,753,753, 47, +743,759,759,743,753, 47, 47,753, 47,753,753,753,753,759,759,761, +753,753,753,753,753,753,753,753,753,753,753, 47,753,753, 47,749, /* block 75 */ -752,752,752,752,752,752, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -752,752, 47,748, 47, 47, 47, 47,752, 47,752, 47, 47,752,752,752, - 47,748,752,752,752,752,752, 47,752,752,748,748,761,752,752,752, - 47, 47,752,752,752,752,752,752,752,752,752,752,752,748,748,752, -752,752,752,752,748,748,752,752, 47,752,752,752,752,752,748, 47, -752, 47,752, 47,748,752,752,752,752,752,752,752,752,752,752,752, -752,752,752,752,752,752,752,752,752, 47,748,752,752,752,752,752, - 47, 47,748,748, 47,748,752, 47, 47,759,748,752,752,748,752,752, +753,753,753,753,753,753, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +753,753, 47,749, 47, 47, 47, 47,753, 47,753, 47, 47,753,753,753, + 47,749,753,753,753,753,753, 47,753,753,749,749,762,753,753,753, + 47, 47,753,753,753,753,753,753,753,753,753,753,753,749,749,753, +753,753,753,753,749,749,753,753, 47,753,753,753,753,753,749, 47, +753, 47,753, 47,749,753,753,753,753,753,753,753,753,753,753,753, +753,753,753,753,753,753,753,753,753, 47,749,753,753,753,753,753, + 47, 47,749,749, 47,749,753, 47, 47,760,749,753,753,749,753,753, /* block 76 */ -752,752, 47,752,752,748, 45, 45, 47, 47,762,762,759,759,752, 47, -752,752, 47, 45, 47, 45, 47, 45, 45, 45, 45, 45, 45, 47, 45, 45, - 45, 47, 45, 45, 45, 45, 45, 45,748, 45, 45, 45, 45, 45, 45, 45, +753,753, 47,753,753,749, 45, 45, 47, 47,763,763,760,760,753, 47, +753,753, 47, 45, 47, 45, 47, 45, 45, 45, 45, 45, 45, 47, 45, 45, + 45, 47, 45, 45, 45, 45, 45, 45,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 47, 45, 45, 47, 45, 45, 45, 45,748, 45,748, 45, - 45, 45, 45,748,748,748, 45,748, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 47, 47,752,752,752,703,704,703,704,703,704,703,704, -703,704,703,704,703,704, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 45, 45, 45, 45, 47, 45, 45, 47, 45, 45, 45, 45,749, 45,749, 45, + 45, 45, 45,749,749,749, 45,749, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 47, 47,753,753,753,704,705,704,705,704,705,704,705, +704,705,704,705,704,705, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 77 */ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 45,748,748,748, 45, 45, 45, 45, 45, 45, 45, 45, + 58, 58, 58, 58, 45,749,749,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -748, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,748, - 50, 50, 50,744,744,746,747, 50,744,744, 50,744, 50,744, 50, 50, - 50, 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50,744,744,744, 50, - 50, 50,744,744,744,744,746,747,746,747,746,747,746,747,746,747, +749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749, + 50, 50, 50,745,745,747,748, 50,745,745, 50,745, 50,745, 50, 50, + 50, 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50,745,745,745, 50, + 50, 50,745,745,745,745,747,748,747,748,747,748,747,748,747,748, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 78 */ -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, /* block 79 */ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,741,741, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50,742,742, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 80 */ - 50, 50, 50,746,747,746,747,746,747,746,747,746,747,746,747,746, -747,746,747,746,747,746,747,746,747, 50, 50,744, 50, 50, 50, 50, -744, 50, 50,744,744,744, 50, 50,744,744,744,744,744,744,744,744, - 50, 50, 50, 50, 50, 50, 50, 50,744, 50, 50, 50, 50, 50, 50, 50, -744,744, 50, 50,744,744, 50, 50, 50, 50, 50, 50, 50, 50, 50,744, -744,744,744, 50,744,744, 50, 50,746,747,746,747, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50,744, 50, 50,744,744, 50, 50,746,747, 50, 50, + 50, 50, 50,747,748,747,748,747,748,747,748,747,748,747,748,747, +748,747,748,747,748,747,748,747,748, 50, 50,745, 50, 50, 50, 50, +745, 50, 50,745,745,745, 50, 50,745,745,745,745,745,745,745,745, + 50, 50, 50, 50, 50, 50, 50, 50,745, 50, 50, 50, 50, 50, 50, 50, +745,745, 50, 50,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50,745, +745,745,745, 50,745,745, 50, 50,747,748,747,748, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50,745, 50, 50,745,745, 50, 50,747,748, 50, 50, /* block 81 */ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744, 50, - 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50, 50,744,744, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745, 50, + 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744,744,744,744, + 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745,745,745, /* block 82 */ -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744, 50, 50, 50,744,744,744,744,744,744,744,744, 50,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,744, 50, 50, 50, 50, 50, 50, 50,744, 50, - 50, 50, 50,744,744,744, 50, 50, 50, 50, 50, 50,744,744,744, 50, - 50, 50, 50, 50, 50, 50, 50,744,744,744,744, 50, 50, 50, 50, 50, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745, 50, 50, 50,745,745,745,745,745,745,745,745, 50,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745, 50, 50, 50, 50, 50, 50, 50,745, 50, + 50, 50, 50,745,745,745, 50, 50, 50, 50, 50, 50,745,745,745, 50, + 50, 50, 50, 50, 50, 50, 50,745,745,745,745, 50, 50, 50, 50, 50, /* block 83 */ 45, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,748,748, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 45, 45, 50, 50, 50, 50, 50, 50, 45, 45, 45, -748, 45, 45, 45, 45,748, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +749, 45, 45, 45, 45,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45,753,753, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45,754,754, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, /* block 84 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45,753, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45,754, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,764, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,765, 45, /* block 85 */ -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, 766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, 766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, 766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, - 65, 66,767,768,769,770,771, 65, 66, 65, 66, 65, 66,772,773,774, -775, 70, 65, 66, 70, 65, 66, 70, 70, 70, 70, 70,645,644,776,776, +767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, +767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, +767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, + 65, 66,768,769,770,771,772, 65, 66, 65, 66, 65, 66,773,774,775, +776, 70, 65, 66, 70, 65, 66, 70, 70, 70, 70, 70,646,645,777,777, /* block 86 */ 211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, @@ -3252,248 +3266,248 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, 211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, 211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, -211,212,211,212,777,778,778,778,778,778,778,211,212,211,212,779, -779,779,211,212,163,163,163,163,163,780,780,780,780,781,780,780, +211,212,211,212,778,779,779,779,779,779,779,211,212,211,212,780, +780,780,211,212,163,163,163,163,163,781,781,781,781,782,781,781, /* block 87 */ -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,163,782,163,163,163,163,163,782,163,163, 783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, 783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,783,783,783,783,163,163,163,163,163,163,163,784, -785,163,163,163,163,163,163,163,163,163,163,163,163,163,163,786, +783,783,783,783,783,783,163,783,163,163,163,163,163,783,163,163, +784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, +784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, +784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, +784,784,784,784,784,784,784,784,163,163,163,163,163,163,163,785, +786,163,163,163,163,163,163,163,163,163,163,163,163,163,163,787, /* block 88 */ -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,163,163,163,163,163,163,163,163,163, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163, -787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787, -787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,163,163,163,163,163,163,163,163,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, +788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, /* block 89 */ - 43, 43,788,789,788,789, 43, 43, 43,788,789, 43,788,789, 43, 43, - 43, 43, 43, 43, 43, 43, 43,680, 43, 43,680, 43,788,789, 43, 43, -788,789,703,704,703,704,703,704,703,704, 43, 43, 43, 43,699,790, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,680,680,699, 43, 43, 43, -680,791,684,792, 43, 43, 43, 43, 43, 43, 43, 43,791, 43,791,791, - 45, 45, 43,699,699,703,704,703,704,703,704,703,704,680,753,753, -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, + 43, 43,789,790,789,790, 43, 43, 43,789,790, 43,789,790, 43, 43, + 43, 43, 43, 43, 43, 43, 43,681, 43, 43,681, 43,789,790, 43, 43, +789,790,704,705,704,705,704,705,704,705, 43, 43, 43, 43,700,791, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,681,681,700, 43, 43, 43, +681,792,685,793, 43, 43, 43, 43, 43, 43, 43, 43,792, 43,792,792, + 45, 45, 43,700,700,704,705,704,705,704,705,704,705,681,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, /* block 90 */ -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,163,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,163,163,163,163,163,163,163,163,163,163,163,163, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,163,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,163,163,163,163,163,163,163,163,163,163,163,163, /* block 91 */ -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, /* block 92 */ -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,163,163,163,163,163,163,163,163,163,163, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -794,794,795,795,794,794,794,794,794,794,794,794,163,163,163,163, +795,795,796,796,795,795,795,795,795,795,795,795,163,163,163,163, /* block 93 */ -675,796,797,798,723,799,800,801,802,803,802,803,804,805,804,805, -802,803, 45,806,802,803,802,803,802,803,802,803,807,808,809,809, - 45,801,801,801,801,801,801,801,801,801,810,810,810,810,811,811, -812,813,813,813,813,813,723,814,801,801,801,815,816,817,818,818, -163,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +676,797,798,799,724,800,801,802,803,804,803,804,805,806,805,806, +803,804, 45,807,803,804,803,804,803,804,803,804,808,809,810,810, + 45,802,802,802,802,802,802,802,802,802,811,811,811,811,812,812, +813,814,814,814,814,814,724,815,802,802,802,816,817,818,819,819, +163,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, /* block 94 */ -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,163,163,820,820,821,821,822,822,819, -823,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,825,826,827,827,824, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,163,163,821,821,822,822,823,823,820, +824,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,826,827,828,828,825, /* block 95 */ -163,163,163,163,163,828,828,828,828,828,828,828,828,828,828,828, -828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828, -828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828, -163,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +163,163,163,163,163,829,829,829,829,829,829,829,829,829,829,829, 829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, 829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,829,830,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +163,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,831,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, /* block 96 */ -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,163, -831,831,832,832,832,832,831,831,831,831,831,831,831,831,831,831, -828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828, -828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828, -818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818, -818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818, -818,818,818,818,163,163,163,163,163,163,163,163,163,163,163,163, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,163, +832,832,833,833,833,833,832,832,832,832,832,832,832,832,832,832, +829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +819,819,819,819,163,163,163,163,163,163,163,163,163,163,163,163, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, /* block 97 */ -833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833, -833,833,833,833,833,833,833,833,833,833,833,833,833,834,834,163, -832,832,832,832,832,832,832,832,832,832,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,835,835,835,835,835,835,835,835, -723, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833, -833,833,833,833,833,833,833,833,833,833,833,833,834,834,834,460, +834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, +834,834,834,834,834,834,834,834,834,834,834,834,834,835,835,163, +833,833,833,833,833,833,833,833,833,833,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,836,836,836,836,836,836,836,836, +724, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, +834,834,834,834,834,834,834,834,834,834,834,834,835,835,835,461, /* block 98 */ -832,832,832,832,832,832,832,832,832,832,831,831,831,831,831,831, -831,831,831,831,831,831,831,836,831,836,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -831,831,831,831,831,831,831,831,831,831,831,831,723,723,723,723, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,831, +833,833,833,833,833,833,833,833,833,833,832,832,832,832,832,832, +832,832,832,832,832,832,832,837,832,837,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +832,832,832,832,832,832,832,832,832,832,832,832,724,724,724,724, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,832, /* block 99 */ -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,460,460,460,460,460,460,723,723,723,723,831,831,831,831,831, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,832,832,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832,461,461,461,461,461,461,724,724,724,724,832,832,832,832,832, /* block 100 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,723,723, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,723, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,724,724, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,724, /* block 101 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 102 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 103 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,840,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,841,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, /* block 104 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, /* block 105 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,163,163,163, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,163,163,163,163,163,163,163,163,163, +840,840,840,840,840,840,840,840,840,840,840,840,840,163,163,163, 842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, 842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, -842,842,842,842,842,842,842,842,843,843,843,843,843,843,844,845, +842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, +842,842,842,842,842,842,842,163,163,163,163,163,163,163,163,163, +843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843, +843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843, +843,843,843,843,843,843,843,843,844,844,844,844,844,844,845,846, /* block 106 */ -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, /* block 107 */ -846,846,846,846,846,846,846,846,846,846,846,846,847,848,849,849, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -850,850,850,850,850,850,850,850,850,850,846,846,163,163,163,163, +847,847,847,847,847,847,847,847,847,847,847,847,848,849,850,850, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +851,851,851,851,851,851,851,851,851,851,847,847,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -240,241,240,241,240,241,240,241,240,241,851,852,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,852,853,240,241,240,241, 240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,853,246, -248,248,248,854,787,787,787,787,787,787,787,787,855,855,854,856, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,854,246, +248,248,248,855,788,788,788,788,788,788,788,788,856,856,855,857, /* block 108 */ 240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,857,857,787,787, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,859,859,859,859,859,859,859,859,859,859, -860,860,861,862,863,863,863,862,163,163,163,163,163,163,163,163, +240,241,240,241,240,241,240,241,240,241,240,241,858,858,788,788, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,860,860,860,860,860,860,860,860,860,860, +861,861,862,863,864,864,864,863,163,163,163,163,163,163,163,163, /* block 109 */ -864,864,864,864,864,864,864,864, 46, 46, 46, 46, 46, 46, 46, 46, +865,865,865,865,865,865,865,865, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,149,149,149,149,149,149,149,149,149, 46, 46, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 70, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, -644, 70, 70, 70, 70, 70, 70, 70, 70, 65, 66, 65, 66,865, 65, 66, +645, 70, 70, 70, 70, 70, 70, 70, 70, 65, 66, 65, 66,866, 65, 66, /* block 110 */ - 65, 66, 65, 66, 65, 66, 65, 66,149,866,866, 65, 66,867, 70, 92, - 65, 66, 65, 66,868, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,869,870,871,872,869, 70, -873,874,875,876, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66,877,878,879, 65, 66, 65, 66,163,163,163,163,163, + 65, 66, 65, 66, 65, 66, 65, 66,149,867,867, 65, 66,868, 70, 92, + 65, 66, 65, 66,869, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,870,871,872,873,870, 70, +874,875,876,877, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66,878,879,880, 65, 66, 65, 66,163,163,163,163,163, 65, 66,163, 70,163, 70, 65, 66, 65, 66,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,880,880,880, 65, 66, 92,147,147, 70, 92, 92, 92, 92, 92, +163,163,645,645,645, 65, 66, 92,147,147, 70, 92, 92, 92, 92, 92, /* block 111 */ 881,881,882,881,881,881,883,881,881,881,881,882,881,881,881,881, @@ -3522,8 +3536,8 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 908,908,908,908,908,908,908,908,908,908,908,908,908,908,908,908, 908,908,908,908,908,908,908,909,909,909,909,909,909,909,909,909, 909,909,910,911,163,163,163,163,163,163,163,163,163,163,163,912, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,163,163,163, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,163,163,163, /* block 114 */ 913,913,913,914,915,915,915,915,915,915,915,915,915,915,915,915, @@ -3532,8 +3546,8 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 915,915,915,916,914,914,913,913,913,913,914,914,913,913,914,914, 917,918,918,918,918,918,918,919,920,920,918,918,918,918,163,921, 922,922,922,922,922,922,922,922,922,922,163,163,163,163,918,918, -461,461,461,461,461,471,923,461,461,461,461,461,461,461,461,461, -472,472,472,472,472,472,472,472,472,472,461,461,461,461,461,163, +462,462,462,462,462,472,923,462,462,462,462,462,462,462,462,462, +473,473,473,473,473,473,473,473,473,473,462,462,462,462,462,163, /* block 115 */ 924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, @@ -3542,8 +3556,8 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 926,925,925,926,926,925,925,163,163,163,163,163,163,163,163,163, 924,924,924,925,924,924,924,924,924,924,924,924,925,926,163,163, 927,927,927,927,927,927,927,927,927,927,163,163,928,929,929,929, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -923,461,461,461,461,461,461,473,473,473,461,470,471,470,461,461, +462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, +923,462,462,462,462,462,462,474,474,474,462,471,472,471,462,462, /* block 116 */ 930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, @@ -3556,159 +3570,159 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 941,941,938,942,942,939,943,163,163,163,163,163,163,163,163,163, /* block 117 */ -163,483,483,483,483,483,483,163,163,483,483,483,483,483,483,163, -163,483,483,483,483,483,483,163,163,163,163,163,163,163,163,163, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163, +163,484,484,484,484,484,484,163,163,484,484,484,484,484,484,163, +163,484,484,484,484,484,484,163,163,163,163,163,163,163,163,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,944, 70, 70, 70, 70, 70, 70, 70,866,147,147,147,147, - 70, 70, 70, 70, 70,221, 70, 70, 70,945, 46, 46,163,163,163,163, -946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946, + 70, 70, 70,944, 70, 70, 70, 70, 70, 70, 70,867,147,147,147,147, + 70, 70, 70, 70, 70,221, 70, 70, 70,147, 46, 46,163,163,163,163, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, /* block 118 */ -946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946, -946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946, -946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946, -946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, 938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, 938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, -938,938,938,939,939,940,939,939,940,939,939,941,947,943,163,163, -948,948,948,948,948,948,948,948,948,948,163,163,163,163,163,163, +938,938,938,939,939,940,939,939,940,939,939,941,946,943,163,163, +947,947,947,947,947,947,947,947,947,947,163,163,163,163,163,163, /* block 119 */ -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 120 */ -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, /* block 121 */ -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 122 */ -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, /* block 123 */ -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 124 */ -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, /* block 125 */ -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 126 */ -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,163,163,163,163,163,163,163,163,163,163,163,163, -481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, -481,481,481,481,481,481,481,163,163,163,163,482,482,482,482,482, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,163,163,163,163,163,163,163,163,163,163,163,163, 482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,163,163,163,163, +482,482,482,482,482,482,482,163,163,163,163,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,163,163,163,163, /* block 127 */ -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, /* block 128 */ -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, /* block 129 */ -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, /* block 130 */ -953,953,953,953,953,953,953,953,953,953,953,953,953,953,838,838, -953,838,953,838,838,953,953,953,953,953,953,953,953,953,953,838, -953,838,953,838,838,953,953,838,838,838,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,163,163, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,839,839, +952,839,952,839,839,952,952,952,952,952,952,952,952,952,952,839, +952,839,952,839,839,952,952,839,839,839,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,163,163, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, /* block 131 */ -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,163,163,163,163,163,163, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 132 */ -652,652,652,652,652,652,652,163,163,163,163,163,163,163,163,163, +653,653,653,653,653,653,653,163,163,163,163,163,163,163,163,163, 163,163,163,257,257,257,257,257,163,163,163,163,163,270,265,270, -270,270,270,270,270,270,270,270,270,954,270,270,270,270,270,270, +270,270,270,270,270,270,270,270,270,953,270,270,270,270,270,270, 270,270,270,270,270,270,270,262,270,270,270,270,270,262,270,262, 270,270,262,270,270,262,270,270,270,270,270,270,270,270,270,270, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, @@ -3731,8 +3745,8 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,955,955, -955,955,955,955,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,954,954, +954,954,954,954,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, /* block 135 */ @@ -3749,7 +3763,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,956,957, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,955,956, 280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, @@ -3761,19 +3775,19 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,302,302,302,302,302,302,302,280, -958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, -958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, -286,286,959,286,286,286,286,286,286,286,955,955,277,960,280,280, +957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957, +957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957, +286,286,958,286,286,286,286,286,286,286,954,954,277,959,280,280, /* block 138 */ -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,962, -963,963,963,964,963,963,963,965,966,963,163,163,163,163,163,163, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,855,855, -963,967,967,700,700,965,966,965,966,965,966,965,966,965,966,965, -966,968,969,968,969,798,798,965,966,963,963,963,963,700,700,700, -970,166,971,163,166,972,973,973,967,974,975,974,975,974,975,976, -963,977,713,978,979,979,715,163,977,431,976,963,163,163,163,163, -955,286,955,286,955,302,955,286,955,286,955,286,955,286,955,286, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,961, +962,962,962,963,962,962,962,964,965,962,163,163,163,163,163,163, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,856,856, +962,966,966,701,701,964,965,964,965,964,965,964,965,964,965,964, +965,967,968,967,968,799,799,964,965,962,962,962,962,701,701,701, +969,166,970,163,166,971,972,972,966,973,974,973,974,973,974,975, +962,976,714,977,978,978,716,163,976,430,975,962,163,163,163,163, +954,286,954,286,954,302,954,286,954,286,954,286,954,286,954,286, /* block 139 */ 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, @@ -3786,64 +3800,64 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 286,286,286,286,286,286,286,286,286,286,286,286,286,302,302, 51, /* block 140 */ -163,973,980,976,431,976,963,981,974,975,963,713,970,982,971,983, -984,984,984,984,984,984,984,984,984,984,972,166,979,715,979,973, -963,985,985,985,985,985,985, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,974,977,975,986,700, - 46,987,987,987,987,987,987, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,974,715,975,715,974, -975,988,989,990,991,825,824,824,824,824,824,824,824,824,824,824, -826,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +163,972,979,975,430,975,962,980,973,974,962,714,969,981,970,982, +983,983,983,983,983,983,983,983,983,983,971,166,978,716,978,972, +962,984,984,984,984,984,984, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,973,976,974,985,701, + 46,986,986,986,986,986,986, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,973,716,974,716,973, +974,987,988,989,990,826,825,825,825,825,825,825,825,825,825,825, +827,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, /* block 141 */ -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,992,992, -830,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,163, -163,163,829,829,829,829,829,829,163,163,829,829,829,829,829,829, -163,163,829,829,829,829,829,829,163,163,829,829,829,163,163,163, -431,431,715, 46,723,431,431,163,723,715,715,715,715,723,723,163, -707,707,707,707,707,707,707,707,707,993,993,993,723,723,958,958, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,991,991, +831,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,163, +163,163,830,830,830,830,830,830,163,163,830,830,830,830,830,830, +163,163,830,830,830,830,830,830,163,163,830,830,830,163,163,163, +430,430,716, 46,724,430,430,163,724,716,716,716,716,724,724,163, +708,708,708,708,708,708,708,708,708,992,992,992,724,724,957,957, /* block 142 */ -994,994,994,994,994,994,994,994,994,994,994,994,163,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,163,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,163,994,994,163,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,163,163, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,163,163, +993,993,993,993,993,993,993,993,993,993,993,993,163,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,163,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,163,993,993,163,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,163,163, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 143 */ -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,163,163,163,163,163, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,163,163,163,163,163, /* block 144 */ -995,996,997,163,163,163,163,998,998,998,998,998,998,998,998,998, -998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998, -998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998, -998,998,998,998,163,163,163,999,999,999,999,999,999,999,999,999, -1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000, -1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000, -1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000, -1000,1000,1000,1000,1000,1001,1001,1001,1001,1002,1002,1002,1002,1002,1002,1002, +994,995,996,163,163,163,163,997,997,997,997,997,997,997,997,997, +997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, +997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, +997,997,997,997,163,163,163,998,998,998,998,998,998,998,998,998, +999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, +999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, +999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, +999,999,999,999,999,1000,1000,1000,1000,1001,1001,1001,1001,1001,1001,1001, /* block 145 */ -1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1001,1001,1002,1003,1003,163, -723,723,723,723,723,723,723,723,723,723,723,723,723,163,163,163, -1002,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1000,1000,1001,1002,1002,163, +724,724,724,724,724,724,724,724,724,724,724,724,724,163,163,163, +1001,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,158,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,158,163,163, /* block 146 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, @@ -3856,97 +3870,97 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 147 */ +1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003, +1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,163,163,163, 1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, -1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,163,163,163, -1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005, -1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005, -1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005, -1005,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1006,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007, -1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,163,163,163,163, +1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, +1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, +1004,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1005,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006, +1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,163,163,163,163, /* block 148 */ -1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008, -1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008, -1009,1009,1009,1009,163,163,163,163,163,163,163,163,163,1008,1008,1008, -1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010, -1010,1011,1010,1010,1010,1010,1010,1010,1010,1010,1011,163,163,163,163,163, -1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012, -1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012, -1012,1012,1012,1012,1012,1012,1013,1013,1013,1013,1013,163,163,163,163,163, +1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007, +1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007, +1008,1008,1008,1008,163,163,163,163,163,163,163,163,163,1007,1007,1007, +1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009, +1009,1010,1009,1009,1009,1009,1009,1009,1009,1009,1010,163,163,163,163,163, +1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, +1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, +1011,1011,1011,1011,1011,1011,1012,1012,1012,1012,1012,163,163,163,163,163, /* block 149 */ -1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014, -1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,163,1015, -1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016, -1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016, -1016,1016,1016,1016,163,163,163,163,1016,1016,1016,1016,1016,1016,1016,1016, -1017,1018,1018,1018,1018,1018,163,163,163,163,163,163,163,163,163,163, +1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013, +1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,163,1014, +1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015, +1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015, +1015,1015,1015,1015,163,163,163,163,1015,1015,1015,1015,1015,1015,1015,1015, +1016,1017,1017,1017,1017,1017,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 150 */ +1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, +1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, +1018,1018,1018,1018,1018,1018,1018,1018,1019,1019,1019,1019,1019,1019,1019,1019, 1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019, 1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019, -1019,1019,1019,1019,1019,1019,1019,1019,1020,1020,1020,1020,1020,1020,1020,1020, 1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, 1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, -1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021, -1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021, -1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021, +1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, /* block 151 */ -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,163,163, -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,163,163,163,163,163,163, +1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021, +1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,163,163, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,163,163,163,163,163,163, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,163,163,163,163,1024,1024,1024,1024,1024,1024,1024,1024, 1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,163,163,163,163,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,163,163,163,163, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,163,163,163,163, /* block 152 */ +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,163,163,163,163,163,163,163,163, 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, -1026,1026,1026,1026,1026,1026,1026,1026,163,163,163,163,163,163,163,163, -1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027, -1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027, -1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027, -1027,1027,1027,1027,163,163,163,163,163,163,163,163,163,163,163,1028, -1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,163,1029,1029,1029,1029, +1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, +1026,1026,1026,1026,163,163,163,163,163,163,163,163,163,163,163,1027, +1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,163,1028,1028,1028,1028, /* block 153 */ -1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,163,1029,1029,1029,1029, -1029,1029,1029,163,1029,1029,163,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,163,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,163,1030,1030,1030,1030,1030,1030,1030,163,1030,1030,163,163,163, +1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,163,1028,1028,1028,1028, +1028,1028,1028,163,1028,1028,163,1029,1029,1029,1029,1029,1029,1029,1029,1029, +1029,1029,163,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029, +1029,1029,163,1029,1029,1029,1029,1029,1029,1029,163,1029,1029,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 154 */ -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, /* block 155 */ -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,163,163,163,163,163,163,163,163,163, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,163,163,163,163,163,163,163,163,163,163, -1031,1031,1031,1031,1031,1031,1031,1031,163,163,163,163,163,163,163,163, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163,163, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163,163,163, +1030,1030,1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 156 */ -147,1032,1032,147,147,147,163,147,147,147,147,147,147,147,147,147, +147,1031,1031,147,147,147,163,147,147,147,147,147,147,147,147,147, 147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, 147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, 147,163,147,147,147,147,147,147,147,147,147,163,163,163,163,163, @@ -3956,79 +3970,79 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 157 */ -1033,1033,1033,1033,1033,1033,262,262,1033,262,1033,1033,1033,1033,1033,1033, +1032,1032,1032,1032,1032,1032,262,262,1032,262,1032,1032,1032,1032,1032,1032, +1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, +1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, +1032,1032,1032,1032,1032,1032,262,1032,1032,262,262,262,1032,262,262,1032, 1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033, -1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033, -1033,1033,1033,1033,1033,1033,262,1033,1033,262,262,262,1033,262,262,1033, -1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034, -1034,1034,1034,1034,1034,1034,262,1035,1036,1036,1036,1036,1036,1036,1036,1036, -1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037, -1037,1037,1037,1037,1037,1037,1037,1038,1038,1039,1039,1039,1039,1039,1039,1039, +1033,1033,1033,1033,1033,1033,262,1034,1035,1035,1035,1035,1035,1035,1035,1035, +1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036, +1036,1036,1036,1036,1036,1036,1036,1037,1037,1038,1038,1038,1038,1038,1038,1038, /* block 158 */ -1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040, -1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,262, -262,262,262,262,262,262,262,1041,1041,1041,1041,1041,1041,1041,1041,1041, +1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039, +1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,262, +262,262,262,262,262,262,262,1040,1040,1040,1040,1040,1040,1040,1040,1040, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042, -1042,1042,1042,262,1042,1042,262,262,262,262,262,1043,1043,1043,1043,1043, +1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041, +1041,1041,1041,262,1041,1041,262,262,262,262,262,1042,1042,1042,1042,1042, /* block 159 */ -1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044, -1044,1044,1044,1044,1044,1044,1045,1045,1045,1045,1045,1045,262,262,262,1046, -1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047, -1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,262,262,262,262,262,1048, +1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043, +1043,1043,1043,1043,1043,1043,1044,1044,1044,1044,1044,1044,262,262,262,1045, +1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046, +1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,262,262,262,262,262,1047, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 160 */ +1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048, +1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048, 1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049, -1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049, +1049,1049,1049,1049,1049,1049,1049,1049,262,262,262,262,1050,1050,1049,1049, +1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, +262,262,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, +1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, 1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, -1050,1050,1050,1050,1050,1050,1050,1050,262,262,262,262,1051,1051,1050,1050, -1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, -262,262,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, -1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, -1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, /* block 161 */ -1052,1053,1053,1053,262,1053,1053,262,262,262,262,262,1053,1053,1053,1053, -1052,1052,1052,1052,262,1052,1052,1052,262,1052,1052,1052,1052,1052,1052,1052, -1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052, -1052,1052,1052,1052,1052,1052,262,262,1054,1054,1054,262,262,262,262,1055, -1056,1056,1056,1056,1056,1056,1056,1056,1056,262,262,262,262,262,262,262, -1057,1057,1057,1057,1057,1057,1058,1058,1057,262,262,262,262,262,262,262, -1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059, -1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1060,1060,1061, +1051,1052,1052,1052,262,1052,1052,262,262,262,262,262,1052,1052,1052,1052, +1051,1051,1051,1051,262,1051,1051,1051,262,1051,1051,1051,1051,1051,1051,1051, +1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, +1051,1051,1051,1051,1051,1051,262,262,1053,1053,1053,262,262,262,262,1054, +1055,1055,1055,1055,1055,1055,1055,1055,1055,262,262,262,262,262,262,262, +1056,1056,1056,1056,1056,1056,1057,1057,1056,262,262,262,262,262,262,262, +1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058, +1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1059,1059,1060, /* block 162 */ -1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062, -1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1063,1063,1063, +1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061, +1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1062,1062,1062, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1064,1064,1064,1064,1064,1064,1064,1064,1065,1064,1064,1064,1064,1064,1064,1064, -1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064, -1064,1064,1064,1064,1064,1066,1066,262,262,262,262,1067,1067,1067,1067,1067, -1068,1068,1069,1068,1068,1068,1070,262,262,262,262,262,262,262,262,262, +1063,1063,1063,1063,1063,1063,1063,1063,1064,1063,1063,1063,1063,1063,1063,1063, +1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063, +1063,1063,1063,1063,1063,1065,1065,262,262,262,262,1066,1066,1066,1066,1066, +1067,1067,1068,1067,1067,1067,1069,262,262,262,262,262,262,262,262,262, /* block 163 */ -1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071, -1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071, -1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071, -1071,1071,1071,1071,1071,1071,262,262,262,1072,1073,1073,1073,1073,1073,1073, -1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074, -1074,1074,1074,1074,1074,1074,262,262,1075,1075,1075,1075,1075,1075,1075,1075, -1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076, -1076,1076,1076,262,262,262,262,262,1077,1077,1077,1077,1077,1077,1077,1077, +1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, +1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, +1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, +1070,1070,1070,1070,1070,1070,262,262,262,1071,1072,1072,1072,1072,1072,1072, +1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073, +1073,1073,1073,1073,1073,1073,262,262,1074,1074,1074,1074,1074,1074,1074,1074, +1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075, +1075,1075,1075,262,262,262,262,262,1076,1076,1076,1076,1076,1076,1076,1076, /* block 164 */ -1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078, -1078,1078,262,262,262,262,262,262,262,1079,1079,1079,1079,262,262,262, -262,262,262,262,262,262,262,262,262,1080,1080,1080,1080,1080,1080,1080, +1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, +1077,1077,262,262,262,262,262,262,262,1078,1078,1078,1078,262,262,262, +262,262,262,262,262,262,262,262,262,1079,1079,1079,1079,1079,1079,1079, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, @@ -4036,30 +4050,30 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 165 */ -1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, -1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, -1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, -1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, -1081,1081,1081,1081,1081,1081,1081,1081,1081,262,262,262,262,262,262,262, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 166 */ +1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, +1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, +1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, +1081,1081,1081,262,262,262,262,262,262,262,262,262,262,262,262,262, 1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, 1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, 1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, -1082,1082,1082,262,262,262,262,262,262,262,262,262,262,262,262,262, -1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083, -1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083, -1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083, -1083,1083,1083,262,262,262,262,262,262,262,1084,1084,1084,1084,1084,1084, +1082,1082,1082,262,262,262,262,262,262,262,1083,1083,1083,1083,1083,1083, /* block 167 */ -1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085, -1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085, -1085,1085,1086,1086,1087,1087,1087,1087,302,302,302,302,302,302,302,302, -1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,302,302,302,302,302,302, +1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084, +1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084, +1084,1084,1085,1085,1086,1086,1086,1086,302,302,302,302,302,302,302,302, +1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,302,302,302,302,302,302, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, @@ -4082,174 +4096,174 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, -1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,262, +1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088, +1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,262, /* block 170 */ -1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090, -1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090, -1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,262,1091,1091,1092,262,262, -1090,1090,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, +1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, +1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,262,1090,1090,1091,262,262, +1089,1089,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,291,291,291, /* block 171 */ -1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093, -1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1094,1094,1094, -1094,1094,1094,1094,1094,1094,1094,1093,262,262,262,262,262,262,262,262, -1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095, -1095,1095,1095,1095,1095,1095,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096, -1096,1097,1097,1097,1097,1098,1098,1098,1098,1098,302,302,302,302,302,302, +1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092, +1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1093,1093,1093, +1093,1093,1093,1093,1093,1093,1093,1092,262,262,262,262,262,262,262,262, +1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094, +1094,1094,1094,1094,1094,1094,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095, +1095,1096,1096,1096,1096,1097,1097,1097,1097,1097,302,302,302,302,302,302, 302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099, +1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098, /* block 172 */ -1099,1099,1100,1100,1100,1100,1101,1101,1101,1101,262,262,262,262,262,262, +1098,1098,1099,1099,1099,1099,1100,1100,1100,1100,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102, -1102,1102,1102,1102,1102,1103,1103,1103,1103,1103,1103,1103,262,262,262,262, +1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101, +1101,1101,1101,1101,1101,1102,1102,1102,1102,1102,1102,1102,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104, -1104,1104,1104,1104,1104,1104,1104,262,262,262,262,262,262,262,262,262, +1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103, +1103,1103,1103,1103,1103,1103,1103,262,262,262,262,262,262,262,262,262, /* block 173 */ -1105,1106,1105,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1106,1106,1106,1106,1106,1106,1106,1106, -1106,1106,1106,1106,1106,1106,1108,1109,1109,1110,1110,1110,1110,1110,163,163, -163,163,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111, -1111,1111,1111,1111,1111,1111,1112,1112,1112,1112,1112,1112,1112,1112,1112,1112, -1108,1107,1107,1106,1106,1107,163,163,163,163,163,163,163,163,163,1113, +1104,1105,1104,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,1106,1106,1106,1106,1105,1105,1105,1105,1105,1105,1105,1105, +1105,1105,1105,1105,1105,1105,1107,1108,1108,1109,1109,1109,1109,1109,163,163, +163,163,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110, +1110,1110,1110,1110,1110,1110,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111, +1107,1106,1106,1105,1105,1106,163,163,163,163,163,163,163,163,163,1112, /* block 174 */ -1114,1114,1115,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116, -1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116, -1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116, -1115,1115,1115,1117,1117,1117,1117,1115,1115,1118,1119,1120,1120,1121,1122,1122, -1122,1122,1117,163,163,163,163,163,163,163,163,163,163,1121,163,163, -1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123, -1123,1123,1123,1123,1123,1123,1123,1123,1123,163,163,163,163,163,163,163, -1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,163,163,163,163,163,163, +1113,1113,1114,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, +1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, +1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, +1114,1114,1114,1113,1113,1113,1113,1114,1114,1116,1117,1118,1118,1119,1120,1120, +1120,1120,1113,163,163,163,163,163,163,163,163,163,163,1119,163,163, +1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121, +1121,1121,1121,1121,1121,1121,1121,1121,1121,163,163,163,163,163,163,163, +1122,1122,1122,1122,1122,1122,1122,1122,1122,1122,163,163,163,163,163,163, /* block 175 */ -1125,1125,1125,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126, -1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126, -1126,1126,1126,1126,1126,1126,1126,1125,1125,1125,1125,1125,1127,1125,1125,1125, -1125,1125,1125,1128,1128,163,1129,1129,1129,1129,1129,1129,1129,1129,1129,1129, -1130,1131,1131,1131,1126,1127,1127,1126,163,163,163,163,163,163,163,163, -1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132, -1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132, -1132,1132,1132,1133,1134,1134,1132,163,163,163,163,163,163,163,163,163, +1123,1123,1123,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124, +1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124, +1124,1124,1124,1124,1124,1124,1124,1123,1123,1123,1123,1123,1125,1123,1123,1123, +1123,1123,1123,1126,1126,163,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, +1128,1129,1129,1129,1124,1125,1125,1124,163,163,163,163,163,163,163,163, +1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130, +1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130, +1130,1130,1130,1131,1132,1132,1130,163,163,163,163,163,163,163,163,163, /* block 176 */ -1135,1135,1136,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137, -1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137, -1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137, -1137,1137,1137,1136,1136,1136,1135,1135,1135,1135,1135,1135,1135,1135,1135,1136, -1138,1137,1139,1139,1137,1140,1140,1141,1141,1142,1143,1143,1143,1140,1136,1135, -1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1137,1141,1137,1141,1140,1140, -163,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145, -1145,1145,1145,1145,1145,163,163,163,163,163,163,163,163,163,163,163, +1133,1133,1134,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, +1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, +1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, +1135,1135,1135,1134,1134,1134,1133,1133,1133,1133,1133,1133,1133,1133,1133,1134, +1136,1135,1137,1137,1135,1138,1138,1139,1139,1140,1141,1141,1141,1138,1134,1133, +1142,1142,1142,1142,1142,1142,1142,1142,1142,1142,1135,1139,1135,1139,1138,1138, +163,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143, +1143,1143,1143,1143,1143,163,163,163,163,163,163,163,163,163,163,163, /* block 177 */ -1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146, -1146,1146,163,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146, -1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1147,1147,1147,1148, -1148,1148,1147,1147,1148,1149,1150,1148,1151,1151,1152,1151,1151,1153,1148,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144, +1144,1144,163,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144, +1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1145,1145,1145,1146, +1146,1146,1145,1145,1146,1147,1148,1146,1149,1149,1150,1149,1149,1151,1146,1144, +1144,1146,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 178 */ -1154,1154,1154,1154,1154,1154,1154,163,1154,163,1154,1154,1154,1154,163,1154, -1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,163,1154, -1154,1154,1154,1154,1154,1154,1154,1154,1154,1155,163,163,163,163,163,163, -1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156, -1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156, -1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1157, -1158,1158,1158,1157,1157,1157,1157,1157,1157,1159,1160,163,163,163,163,163, -1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,163,163,163,163,163,163, +1152,1152,1152,1152,1152,1152,1152,163,1152,163,1152,1152,1152,1152,163,1152, +1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,163,1152, +1152,1152,1152,1152,1152,1152,1152,1152,1152,1153,163,163,163,163,163,163, +1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154, +1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154, +1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1155, +1156,1156,1156,1155,1155,1155,1155,1155,1155,1157,1158,163,163,163,163,163, +1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,163,163,163,163,163,163, /* block 179 */ -1162,1163,1164,1165,163,1166,1166,1166,1166,1166,1166,1166,1166,163,163,1166, -1166,163,163,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166, -1166,1166,1166,1166,1166,1166,1166,1166,1166,163,1166,1166,1166,1166,1166,1166, -1166,163,1166,1166,163,1166,1166,1166,1166,1166,163,1167,1168,1166,1169,1164, -1162,1164,1164,1164,1164,163,163,1164,1164,163,163,1164,1164,1170,163,163, -1166,163,163,163,163,163,163,1169,163,163,163,163,163,1171,1166,1166, -1166,1166,1164,1164,163,163,1172,1172,1172,1172,1172,1172,1172,163,163,163, -1172,1172,1172,1172,1172,163,163,163,163,163,163,163,163,163,163,163, +1160,1161,1162,1163,163,1164,1164,1164,1164,1164,1164,1164,1164,163,163,1164, +1164,163,163,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164, +1164,1164,1164,1164,1164,1164,1164,1164,1164,163,1164,1164,1164,1164,1164,1164, +1164,163,1164,1164,163,1164,1164,1164,1164,1164,163,1165,1166,1164,1167,1162, +1160,1162,1162,1162,1162,163,163,1162,1162,163,163,1162,1162,1168,163,163, +1164,163,163,163,163,163,163,1167,163,163,163,163,163,1169,1164,1164, +1164,1164,1162,1162,163,163,1170,1170,1170,1170,1170,1170,1170,163,163,163, +1170,1170,1170,1170,1170,163,163,163,163,163,163,163,163,163,163,163, /* block 180 */ -1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173, -1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173, -1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173, -1173,1173,1173,1173,1173,1174,1174,1174,1175,1175,1175,1175,1175,1175,1175,1175, -1174,1174,1176,1175,1175,1174,1177,1173,1173,1173,1173,1178,1178,1179,1180,1180, -1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1179,1179,163,1180,1182,1173, -1173,1173,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, +1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, +1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, +1171,1171,1171,1171,1171,1172,1172,1172,1173,1173,1173,1173,1173,1173,1173,1173, +1172,1172,1174,1173,1173,1172,1175,1171,1171,1171,1171,1176,1176,1177,1178,1178, +1179,1179,1179,1179,1179,1179,1179,1179,1179,1179,1177,1177,163,1178,1180,1171, +1171,1171,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 181 */ -1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183, -1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183, -1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183, -1184,1185,1185,1186,1186,1186,1186,1186,1186,1185,1186,1185,1185,1184,1185,1186, -1186,1185,1187,1188,1183,1183,1189,1183,163,163,163,163,163,163,163,163, -1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,163,163,163,163,163,163, +1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, +1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, +1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, +1182,1183,1183,1184,1184,1184,1184,1184,1184,1183,1184,1183,1183,1182,1183,1184, +1184,1183,1185,1186,1181,1181,1187,1181,163,163,163,163,163,163,163,163, +1188,1188,1188,1188,1188,1188,1188,1188,1188,1188,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 182 */ -1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191, -1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191, -1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1192, -1193,1193,1194,1194,1194,1194,163,163,1193,1193,1193,1193,1194,1194,1193,1195, -1196,1197,1198,1198,1199,1199,1200,1200,1200,1198,1198,1198,1198,1198,1198,1198, -1198,1198,1198,1198,1198,1198,1198,1198,1191,1191,1191,1191,1194,1194,163,163, +1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189, +1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189, +1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1190, +1191,1191,1192,1192,1192,1192,163,163,1191,1191,1191,1191,1192,1192,1191,1193, +1194,1195,1196,1196,1197,1197,1198,1198,1198,1196,1196,1196,1196,1196,1196,1196, +1196,1196,1196,1196,1196,1196,1196,1196,1189,1189,1189,1189,1192,1192,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 183 */ -1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201, -1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201, -1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201, -1202,1202,1202,1203,1203,1203,1203,1203,1203,1203,1203,1202,1202,1203,1202,1204, -1203,1205,1205,1206,1201,163,163,163,163,163,163,163,163,163,163,163, -1207,1207,1207,1207,1207,1207,1207,1207,1207,1207,163,163,163,163,163,163, -530,530,530,530,530,530,530,530,530,530,530,530,530,163,163,163, +1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, +1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, +1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, +1200,1200,1200,1201,1201,1201,1201,1201,1201,1201,1201,1200,1200,1201,1200,1202, +1201,1203,1203,1204,1199,163,163,163,163,163,163,163,163,163,163,163, +1205,1205,1205,1205,1205,1205,1205,1205,1205,1205,163,163,163,163,163,163, +531,531,531,531,531,531,531,531,531,531,531,531,531,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 184 */ -1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208, -1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208, -1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1209,1210,1209,1210,1210, -1209,1209,1209,1209,1209,1209,1211,1212,1208,1213,163,163,163,163,163,163, -1214,1214,1214,1214,1214,1214,1214,1214,1214,1214,163,163,163,163,163,163, +1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206, +1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206, +1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1207,1208,1207,1208,1208, +1207,1207,1207,1207,1207,1207,1209,1210,1206,1211,163,163,163,163,163,163, +1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 185 */ -1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215, -1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,163,163,1216,1216,1216, -1217,1217,1216,1216,1216,1216,1218,1216,1216,1216,1216,1219,163,163,163,163, -1220,1220,1220,1220,1220,1220,1220,1220,1220,1220,1221,1221,1222,1222,1222,1223, -1215,1215,1215,1215,1215,1215,1215,163,163,163,163,163,163,163,163,163, +1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213, +1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,163,163,1214,1214,1214, +1215,1215,1214,1214,1214,1214,1216,1214,1214,1214,1214,1217,163,163,163,163, +1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1219,1219,1220,1220,1220,1221, +1213,1213,1213,1213,1213,1213,1213,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 186 */ -1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224, -1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224, -1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1225,1225,1225,1226, -1226,1226,1226,1226,1226,1226,1226,1226,1225,1227,1228,1229,163,163,163,163, +1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222, +1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222, +1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1223,1223,1223,1224, +1224,1224,1224,1224,1224,1224,1224,1224,1223,1225,1226,1227,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, @@ -4258,266 +4272,266 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ /* block 187 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230, -1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230, -1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231, -1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231, -1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1233,1233,1233,1233,1233,1233, -1233,1233,1233,163,163,163,163,163,163,163,163,163,163,163,163,1234, +1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228, +1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228, +1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229, +1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229, +1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1231,1231,1231,1231,1231,1231, +1231,1231,1231,163,163,163,163,163,163,163,163,163,163,163,163,1232, /* block 188 */ -1235,1235,1235,1235,1235,1235,1235,163,163,1235,163,163,1235,1235,1235,1235, -1235,1235,1235,1235,163,1235,1235,163,1235,1235,1235,1235,1235,1235,1235,1235, -1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235, -1236,1237,1237,1237,1237,1237,163,1237,1237,163,163,1238,1238,1239,1240,1241, -1237,1241,1237,1242,1243,1244,1243,163,163,163,163,163,163,163,163,163, -1245,1245,1245,1245,1245,1245,1245,1245,1245,1245,163,163,163,163,163,163, +1233,1233,1233,1233,1233,1233,1233,163,163,1233,163,163,1233,1233,1233,1233, +1233,1233,1233,1233,163,1233,1233,163,1233,1233,1233,1233,1233,1233,1233,1233, +1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233, +1234,1235,1235,1235,1235,1235,163,1235,1235,163,163,1236,1236,1237,1238,1239, +1235,1239,1235,1240,1241,1242,1241,163,163,163,163,163,163,163,163,163, +1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 189 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1246,1246,1246,1246,1246,1246,1246,1246,163,163,1246,1246,1246,1246,1246,1246, -1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246, -1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246, -1246,1247,1247,1247,1248,1248,1248,1248,163,163,1248,1248,1247,1247,1247,1247, -1249,1246,1250,1246,1247,163,163,163,163,163,163,163,163,163,163,163, +1244,1244,1244,1244,1244,1244,1244,1244,163,163,1244,1244,1244,1244,1244,1244, +1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244, +1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244, +1244,1245,1245,1245,1246,1246,1246,1246,163,163,1246,1246,1245,1245,1245,1245, +1247,1244,1248,1244,1245,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 190 */ -1251,1252,1252,1252,1252,1252,1252,1253,1253,1252,1252,1251,1251,1251,1251,1251, -1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251, -1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251, -1251,1251,1251,1254,1255,1252,1252,1252,1252,1256,1257,1252,1252,1252,1252,1258, -1258,1258,1259,1259,1258,1258,1258,1255,163,163,163,163,163,163,163,163, -1260,1261,1261,1261,1261,1261,1261,1262,1262,1261,1261,1261,1260,1260,1260,1260, -1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260, -1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260, +1249,1250,1250,1250,1250,1250,1250,1251,1251,1250,1250,1249,1249,1249,1249,1249, +1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249, +1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249, +1249,1249,1249,1252,1253,1250,1250,1250,1250,1254,1255,1250,1250,1250,1250,1256, +1256,1256,1257,1257,1256,1256,1256,1253,163,163,163,163,163,163,163,163, +1258,1259,1259,1259,1259,1259,1259,1260,1260,1259,1259,1259,1258,1258,1258,1258, +1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258, +1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258, /* block 191 */ -1260,1260,1260,1260,1263,1263,1263,1263,1263,1263,1261,1261,1261,1261,1261,1261, -1261,1261,1261,1261,1261,1261,1261,1262,1264,1265,1266,1267,1267,1260,1266,1266, -1266,1268,1268,163,163,163,163,163,163,163,163,163,163,163,163,163, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269, -1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269, -1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269, -1269,1269,1269,1269,1269,1269,1269,1269,1269,163,163,163,163,163,163,163, +1258,1258,1258,1258,1261,1261,1261,1261,1261,1261,1259,1259,1259,1259,1259,1259, +1259,1259,1259,1259,1259,1259,1259,1260,1262,1263,1264,1265,1265,1258,1264,1264, +1264,1266,1266,163,163,163,163,163,163,163,163,163,163,163,163,163, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, +1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, +1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, +1267,1267,1267,1267,1267,1267,1267,1267,1267,163,163,163,163,163,163,163, /* block 192 */ -1270,1270,1270,1270,1270,1270,1270,1270,1270,163,1270,1270,1270,1270,1270,1270, -1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270, -1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1271, -1272,1272,1272,1272,1272,1272,1272,163,1272,1272,1272,1272,1272,1272,1271,1273, -1270,1274,1274,1275,1276,1276,163,163,163,163,163,163,163,163,163,163, -1277,1277,1277,1277,1277,1277,1277,1277,1277,1277,1278,1278,1278,1278,1278,1278, -1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,163,163,163, -1279,1280,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281, +343,343,343,343,343,343,343,343,343,343,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 193 */ -1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281, -163,163,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, -1282,1282,1282,1282,1282,1282,1282,1282,163,1283,1282,1282,1282,1282,1282,1282, -1282,1283,1282,1282,1283,1282,1282,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1268,1268,1268,1268,1268,1268,1268,1268,1268,163,1268,1268,1268,1268,1268,1268, +1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268, +1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1269, +1270,1270,1270,1270,1270,1270,1270,163,1270,1270,1270,1270,1270,1270,1269,1271, +1268,1272,1272,1273,1274,1274,163,163,163,163,163,163,163,163,163,163, +1275,1275,1275,1275,1275,1275,1275,1275,1275,1275,1276,1276,1276,1276,1276,1276, +1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,163,163,163, +1277,1278,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279, /* block 194 */ -1284,1284,1284,1284,1284,1284,1284,163,1284,1284,163,1284,1284,1284,1284,1284, -1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284, -1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284, -1284,1285,1285,1285,1285,1285,1285,163,163,163,1285,163,1285,1285,163,1285, -1285,1285,1286,1285,1287,1287,1288,1285,163,163,163,163,163,163,163,163, -1289,1289,1289,1289,1289,1289,1289,1289,1289,1289,163,163,163,163,163,163, -1290,1290,1290,1290,1290,1290,163,1290,1290,163,1290,1290,1290,1290,1290,1290, -1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290, +1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279, +163,163,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280, +1280,1280,1280,1280,1280,1280,1280,1280,163,1281,1280,1280,1280,1280,1280,1280, +1280,1281,1280,1280,1281,1280,1280,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 195 */ -1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1291,1291,1291,1291,1291,163, -1292,1292,163,1291,1291,1292,1291,1293,1290,163,163,163,163,163,163,163, -1294,1294,1294,1294,1294,1294,1294,1294,1294,1294,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1282,1282,1282,1282,1282,1282,1282,163,1282,1282,163,1282,1282,1282,1282,1282, +1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, +1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, +1282,1283,1283,1283,1283,1283,1283,163,163,163,1283,163,1283,1283,163,1283, +1283,1283,1284,1283,1285,1285,1286,1283,163,163,163,163,163,163,163,163, +1287,1287,1287,1287,1287,1287,1287,1287,1287,1287,163,163,163,163,163,163, +1288,1288,1288,1288,1288,1288,163,1288,1288,163,1288,1288,1288,1288,1288,1288, +1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288, /* block 196 */ +1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1289,1289,1289,1289,1289,163, +1290,1290,163,1289,1289,1290,1289,1291,1288,163,163,163,163,163,163,163, +1292,1292,1292,1292,1292,1292,1292,1292,1292,1292,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295, -1295,1295,1295,1296,1296,1297,1297,1298,1298,163,163,163,163,163,163,163, /* block 197 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -842,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299, -388,388,1299,388,1299,390,390,390,390,390,390,390,390,391,391,391, -391,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390, -390,390,163,163,163,163,163,163,163,163,163,163,163,163,163,1300, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293, +1293,1293,1293,1294,1294,1295,1295,1296,1296,163,163,163,163,163,163,163, /* block 198 */ -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, +1297,1297,1298,1299,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1300,163,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1300,1300,1300,1300,1299,1299,1297,1297,1297,1297,1297,163,163,163,1299,1299, +1297,1301,1302,1303,1303,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, +1305,1305,1305,1305,1305,1305,1305,1305,1305,1305,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 199 */ -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +843,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, +388,388,1306,388,1306,390,390,390,390,390,390,390,390,391,391,391, +391,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390, +390,390,163,163,163,163,163,163,163,163,163,163,163,163,163,1307, /* block 200 */ -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,163, -1303,1303,1303,1303,1303,163,163,163,163,163,163,163,163,163,163,163, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, /* block 201 */ -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,163,163,163,163,163,163,163,163,163,163,163,163, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 202 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1305,1305,163,163,163,163,163,163,163,163,163,163,163,163,163, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,163, +1310,1310,1310,1310,1310,163,163,163,163,163,163,163,163,163,163,163, /* block 203 */ -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 204 */ -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,163, -1307,1307,1307,1307,1307,1307,1307,1307,1307,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1312,1312,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 205 */ -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, /* block 206 */ -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314, +1315,1313,1313,1313,1313,1313,1313,1316,1316,1316,1316,1316,1316,1316,1316,1316, +1316,1316,1316,1316,1316,1316,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 207 */ -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, /* block 208 */ -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,163,163,163,163,163,163,163, -1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, -1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,163, -1310,1310,1310,1310,1310,1310,1310,1310,1310,1310,163,163,163,163,1311,1311, -1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 209 */ -1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312, -1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312, -1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312, -1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,163, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,163,163,163,163,163,163, -1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314, -1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,163,163, -1315,1315,1315,1315,1315,1316,163,163,163,163,163,163,163,163,163,163, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, /* block 210 */ -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1318,1318,1318,1318,1318,1318,1318,1319,1319,1320,1321,1321,1322,1322,1322,1322, -1323,1323,1324,1324,1319,1322,163,163,163,163,163,163,163,163,163,163, -1325,1325,1325,1325,1325,1325,1325,1325,1325,1325,163,1326,1326,1326,1326,1326, -1326,1326,163,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,163,163,163,163,163,1317,1317,1317, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,163,163,163,163,163,163,163, +1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318, +1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,163, +1319,1319,1319,1319,1319,1319,1319,1319,1319,1319,163,163,163,163,1320,1320, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, /* block 211 */ -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,163, +1322,1322,1322,1322,1322,1322,1322,1322,1322,1322,163,163,163,163,163,163, +1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323, +1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,163,163, +1324,1324,1324,1324,1324,1325,163,163,163,163,163,163,163,163,163,163, /* block 212 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327, -1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327, -1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328, -1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1327,1327,1327,1327,1327,1327,1327,1328,1328,1329,1330,1330,1331,1331,1331,1331, +1332,1332,1333,1333,1328,1331,163,163,163,163,163,163,163,163,163,163, +1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,163,1335,1335,1335,1335,1335, +1335,1335,163,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1326,1326,1326,1326,1326,1326,1326,1326,163,163,163,163,163,1326,1326,1326, /* block 213 */ -1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329, -1329,1329,1329,1329,1329,1329,1329,1330,1331,1332,1332,163,163,163,163,163, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, @@ -4526,369 +4540,369 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 214 */ -1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333, -1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333, -1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333, -1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333, -1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,163,163,163,163,1334, -1333,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335, -1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335, -1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336, +1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336, +1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337, +1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337, /* block 215 */ -1335,1335,1335,1335,1335,1335,1335,1335,163,163,163,163,163,163,163,1336, -1336,1336,1336,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337, +1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338, +1338,1338,1338,1338,1338,1338,1338,1339,1340,1341,1341,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1338,1339,1340,799,1341,163,163,163,163,163,163,163,163,163,163,163, -1342,1342,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 216 */ -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,163,163,163,163,1343, +1342,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, +1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, +1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, /* block 217 */ -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,163,163,163,163,163,163,163,163, +1344,1344,1344,1344,1344,1344,1344,1344,163,163,163,163,163,163,163,1345, +1345,1345,1345,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1347,1348,1349,800,1350,163,163,163,163,163,163,163,163,163,163,163, +1351,1351,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 218 */ -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, /* block 219 */ -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,163,163,163,163,163,163,163,163, /* block 220 */ -1343,1343,1343,1343,1343,1343,1343,1343,1343,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, /* block 221 */ +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1345,1345,1345,1345,163,1345,1345,1345,1345,1345,1345,1345,163,1345,1345,163, /* block 222 */ -824,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +1352,1352,1352,1352,1352,1352,1352,1352,1352,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 223 */ -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1354,1354,1354,1354,163,1354,1354,1354,1354,1354,1354,1354,163,1354,1354,163, /* block 224 */ -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -824,824,824,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -819,819,819,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,824,824,824,824,163,163,163,163,163,163,163,163, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, +825,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, /* block 225 */ -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, /* block 226 */ -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,163,163,163,163, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +825,825,825,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,820,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +820,820,820,163,163,825,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,825,825,825,825,163,163,163,163,163,163,163,163, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, /* block 227 */ -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,163,163,163, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,163, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, /* block 228 */ -1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,163,163,163,163,163, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,1348,1349,1350,1351, -1352,1352,1352,1352,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,163,163,163,163, /* block 229 */ -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,163,163, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,163,163,163,163,163,163,163,163,163, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163,163,163, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163, /* block 230 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,163,163,163,163,163,163,163,163,163,163,163,163, +1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163,163,163,163,163, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,1357,1358,1359,1360, +1361,1361,1361,1361,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 231 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,163,163, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,163,163,163,163,163,163,163,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, /* block 232 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,163,163,163,163,163,163,163,163,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 233 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,163,163,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,1353,1354,154,154,154,460,460,460,1355,1356,1356, -1356,1356,1356, 51, 51, 51, 51, 51, 51, 51, 51,154,154,154,154,154, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, /* block 234 */ -154,154,154,460,460,154,154,154,154,154,154,154,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,154,154,154,154,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,723,723,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,163,163,163,163,163,163,163,163,163,163, /* block 235 */ -1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002, -1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002, -1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002, -1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002, -1002,1002,1357,1357,1357,1002,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,163,163,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,1362,1363,154,154,154,461,461,461,1364,1365,1365, +1365,1365,1365, 51, 51, 51, 51, 51, 51, 51, 51,154,154,154,154,154, /* block 236 */ +154,154,154,461,461,154,154,154,154,154,154,154,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,154,154,154,154,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,724,724,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835, -835,835,835,835,163,163,163,163,163,163,163,163,163,163,163,163, /* block 237 */ -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,163,163,163,163,163,163,163,163,163, -832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, -832,832,835,835,835,835,835,835,835,163,163,163,163,163,163,163, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1366,1366,1366,1001,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 238 */ -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725, -725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,725,725, -725,725,725,725,725,163,736,736,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836, +836,836,836,836,163,163,163,163,163,163,163,163,163,163,163,163, +836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836, +836,836,836,836,163,163,163,163,163,163,163,163,163,163,163,163, /* block 239 */ -724,724,725,725,725,725,725,725,725,725,736,736,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,724,163,724,724, -163,163,724,163,163,724,724,163,163,724,724,724,724,163,724,724, -724,724,724,724,724,724,725,725,725,725,163,725,163,725,736,736, -725,725,725,725,163,725,725,725,725,725,725,725,725,725,725,725, 724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725, -725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,163,163,163,163,163,163,163,163,163, +833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833, +833,833,836,836,836,836,836,836,836,163,163,163,163,163,163,163, /* block 240 */ -725,725,725,725,724,724,163,724,724,724,724,163,163,724,724,724, -724,724,724,724,724,163,724,724,724,724,724,724,724,163,725,725, -725,725,725,725,725,725,736,736,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,724,724,163,724,724,724,724,163, -724,724,724,724,724,163,724,163,163,163,724,724,724,724,724,724, -724,163,725,725,725,725,725,725,725,725,736,736,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,726,726, +726,726,726,726,726,163,737,737,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, /* block 241 */ -724,724,724,724,724,724,725,725,725,725,725,725,725,725,736,736, +725,725,726,726,726,726,726,726,726,726,737,737,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,725,163,725,725, +163,163,725,163,163,725,725,163,163,725,725,725,725,163,725,725, +725,725,725,725,725,725,726,726,726,726,163,726,163,726,737,737, +726,726,726,726,163,726,726,726,726,726,726,726,726,726,726,726, 725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725, -725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,725,725, -725,725,725,725,725,725,736,736,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, /* block 242 */ -725,725,725,725,725,725,725,725,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,725,725,725,725,725,725,725,725,736,736,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,725,725,725,725,725,725,725,725,736,736, +726,726,726,726,725,725,163,725,725,725,725,163,163,725,725,725, +725,725,725,725,725,163,725,725,725,725,725,725,725,163,726,726, +726,726,726,726,726,726,737,737,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,725,725,163,725,725,725,725,163, +725,725,725,725,725,163,725,163,163,163,725,725,725,725,725,725, +725,163,726,726,726,726,726,726,726,726,737,737,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,725,725,725,725, 725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 243 */ -724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725, -725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,163,163,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,1358,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,715,725,725,725,725, -725,725,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,1358,725,725,725,725, +725,725,725,725,725,725,726,726,726,726,726,726,726,726,737,737, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,726,726, +726,726,726,726,726,726,737,737,726,726,726,726,726,726,726,726, /* block 244 */ +726,726,726,726,726,726,726,726,725,725,725,725,725,725,725,725, 725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,715,725,725,725,725,725,725,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,1358,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,715, -725,725,725,725,725,725,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,1358, +725,725,726,726,726,726,726,726,726,726,737,737,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,726,726,726,726,726,726,726,726,737,737, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, 725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, /* block 245 */ -725,725,725,725,725,725,725,725,725,715,725,725,725,725,725,725, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,1358,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,163,163,725,725,725,725,725,725,725,725, 725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,715,725,725,725,725,725,725,724,725,163,163,1359,1359, -1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359, -1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359, -1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359, +725,1367,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,716,726,726,726,726, +726,726,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,1367,726,726,726,726, /* block 246 */ -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,716,726,726,726,726,726,726,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,1367,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,716, +726,726,726,726,726,726,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,1367, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, /* block 247 */ -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1360,1360,1360,1360,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1360,1360,1360, -1360,1360,1360,1360,1360,1361,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, +726,726,726,726,726,726,726,726,726,716,726,726,726,726,726,726, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,1367,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,716,726,726,726,726,726,726,725,726,163,163,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, /* block 248 */ -1360,1360,1360,1360,1361,1360,1360,1362,1363,1362,1362,1364,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,1361,1361,1361,1361,1361, -163,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, /* block 249 */ - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 92, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,643, 70, 70, 70, 70,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1369,1369,1369,1369,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1369,1369,1369, +1369,1369,1369,1369,1369,1370,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, /* block 250 */ -1365,1365,1365,1365,1365,1365,1365,163,1365,1365,1365,1365,1365,1365,1365,1365, -1365,1365,1365,1365,1365,1365,1365,1365,1365,163,163,1365,1365,1365,1365,1365, -1365,1365,163,1365,1365,163,1365,1365,1365,1365,1365,163,163,163,163,163, +1369,1369,1369,1369,1370,1369,1369,1371,1372,1371,1371,1373,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,1370,1370,1370,1370,1370, +163,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, @@ -4896,494 +4910,544 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 251 */ -1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366, -1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366, -1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,163,163,163, -1367,1367,1367,1367,1367,1367,1367,1368,1368,1368,1368,1368,1369,1369,163,163, -1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,163,163,163,163,1366,1371, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 92, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,644, 70, 70, 70, 70,163, +163,163,163,163,163, 70, 70, 70, 70, 70, 70,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 252 */ +1374,1374,1374,1374,1374,1374,1374,163,1374,1374,1374,1374,1374,1374,1374,1374, +1374,1374,1374,1374,1374,1374,1374,1374,1374,163,163,1374,1374,1374,1374,1374, +1374,1374,163,1374,1374,163,1374,1374,1374,1374,1374,163,163,163,163,163, +858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +858,858,858,858,858,858,858,858,858,858,858,858,1375,1375,858,858, +858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +858,858,858,858,858,858,858,858,1375,858,858,858,858,858,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372, -1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1373,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374, -1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374, -1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1375,1375,1375,1375, -1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,163,163,163,163,163,1377, /* block 253 */ +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,788, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -483,483,483,483,483,483,483,163,483,483,483,483,163,483,483,163, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,163, /* block 254 */ -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, +1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376, +1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376, +1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,163,163,163, +1377,1377,1377,1377,1377,1377,1377,1378,1378,1378,1378,1378,1379,1379,163,163, +1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,163,163,163,163,1376,1381, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 255 */ -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,262,262,1379,1379,1379,1379,1379,1379,1379,1379,1379, -1380,1380,1380,1380,1380,1380,1380,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382, +1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1383,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384, +1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384, +1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1385,1385,1385,1385, +1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,163,163,163,163,163,1387, /* block 256 */ -1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381, -1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381, -1381,1381,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382, -1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382, -1382,1382,1382,1382,1383,1383,1383,1384,1385,1385,1385,1386,262,262,262,262, -1387,1387,1387,1387,1387,1387,1387,1387,1387,1387,262,262,262,262,1388,1388, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388, +1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1389,1390,1390,1390,1390, +1391,1391,1391,1391,1391,1391,1391,1391,1391,1391,163,163,163,163,163,163, /* block 257 */ -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -302,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +484,484,484,484,484,484,484,163,484,484,484,484,163,484,484,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,163, /* block 258 */ -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389, -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389, -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1390,1389,1389,1389, -1391,1389,1389,1389,1389,302,302,302,302,302,302,302,302,302,302,302, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, + +/* block 259 */ +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,262,262,1393,1393,1393,1393,1393,1393,1393,1393,1393, +1394,1394,1394,1394,1394,1394,1394,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, + +/* block 260 */ +1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1395,1395,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, +1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, +1396,1396,1396,1396,1397,1397,1397,1398,1399,1399,1399,1400,262,262,262,262, +1401,1401,1401,1401,1401,1401,1401,1401,1401,1401,262,262,262,262,1402,1402, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, + +/* block 261 */ +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +302,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, + +/* block 262 */ +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1404,1403,1403,1403, +1405,1403,1403,1403,1403,302,302,302,302,302,302,302,302,302,302,302, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -/* block 259 */ -302,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389, -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389, -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1390,1389, -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,302,302, +/* block 263 */ +302,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1404,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,302,302, 302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -/* block 260 */ -1392,1392,1392,1392,302,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -302,1392,1392,302,1392,302,302,1392,302,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,302,1392,1392,1392,1392,302,1392,302,1392,302,302,302,302, -302,302,1392,302,302,302,302,1392,302,1392,302,1392,302,1392,1392,1392, -302,1392,1392,302,1392,302,302,1392,302,1392,302,1392,302,1392,302,1392, -302,1392,1392,302,1392,302,302,1392,1392,1392,1392,302,1392,1392,1392,1392, -1392,1392,1392,302,1392,1392,1392,1392,302,1392,1392,1392,1392,302,1392,302, +/* block 264 */ +1406,1406,1406,1406,302,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406, +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406, +302,1406,1406,302,1406,302,302,1406,302,1406,1406,1406,1406,1406,1406,1406, +1406,1406,1406,302,1406,1406,1406,1406,302,1406,302,1406,302,302,302,302, +302,302,1406,302,302,302,302,1406,302,1406,302,1406,302,1406,1406,1406, +302,1406,1406,302,1406,302,302,1406,302,1406,302,1406,302,1406,302,1406, +302,1406,1406,302,1406,302,302,1406,1406,1406,1406,302,1406,1406,1406,1406, +1406,1406,1406,302,1406,1406,1406,1406,302,1406,1406,1406,1406,302,1406,302, -/* block 261 */ -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,302,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,302,302,302,302, -302,1392,1392,1392,302,1392,1392,1392,1392,1392,302,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,302,302,302,302, +/* block 265 */ +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,1406,1406,1406,1406,1406, +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,302,302,302, +302,1406,1406,1406,302,1406,1406,1406,1406,1406,302,1406,1406,1406,1406,1406, +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,302,302,302, 302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, 302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, 302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, 274,274,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -/* block 262 */ -1393,1393,1393,1393,1394,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1395,1395,1395,1395, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, - -/* block 263 */ -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1395, -1395,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1395,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1394, -1395,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, - -/* block 264 */ - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 58, 58,1393,1393,1393, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,1393, -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,460,460,460,460,460,460, -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,723,723,1393,1393,1393,1393, -1397,1397,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1397,1397, - -/* block 265 */ -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,460,460,460,460,1398,460, -460,1398,1398,1398,1398,1398,1398,1398,1398,1398,1398,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,1393,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399, -1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399, - /* block 266 */ -1400,1398,1401,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -460,460,460,460,460,460,460,460,460,460,1398,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,1398, -460,460,1398,1398,1398,1398,1398,1401,1398,1398,1398,460,1395,1395,1395,1395, -460,460,460,460,460,460,460,460,460,1395,1395,1395,1395,1395,1395,1395, -1402,1402,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1393,1393,1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1407,1407,1407,1407,1408,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, /* block 267 */ -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409, +1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1408, +1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 268 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,727,1393,1393,727,727,727,727,727,727,727,727,727,1394,1394,1394, -1394,1394,1394,1394,1394,1394,727,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,727,1394,1394, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 58, 58,1407,1407,1407, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,1407, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,461,461,461,461,461,461, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,724,724,1407,1407,1407,1407, +1411,1411,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1411,1411, /* block 269 */ -1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1393,1393,727,727,1393,727,727,727,1393,1393,727,727, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1403,1403,1403,1394,1394,1403,1394,1394,1403,1404,1404,727,727,1394, -1394,1394,1394,1394,727,727,727,727,727,727,727,727,727,727,727,727, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1393,1393,727,1394,727,1393,727,1394,1394,1394,1405,1405,1405,1405,1405, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,461,461,461,461,1412,461, +461,1412,1412,1412,1412,1412,1412,1412,1412,1412,1412,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,1407,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, /* block 270 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,727, -1394,727,1403,1403,1394,1394,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, -1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, -1403,1403,1403,1403,1403,1403,1403,1403,1403,1394,1394,1394,1403,1394,1394,1394, +1414,1412,1415,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +461,461,461,461,461,461,461,461,461,461,1412,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,1412, +461,461,1412,1412,1412,1412,1412,1415,1412,1412,1412,461,1409,1409,1409,1409, +461,461,461,461,461,461,461,461,461,1409,1409,1409,1409,1409,1409,1409, +1416,1416,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 271 */ -1394,1403,1403,1403,1394,1403,1403,1403,1394,1394,1394,1394,1394,1394,1394,1403, -1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,727,1393,1394, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 272 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,723,723, -723,723,723,723,723,723,1393,1393,1393,727,727,1394,1394,1394,1394,1393, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1393,1393,1393,1393,1393,1393,1393,727, -727,1393,1393,727,1404,1404,727,727,727,727,1403,1393,1393,1393,1393,1393, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,728,1407,1407,728,728,728,728,728,728,728,728,728,1408,1408,1408, +1408,1408,1408,1408,1408,1408,728,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728,1408,1408, /* block 273 */ -1393,1393,1393,1393,1393,1393,1393,727,1393,1393,727,727,727,727,1393,1393, -1404,1393,1393,1393,1393,1403,1403,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1394,727,1393,1393,727,1393,1393,1393,1393,1393,1393,1393, -1393,727,727,1393,1393,1393,1393,1393,1393,1393,1393,1393,727,1393,1393,1393, -1393,1393,727,727,727,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,727,727,727,1393,1393,1393,1393,1393,1393,1393,1393,727,727,727,1393, -1393,727,1393,727,1393,1393,1393,1393,727,1393,1393,1393,1393,1393,1393,727, -1393,1393,1393,727,1393,1393,1393,1393,1393,1393,727,1394,1394,1394,1394,1394, +1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1407,1407,728,728,1407,728,728,728,1407,1407,728,728, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1417,1417,1417,1408,1408,1417,1408,1408,1417,1418,1418,728,728,1408, +1408,1408,1408,1408,728,728,728,728,728,728,728,728,728,728,728,728, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1407,1407,728,1408,728,1407,728,1408,1408,1408,1419,1419,1419,1419,1419, /* block 274 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1403,1403,1403,1394,1394,1394,1403,1403,1403,1403,1403, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728, +1408,728,1417,1417,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417, +1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417, +1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,1408,1408,1417,1408,1408,1408, /* block 275 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1403,1403,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1403,1394,1394,1394,1394,1394,1393,1393,1393,1393,1393,727,1403,727,727,727, -1394,1394,1394,1393,1393,1394,1394,1394,1395,1395,1395,1395,1395,1394,1394,1394, -727,727,727,727,727,727,1393,1393,1393,727,1393,1394,1394,1395,1395,1395, -727,1393,1393,727,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395, +1408,1417,1417,1417,1408,1417,1417,1417,1408,1408,1408,1408,1408,1408,1408,1417, +1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728,1407,1408, /* block 276 */ -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,724,724, +724,724,724,724,724,724,1407,1407,1407,728,728,1408,1408,1408,1408,1407, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1407,1407,1407,1407,1407,1407,1407,728, +728,1407,1407,728,1418,1418,728,728,728,728,1417,1407,1407,1407,1407,1407, /* block 277 */ -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395, -1394,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1407,1407,1407,1407,1407,1407,1407,728,1407,1407,728,728,728,728,1407,1407, +1418,1407,1407,1407,1407,1417,1417,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1408,728,1407,1407,728,1407,1407,1407,1407,1407,1407,1407, +1407,728,728,1407,1407,1407,1407,1407,1407,1407,1407,1407,728,1407,1407,1407, +1407,1407,728,728,728,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,728,728,728,1407,1407,1407,1407,1407,1407,1407,1407,728,728,728,1407, +1407,728,1407,728,1407,1407,1407,1407,728,1407,1407,1407,1407,1407,1407,728, +1407,1407,1407,728,1407,1407,1407,1407,1407,1407,728,1408,1408,1408,1408,1408, /* block 278 */ -723,723,723,723,723,723,723,723,723,723,723,723,1395,1395,1395,1395, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,1395,1395,1395,1395,1395,1395,1395,1395, -723,723,723,723,723,723,723,723,723,723,1395,1395,1395,1395,1395,1395, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1417,1417,1417,1408,1408,1408,1417,1417,1417,1417,1417, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 279 */ -723,723,723,723,723,723,723,723,1395,1395,1395,1395,1395,1395,1395,1395, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,1395,1395, -1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1417,1417,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1417,1408,1408,1408,1408,1408,1407,1407,1407,1407,1407,728,1417,728,728,728, +1408,1408,1408,1407,1407,1408,1408,1408,1409,1409,1409,1409,1408,1408,1408,1408, +728,728,728,728,728,728,1407,1407,1407,728,1407,1408,1408,1409,1409,1409, +728,1407,1407,728,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409, /* block 280 */ -723,723,723,723,723,723,723,723,723,723,723,723,1403,1394,1394,1403, -1394,1394,1394,1394,1394,1394,1394,1394,1403,1403,1403,1403,1403,1403,1403,1403, -1394,1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1394,723,1403,1403,1403,1394, -1394,1394,1394,1394,1394,1394,723,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,1407,1407,1407,1409,1409,1409,1409,1407,1407,1407,1407,1407, /* block 281 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1406,1406,1406,1406,1394,1403,1403,1394,1403,1403,1394,1403,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1403,1403,1403, -1394,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409, +1408,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 282 */ -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1395,1395, -1394,1394,1394,1394,1394,1395,1395,1395,1394,1394,1394,1394,1394,1395,1395,1395, +724,724,724,724,724,724,724,724,724,724,724,724,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 283 */ -1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395, -1394,1394,1394,1403,1403,1403,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395,1395, -1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395,1395,1395,1395, -1403,1403,1403,1403,1403,1403,1403,1395,1395,1395,1395,1395,1395,1395,1395,1395, +724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,1409,1409, +1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 284 */ -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, +724,724,724,724,724,724,724,724,724,724,724,724,1417,1408,1408,1417, +1408,1408,1408,1408,1408,1408,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417, +1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,724,1417,1417,1417,1408, +1408,1408,1408,1408,1408,1408,724,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408, /* block 285 */ -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,163,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,163,163,163,163,163,163, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1420,1420,1420,1420,1408,1417,1417,1408,1417,1417,1408,1417,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1417,1417,1417, +1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, /* block 286 */ -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,958,958, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409, /* block 287 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409,1409,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1408, +1408,1408,1408,1417,1417,1417,1409,1409,1409,1409,1409,1409,1409,1409,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409,1409,1409,1409, +1417,1417,1417,1417,1417,1417,1417,1417,1417,1409,1409,1409,1409,1409,1409,1409, /* block 288 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,163,163,163,163,163,163,163, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 289 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,163,163, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,163,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1421,1421,1421,1421,1421,1421,1421,1421,1421,1421,163,163,163,163,163,163, /* block 290 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,957,957, /* block 291 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 292 */ -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 293 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,958,958, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 294 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 295 */ -707,712,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 296 */ -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 297 */ -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,957,957, /* block 298 */ -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 299 */ -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,958,958, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, + +/* block 300 */ +708,713,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, + +/* block 301 */ +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, + +/* block 302 */ +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, + +/* block 303 */ +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, + +/* block 304 */ +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,957,957, }; #if UCD_BLOCK_SIZE != 128 diff --git a/src/3rdparty/pcre2/src/pcre2_ucp.h b/src/3rdparty/pcre2/src/pcre2_ucp.h index 282238982dc..9ccc8297508 100644 --- a/src/3rdparty/pcre2/src/pcre2_ucp.h +++ b/src/3rdparty/pcre2/src/pcre2_ucp.h @@ -166,29 +166,29 @@ enum { /* These are the bidi class values. */ enum { - ucp_bidiAL, /* Arabic letter */ - ucp_bidiAN, /* Arabic number */ - ucp_bidiB, /* Paragraph separator */ - ucp_bidiBN, /* Boundary neutral */ - ucp_bidiCS, /* Common separator */ - ucp_bidiEN, /* European number */ - ucp_bidiES, /* European separator */ - ucp_bidiET, /* European terminator */ - ucp_bidiFSI, /* First strong isolate */ - ucp_bidiL, /* Left to right */ - ucp_bidiLRE, /* Left to right embedding */ - ucp_bidiLRI, /* Left to right isolate */ - ucp_bidiLRO, /* Left to right override */ - ucp_bidiNSM, /* Non-spacing mark */ - ucp_bidiON, /* Other neutral */ - ucp_bidiPDF, /* Pop directional format */ - ucp_bidiPDI, /* Pop directional isolate */ - ucp_bidiR, /* Right to left */ - ucp_bidiRLE, /* Right to left embedding */ - ucp_bidiRLI, /* Right to left isolate */ - ucp_bidiRLO, /* Right to left override */ - ucp_bidiS, /* Segment separator */ - ucp_bidiWS, /* White space */ + ucp_bidiAL, /* Arabic_Letter */ + ucp_bidiAN, /* Arabic_Number */ + ucp_bidiB, /* Paragraph_Separator */ + ucp_bidiBN, /* Boundary_Neutral */ + ucp_bidiCS, /* Common_Separator */ + ucp_bidiEN, /* European_Number */ + ucp_bidiES, /* European_Separator */ + ucp_bidiET, /* European_Terminator */ + ucp_bidiFSI, /* First_Strong_Isolate */ + ucp_bidiL, /* Left_To_Right */ + ucp_bidiLRE, /* Left_To_Right_Embedding */ + ucp_bidiLRI, /* Left_To_Right_Isolate */ + ucp_bidiLRO, /* Left_To_Right_Override */ + ucp_bidiNSM, /* Nonspacing_Mark */ + ucp_bidiON, /* Other_Neutral */ + ucp_bidiPDF, /* Pop_Directional_Format */ + ucp_bidiPDI, /* Pop_Directional_Isolate */ + ucp_bidiR, /* Right_To_Left */ + ucp_bidiRLE, /* Right_To_Left_Embedding */ + ucp_bidiRLI, /* Right_To_Left_Isolate */ + ucp_bidiRLO, /* Right_To_Left_Override */ + ucp_bidiS, /* Segment_Separator */ + ucp_bidiWS, /* White_Space */ }; /* These are grapheme break properties. The Extended Pictographic property @@ -380,6 +380,8 @@ enum { ucp_Tangsa, ucp_Toto, ucp_Vithkuqi, + ucp_Kawi, + ucp_Nag_Mundari, /* This must be last */ ucp_Script_Count diff --git a/src/3rdparty/pcre2/src/pcre2_ucptables.c b/src/3rdparty/pcre2/src/pcre2_ucptables.c index bd1b67a9f1b..2110014c29e 100644 --- a/src/3rdparty/pcre2/src/pcre2_ucptables.c +++ b/src/3rdparty/pcre2/src/pcre2_ucptables.c @@ -265,6 +265,7 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_kana0 STR_k STR_a STR_n STR_a "\0" #define STRING_kannada0 STR_k STR_a STR_n STR_n STR_a STR_d STR_a "\0" #define STRING_katakana0 STR_k STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0" +#define STRING_kawi0 STR_k STR_a STR_w STR_i "\0" #define STRING_kayahli0 STR_k STR_a STR_y STR_a STR_h STR_l STR_i "\0" #define STRING_khar0 STR_k STR_h STR_a STR_r "\0" #define STRING_kharoshthi0 STR_k STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0" @@ -347,6 +348,8 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_mymr0 STR_m STR_y STR_m STR_r "\0" #define STRING_n0 STR_n "\0" #define STRING_nabataean0 STR_n STR_a STR_b STR_a STR_t STR_a STR_e STR_a STR_n "\0" +#define STRING_nagm0 STR_n STR_a STR_g STR_m "\0" +#define STRING_nagmundari0 STR_n STR_a STR_g STR_m STR_u STR_n STR_d STR_a STR_r STR_i "\0" #define STRING_nand0 STR_n STR_a STR_n STR_d "\0" #define STRING_nandinagari0 STR_n STR_a STR_n STR_d STR_i STR_n STR_a STR_g STR_a STR_r STR_i "\0" #define STRING_narb0 STR_n STR_a STR_r STR_b "\0" @@ -753,6 +756,7 @@ const char PRIV(utt_names)[] = STRING_kana0 STRING_kannada0 STRING_katakana0 + STRING_kawi0 STRING_kayahli0 STRING_khar0 STRING_kharoshthi0 @@ -835,6 +839,8 @@ const char PRIV(utt_names)[] = STRING_mymr0 STRING_n0 STRING_nabataean0 + STRING_nagm0 + STRING_nagmundari0 STRING_nand0 STRING_nandinagari0 STRING_narb0 @@ -1241,280 +1247,283 @@ const ucp_type_table PRIV(utt)[] = { { 1665, PT_SCX, ucp_Katakana }, { 1670, PT_SCX, ucp_Kannada }, { 1678, PT_SCX, ucp_Katakana }, - { 1687, PT_SCX, ucp_Kayah_Li }, - { 1695, PT_SC, ucp_Kharoshthi }, + { 1687, PT_SC, ucp_Kawi }, + { 1692, PT_SCX, ucp_Kayah_Li }, { 1700, PT_SC, ucp_Kharoshthi }, - { 1711, PT_SC, ucp_Khitan_Small_Script }, - { 1729, PT_SC, ucp_Khmer }, - { 1735, PT_SC, ucp_Khmer }, - { 1740, PT_SCX, ucp_Khojki }, + { 1705, PT_SC, ucp_Kharoshthi }, + { 1716, PT_SC, ucp_Khitan_Small_Script }, + { 1734, PT_SC, ucp_Khmer }, + { 1740, PT_SC, ucp_Khmer }, { 1745, PT_SCX, ucp_Khojki }, - { 1752, PT_SCX, ucp_Khudawadi }, - { 1762, PT_SC, ucp_Khitan_Small_Script }, - { 1767, PT_SCX, ucp_Kannada }, - { 1772, PT_SCX, ucp_Kaithi }, - { 1777, PT_GC, ucp_L }, - { 1779, PT_LAMP, 0 }, - { 1782, PT_SC, ucp_Tai_Tham }, - { 1787, PT_SC, ucp_Lao }, - { 1791, PT_SC, ucp_Lao }, - { 1796, PT_SCX, ucp_Latin }, - { 1802, PT_SCX, ucp_Latin }, - { 1807, PT_LAMP, 0 }, - { 1810, PT_SC, ucp_Lepcha }, + { 1750, PT_SCX, ucp_Khojki }, + { 1757, PT_SCX, ucp_Khudawadi }, + { 1767, PT_SC, ucp_Khitan_Small_Script }, + { 1772, PT_SCX, ucp_Kannada }, + { 1777, PT_SCX, ucp_Kaithi }, + { 1782, PT_GC, ucp_L }, + { 1784, PT_LAMP, 0 }, + { 1787, PT_SC, ucp_Tai_Tham }, + { 1792, PT_SC, ucp_Lao }, + { 1796, PT_SC, ucp_Lao }, + { 1801, PT_SCX, ucp_Latin }, + { 1807, PT_SCX, ucp_Latin }, + { 1812, PT_LAMP, 0 }, { 1815, PT_SC, ucp_Lepcha }, - { 1822, PT_SCX, ucp_Limbu }, + { 1820, PT_SC, ucp_Lepcha }, { 1827, PT_SCX, ucp_Limbu }, - { 1833, PT_SCX, ucp_Linear_A }, - { 1838, PT_SCX, ucp_Linear_B }, - { 1843, PT_SCX, ucp_Linear_A }, - { 1851, PT_SCX, ucp_Linear_B }, - { 1859, PT_SC, ucp_Lisu }, - { 1864, PT_PC, ucp_Ll }, - { 1867, PT_PC, ucp_Lm }, - { 1870, PT_PC, ucp_Lo }, - { 1873, PT_BOOL, ucp_Logical_Order_Exception }, - { 1877, PT_BOOL, ucp_Logical_Order_Exception }, - { 1899, PT_BOOL, ucp_Lowercase }, - { 1905, PT_BOOL, ucp_Lowercase }, - { 1915, PT_PC, ucp_Lt }, - { 1918, PT_PC, ucp_Lu }, - { 1921, PT_SC, ucp_Lycian }, + { 1832, PT_SCX, ucp_Limbu }, + { 1838, PT_SCX, ucp_Linear_A }, + { 1843, PT_SCX, ucp_Linear_B }, + { 1848, PT_SCX, ucp_Linear_A }, + { 1856, PT_SCX, ucp_Linear_B }, + { 1864, PT_SC, ucp_Lisu }, + { 1869, PT_PC, ucp_Ll }, + { 1872, PT_PC, ucp_Lm }, + { 1875, PT_PC, ucp_Lo }, + { 1878, PT_BOOL, ucp_Logical_Order_Exception }, + { 1882, PT_BOOL, ucp_Logical_Order_Exception }, + { 1904, PT_BOOL, ucp_Lowercase }, + { 1910, PT_BOOL, ucp_Lowercase }, + { 1920, PT_PC, ucp_Lt }, + { 1923, PT_PC, ucp_Lu }, { 1926, PT_SC, ucp_Lycian }, - { 1933, PT_SC, ucp_Lydian }, + { 1931, PT_SC, ucp_Lycian }, { 1938, PT_SC, ucp_Lydian }, - { 1945, PT_GC, ucp_M }, - { 1947, PT_SCX, ucp_Mahajani }, - { 1956, PT_SCX, ucp_Mahajani }, - { 1961, PT_SC, ucp_Makasar }, + { 1943, PT_SC, ucp_Lydian }, + { 1950, PT_GC, ucp_M }, + { 1952, PT_SCX, ucp_Mahajani }, + { 1961, PT_SCX, ucp_Mahajani }, { 1966, PT_SC, ucp_Makasar }, - { 1974, PT_SCX, ucp_Malayalam }, - { 1984, PT_SCX, ucp_Mandaic }, + { 1971, PT_SC, ucp_Makasar }, + { 1979, PT_SCX, ucp_Malayalam }, { 1989, PT_SCX, ucp_Mandaic }, - { 1997, PT_SCX, ucp_Manichaean }, + { 1994, PT_SCX, ucp_Mandaic }, { 2002, PT_SCX, ucp_Manichaean }, - { 2013, PT_SC, ucp_Marchen }, + { 2007, PT_SCX, ucp_Manichaean }, { 2018, PT_SC, ucp_Marchen }, - { 2026, PT_SCX, ucp_Masaram_Gondi }, - { 2039, PT_BOOL, ucp_Math }, - { 2044, PT_PC, ucp_Mc }, - { 2047, PT_PC, ucp_Me }, - { 2050, PT_SC, ucp_Medefaidrin }, - { 2062, PT_SC, ucp_Medefaidrin }, - { 2067, PT_SC, ucp_Meetei_Mayek }, - { 2079, PT_SC, ucp_Mende_Kikakui }, + { 2023, PT_SC, ucp_Marchen }, + { 2031, PT_SCX, ucp_Masaram_Gondi }, + { 2044, PT_BOOL, ucp_Math }, + { 2049, PT_PC, ucp_Mc }, + { 2052, PT_PC, ucp_Me }, + { 2055, PT_SC, ucp_Medefaidrin }, + { 2067, PT_SC, ucp_Medefaidrin }, + { 2072, PT_SC, ucp_Meetei_Mayek }, { 2084, PT_SC, ucp_Mende_Kikakui }, - { 2097, PT_SC, ucp_Meroitic_Cursive }, - { 2102, PT_SC, ucp_Meroitic_Hieroglyphs }, - { 2107, PT_SC, ucp_Meroitic_Cursive }, - { 2123, PT_SC, ucp_Meroitic_Hieroglyphs }, - { 2143, PT_SC, ucp_Miao }, - { 2148, PT_SCX, ucp_Malayalam }, - { 2153, PT_PC, ucp_Mn }, - { 2156, PT_SCX, ucp_Modi }, - { 2161, PT_SCX, ucp_Mongolian }, + { 2089, PT_SC, ucp_Mende_Kikakui }, + { 2102, PT_SC, ucp_Meroitic_Cursive }, + { 2107, PT_SC, ucp_Meroitic_Hieroglyphs }, + { 2112, PT_SC, ucp_Meroitic_Cursive }, + { 2128, PT_SC, ucp_Meroitic_Hieroglyphs }, + { 2148, PT_SC, ucp_Miao }, + { 2153, PT_SCX, ucp_Malayalam }, + { 2158, PT_PC, ucp_Mn }, + { 2161, PT_SCX, ucp_Modi }, { 2166, PT_SCX, ucp_Mongolian }, - { 2176, PT_SC, ucp_Mro }, - { 2180, PT_SC, ucp_Mro }, - { 2185, PT_SC, ucp_Meetei_Mayek }, - { 2190, PT_SCX, ucp_Multani }, + { 2171, PT_SCX, ucp_Mongolian }, + { 2181, PT_SC, ucp_Mro }, + { 2185, PT_SC, ucp_Mro }, + { 2190, PT_SC, ucp_Meetei_Mayek }, { 2195, PT_SCX, ucp_Multani }, - { 2203, PT_SCX, ucp_Myanmar }, - { 2211, PT_SCX, ucp_Myanmar }, - { 2216, PT_GC, ucp_N }, - { 2218, PT_SC, ucp_Nabataean }, - { 2228, PT_SCX, ucp_Nandinagari }, - { 2233, PT_SCX, ucp_Nandinagari }, - { 2245, PT_SC, ucp_Old_North_Arabian }, - { 2250, PT_SC, ucp_Nabataean }, - { 2255, PT_BOOL, ucp_Noncharacter_Code_Point }, - { 2261, PT_PC, ucp_Nd }, - { 2264, PT_SC, ucp_Newa }, - { 2269, PT_SC, ucp_New_Tai_Lue }, - { 2279, PT_SCX, ucp_Nko }, - { 2283, PT_SCX, ucp_Nko }, - { 2288, PT_PC, ucp_Nl }, - { 2291, PT_PC, ucp_No }, - { 2294, PT_BOOL, ucp_Noncharacter_Code_Point }, - { 2316, PT_SC, ucp_Nushu }, - { 2321, PT_SC, ucp_Nushu }, - { 2327, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, - { 2348, PT_SC, ucp_Ogham }, - { 2353, PT_SC, ucp_Ogham }, - { 2359, PT_SC, ucp_Ol_Chiki }, - { 2367, PT_SC, ucp_Ol_Chiki }, - { 2372, PT_SC, ucp_Old_Hungarian }, - { 2385, PT_SC, ucp_Old_Italic }, - { 2395, PT_SC, ucp_Old_North_Arabian }, - { 2411, PT_SCX, ucp_Old_Permic }, - { 2421, PT_SC, ucp_Old_Persian }, - { 2432, PT_SC, ucp_Old_Sogdian }, - { 2443, PT_SC, ucp_Old_South_Arabian }, - { 2459, PT_SC, ucp_Old_Turkic }, - { 2469, PT_SCX, ucp_Old_Uyghur }, - { 2479, PT_SCX, ucp_Oriya }, - { 2485, PT_SC, ucp_Old_Turkic }, - { 2490, PT_SCX, ucp_Oriya }, - { 2495, PT_SC, ucp_Osage }, - { 2501, PT_SC, ucp_Osage }, - { 2506, PT_SC, ucp_Osmanya }, - { 2511, PT_SC, ucp_Osmanya }, - { 2519, PT_SCX, ucp_Old_Uyghur }, - { 2524, PT_GC, ucp_P }, - { 2526, PT_SC, ucp_Pahawh_Hmong }, - { 2538, PT_SC, ucp_Palmyrene }, - { 2543, PT_SC, ucp_Palmyrene }, - { 2553, PT_BOOL, ucp_Pattern_Syntax }, - { 2560, PT_BOOL, ucp_Pattern_Syntax }, - { 2574, PT_BOOL, ucp_Pattern_White_Space }, - { 2592, PT_BOOL, ucp_Pattern_White_Space }, - { 2598, PT_SC, ucp_Pau_Cin_Hau }, - { 2603, PT_SC, ucp_Pau_Cin_Hau }, - { 2613, PT_PC, ucp_Pc }, - { 2616, PT_BOOL, ucp_Prepended_Concatenation_Mark }, - { 2620, PT_PC, ucp_Pd }, - { 2623, PT_PC, ucp_Pe }, - { 2626, PT_SCX, ucp_Old_Permic }, - { 2631, PT_PC, ucp_Pf }, - { 2634, PT_SCX, ucp_Phags_Pa }, - { 2639, PT_SCX, ucp_Phags_Pa }, - { 2647, PT_SC, ucp_Inscriptional_Pahlavi }, - { 2652, PT_SCX, ucp_Psalter_Pahlavi }, - { 2657, PT_SC, ucp_Phoenician }, - { 2662, PT_SC, ucp_Phoenician }, - { 2673, PT_PC, ucp_Pi }, - { 2676, PT_SC, ucp_Miao }, - { 2681, PT_PC, ucp_Po }, - { 2684, PT_BOOL, ucp_Prepended_Concatenation_Mark }, - { 2711, PT_SC, ucp_Inscriptional_Parthian }, - { 2716, PT_PC, ucp_Ps }, - { 2719, PT_SCX, ucp_Psalter_Pahlavi }, - { 2734, PT_SCX, ucp_Coptic }, - { 2739, PT_SC, ucp_Inherited }, - { 2744, PT_BOOL, ucp_Quotation_Mark }, - { 2750, PT_BOOL, ucp_Quotation_Mark }, - { 2764, PT_BOOL, ucp_Radical }, - { 2772, PT_BOOL, ucp_Regional_Indicator }, - { 2790, PT_SC, ucp_Rejang }, - { 2797, PT_BOOL, ucp_Regional_Indicator }, - { 2800, PT_SC, ucp_Rejang }, - { 2805, PT_SCX, ucp_Hanifi_Rohingya }, - { 2810, PT_SC, ucp_Runic }, - { 2816, PT_SC, ucp_Runic }, - { 2821, PT_GC, ucp_S }, - { 2823, PT_SC, ucp_Samaritan }, - { 2833, PT_SC, ucp_Samaritan }, - { 2838, PT_SC, ucp_Old_South_Arabian }, - { 2843, PT_SC, ucp_Saurashtra }, - { 2848, PT_SC, ucp_Saurashtra }, - { 2859, PT_PC, ucp_Sc }, - { 2862, PT_BOOL, ucp_Soft_Dotted }, - { 2865, PT_BOOL, ucp_Sentence_Terminal }, - { 2882, PT_SC, ucp_SignWriting }, - { 2887, PT_SCX, ucp_Sharada }, - { 2895, PT_SC, ucp_Shavian }, - { 2903, PT_SC, ucp_Shavian }, + { 2200, PT_SCX, ucp_Multani }, + { 2208, PT_SCX, ucp_Myanmar }, + { 2216, PT_SCX, ucp_Myanmar }, + { 2221, PT_GC, ucp_N }, + { 2223, PT_SC, ucp_Nabataean }, + { 2233, PT_SC, ucp_Nag_Mundari }, + { 2238, PT_SC, ucp_Nag_Mundari }, + { 2249, PT_SCX, ucp_Nandinagari }, + { 2254, PT_SCX, ucp_Nandinagari }, + { 2266, PT_SC, ucp_Old_North_Arabian }, + { 2271, PT_SC, ucp_Nabataean }, + { 2276, PT_BOOL, ucp_Noncharacter_Code_Point }, + { 2282, PT_PC, ucp_Nd }, + { 2285, PT_SC, ucp_Newa }, + { 2290, PT_SC, ucp_New_Tai_Lue }, + { 2300, PT_SCX, ucp_Nko }, + { 2304, PT_SCX, ucp_Nko }, + { 2309, PT_PC, ucp_Nl }, + { 2312, PT_PC, ucp_No }, + { 2315, PT_BOOL, ucp_Noncharacter_Code_Point }, + { 2337, PT_SC, ucp_Nushu }, + { 2342, PT_SC, ucp_Nushu }, + { 2348, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, + { 2369, PT_SC, ucp_Ogham }, + { 2374, PT_SC, ucp_Ogham }, + { 2380, PT_SC, ucp_Ol_Chiki }, + { 2388, PT_SC, ucp_Ol_Chiki }, + { 2393, PT_SC, ucp_Old_Hungarian }, + { 2406, PT_SC, ucp_Old_Italic }, + { 2416, PT_SC, ucp_Old_North_Arabian }, + { 2432, PT_SCX, ucp_Old_Permic }, + { 2442, PT_SC, ucp_Old_Persian }, + { 2453, PT_SC, ucp_Old_Sogdian }, + { 2464, PT_SC, ucp_Old_South_Arabian }, + { 2480, PT_SC, ucp_Old_Turkic }, + { 2490, PT_SCX, ucp_Old_Uyghur }, + { 2500, PT_SCX, ucp_Oriya }, + { 2506, PT_SC, ucp_Old_Turkic }, + { 2511, PT_SCX, ucp_Oriya }, + { 2516, PT_SC, ucp_Osage }, + { 2522, PT_SC, ucp_Osage }, + { 2527, PT_SC, ucp_Osmanya }, + { 2532, PT_SC, ucp_Osmanya }, + { 2540, PT_SCX, ucp_Old_Uyghur }, + { 2545, PT_GC, ucp_P }, + { 2547, PT_SC, ucp_Pahawh_Hmong }, + { 2559, PT_SC, ucp_Palmyrene }, + { 2564, PT_SC, ucp_Palmyrene }, + { 2574, PT_BOOL, ucp_Pattern_Syntax }, + { 2581, PT_BOOL, ucp_Pattern_Syntax }, + { 2595, PT_BOOL, ucp_Pattern_White_Space }, + { 2613, PT_BOOL, ucp_Pattern_White_Space }, + { 2619, PT_SC, ucp_Pau_Cin_Hau }, + { 2624, PT_SC, ucp_Pau_Cin_Hau }, + { 2634, PT_PC, ucp_Pc }, + { 2637, PT_BOOL, ucp_Prepended_Concatenation_Mark }, + { 2641, PT_PC, ucp_Pd }, + { 2644, PT_PC, ucp_Pe }, + { 2647, PT_SCX, ucp_Old_Permic }, + { 2652, PT_PC, ucp_Pf }, + { 2655, PT_SCX, ucp_Phags_Pa }, + { 2660, PT_SCX, ucp_Phags_Pa }, + { 2668, PT_SC, ucp_Inscriptional_Pahlavi }, + { 2673, PT_SCX, ucp_Psalter_Pahlavi }, + { 2678, PT_SC, ucp_Phoenician }, + { 2683, PT_SC, ucp_Phoenician }, + { 2694, PT_PC, ucp_Pi }, + { 2697, PT_SC, ucp_Miao }, + { 2702, PT_PC, ucp_Po }, + { 2705, PT_BOOL, ucp_Prepended_Concatenation_Mark }, + { 2732, PT_SC, ucp_Inscriptional_Parthian }, + { 2737, PT_PC, ucp_Ps }, + { 2740, PT_SCX, ucp_Psalter_Pahlavi }, + { 2755, PT_SCX, ucp_Coptic }, + { 2760, PT_SC, ucp_Inherited }, + { 2765, PT_BOOL, ucp_Quotation_Mark }, + { 2771, PT_BOOL, ucp_Quotation_Mark }, + { 2785, PT_BOOL, ucp_Radical }, + { 2793, PT_BOOL, ucp_Regional_Indicator }, + { 2811, PT_SC, ucp_Rejang }, + { 2818, PT_BOOL, ucp_Regional_Indicator }, + { 2821, PT_SC, ucp_Rejang }, + { 2826, PT_SCX, ucp_Hanifi_Rohingya }, + { 2831, PT_SC, ucp_Runic }, + { 2837, PT_SC, ucp_Runic }, + { 2842, PT_GC, ucp_S }, + { 2844, PT_SC, ucp_Samaritan }, + { 2854, PT_SC, ucp_Samaritan }, + { 2859, PT_SC, ucp_Old_South_Arabian }, + { 2864, PT_SC, ucp_Saurashtra }, + { 2869, PT_SC, ucp_Saurashtra }, + { 2880, PT_PC, ucp_Sc }, + { 2883, PT_BOOL, ucp_Soft_Dotted }, + { 2886, PT_BOOL, ucp_Sentence_Terminal }, + { 2903, PT_SC, ucp_SignWriting }, { 2908, PT_SCX, ucp_Sharada }, - { 2913, PT_SC, ucp_Siddham }, - { 2918, PT_SC, ucp_Siddham }, - { 2926, PT_SC, ucp_SignWriting }, - { 2938, PT_SCX, ucp_Khudawadi }, - { 2943, PT_SCX, ucp_Sinhala }, - { 2948, PT_SCX, ucp_Sinhala }, - { 2956, PT_PC, ucp_Sk }, - { 2959, PT_PC, ucp_Sm }, - { 2962, PT_PC, ucp_So }, - { 2965, PT_BOOL, ucp_Soft_Dotted }, - { 2976, PT_SCX, ucp_Sogdian }, - { 2981, PT_SCX, ucp_Sogdian }, - { 2989, PT_SC, ucp_Old_Sogdian }, - { 2994, PT_SC, ucp_Sora_Sompeng }, - { 2999, PT_SC, ucp_Sora_Sompeng }, - { 3011, PT_SC, ucp_Soyombo }, - { 3016, PT_SC, ucp_Soyombo }, - { 3024, PT_BOOL, ucp_White_Space }, - { 3030, PT_BOOL, ucp_Sentence_Terminal }, - { 3036, PT_SC, ucp_Sundanese }, - { 3041, PT_SC, ucp_Sundanese }, - { 3051, PT_SCX, ucp_Syloti_Nagri }, - { 3056, PT_SCX, ucp_Syloti_Nagri }, - { 3068, PT_SCX, ucp_Syriac }, - { 3073, PT_SCX, ucp_Syriac }, - { 3080, PT_SCX, ucp_Tagalog }, - { 3088, PT_SCX, ucp_Tagbanwa }, - { 3093, PT_SCX, ucp_Tagbanwa }, - { 3102, PT_SCX, ucp_Tai_Le }, - { 3108, PT_SC, ucp_Tai_Tham }, - { 3116, PT_SC, ucp_Tai_Viet }, - { 3124, PT_SCX, ucp_Takri }, - { 3129, PT_SCX, ucp_Takri }, - { 3135, PT_SCX, ucp_Tai_Le }, - { 3140, PT_SC, ucp_New_Tai_Lue }, - { 3145, PT_SCX, ucp_Tamil }, - { 3151, PT_SCX, ucp_Tamil }, - { 3156, PT_SC, ucp_Tangut }, - { 3161, PT_SC, ucp_Tangsa }, - { 3168, PT_SC, ucp_Tangut }, - { 3175, PT_SC, ucp_Tai_Viet }, - { 3180, PT_SCX, ucp_Telugu }, - { 3185, PT_SCX, ucp_Telugu }, - { 3192, PT_BOOL, ucp_Terminal_Punctuation }, - { 3197, PT_BOOL, ucp_Terminal_Punctuation }, - { 3217, PT_SC, ucp_Tifinagh }, - { 3222, PT_SCX, ucp_Tagalog }, - { 3227, PT_SCX, ucp_Thaana }, - { 3232, PT_SCX, ucp_Thaana }, - { 3239, PT_SC, ucp_Thai }, - { 3244, PT_SC, ucp_Tibetan }, - { 3252, PT_SC, ucp_Tibetan }, - { 3257, PT_SC, ucp_Tifinagh }, - { 3266, PT_SCX, ucp_Tirhuta }, - { 3271, PT_SCX, ucp_Tirhuta }, - { 3279, PT_SC, ucp_Tangsa }, - { 3284, PT_SC, ucp_Toto }, - { 3289, PT_SC, ucp_Ugaritic }, - { 3294, PT_SC, ucp_Ugaritic }, - { 3303, PT_BOOL, ucp_Unified_Ideograph }, - { 3309, PT_BOOL, ucp_Unified_Ideograph }, - { 3326, PT_SC, ucp_Unknown }, - { 3334, PT_BOOL, ucp_Uppercase }, - { 3340, PT_BOOL, ucp_Uppercase }, - { 3350, PT_SC, ucp_Vai }, - { 3354, PT_SC, ucp_Vai }, - { 3359, PT_BOOL, ucp_Variation_Selector }, - { 3377, PT_SC, ucp_Vithkuqi }, - { 3382, PT_SC, ucp_Vithkuqi }, - { 3391, PT_BOOL, ucp_Variation_Selector }, - { 3394, PT_SC, ucp_Wancho }, - { 3401, PT_SC, ucp_Warang_Citi }, - { 3406, PT_SC, ucp_Warang_Citi }, - { 3417, PT_SC, ucp_Wancho }, - { 3422, PT_BOOL, ucp_White_Space }, - { 3433, PT_BOOL, ucp_White_Space }, - { 3440, PT_ALNUM, 0 }, - { 3444, PT_BOOL, ucp_XID_Continue }, - { 3449, PT_BOOL, ucp_XID_Continue }, - { 3461, PT_BOOL, ucp_XID_Start }, - { 3466, PT_BOOL, ucp_XID_Start }, - { 3475, PT_SC, ucp_Old_Persian }, - { 3480, PT_PXSPACE, 0 }, - { 3484, PT_SPACE, 0 }, - { 3488, PT_SC, ucp_Cuneiform }, - { 3493, PT_UCNC, 0 }, - { 3497, PT_WORD, 0 }, - { 3501, PT_SCX, ucp_Yezidi }, - { 3506, PT_SCX, ucp_Yezidi }, - { 3513, PT_SCX, ucp_Yi }, - { 3516, PT_SCX, ucp_Yi }, - { 3521, PT_GC, ucp_Z }, - { 3523, PT_SC, ucp_Zanabazar_Square }, - { 3539, PT_SC, ucp_Zanabazar_Square }, - { 3544, PT_SC, ucp_Inherited }, - { 3549, PT_PC, ucp_Zl }, - { 3552, PT_PC, ucp_Zp }, - { 3555, PT_PC, ucp_Zs }, - { 3558, PT_SC, ucp_Common }, - { 3563, PT_SC, ucp_Unknown } + { 2916, PT_SC, ucp_Shavian }, + { 2924, PT_SC, ucp_Shavian }, + { 2929, PT_SCX, ucp_Sharada }, + { 2934, PT_SC, ucp_Siddham }, + { 2939, PT_SC, ucp_Siddham }, + { 2947, PT_SC, ucp_SignWriting }, + { 2959, PT_SCX, ucp_Khudawadi }, + { 2964, PT_SCX, ucp_Sinhala }, + { 2969, PT_SCX, ucp_Sinhala }, + { 2977, PT_PC, ucp_Sk }, + { 2980, PT_PC, ucp_Sm }, + { 2983, PT_PC, ucp_So }, + { 2986, PT_BOOL, ucp_Soft_Dotted }, + { 2997, PT_SCX, ucp_Sogdian }, + { 3002, PT_SCX, ucp_Sogdian }, + { 3010, PT_SC, ucp_Old_Sogdian }, + { 3015, PT_SC, ucp_Sora_Sompeng }, + { 3020, PT_SC, ucp_Sora_Sompeng }, + { 3032, PT_SC, ucp_Soyombo }, + { 3037, PT_SC, ucp_Soyombo }, + { 3045, PT_BOOL, ucp_White_Space }, + { 3051, PT_BOOL, ucp_Sentence_Terminal }, + { 3057, PT_SC, ucp_Sundanese }, + { 3062, PT_SC, ucp_Sundanese }, + { 3072, PT_SCX, ucp_Syloti_Nagri }, + { 3077, PT_SCX, ucp_Syloti_Nagri }, + { 3089, PT_SCX, ucp_Syriac }, + { 3094, PT_SCX, ucp_Syriac }, + { 3101, PT_SCX, ucp_Tagalog }, + { 3109, PT_SCX, ucp_Tagbanwa }, + { 3114, PT_SCX, ucp_Tagbanwa }, + { 3123, PT_SCX, ucp_Tai_Le }, + { 3129, PT_SC, ucp_Tai_Tham }, + { 3137, PT_SC, ucp_Tai_Viet }, + { 3145, PT_SCX, ucp_Takri }, + { 3150, PT_SCX, ucp_Takri }, + { 3156, PT_SCX, ucp_Tai_Le }, + { 3161, PT_SC, ucp_New_Tai_Lue }, + { 3166, PT_SCX, ucp_Tamil }, + { 3172, PT_SCX, ucp_Tamil }, + { 3177, PT_SC, ucp_Tangut }, + { 3182, PT_SC, ucp_Tangsa }, + { 3189, PT_SC, ucp_Tangut }, + { 3196, PT_SC, ucp_Tai_Viet }, + { 3201, PT_SCX, ucp_Telugu }, + { 3206, PT_SCX, ucp_Telugu }, + { 3213, PT_BOOL, ucp_Terminal_Punctuation }, + { 3218, PT_BOOL, ucp_Terminal_Punctuation }, + { 3238, PT_SC, ucp_Tifinagh }, + { 3243, PT_SCX, ucp_Tagalog }, + { 3248, PT_SCX, ucp_Thaana }, + { 3253, PT_SCX, ucp_Thaana }, + { 3260, PT_SC, ucp_Thai }, + { 3265, PT_SC, ucp_Tibetan }, + { 3273, PT_SC, ucp_Tibetan }, + { 3278, PT_SC, ucp_Tifinagh }, + { 3287, PT_SCX, ucp_Tirhuta }, + { 3292, PT_SCX, ucp_Tirhuta }, + { 3300, PT_SC, ucp_Tangsa }, + { 3305, PT_SC, ucp_Toto }, + { 3310, PT_SC, ucp_Ugaritic }, + { 3315, PT_SC, ucp_Ugaritic }, + { 3324, PT_BOOL, ucp_Unified_Ideograph }, + { 3330, PT_BOOL, ucp_Unified_Ideograph }, + { 3347, PT_SC, ucp_Unknown }, + { 3355, PT_BOOL, ucp_Uppercase }, + { 3361, PT_BOOL, ucp_Uppercase }, + { 3371, PT_SC, ucp_Vai }, + { 3375, PT_SC, ucp_Vai }, + { 3380, PT_BOOL, ucp_Variation_Selector }, + { 3398, PT_SC, ucp_Vithkuqi }, + { 3403, PT_SC, ucp_Vithkuqi }, + { 3412, PT_BOOL, ucp_Variation_Selector }, + { 3415, PT_SC, ucp_Wancho }, + { 3422, PT_SC, ucp_Warang_Citi }, + { 3427, PT_SC, ucp_Warang_Citi }, + { 3438, PT_SC, ucp_Wancho }, + { 3443, PT_BOOL, ucp_White_Space }, + { 3454, PT_BOOL, ucp_White_Space }, + { 3461, PT_ALNUM, 0 }, + { 3465, PT_BOOL, ucp_XID_Continue }, + { 3470, PT_BOOL, ucp_XID_Continue }, + { 3482, PT_BOOL, ucp_XID_Start }, + { 3487, PT_BOOL, ucp_XID_Start }, + { 3496, PT_SC, ucp_Old_Persian }, + { 3501, PT_PXSPACE, 0 }, + { 3505, PT_SPACE, 0 }, + { 3509, PT_SC, ucp_Cuneiform }, + { 3514, PT_UCNC, 0 }, + { 3518, PT_WORD, 0 }, + { 3522, PT_SCX, ucp_Yezidi }, + { 3527, PT_SCX, ucp_Yezidi }, + { 3534, PT_SCX, ucp_Yi }, + { 3537, PT_SCX, ucp_Yi }, + { 3542, PT_GC, ucp_Z }, + { 3544, PT_SC, ucp_Zanabazar_Square }, + { 3560, PT_SC, ucp_Zanabazar_Square }, + { 3565, PT_SC, ucp_Inherited }, + { 3570, PT_PC, ucp_Zl }, + { 3573, PT_PC, ucp_Zp }, + { 3576, PT_PC, ucp_Zs }, + { 3579, PT_SC, ucp_Common }, + { 3584, PT_SC, ucp_Unknown } }; const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table); diff --git a/src/3rdparty/pcre2/src/pcre2_valid_utf.c b/src/3rdparty/pcre2/src/pcre2_valid_utf.c index e47ea78f161..de411b919e1 100644 --- a/src/3rdparty/pcre2/src/pcre2_valid_utf.c +++ b/src/3rdparty/pcre2/src/pcre2_valid_utf.c @@ -171,7 +171,7 @@ for (p = string; length > 0; p++) if (((d = *(++p)) & 0xc0) != 0x80) { - *erroroffset = (int)(p - string) - 1; + *erroroffset = (PCRE2_SIZE)(p - string) - 1; return PCRE2_ERROR_UTF8_ERR6; } @@ -186,7 +186,7 @@ for (p = string; length > 0; p++) case 1: if ((c & 0x3e) == 0) { - *erroroffset = (int)(p - string) - 1; + *erroroffset = (PCRE2_SIZE)(p - string) - 1; return PCRE2_ERROR_UTF8_ERR15; } break; @@ -198,17 +198,17 @@ for (p = string; length > 0; p++) case 2: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR7; } if (c == 0xe0 && (d & 0x20) == 0) { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR16; } if (c == 0xed && d >= 0xa0) { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR14; } break; @@ -220,22 +220,22 @@ for (p = string; length > 0; p++) case 3: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR7; } if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ { - *erroroffset = (int)(p - string) - 3; + *erroroffset = (PCRE2_SIZE)(p - string) - 3; return PCRE2_ERROR_UTF8_ERR8; } if (c == 0xf0 && (d & 0x30) == 0) { - *erroroffset = (int)(p - string) - 3; + *erroroffset = (PCRE2_SIZE)(p - string) - 3; return PCRE2_ERROR_UTF8_ERR17; } if (c > 0xf4 || (c == 0xf4 && d > 0x8f)) { - *erroroffset = (int)(p - string) - 3; + *erroroffset = (PCRE2_SIZE)(p - string) - 3; return PCRE2_ERROR_UTF8_ERR13; } break; @@ -251,22 +251,22 @@ for (p = string; length > 0; p++) case 4: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR7; } if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ { - *erroroffset = (int)(p - string) - 3; + *erroroffset = (PCRE2_SIZE)(p - string) - 3; return PCRE2_ERROR_UTF8_ERR8; } if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ { - *erroroffset = (int)(p - string) - 4; + *erroroffset = (PCRE2_SIZE)(p - string) - 4; return PCRE2_ERROR_UTF8_ERR9; } if (c == 0xf8 && (d & 0x38) == 0) { - *erroroffset = (int)(p - string) - 4; + *erroroffset = (PCRE2_SIZE)(p - string) - 4; return PCRE2_ERROR_UTF8_ERR18; } break; @@ -277,27 +277,27 @@ for (p = string; length > 0; p++) case 5: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR7; } if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ { - *erroroffset = (int)(p - string) - 3; + *erroroffset = (PCRE2_SIZE)(p - string) - 3; return PCRE2_ERROR_UTF8_ERR8; } if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ { - *erroroffset = (int)(p - string) - 4; + *erroroffset = (PCRE2_SIZE)(p - string) - 4; return PCRE2_ERROR_UTF8_ERR9; } if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */ { - *erroroffset = (int)(p - string) - 5; + *erroroffset = (PCRE2_SIZE)(p - string) - 5; return PCRE2_ERROR_UTF8_ERR10; } if (c == 0xfc && (d & 0x3c) == 0) { - *erroroffset = (int)(p - string) - 5; + *erroroffset = (PCRE2_SIZE)(p - string) - 5; return PCRE2_ERROR_UTF8_ERR19; } break; @@ -309,7 +309,7 @@ for (p = string; length > 0; p++) if (ab > 3) { - *erroroffset = (int)(p - string) - ab; + *erroroffset = (PCRE2_SIZE)(p - string) - ab; return (ab == 4)? PCRE2_ERROR_UTF8_ERR11 : PCRE2_ERROR_UTF8_ERR12; } } @@ -340,21 +340,21 @@ for (p = string; length > 0; p++) /* High surrogate. Must be a followed by a low surrogate. */ if (length == 0) { - *erroroffset = p - string; + *erroroffset = (PCRE2_SIZE)(p - string); return PCRE2_ERROR_UTF16_ERR1; } p++; length--; if ((*p & 0xfc00) != 0xdc00) { - *erroroffset = p - string - 1; + *erroroffset = (PCRE2_SIZE)(p - string) - 1; return PCRE2_ERROR_UTF16_ERR2; } } else { /* Isolated low surrogate. Always an error. */ - *erroroffset = p - string; + *erroroffset = (PCRE2_SIZE)(p - string); return PCRE2_ERROR_UTF16_ERR3; } } @@ -379,14 +379,14 @@ for (p = string; length > 0; length--, p++) /* Normal UTF-32 code point. Neither high nor low surrogate. */ if (c > 0x10ffffu) { - *erroroffset = p - string; + *erroroffset = (PCRE2_SIZE)(p - string); return PCRE2_ERROR_UTF32_ERR2; } } else { /* A surrogate */ - *erroroffset = p - string; + *erroroffset = (PCRE2_SIZE)(p - string); return PCRE2_ERROR_UTF32_ERR1; } } diff --git a/src/3rdparty/pcre2/src/pcre2_xclass.c b/src/3rdparty/pcre2/src/pcre2_xclass.c index bb57196449a..5df25d2c8df 100644 --- a/src/3rdparty/pcre2/src/pcre2_xclass.c +++ b/src/3rdparty/pcre2/src/pcre2_xclass.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -133,6 +133,7 @@ while ((t = *data++) != XCL_END) #ifdef SUPPORT_UNICODE else /* XCL_PROP & XCL_NOTPROP */ { + int chartype; const ucd_record *prop = GET_UCD(c); BOOL isprop = t == XCL_PROP; BOOL ok; @@ -144,8 +145,9 @@ while ((t = *data++) != XCL_END) break; case PT_LAMP: - if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt) == isprop) return !negated; + chartype = prop->chartype; + if ((chartype == ucp_Lu || chartype == ucp_Ll || + chartype == ucp_Lt) == isprop) return !negated; break; case PT_GC: @@ -168,8 +170,9 @@ while ((t = *data++) != XCL_END) break; case PT_ALNUM: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop) + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N) == isprop) return !negated; break; @@ -194,9 +197,10 @@ while ((t = *data++) != XCL_END) break; case PT_WORD: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) - == isprop) + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc) == isprop) return !negated; break; @@ -238,9 +242,10 @@ while ((t = *data++) != XCL_END) */ case PT_PXGRAPH: - if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z && - (PRIV(ucp_gentype)[prop->chartype] != ucp_C || - (prop->chartype == ucp_Cf && + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] != ucp_Z && + (PRIV(ucp_gentype)[chartype] != ucp_C || + (chartype == ucp_Cf && c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069)) )) == isprop) return !negated; @@ -250,10 +255,11 @@ while ((t = *data++) != XCL_END) not Zl and not Zp, and U+180E. */ case PT_PXPRINT: - if ((prop->chartype != ucp_Zl && - prop->chartype != ucp_Zp && - (PRIV(ucp_gentype)[prop->chartype] != ucp_C || - (prop->chartype == ucp_Cf && + chartype = prop->chartype; + if ((chartype != ucp_Zl && + chartype != ucp_Zp && + (PRIV(ucp_gentype)[chartype] != ucp_C || + (chartype == ucp_Cf && c != 0x061c && (c < 0x2066 || c > 0x2069)) )) == isprop) return !negated; @@ -264,8 +270,21 @@ while ((t = *data++) != XCL_END) compatibility (these are $+<=>^`|~). */ case PT_PXPUNCT: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P || - (c < 128 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop) + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] == ucp_P || + (c < 128 && PRIV(ucp_gentype)[chartype] == ucp_S)) == isprop) + return !negated; + break; + + /* Perl has two sets of hex digits */ + + case PT_PXXDIGIT: + if (((c >= CHAR_0 && c <= CHAR_9) || + (c >= CHAR_A && c <= CHAR_F) || + (c >= CHAR_a && c <= CHAR_f) || + (c >= 0xff10 && c <= 0xff19) || /* Fullwidth digits */ + (c >= 0xff21 && c <= 0xff26) || /* Fullwidth letters */ + (c >= 0xff41 && c <= 0xff46)) == isprop) return !negated; break; diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c new file mode 100644 index 00000000000..95b9842fa97 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c @@ -0,0 +1,133 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * 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 COPYRIGHT HOLDER(S) 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 COPYRIGHT HOLDER(S) 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. + */ + +#include +#include +/* + On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a + version where it's OK to have more than one JIT block or where MAP_JIT is + required. + On non-macOS systems, returns MAP_JIT if it is defined. +*/ +#include + +#if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (TARGET_OS_MAC && !TARGET_OS_IPHONE) + +#if defined(SLJIT_CONFIG_X86) && SLJIT_CONFIG_X86 + +#include +#include + +#define SLJIT_MAP_JIT (get_map_jit_flag()) +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) + +static SLJIT_INLINE int get_map_jit_flag(void) +{ + size_t page_size; + void *ptr; + struct utsname name; + static int map_jit_flag = -1; + + if (map_jit_flag < 0) { + map_jit_flag = 0; + uname(&name); + + /* Kernel version for 10.14.0 (Mojave) or later */ + if (atoi(name.release) >= 18) { + page_size = get_page_alignment() + 1; + /* Only use MAP_JIT if a hardened runtime is used */ + ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANON, -1, 0); + + if (ptr != MAP_FAILED) + munmap(ptr, page_size); + else + map_jit_flag = MAP_JIT; + } + } + return map_jit_flag; +} + +#elif defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM + +#include +#include + +#define SLJIT_MAP_JIT (MAP_JIT) +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \ + apple_update_wx_flags(enable_exec) + +static SLJIT_INLINE void apple_update_wx_flags(sljit_s32 enable_exec) +{ +#if MAC_OS_X_VERSION_MIN_REQUIRED < 110000 + if (__builtin_available(macos 11, *)) +#endif /* BigSur */ + pthread_jit_write_protect_np(enable_exec); +} + +#elif defined(SLJIT_CONFIG_PPC) && SLJIT_CONFIG_PPC + +#define SLJIT_MAP_JIT (0) +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) + +#else +#error "Unsupported architecture" +#endif /* SLJIT_CONFIG */ + +#else /* !TARGET_OS_OSX */ + +#ifdef MAP_JIT +#define SLJIT_MAP_JIT (MAP_JIT) +#else +#define SLJIT_MAP_JIT (0) +#endif + +#endif /* TARGET_OS_OSX */ + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + void *retval; + int prot = PROT_READ | PROT_WRITE | PROT_EXEC; + int flags = MAP_PRIVATE; + int fd = -1; + + flags |= MAP_ANON | SLJIT_MAP_JIT; + + retval = mmap(NULL, size, prot, flags, fd, 0); + if (retval == MAP_FAILED) + return NULL; + + SLJIT_UPDATE_WX_FLAGS(retval, (uint8_t *)retval + size, 0); + + return retval; +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + munmap(chunk, size); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c new file mode 100644 index 00000000000..6cd391104c2 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c @@ -0,0 +1,330 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * 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 COPYRIGHT HOLDER(S) 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 COPYRIGHT HOLDER(S) 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. + */ + +/* + This file contains a simple executable memory allocator + + It is assumed, that executable code blocks are usually medium (or sometimes + large) memory blocks, and the allocator is not too frequently called (less + optimized than other allocators). Thus, using it as a generic allocator is + not suggested. + + How does it work: + Memory is allocated in continuous memory areas called chunks by alloc_chunk() + Chunk format: + [ block ][ block ] ... [ block ][ block terminator ] + + All blocks and the block terminator is started with block_header. The block + header contains the size of the previous and the next block. These sizes + can also contain special values. + Block size: + 0 - The block is a free_block, with a different size member. + 1 - The block is a block terminator. + n - The block is used at the moment, and the value contains its size. + Previous block size: + 0 - This is the first block of the memory chunk. + n - The size of the previous block. + + Using these size values we can go forward or backward on the block chain. + The unused blocks are stored in a chain list pointed by free_blocks. This + list is useful if we need to find a suitable memory area when the allocator + is called. + + When a block is freed, the new free block is connected to its adjacent free + blocks if possible. + + [ free block ][ used block ][ free block ] + and "used block" is freed, the three blocks are connected together: + [ one big free block ] +*/ + +/* Expected functions: + alloc_chunk / free_chunk : + * allocate executable system memory chunks + * the size is always divisible by CHUNK_SIZE + SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK : + * provided as part of sljitUtils + * only the allocator requires this lock, sljit is fully thread safe + as it only uses local variables + + Supported defines: + SLJIT_HAS_CHUNK_HEADER - (optional) sljit_chunk_header is defined + SLJIT_HAS_EXECUTABLE_OFFSET - (optional) has executable offset data + SLJIT_UPDATE_WX_FLAGS - (optional) update WX flags +*/ + +#ifdef SLJIT_HAS_CHUNK_HEADER +#define CHUNK_HEADER_SIZE (sizeof(struct sljit_chunk_header)) +#else /* !SLJIT_HAS_CHUNK_HEADER */ +#define CHUNK_HEADER_SIZE 0 +#endif /* SLJIT_HAS_CHUNK_HEADER */ + +#ifndef SLJIT_UPDATE_WX_FLAGS +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) +#endif /* SLJIT_UPDATE_WX_FLAGS */ + +#ifndef CHUNK_SIZE +/* 64 KByte if not specified. */ +#define CHUNK_SIZE (sljit_uw)0x10000 +#endif /* CHUNK_SIZE */ + +struct block_header { + sljit_uw size; + sljit_uw prev_size; +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + sljit_sw executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ +}; + +struct free_block { + struct block_header header; + struct free_block *next; + struct free_block *prev; + sljit_uw size; +}; + +#define AS_BLOCK_HEADER(base, offset) \ + ((struct block_header*)(((sljit_u8*)base) + offset)) +#define AS_FREE_BLOCK(base, offset) \ + ((struct free_block*)(((sljit_u8*)base) + offset)) +#define MEM_START(base) ((void*)((base) + 1)) +#define CHUNK_MASK (~(CHUNK_SIZE - 1)) +#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7u) & ~(sljit_uw)7) +#define CHUNK_EXTRA_SIZE (sizeof(struct block_header) + CHUNK_HEADER_SIZE) + +static struct free_block* free_blocks; +static sljit_uw allocated_size; +static sljit_uw total_size; + +static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size) +{ + free_block->header.size = 0; + free_block->size = size; + + free_block->next = free_blocks; + free_block->prev = NULL; + if (free_blocks) + free_blocks->prev = free_block; + free_blocks = free_block; +} + +static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block) +{ + if (free_block->next) + free_block->next->prev = free_block->prev; + + if (free_block->prev) + free_block->prev->next = free_block->next; + else { + SLJIT_ASSERT(free_blocks == free_block); + free_blocks = free_block->next; + } +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) +{ + struct block_header *header; + struct block_header *next_header; + struct free_block *free_block; + sljit_uw chunk_size; + +#ifdef SLJIT_HAS_CHUNK_HEADER + struct sljit_chunk_header *chunk_header; +#else /* !SLJIT_HAS_CHUNK_HEADER */ + void *chunk_header; +#endif /* SLJIT_HAS_CHUNK_HEADER */ + +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + sljit_sw executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + + if (size < (64 - sizeof(struct block_header))) + size = (64 - sizeof(struct block_header)); + size = ALIGN_SIZE(size); + + SLJIT_ALLOCATOR_LOCK(); + free_block = free_blocks; + while (free_block) { + if (free_block->size >= size) { + chunk_size = free_block->size; + SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0); + if (chunk_size > size + 64) { + /* We just cut a block from the end of the free block. */ + chunk_size -= size; + free_block->size = chunk_size; + header = AS_BLOCK_HEADER(free_block, chunk_size); + header->prev_size = chunk_size; +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + header->executable_offset = free_block->header.executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + AS_BLOCK_HEADER(header, size)->prev_size = size; + } + else { + sljit_remove_free_block(free_block); + header = (struct block_header*)free_block; + size = chunk_size; + } + allocated_size += size; + header->size = size; + SLJIT_ALLOCATOR_UNLOCK(); + return MEM_START(header); + } + free_block = free_block->next; + } + + chunk_size = (size + CHUNK_EXTRA_SIZE + CHUNK_SIZE - 1) & CHUNK_MASK; + + chunk_header = alloc_chunk(chunk_size); + if (!chunk_header) { + SLJIT_ALLOCATOR_UNLOCK(); + return NULL; + } + +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + executable_offset = (sljit_sw)((sljit_u8*)chunk_header->executable - (sljit_u8*)chunk_header); +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + + chunk_size -= CHUNK_EXTRA_SIZE; + total_size += chunk_size; + + header = (struct block_header*)(((sljit_u8*)chunk_header) + CHUNK_HEADER_SIZE); + + header->prev_size = 0; +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + header->executable_offset = executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + + if (chunk_size > size + 64) { + /* Cut the allocated space into a free and a used block. */ + allocated_size += size; + header->size = size; + chunk_size -= size; + + free_block = AS_FREE_BLOCK(header, size); + free_block->header.prev_size = size; +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + free_block->header.executable_offset = executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + sljit_insert_free_block(free_block, chunk_size); + next_header = AS_BLOCK_HEADER(free_block, chunk_size); + } + else { + /* All space belongs to this allocation. */ + allocated_size += chunk_size; + header->size = chunk_size; + next_header = AS_BLOCK_HEADER(header, chunk_size); + } + SLJIT_ALLOCATOR_UNLOCK(); + next_header->size = 1; + next_header->prev_size = chunk_size; +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + next_header->executable_offset = executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + return MEM_START(header); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) +{ + struct block_header *header; + struct free_block* free_block; + + SLJIT_ALLOCATOR_LOCK(); + header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header)); +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + header = AS_BLOCK_HEADER(header, -header->executable_offset); +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + allocated_size -= header->size; + + SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0); + + /* Connecting free blocks together if possible. */ + + /* If header->prev_size == 0, free_block will equal to header. + In this case, free_block->header.size will be > 0. */ + free_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size); + if (SLJIT_UNLIKELY(!free_block->header.size)) { + free_block->size += header->size; + header = AS_BLOCK_HEADER(free_block, free_block->size); + header->prev_size = free_block->size; + } + else { + free_block = (struct free_block*)header; + sljit_insert_free_block(free_block, header->size); + } + + header = AS_BLOCK_HEADER(free_block, free_block->size); + if (SLJIT_UNLIKELY(!header->size)) { + free_block->size += ((struct free_block*)header)->size; + sljit_remove_free_block((struct free_block*)header); + header = AS_BLOCK_HEADER(free_block, free_block->size); + header->prev_size = free_block->size; + } + + /* The whole chunk is free. */ + if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) { + /* If this block is freed, we still have (allocated_size / 2) free space. */ + if (total_size - free_block->size > (allocated_size * 3 / 2)) { + total_size -= free_block->size; + sljit_remove_free_block(free_block); + free_chunk(free_block, free_block->size + CHUNK_EXTRA_SIZE); + } + } + + SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1); + SLJIT_ALLOCATOR_UNLOCK(); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) +{ + struct free_block* free_block; + struct free_block* next_free_block; + + SLJIT_ALLOCATOR_LOCK(); + SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0); + + free_block = free_blocks; + while (free_block) { + next_free_block = free_block->next; + if (!free_block->header.prev_size && + AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) { + total_size -= free_block->size; + sljit_remove_free_block(free_block); + free_chunk(free_block, free_block->size + CHUNK_EXTRA_SIZE); + } + free_block = next_free_block; + } + + SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks)); + SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1); + SLJIT_ALLOCATOR_UNLOCK(); +} + +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET +SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr) +{ + return ((struct block_header *)(ptr))[-1].executable_offset; +} +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c new file mode 100644 index 00000000000..3b93a4df76c --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c @@ -0,0 +1,89 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * 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 COPYRIGHT HOLDER(S) 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 COPYRIGHT HOLDER(S) 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. + */ + +#include +#include + +#ifdef PROC_WXMAP_CTL +static SLJIT_INLINE int sljit_is_wx_block(void) +{ + static int wx_block = -1; + if (wx_block < 0) { + int sljit_wx_enable = PROC_WX_MAPPINGS_PERMIT; + wx_block = !!procctl(P_PID, 0, PROC_WXMAP_CTL, &sljit_wx_enable); + } + return wx_block; +} + +#define SLJIT_IS_WX_BLOCK sljit_is_wx_block() +#else /* !PROC_WXMAP_CTL */ +#define SLJIT_IS_WX_BLOCK (1) +#endif /* PROC_WXMAP_CTL */ + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + void *retval; + int prot = PROT_READ | PROT_WRITE | PROT_EXEC; + int flags = MAP_PRIVATE; + int fd = -1; + +#ifdef PROT_MAX + prot |= PROT_MAX(prot); +#endif + +#ifdef MAP_ANON + flags |= MAP_ANON; +#else /* !MAP_ANON */ + if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) + return NULL; + + fd = dev_zero; +#endif /* MAP_ANON */ + +retry: + retval = mmap(NULL, size, prot, flags, fd, 0); + if (retval == MAP_FAILED) { + if (!SLJIT_IS_WX_BLOCK) + goto retry; + + return NULL; + } + + /* HardenedBSD's mmap lies, so check permissions again. */ + if (mprotect(retval, size, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) { + munmap(retval, size); + return NULL; + } + + return retval; +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + munmap(chunk, size); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c new file mode 100644 index 00000000000..a775f5629a5 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c @@ -0,0 +1,62 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * 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 COPYRIGHT HOLDER(S) 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 COPYRIGHT HOLDER(S) 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. + */ + +#include +#include + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + void *retval; + int prot = PROT_READ | PROT_WRITE | PROT_EXEC; + int flags = MAP_PRIVATE; + int fd = -1; + +#ifdef PROT_MAX + prot |= PROT_MAX(prot); +#endif + +#ifdef MAP_ANON + flags |= MAP_ANON; +#else /* !MAP_ANON */ + if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) + return NULL; + + fd = dev_zero; +#endif /* MAP_ANON */ + + retval = mmap(NULL, size, prot, flags, fd, 0); + if (retval == MAP_FAILED) + return NULL; + + return retval; +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + munmap(chunk, size); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c new file mode 100644 index 00000000000..f152a5a2cd4 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c @@ -0,0 +1,40 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * 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 COPYRIGHT HOLDER(S) 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 COPYRIGHT HOLDER(S) 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. + */ + +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + SLJIT_UNUSED_ARG(size); + VirtualFree(chunk, 0, MEM_RELEASE); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c new file mode 100644 index 00000000000..0b7fd577879 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c @@ -0,0 +1,72 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * 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 COPYRIGHT HOLDER(S) 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 COPYRIGHT HOLDER(S) 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. + */ + +#define SLJIT_HAS_CHUNK_HEADER +#define SLJIT_HAS_EXECUTABLE_OFFSET + +struct sljit_chunk_header { + void *executable; +}; + +/* + * MAP_REMAPDUP is a NetBSD extension available sinde 8.0, make sure to + * adjust your feature macros (ex: -D_NETBSD_SOURCE) as needed + */ +static SLJIT_INLINE struct sljit_chunk_header* alloc_chunk(sljit_uw size) +{ + struct sljit_chunk_header *retval; + + retval = (struct sljit_chunk_header *)mmap(NULL, size, + PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC), + MAP_ANON | MAP_SHARED, -1, 0); + + if (retval == MAP_FAILED) + return NULL; + + retval->executable = mremap(retval, size, NULL, size, MAP_REMAPDUP); + if (retval->executable == MAP_FAILED) { + munmap((void *)retval, size); + return NULL; + } + + if (mprotect(retval->executable, size, PROT_READ | PROT_EXEC) == -1) { + munmap(retval->executable, size); + munmap((void *)retval, size); + return NULL; + } + + return retval; +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + struct sljit_chunk_header *header = ((struct sljit_chunk_header *)chunk) - 1; + + munmap(header->executable, size); + munmap((void *)header, size); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c new file mode 100644 index 00000000000..f7cb6c56705 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c @@ -0,0 +1,172 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * 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 COPYRIGHT HOLDER(S) 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 COPYRIGHT HOLDER(S) 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. + */ + +#define SLJIT_HAS_CHUNK_HEADER +#define SLJIT_HAS_EXECUTABLE_OFFSET + +struct sljit_chunk_header { + void *executable; +}; + +#include +#include +#include +#include + +#ifndef O_NOATIME +#define O_NOATIME 0 +#endif + +/* this is a linux extension available since kernel 3.11 */ +#ifndef O_TMPFILE +#define O_TMPFILE 0x404000 +#endif + +#ifndef _GNU_SOURCE +char *secure_getenv(const char *name); +int mkostemp(char *template, int flags); +#endif + +static SLJIT_INLINE int create_tempfile(void) +{ + int fd; + char tmp_name[256]; + size_t tmp_name_len = 0; + char *dir; + struct stat st; +#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED + mode_t mode; +#endif + +#ifdef HAVE_MEMFD_CREATE + /* this is a GNU extension, make sure to use -D_GNU_SOURCE */ + fd = memfd_create("sljit", MFD_CLOEXEC); + if (fd != -1) { + fchmod(fd, 0); + return fd; + } +#endif + + dir = secure_getenv("TMPDIR"); + + if (dir) { + size_t len = strlen(dir); + if (len > 0 && len < sizeof(tmp_name)) { + if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode)) { + memcpy(tmp_name, dir, len + 1); + tmp_name_len = len; + } + } + } + +#ifdef P_tmpdir + if (!tmp_name_len) { + tmp_name_len = strlen(P_tmpdir); + if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)) + strcpy(tmp_name, P_tmpdir); + } +#endif + if (!tmp_name_len) { + strcpy(tmp_name, "/tmp"); + tmp_name_len = 4; + } + + SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)); + + if (tmp_name_len > 1 && tmp_name[tmp_name_len - 1] == '/') + tmp_name[--tmp_name_len] = '\0'; + + fd = open(tmp_name, O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0); + if (fd != -1) + return fd; + + if (tmp_name_len >= sizeof(tmp_name) - 7) + return -1; + + strcpy(tmp_name + tmp_name_len, "/XXXXXX"); +#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED + mode = umask(0777); +#endif + fd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME); +#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED + umask(mode); +#else + fchmod(fd, 0); +#endif + + if (fd == -1) + return -1; + + if (unlink(tmp_name)) { + close(fd); + return -1; + } + + return fd; +} + +static SLJIT_INLINE struct sljit_chunk_header* alloc_chunk(sljit_uw size) +{ + struct sljit_chunk_header *retval; + int fd; + + fd = create_tempfile(); + if (fd == -1) + return NULL; + + if (ftruncate(fd, (off_t)size)) { + close(fd); + return NULL; + } + + retval = (struct sljit_chunk_header *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + if (retval == MAP_FAILED) { + close(fd); + return NULL; + } + + retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0); + + if (retval->executable == MAP_FAILED) { + munmap((void *)retval, size); + close(fd); + return NULL; + } + + close(fd); + return retval; +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + struct sljit_chunk_header *header = ((struct sljit_chunk_header *)chunk) - 1; + + munmap(header->executable, size); + munmap((void *)header, size); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c new file mode 100644 index 00000000000..36d301434a4 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c @@ -0,0 +1,141 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * 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 COPYRIGHT HOLDER(S) 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 COPYRIGHT HOLDER(S) 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. + */ + +/* + This file contains a simple W^X executable memory allocator + + In *NIX, MAP_ANON is required (that is considered a feature) so make + sure to set the right availability macros for your system or the code + will fail to build. + + If your system doesn't support mapping of anonymous pages (ex: IRIX) it + is also likely that it doesn't need this allocator and should be using + the standard one instead. + + It allocates a separate map for each code block and may waste a lot of + memory, because whatever was requested, will be rounded up to the page + size (minimum 4KB, but could be even bigger). + + It changes the page permissions (RW <-> RX) as needed and therefore, if you + will be updating the code after it has been generated, need to make sure to + block any concurrent execution, or could result in a SIGBUS, that could + even manifest itself at a different address than the one that was being + modified. + + Only use if you are unable to use the regular allocator because of security + restrictions and adding exceptions to your application or the system are + not possible. +*/ + +#include +#include + +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \ + sljit_update_wx_flags((from), (to), (enable_exec)) + +#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) +#include +#define SLJIT_SE_LOCK() pthread_mutex_lock(&se_lock) +#define SLJIT_SE_UNLOCK() pthread_mutex_unlock(&se_lock) +#else +#define SLJIT_SE_LOCK() +#define SLJIT_SE_UNLOCK() +#endif /* !SLJIT_SINGLE_THREADED */ + +#define SLJIT_WX_IS_BLOCK(ptr, size) generic_check_is_wx_block(ptr, size) + +static SLJIT_INLINE int generic_check_is_wx_block(void *ptr, sljit_uw size) +{ + if (SLJIT_LIKELY(!mprotect(ptr, size, PROT_EXEC))) + return !!mprotect(ptr, size, PROT_READ | PROT_WRITE); + + return 1; +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) +{ +#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) + static pthread_mutex_t se_lock = PTHREAD_MUTEX_INITIALIZER; +#endif + static int wx_block = -1; + int prot = PROT_READ | PROT_WRITE; + sljit_uw* ptr; + + if (SLJIT_UNLIKELY(wx_block > 0)) + return NULL; + +#ifdef PROT_MAX + prot |= PROT_MAX(PROT_READ | PROT_WRITE | PROT_EXEC); +#endif + + size += sizeof(sljit_uw); + ptr = (sljit_uw*)mmap(NULL, size, prot, MAP_PRIVATE | MAP_ANON, -1, 0); + + if (ptr == MAP_FAILED) + return NULL; + + if (SLJIT_UNLIKELY(wx_block < 0)) { + SLJIT_SE_LOCK(); + wx_block = SLJIT_WX_IS_BLOCK(ptr, size); + SLJIT_SE_UNLOCK(); + if (SLJIT_UNLIKELY(wx_block)) { + munmap((void *)ptr, size); + return NULL; + } + } + + *ptr++ = size; + return ptr; +} + +#undef SLJIT_SE_UNLOCK +#undef SLJIT_SE_LOCK + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) +{ + sljit_uw *start_ptr = ((sljit_uw*)ptr) - 1; + munmap((void*)start_ptr, *start_ptr); +} + +static void sljit_update_wx_flags(void *from, void *to, int enable_exec) +{ + sljit_uw page_mask = (sljit_uw)get_page_alignment(); + sljit_uw start = (sljit_uw)from; + sljit_uw end = (sljit_uw)to; + int prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE); + + SLJIT_ASSERT(start < end); + + start &= ~page_mask; + end = (end + page_mask) & ~page_mask; + + mprotect((void*)start, end - start, prot); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) +{ + /* This allocator does not keep unused memory for future allocations. */ +} diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c new file mode 100644 index 00000000000..a9553bd7da4 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c @@ -0,0 +1,102 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * 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 COPYRIGHT HOLDER(S) 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 COPYRIGHT HOLDER(S) 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. + */ + +/* + This file contains a simple W^X executable memory allocator + + In *NIX, MAP_ANON is required (that is considered a feature) so make + sure to set the right availability macros for your system or the code + will fail to build. + + If your system doesn't support mapping of anonymous pages (ex: IRIX) it + is also likely that it doesn't need this allocator and should be using + the standard one instead. + + It allocates a separate map for each code block and may waste a lot of + memory, because whatever was requested, will be rounded up to the page + size (minimum 4KB, but could be even bigger). + + It changes the page permissions (RW <-> RX) as needed and therefore, if you + will be updating the code after it has been generated, need to make sure to + block any concurrent execution, or could result in a SIGBUS, that could + even manifest itself at a different address than the one that was being + modified. + + Only use if you are unable to use the regular allocator because of security + restrictions and adding exceptions to your application or the system are + not possible. +*/ + +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \ + sljit_update_wx_flags((from), (to), (enable_exec)) + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) +{ + sljit_uw *ptr; + + size += sizeof(sljit_uw); + ptr = (sljit_uw*)VirtualAlloc(NULL, size, + MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + + if (!ptr) + return NULL; + + *ptr++ = size; + + return ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) +{ + sljit_uw start = (sljit_uw)ptr - sizeof(sljit_uw); +#if defined(SLJIT_DEBUG) && SLJIT_DEBUG + sljit_uw page_mask = (sljit_uw)get_page_alignment(); + + SLJIT_ASSERT(!(start & page_mask)); +#endif + VirtualFree((void*)start, 0, MEM_RELEASE); +} + +static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec) +{ + DWORD oldprot; + sljit_uw page_mask = (sljit_uw)get_page_alignment(); + sljit_uw start = (sljit_uw)from; + sljit_uw end = (sljit_uw)to; + DWORD prot = enable_exec ? PAGE_EXECUTE : PAGE_READWRITE; + + SLJIT_ASSERT(start < end); + + start &= ~page_mask; + end = (end + page_mask) & ~page_mask; + + VirtualProtect((void*)start, end - start, prot, &oldprot); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) +{ + /* This allocator does not keep unused memory for future allocations. */ +} diff --git a/src/3rdparty/pcre2/src/sljit/sljitConfig.h b/src/3rdparty/pcre2/src/sljit/sljitConfig.h index 5fba7aa6380..364c8bb7884 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitConfig.h +++ b/src/3rdparty/pcre2/src/sljit/sljitConfig.h @@ -38,28 +38,6 @@ extern "C" { non-zero value. */ -/* --------------------------------------------------------------------- */ -/* Architecture */ -/* --------------------------------------------------------------------- */ - -/* Architecture selection. */ -/* #define SLJIT_CONFIG_X86_32 1 */ -/* #define SLJIT_CONFIG_X86_64 1 */ -/* #define SLJIT_CONFIG_ARM_V5 1 */ -/* #define SLJIT_CONFIG_ARM_V7 1 */ -/* #define SLJIT_CONFIG_ARM_THUMB2 1 */ -/* #define SLJIT_CONFIG_ARM_64 1 */ -/* #define SLJIT_CONFIG_PPC_32 1 */ -/* #define SLJIT_CONFIG_PPC_64 1 */ -/* #define SLJIT_CONFIG_MIPS_32 1 */ -/* #define SLJIT_CONFIG_MIPS_64 1 */ -/* #define SLJIT_CONFIG_RISCV_32 1 */ -/* #define SLJIT_CONFIG_RISCV_64 1 */ -/* #define SLJIT_CONFIG_S390X 1 */ - -/* #define SLJIT_CONFIG_AUTO 1 */ -/* #define SLJIT_CONFIG_UNSUPPORTED 1 */ - /* --------------------------------------------------------------------- */ /* Utilities */ /* --------------------------------------------------------------------- */ @@ -96,7 +74,9 @@ extern "C" { /* Executable code allocation: If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should - define SLJIT_MALLOC_EXEC, SLJIT_FREE_EXEC, and SLJIT_EXEC_OFFSET. */ + define SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. + Optionally, depending on the implementation used for the allocator, + SLJIT_EXEC_OFFSET and SLJIT_UPDATE_WX_FLAGS might also be needed. */ #ifndef SLJIT_EXECUTABLE_ALLOCATOR /* Enabled by default. */ #define SLJIT_EXECUTABLE_ALLOCATOR 1 diff --git a/src/3rdparty/pcre2/src/sljit/sljitConfigCPU.h b/src/3rdparty/pcre2/src/sljit/sljitConfigCPU.h new file mode 100644 index 00000000000..2720bdab0bd --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/sljitConfigCPU.h @@ -0,0 +1,188 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * 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 COPYRIGHT HOLDER(S) 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 COPYRIGHT HOLDER(S) 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. + */ + +#ifndef SLJIT_CONFIG_CPU_H_ +#define SLJIT_CONFIG_CPU_H_ + +/* --------------------------------------------------------------------- */ +/* Architecture */ +/* --------------------------------------------------------------------- */ + +/* Architecture selection. */ +/* #define SLJIT_CONFIG_X86_32 1 */ +/* #define SLJIT_CONFIG_X86_64 1 */ +/* #define SLJIT_CONFIG_ARM_V6 1 */ +/* #define SLJIT_CONFIG_ARM_V7 1 */ +/* #define SLJIT_CONFIG_ARM_THUMB2 1 */ +/* #define SLJIT_CONFIG_ARM_64 1 */ +/* #define SLJIT_CONFIG_PPC_32 1 */ +/* #define SLJIT_CONFIG_PPC_64 1 */ +/* #define SLJIT_CONFIG_MIPS_32 1 */ +/* #define SLJIT_CONFIG_MIPS_64 1 */ +/* #define SLJIT_CONFIG_RISCV_32 1 */ +/* #define SLJIT_CONFIG_RISCV_64 1 */ +/* #define SLJIT_CONFIG_S390X 1 */ +/* #define SLJIT_CONFIG_LOONGARCH_64 */ + +/* #define SLJIT_CONFIG_AUTO 1 */ +/* #define SLJIT_CONFIG_UNSUPPORTED 1 */ + +/*****************/ +/* Sanity check. */ +/*****************/ + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + + (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) \ + + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + + (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ + + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ + + (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \ + + (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ + + (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + + (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) \ + + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ + + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 +#error "Multiple architectures are selected" +#endif + +#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + && !(defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) \ + && !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + && !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ + && !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + && !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ + && !(defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \ + && !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ + && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + && !(defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) \ + && !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \ + && !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) +#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO +#error "An architecture must be selected" +#else /* SLJIT_CONFIG_AUTO */ +#define SLJIT_CONFIG_AUTO 1 +#endif /* !SLJIT_CONFIG_AUTO */ +#endif /* !SLJIT_CONFIG */ + +/********************************************************/ +/* Automatic CPU detection (requires compiler support). */ +/********************************************************/ + +#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) +#ifndef _WIN32 + +#if defined(__i386__) || defined(__i386) +#define SLJIT_CONFIG_X86_32 1 +#elif defined(__x86_64__) +#define SLJIT_CONFIG_X86_64 1 +#elif defined(__aarch64__) +#define SLJIT_CONFIG_ARM_64 1 +#elif defined(__thumb2__) +#define SLJIT_CONFIG_ARM_THUMB2 1 +#elif (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \ + ((defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7S__)) \ + || (defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8R__)) \ + || (defined(__ARM_ARCH_9A__))) +#define SLJIT_CONFIG_ARM_V7 1 +#elif defined(__arm__) || defined (__ARM__) +#define SLJIT_CONFIG_ARM_V6 1 +#elif defined(__ppc64__) || defined(__powerpc64__) || (defined(_ARCH_PPC64) && defined(__64BIT__)) || (defined(_POWER) && defined(__64BIT__)) +#define SLJIT_CONFIG_PPC_64 1 +#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER) +#define SLJIT_CONFIG_PPC_32 1 +#elif defined(__mips__) && !defined(_LP64) +#define SLJIT_CONFIG_MIPS_32 1 +#elif defined(__mips64) +#define SLJIT_CONFIG_MIPS_64 1 +#elif defined (__riscv_xlen) && (__riscv_xlen == 32) +#define SLJIT_CONFIG_RISCV_32 1 +#elif defined (__riscv_xlen) && (__riscv_xlen == 64) +#define SLJIT_CONFIG_RISCV_64 1 +#elif defined (__loongarch_lp64) +#define SLJIT_CONFIG_LOONGARCH_64 1 +#elif defined(__s390x__) +#define SLJIT_CONFIG_S390X 1 +#else +/* Unsupported architecture */ +#define SLJIT_CONFIG_UNSUPPORTED 1 +#endif + +#else /* _WIN32 */ + +#if defined(_M_X64) || defined(__x86_64__) +#define SLJIT_CONFIG_X86_64 1 +#elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__) +#define SLJIT_CONFIG_ARM_THUMB2 1 +#elif (defined(_M_ARM) && _M_ARM >= 7) +#define SLJIT_CONFIG_ARM_V7 1 +#elif defined(_ARM_) +#define SLJIT_CONFIG_ARM_V6 1 +#elif defined(_M_ARM64) || defined(__aarch64__) +#define SLJIT_CONFIG_ARM_64 1 +#else +#define SLJIT_CONFIG_X86_32 1 +#endif + +#endif /* !_WIN32 */ +#endif /* SLJIT_CONFIG_AUTO */ + +#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) +#undef SLJIT_EXECUTABLE_ALLOCATOR +#endif /* SLJIT_CONFIG_UNSUPPORTED */ + +/******************************/ +/* CPU family type detection. */ +/******************************/ + +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) +#define SLJIT_CONFIG_ARM_32 1 +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +#define SLJIT_CONFIG_X86 1 +#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) +#define SLJIT_CONFIG_ARM 1 +#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_CONFIG_PPC 1 +#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) +#define SLJIT_CONFIG_MIPS 1 +#elif (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) +#define SLJIT_CONFIG_RISCV 1 +#elif (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) +#define SLJIT_CONFIG_LOONGARCH 1 +#endif + +#endif /* SLJIT_CONFIG_CPU_H_ */ diff --git a/src/3rdparty/pcre2/src/sljit/sljitConfigInternal.h b/src/3rdparty/pcre2/src/sljit/sljitConfigInternal.h index cd3ce697346..ce4e7b04ec4 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitConfigInternal.h +++ b/src/3rdparty/pcre2/src/sljit/sljitConfigInternal.h @@ -61,6 +61,8 @@ extern "C" { SLJIT_BIG_ENDIAN : big endian architecture SLJIT_UNALIGNED : unaligned memory accesses for non-fpu operations are supported SLJIT_FPU_UNALIGNED : unaligned memory accesses for fpu operations are supported + SLJIT_MASKED_SHIFT : all word shifts are always masked + SLJIT_MASKED_SHIFT32 : all 32 bit shifts are always masked SLJIT_INDIRECT_CALL : see SLJIT_FUNC_ADDR() for more information Constants: @@ -70,6 +72,8 @@ extern "C" { SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS : number of available temporary registers + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS : number of available temporary floating point registers SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index SLJIT_F32_SHIFT : the shift required to apply when accessing a single precision floating point array by index @@ -79,141 +83,27 @@ extern "C" { the scratch register index of ecx is stored in this variable SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET) SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address + SLJIT_CONV_MAX_FLOAT : result when a floating point value is converted to integer + and the floating point value is higher than the maximum integer value + (possible values: SLJIT_CONV_RESULT_MAX_INT or SLJIT_CONV_RESULT_MIN_INT) + SLJIT_CONV_MIN_FLOAT : result when a floating point value is converted to integer + and the floating point value is lower than the minimum integer value + (possible values: SLJIT_CONV_RESULT_MAX_INT or SLJIT_CONV_RESULT_MIN_INT) + SLJIT_CONV_NAN_FLOAT : result when a NaN floating point value is converted to integer + (possible values: SLJIT_CONV_RESULT_MAX_INT, SLJIT_CONV_RESULT_MIN_INT, + or SLJIT_CONV_RESULT_ZERO) Other macros: + SLJIT_TMP_R0 .. R9 : accessing temporary registers + SLJIT_TMP_R(i) : accessing temporary registers + SLJIT_TMP_FR0 .. FR9 : accessing temporary floating point registers + SLJIT_TMP_FR(i) : accessing temporary floating point registers SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper) + SLJIT_F64_SECOND(reg) : provides the register index of the second 32 bit part of a 64 bit + floating point register when SLJIT_HAS_F64_AS_F32_PAIR returns non-zero */ -/*****************/ -/* Sanity check. */ -/*****************/ - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ - + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ - + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ - + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ - + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ - + (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ - + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ - + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ - + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ - + (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \ - + (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ - + (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ - + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ - + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 -#error "Multiple architectures are selected" -#endif - -#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ - && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ - && !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ - && !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ - && !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ - && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ - && !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ - && !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ - && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ - && !(defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \ - && !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ - && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ - && !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \ - && !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) -#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO -#error "An architecture must be selected" -#else /* SLJIT_CONFIG_AUTO */ -#define SLJIT_CONFIG_AUTO 1 -#endif /* !SLJIT_CONFIG_AUTO */ -#endif /* !SLJIT_CONFIG */ - -/********************************************************/ -/* Automatic CPU detection (requires compiler support). */ -/********************************************************/ - -#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) - -#ifndef _WIN32 - -#if defined(__i386__) || defined(__i386) -#define SLJIT_CONFIG_X86_32 1 -#elif defined(__x86_64__) -#define SLJIT_CONFIG_X86_64 1 -#elif defined(__arm__) || defined(__ARM__) -#ifdef __thumb2__ -#define SLJIT_CONFIG_ARM_THUMB2 1 -#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) -#define SLJIT_CONFIG_ARM_V7 1 -#else -#define SLJIT_CONFIG_ARM_V5 1 -#endif -#elif defined (__aarch64__) -#define SLJIT_CONFIG_ARM_64 1 -#elif defined(__ppc64__) || defined(__powerpc64__) || (defined(_ARCH_PPC64) && defined(__64BIT__)) || (defined(_POWER) && defined(__64BIT__)) -#define SLJIT_CONFIG_PPC_64 1 -#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER) -#define SLJIT_CONFIG_PPC_32 1 -#elif defined(__mips__) && !defined(_LP64) -#define SLJIT_CONFIG_MIPS_32 1 -#elif defined(__mips64) -#define SLJIT_CONFIG_MIPS_64 1 -#elif defined (__riscv_xlen) && (__riscv_xlen == 32) -#define SLJIT_CONFIG_RISCV_32 1 -#elif defined (__riscv_xlen) && (__riscv_xlen == 64) -#define SLJIT_CONFIG_RISCV_64 1 -#elif defined(__s390x__) -#define SLJIT_CONFIG_S390X 1 -#else -/* Unsupported architecture */ -#define SLJIT_CONFIG_UNSUPPORTED 1 -#endif - -#else /* _WIN32 */ - -#if defined(_M_X64) || defined(__x86_64__) -#define SLJIT_CONFIG_X86_64 1 -#elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__) -#define SLJIT_CONFIG_ARM_THUMB2 1 -#elif (defined(_M_ARM) && _M_ARM >= 7) -#define SLJIT_CONFIG_ARM_V7 1 -#elif defined(_ARM_) -#define SLJIT_CONFIG_ARM_V5 1 -#elif defined(_M_ARM64) || defined(__aarch64__) -#define SLJIT_CONFIG_ARM_64 1 -#else -#define SLJIT_CONFIG_X86_32 1 -#endif - -#endif /* !_WIN32 */ -#endif /* SLJIT_CONFIG_AUTO */ - -#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) -#undef SLJIT_EXECUTABLE_ALLOCATOR -#endif - -/******************************/ -/* CPU family type detection. */ -/******************************/ - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ - || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) -#define SLJIT_CONFIG_ARM_32 1 -#endif - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -#define SLJIT_CONFIG_X86 1 -#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) -#define SLJIT_CONFIG_ARM 1 -#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define SLJIT_CONFIG_PPC 1 -#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) -#define SLJIT_CONFIG_MIPS 1 -#elif (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) -#define SLJIT_CONFIG_RISCV 1 -#endif - /***********************************************************/ /* Intel Control-flow Enforcement Technology (CET) spport. */ /***********************************************************/ @@ -328,6 +218,10 @@ extern "C" { /* Instruction cache flush. */ /****************************/ +#ifdef __APPLE__ +#include +#endif + /* * TODO: * @@ -368,7 +262,7 @@ extern "C" { /* Not required to implement on archs with unified caches. */ #define SLJIT_CACHE_FLUSH(from, to) -#elif defined __APPLE__ +#elif defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 /* Supported by all macs since Mac OS 10.5. However, it does not work on non-jailbroken iOS devices, @@ -433,14 +327,15 @@ typedef signed int sljit_s32; #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) /* Just to have something. */ #define SLJIT_WORD_SHIFT 0 -typedef unsigned long int sljit_uw; -typedef long int sljit_sw; +typedef unsigned int sljit_uw; +typedef int sljit_sw; #elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ && !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ - && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + && !(defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) #define SLJIT_32BIT_ARCHITECTURE 1 #define SLJIT_WORD_SHIFT 2 typedef unsigned int sljit_uw; @@ -476,12 +371,42 @@ typedef double sljit_f64; #define SLJIT_F32_SHIFT 2 #define SLJIT_F64_SHIFT 3 +#define SLJIT_CONV_RESULT_MAX_INT 0 +#define SLJIT_CONV_RESULT_MIN_INT 1 +#define SLJIT_CONV_RESULT_ZERO 2 + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#elif (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_ZERO +#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MAX_INT +#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MAX_INT +#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#else +#error "Result for float to integer conversion is not defined" +#endif + #ifndef SLJIT_W /* Defining long constants. */ -#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) -#define SLJIT_W(w) (w##l) -#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) #ifdef _WIN64 #define SLJIT_W(w) (w##ll) #else /* !windows */ @@ -521,9 +446,10 @@ typedef double sljit_f64; /* Auto detecting mips revision. */ #if (defined __mips_isa_rev) && (__mips_isa_rev >= 6) #define SLJIT_MIPS_REV 6 -#elif (defined __mips_isa_rev && __mips_isa_rev >= 1) \ - || (defined __clang__ && defined _MIPS_ARCH_OCTEON) \ - || (defined __clang__ && defined _MIPS_ARCH_P5600) +#elif defined(__mips_isa_rev) && __mips_isa_rev >= 1 +#define SLJIT_MIPS_REV __mips_isa_rev +#elif defined(__clang__) \ + && (defined(_MIPS_ARCH_OCTEON) || defined(_MIPS_ARCH_P5600)) /* clang either forgets to define (clang-7) __mips_isa_rev at all * or sets it to zero (clang-8,-9) for -march=octeon (MIPS64 R2+) * and -march=p5600 (MIPS32 R5). @@ -562,7 +488,8 @@ typedef double sljit_f64; || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \ || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ - || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + || (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) #define SLJIT_UNALIGNED 1 #endif @@ -574,7 +501,8 @@ typedef double sljit_f64; || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \ || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ - || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + || (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) #define SLJIT_FPU_UNALIGNED 1 #endif @@ -594,6 +522,19 @@ typedef double sljit_f64; #define SLJIT_FUNC #endif /* !SLJIT_FUNC */ +/* Disable instrumentation for these functions as they may not be sound */ +#ifndef SLJIT_FUNC_ATTRIBUTE +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#define SLJIT_FUNC_ATTRIBUTE __attribute__((no_sanitize("memory"))) +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ +#endif + +#ifndef SLJIT_FUNC_ATTRIBUTE +#define SLJIT_FUNC_ATTRIBUTE +#endif + #ifndef SLJIT_INDIRECT_CALL #if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (!defined _CALL_ELF || _CALL_ELF == 1)) \ || ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX) @@ -631,12 +572,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void); #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_EXEC_OFFSET(ptr) sljit_exec_offset(ptr) -#else -#define SLJIT_EXEC_OFFSET(ptr) 0 #endif #endif /* SLJIT_EXECUTABLE_ALLOCATOR */ +#ifndef SLJIT_EXEC_OFFSET +#define SLJIT_EXEC_OFFSET(ptr) 0 +#endif + /**********************************************/ /* Registers and locals offset determination. */ /**********************************************/ @@ -645,15 +588,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_NUMBER_OF_REGISTERS 12 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 7 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 1 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 7 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1 #define SLJIT_LOCALS_OFFSET_BASE (8 * SSIZE_OF(sw)) #define SLJIT_PREF_SHIFT_REG SLJIT_R2 +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 #elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #define SLJIT_NUMBER_OF_REGISTERS 13 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 2 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1 #ifndef _WIN64 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 6 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0 @@ -664,37 +613,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_LOCALS_OFFSET_BASE (4 * SSIZE_OF(sw)) #endif /* !_WIN64 */ #define SLJIT_PREF_SHIFT_REG SLJIT_R3 +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 -#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - -#define SLJIT_NUMBER_OF_REGISTERS 12 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 -#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14 -#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8 -#define SLJIT_LOCALS_OFFSET_BASE 0 - -#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) +#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) #define SLJIT_NUMBER_OF_REGISTERS 12 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 2 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 #define SLJIT_LOCALS_OFFSET_BASE 0 #elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) #define SLJIT_NUMBER_OF_REGISTERS 26 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 10 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 #define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof(sljit_sw)) +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 #elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) #define SLJIT_NUMBER_OF_REGISTERS 23 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 17 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 18 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX) #define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * (sljit_s32)sizeof(sljit_sw)) #elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) @@ -717,14 +668,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 29 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8 #endif +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 3 +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 #elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) #define SLJIT_NUMBER_OF_REGISTERS 23 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 12 -#define SLJIT_LOCALS_OFFSET_BASE 0 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 +#define SLJIT_LOCALS_OFFSET_BASE 0 +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) @@ -751,16 +710,34 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_NUMBER_OF_REGISTERS 12 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1 #define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE +#define SLJIT_MASKED_SHIFT 1 + +#elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) + +#define SLJIT_NUMBER_OF_REGISTERS 23 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5 +#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30 +#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 +#define SLJIT_LOCALS_OFFSET_BASE 0 +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 #elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) +/* Just to have something. */ #define SLJIT_NUMBER_OF_REGISTERS 0 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 0 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 0 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 0 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 0 #define SLJIT_LOCALS_OFFSET_BASE 0 #endif @@ -773,6 +750,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \ (SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS) +/**********************************/ +/* Temporary register management. */ +/**********************************/ + +#define SLJIT_TMP_REGISTER_BASE (SLJIT_NUMBER_OF_REGISTERS + 2) +#define SLJIT_TMP_FREGISTER_BASE (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) + +/* WARNING: Accessing temporary registers is not recommended, because they + are also used by the JIT compiler for various computations. Using them + might have any side effects including incorrect operations and crashes, + so use them at your own risk. The machine registers themselves might have + limitations, e.g. the r0 register on s390x / ppc cannot be used as + base address for memory operations. */ + +/* Temporary registers */ +#define SLJIT_TMP_R0 (SLJIT_TMP_REGISTER_BASE + 0) +#define SLJIT_TMP_R1 (SLJIT_TMP_REGISTER_BASE + 1) +#define SLJIT_TMP_R2 (SLJIT_TMP_REGISTER_BASE + 2) +#define SLJIT_TMP_R3 (SLJIT_TMP_REGISTER_BASE + 3) +#define SLJIT_TMP_R4 (SLJIT_TMP_REGISTER_BASE + 4) +#define SLJIT_TMP_R5 (SLJIT_TMP_REGISTER_BASE + 5) +#define SLJIT_TMP_R6 (SLJIT_TMP_REGISTER_BASE + 6) +#define SLJIT_TMP_R7 (SLJIT_TMP_REGISTER_BASE + 7) +#define SLJIT_TMP_R8 (SLJIT_TMP_REGISTER_BASE + 8) +#define SLJIT_TMP_R9 (SLJIT_TMP_REGISTER_BASE + 9) +#define SLJIT_TMP_R(i) (SLJIT_TMP_REGISTER_BASE + (i)) + +#define SLJIT_TMP_FR0 (SLJIT_TMP_FREGISTER_BASE + 0) +#define SLJIT_TMP_FR1 (SLJIT_TMP_FREGISTER_BASE + 1) +#define SLJIT_TMP_FR2 (SLJIT_TMP_FREGISTER_BASE + 2) +#define SLJIT_TMP_FR3 (SLJIT_TMP_FREGISTER_BASE + 3) +#define SLJIT_TMP_FR4 (SLJIT_TMP_FREGISTER_BASE + 4) +#define SLJIT_TMP_FR5 (SLJIT_TMP_FREGISTER_BASE + 5) +#define SLJIT_TMP_FR6 (SLJIT_TMP_FREGISTER_BASE + 6) +#define SLJIT_TMP_FR7 (SLJIT_TMP_FREGISTER_BASE + 7) +#define SLJIT_TMP_FR8 (SLJIT_TMP_FREGISTER_BASE + 8) +#define SLJIT_TMP_FR9 (SLJIT_TMP_FREGISTER_BASE + 9) +#define SLJIT_TMP_FR(i) (SLJIT_TMP_FREGISTER_BASE + (i)) + /********************************/ /* CPU status flags management. */ /********************************/ @@ -781,10 +797,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \ || (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \ || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ - || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + || (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) #define SLJIT_HAS_STATUS_FLAGS_STATE 1 #endif +/***************************************/ +/* Floating point register management. */ +/***************************************/ + +#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \ + || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define SLJIT_F64_SECOND(reg) \ + ((reg) + SLJIT_FS0 + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS) +#else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */ +#define SLJIT_F64_SECOND(reg) \ + (reg) +#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */ + /*************************************/ /* Debug and verbose related macros. */ /*************************************/ diff --git a/src/3rdparty/pcre2/src/sljit/sljitLir.c b/src/3rdparty/pcre2/src/sljit/sljitLir.c index abafe1add97..6f19300081a 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitLir.c +++ b/src/3rdparty/pcre2/src/sljit/sljitLir.c @@ -93,7 +93,8 @@ #define SSIZE_OF(type) ((sljit_s32)sizeof(sljit_ ## type)) #define VARIABLE_FLAG_SHIFT (10) -#define VARIABLE_FLAG_MASK (0x3f << VARIABLE_FLAG_SHIFT) +/* All variable flags are even. */ +#define VARIABLE_FLAG_MASK (0x3e << VARIABLE_FLAG_SHIFT) #define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT) #define GET_OPCODE(op) \ @@ -122,25 +123,34 @@ #endif /* Parameter parsing. */ -#define REG_MASK 0x3f +#define REG_MASK 0x7f #define OFFS_REG(reg) (((reg) >> 8) & REG_MASK) #define OFFS_REG_MASK (REG_MASK << 8) #define TO_OFFS_REG(reg) ((reg) << 8) -/* When reg cannot be unused. */ -#define FAST_IS_REG(reg) ((reg) <= REG_MASK) +#define FAST_IS_REG(reg) ((reg) < REG_MASK) /* Mask for argument types. */ #define SLJIT_ARG_MASK 0x7 #define SLJIT_ARG_FULL_MASK (SLJIT_ARG_MASK | SLJIT_ARG_TYPE_SCRATCH_REG) -/* Mask for sljit_emit_mem. */ -#define REG_PAIR_MASK 0xff00 -#define REG_PAIR_FIRST(reg) ((reg) & 0xff) +/* Mask for register pairs. */ +#define REG_PAIR_MASK 0x7f00 +#define REG_PAIR_FIRST(reg) ((reg) & 0x7f) #define REG_PAIR_SECOND(reg) ((reg) >> 8) /* Mask for sljit_emit_enter. */ #define SLJIT_KEPT_SAVEDS_COUNT(options) ((options) & 0x3) +/* Getters for simd operations, which returns with log2(size). */ +#define SLJIT_SIMD_GET_OPCODE(type) ((type) & 0xff) +#define SLJIT_SIMD_GET_REG_SIZE(type) (((type) >> 12) & 0x3f) +#define SLJIT_SIMD_GET_ELEM_SIZE(type) (((type) >> 18) & 0x3f) +#define SLJIT_SIMD_GET_ELEM2_SIZE(type) (((type) >> 24) & 0x3f) + +#define SLJIT_SIMD_CHECK_REG(type) (((type) & 0x3f000) >= SLJIT_SIMD_REG_64 && ((type) & 0x3f000) <= SLJIT_SIMD_REG_512) +#define SLJIT_SIMD_TYPE_MASK(m) ((sljit_s32)0xff000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m))) +#define SLJIT_SIMD_TYPE_MASK2(m) ((sljit_s32)0xc0000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m))) + /* Jump flags. */ #define JUMP_LABEL 0x1 #define JUMP_ADDR 0x2 @@ -155,14 +165,14 @@ # define TYPE_SHIFT 13 #endif /* SLJIT_CONFIG_X86 */ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) # define IS_BL 0x4 # define PATCH_B 0x8 -#endif /* SLJIT_CONFIG_ARM_V5 || SLJIT_CONFIG_ARM_V7 */ +#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V6 */ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) # define CPOOL_SIZE 512 -#endif /* SLJIT_CONFIG_ARM_V5 */ +#endif /* SLJIT_CONFIG_ARM_V6 */ #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) # define IS_COND 0x04 @@ -248,15 +258,27 @@ #endif /* SLJIT_CONFIG_RISCV_64 */ #endif /* SLJIT_CONFIG_RISCV */ +#if (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) +# define IS_COND 0x004 +# define IS_CALL 0x008 + +# define PATCH_B 0x010 +# define PATCH_J 0x020 + +# define PATCH_REL32 0x040 +# define PATCH_ABS32 0x080 +# define PATCH_ABS52 0x100 + +#endif /* SLJIT_CONFIG_LOONGARCH */ /* Stack management. */ #define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \ (((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \ (saveds) + (sljit_s32)(extra)) * (sljit_s32)sizeof(sljit_sw)) -#define GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, size) \ +#define GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, type) \ (((fscratches < SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS ? 0 : (fscratches - SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)) + \ - (fsaveds)) * (sljit_s32)(size)) + (fsaveds)) * SSIZE_OF(type)) #define ADJUST_LOCAL_OFFSET(p, i) \ if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ @@ -272,25 +294,49 @@ #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) -#include "sljitProtExecAllocator.c" -#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR) -#include "sljitWXExecAllocator.c" + +#if defined(__NetBSD__) +#include "allocator_src/sljitProtExecAllocatorNetBSD.c" #else -#include "sljitExecAllocator.c" +#include "allocator_src/sljitProtExecAllocatorPosix.c" +#endif + +#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR) + +#if defined(_WIN32) +#include "allocator_src/sljitWXExecAllocatorWindows.c" +#else +#include "allocator_src/sljitWXExecAllocatorPosix.c" +#endif + +#else + +#if defined(_WIN32) +#include "allocator_src/sljitExecAllocatorWindows.c" +#elif defined(__APPLE__) +#include "allocator_src/sljitExecAllocatorApple.c" +#elif defined(__FreeBSD__) +#include "allocator_src/sljitExecAllocatorFreeBSD.c" +#else +#include "allocator_src/sljitExecAllocatorPosix.c" #endif #endif +#else /* !SLJIT_EXECUTABLE_ALLOCATOR */ + +#ifndef SLJIT_UPDATE_WX_FLAGS +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) +#endif + +#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ + #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset)) #else #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr)) #endif -#ifndef SLJIT_UPDATE_WX_FLAGS -#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) -#endif - /* Argument checking features. */ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -422,9 +468,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) compiler->args_size = -1; -#endif +#endif /* SLJIT_CONFIG_X86_32 */ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) + CPOOL_SIZE * sizeof(sljit_u8), allocator_data); if (!compiler->cpool) { @@ -435,18 +481,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo } compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE); compiler->cpool_diff = 0xffffffff; -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) compiler->delay_slot = UNMOVABLE_INS; -#endif +#endif /* SLJIT_CONFIG_MIPS */ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->last_flags = 0; compiler->last_return = -1; compiler->logical_local_size = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT) if (!compiler_initialized) { @@ -479,7 +525,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile SLJIT_FREE(curr, allocator_data); } -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) SLJIT_FREE(compiler->cpool, allocator_data); #endif SLJIT_FREE(compiler, allocator_data); @@ -802,11 +848,8 @@ static sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratch #define FUNCTION_CHECK_IS_REG(r) \ (((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) \ - || ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0)) - -#define FUNCTION_CHECK_IS_FREG(fr) \ - (((fr) >= SLJIT_FR0 && (fr) < (SLJIT_FR0 + compiler->fscratches)) \ - || ((fr) > (SLJIT_FS0 - compiler->fsaveds) && (fr) <= SLJIT_FS0)) + || ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0) \ + || ((r) >= SLJIT_TMP_REGISTER_BASE && (r) < (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS))) #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #define CHECK_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8) @@ -816,7 +859,7 @@ static sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratch static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if (compiler->scratches == -1 || compiler->saveds == -1) + if (compiler->scratches == -1) return 0; if (!(p & SLJIT_MEM)) @@ -853,7 +896,7 @@ static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s static sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if (compiler->scratches == -1 || compiler->saveds == -1) + if (compiler->scratches == -1) return 0; if (FUNCTION_CHECK_IS_REG(p)) @@ -870,7 +913,7 @@ static sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if (compiler->scratches == -1 || compiler->saveds == -1) + if (compiler->scratches == -1) return 0; if (FUNCTION_CHECK_IS_REG(p)) @@ -882,19 +925,59 @@ static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p #define FUNCTION_CHECK_DST(p, i) \ CHECK_ARGUMENT(function_check_dst(compiler, p, i)); -static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) +#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \ + || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + +#define FUNCTION_CHECK_IS_FREG(fr, is_32) \ + function_check_is_freg(compiler, (fr), (is_32)) + +static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32); + +#define FUNCTION_FCHECK(p, i, is_32) \ + CHECK_ARGUMENT(function_fcheck(compiler, (p), (i), (is_32))); + +static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 is_32) { - if (compiler->scratches == -1 || compiler->saveds == -1) + if (compiler->scratches == -1) return 0; - if (FUNCTION_CHECK_IS_FREG(p)) + if (FUNCTION_CHECK_IS_FREG(p, is_32)) return (i == 0); return function_check_src_mem(compiler, p, i); } -#define FUNCTION_FCHECK(p, i) \ - CHECK_ARGUMENT(function_fcheck(compiler, p, i)); +#else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */ +#define FUNCTION_CHECK_IS_FREG(fr, is_32) \ + function_check_is_freg(compiler, (fr)) + +static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr) +{ + if (compiler->scratches == -1) + return 0; + + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) + || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); +} + +#define FUNCTION_FCHECK(p, i, is_32) \ + CHECK_ARGUMENT(function_fcheck(compiler, (p), (i))); + +static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) +{ + if (compiler->scratches == -1) + return 0; + + if ((p >= SLJIT_FR0 && p < (SLJIT_FR0 + compiler->fscratches)) + || (p > (SLJIT_FS0 - compiler->fsaveds) && p <= SLJIT_FS0) + || (p >= SLJIT_TMP_FREGISTER_BASE && p < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS))) + return (i == 0); + + return function_check_src_mem(compiler, p, i); +} + +#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */ #endif /* SLJIT_ARGUMENT_CHECKS */ @@ -923,23 +1006,35 @@ static void sljit_verbose_reg(struct sljit_compiler *compiler, sljit_s32 r) { if (r < (SLJIT_R0 + compiler->scratches)) fprintf(compiler->verbose, "r%d", r - SLJIT_R0); - else if (r != SLJIT_SP) + else if (r < SLJIT_SP) fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - r); - else + else if (r == SLJIT_SP) fprintf(compiler->verbose, "sp"); + else + fprintf(compiler->verbose, "t%d", r - SLJIT_TMP_REGISTER_BASE); } static void sljit_verbose_freg(struct sljit_compiler *compiler, sljit_s32 r) { +#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \ + || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + if (r >= SLJIT_F64_SECOND(SLJIT_FR0)) { + fprintf(compiler->verbose, "^"); + r -= SLJIT_F64_SECOND(0); + } +#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */ + if (r < (SLJIT_FR0 + compiler->fscratches)) fprintf(compiler->verbose, "fr%d", r - SLJIT_FR0); - else + else if (r < SLJIT_TMP_FREGISTER_BASE) fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - r); + else + fprintf(compiler->verbose, "ft%d", r - SLJIT_TMP_FREGISTER_BASE); } static void sljit_verbose_param(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if ((p) & SLJIT_IMM) + if ((p) == SLJIT_IMM) fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); else if ((p) & SLJIT_MEM) { if ((p) & REG_MASK) { @@ -991,9 +1086,17 @@ static const char* op0_names[] = { }; static const char* op1_names[] = { + "mov", "mov", "mov", "mov", + "mov", "mov", "mov", "mov", + "mov", "clz", "ctz", "rev", + "rev", "rev", "rev", "rev" +}; + +static const char* op1_types[] = { "", ".u8", ".s8", ".u16", ".s16", ".u32", ".s32", "32", - ".p", "not", "clz", "ctz" + ".p", "", "", "", + ".u16", ".s16", ".u32", ".s32" }; static const char* op2_names[] = { @@ -1003,22 +1106,36 @@ static const char* op2_names[] = { "ashr", "mashr", "rotl", "rotr" }; -static const char* op_src_names[] = { +static const char* op_src_dst_names[] = { "fast_return", "skip_frames_before_fast_return", "prefetch_l1", "prefetch_l2", "prefetch_l3", "prefetch_once", + "fast_enter", "get_return_address" }; static const char* fop1_names[] = { "mov", "conv", "conv", "conv", - "conv", "conv", "cmp", "neg", - "abs", + "conv", "conv", "conv", "conv", + "cmp", "neg", "abs", +}; + +static const char* fop1_conv_types[] = { + "sw", "s32", "sw", "s32", + "uw", "u32" }; static const char* fop2_names[] = { "add", "sub", "mul", "div" }; +static const char* fop2r_names[] = { + "copysign" +}; + +static const char* simd_op2_names[] = { + "and", "or", "xor" +}; + static const char* jump_names[] = { "equal", "not_equal", "less", "greater_equal", @@ -1026,7 +1143,8 @@ static const char* jump_names[] = { "sig_less", "sig_greater_equal", "sig_greater", "sig_less_equal", "overflow", "not_overflow", - "carry", "", + "carry", "not_carry", + "atomic_stored", "atomic_not_stored", "f_equal", "f_not_equal", "f_less", "f_greater_equal", "f_greater", "f_less_equal", @@ -1126,7 +1244,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compil fprintf(compiler->verbose, " keep:%d,", SLJIT_KEPT_SAVEDS_COUNT(options)); } - fprintf(compiler->verbose, "scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n", + fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n", scratches, saveds, fscratches, fsaveds, local_size); } #endif @@ -1198,7 +1316,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_void(struct sljit_ } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_VOID); + CHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_RET_VOID); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) @@ -1241,7 +1359,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi if (GET_OPCODE(op) < SLJIT_MOV_F64) { FUNCTION_CHECK_SRC(src, srcw); } else { - FUNCTION_FCHECK(src, srcw); + FUNCTION_FCHECK(src, srcw, op & SLJIT_32); } compiler->last_flags = 0; #endif @@ -1249,7 +1367,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (GET_OPCODE(op) < SLJIT_MOV_F64) { fprintf(compiler->verbose, " return%s%s ", !(op & SLJIT_32) ? "" : "32", - op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE]); + op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]); sljit_verbose_param(compiler, src, srcw); } else { fprintf(compiler->verbose, " return%s ", !(op & SLJIT_32) ? ".f64" : ".f32"); @@ -1277,22 +1395,6 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_to(struct sljit_co CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - FUNCTION_CHECK_DST(dst, dstw); - compiler->last_flags = 0; -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " fast_enter "); - sljit_verbose_param(compiler, dst, dstw); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1326,16 +1428,16 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CTZ); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_REV_S32); switch (GET_OPCODE(op)) { - case SLJIT_NOT: - /* Only SLJIT_32 and SLJIT_SET_Z are allowed. */ - CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)); - break; case SLJIT_MOV: case SLJIT_MOV_U32: + case SLJIT_MOV_S32: + case SLJIT_MOV32: case SLJIT_MOV_P: + case SLJIT_REV_U32: + case SLJIT_REV_S32: /* Nothing allowed */ CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))); break; @@ -1347,25 +1449,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler FUNCTION_CHECK_DST(dst, dstw); FUNCTION_CHECK_SRC(src, srcw); - - if (GET_OPCODE(op) >= SLJIT_NOT) { - CHECK_ARGUMENT(src != SLJIT_IMM); - compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z)); - } #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - if (GET_OPCODE(op) <= SLJIT_MOV_P) - { - fprintf(compiler->verbose, " mov%s%s ", !(op & SLJIT_32) ? "" : "32", - op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE]); - } - else - { - fprintf(compiler->verbose, " %s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_32) ? "" : "32", - !(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".", - !(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]); - } + fprintf(compiler->verbose, " %s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], + !(op & SLJIT_32) ? "" : "32", op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", "); @@ -1376,6 +1464,94 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler CHECK_RETURN_OK; } +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC)); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P); + CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32); + + /* All arguments must be valid registers. */ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg)); + + if (op == SLJIT_MOV32_U8 || op == SLJIT_MOV32_U16) { + /* Only SLJIT_32 is allowed. */ + CHECK_ARGUMENT(!(op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z))); + } else { + /* Nothing allowed. */ + CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))); + } + + compiler->last_flags = 0; +#endif /* SLJIT_ARGUMENT_CHECKS */ +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " atomic_load%s%s ", !(op & SLJIT_32) ? "" : "32", + op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]); + sljit_verbose_reg(compiler, dst_reg); + fprintf(compiler->verbose, ", ["); + sljit_verbose_reg(compiler, mem_reg); + fprintf(compiler->verbose, "]\n"); + } +#endif /* SLJIT_VERBOSE */ + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC)); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P); + CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32); + + /* All arguments must be valid registers. */ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src_reg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(temp_reg) && src_reg != temp_reg); + + CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE(op) == SLJIT_ATOMIC_STORED); + + if (GET_OPCODE(op) == SLJIT_MOV_U8 || GET_OPCODE(op) == SLJIT_MOV_U16) { + /* Only SLJIT_32, SLJIT_ATOMIC_STORED are allowed. */ + CHECK_ARGUMENT(!(op & SLJIT_SET_Z)); + } else { + /* Only SLJIT_ATOMIC_STORED is allowed. */ + CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z))); + } + + compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32); +#endif /* SLJIT_ARGUMENT_CHECKS */ +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " atomic_store%s%s%s ", !(op & SLJIT_32) ? "" : "32", + op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & VARIABLE_FLAG_MASK) ? "" : ".stored"); + sljit_verbose_reg(compiler, src_reg); + fprintf(compiler->verbose, ", ["); + sljit_verbose_reg(compiler, mem_reg); + fprintf(compiler->verbose, "], "); + sljit_verbose_reg(compiler, temp_reg); + fprintf(compiler->verbose, "\n"); + } +#endif /* SLJIT_VERBOSE */ + CHECK_RETURN_OK; +} + static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 unset, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, @@ -1461,28 +1637,33 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_LSHR || GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR); CHECK_ARGUMENT((op & ~(0xff | SLJIT_32 | SLJIT_SHIFT_INTO_NON_ZERO)) == 0); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src_dst)); - FUNCTION_CHECK_SRC(src1, src1w); - FUNCTION_CHECK_SRC(src2, src2w); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src1_reg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg)); + FUNCTION_CHECK_SRC(src3, src3w); + CHECK_ARGUMENT(dst_reg != src2_reg); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.into%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32", (op & SLJIT_SHIFT_INTO_NON_ZERO) ? ".nz" : ""); - sljit_verbose_reg(compiler, src_dst); + sljit_verbose_reg(compiler, dst_reg); fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src1, src1w); + sljit_verbose_reg(compiler, src1_reg); fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src2, src2w); + sljit_verbose_reg(compiler, src2_reg); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, src3, src3w); fprintf(compiler->verbose, "\n"); } #endif @@ -1496,19 +1677,16 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compi CHECK_ARGUMENT(op >= SLJIT_FAST_RETURN && op <= SLJIT_PREFETCH_ONCE); FUNCTION_CHECK_SRC(src, srcw); - if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN) - { + if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN) { CHECK_ARGUMENT(src != SLJIT_IMM); compiler->last_flags = 0; - } - else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE) - { + } else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE) { CHECK_ARGUMENT(src & SLJIT_MEM); } #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s ", op_src_names[op - SLJIT_OP_SRC_BASE]); + fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } @@ -1516,20 +1694,39 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compi CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - SLJIT_UNUSED_ARG(reg); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(op >= SLJIT_FAST_ENTER && op <= SLJIT_GET_RETURN_ADDRESS); + FUNCTION_CHECK_DST(dst, dstw); + + if (op == SLJIT_FAST_ENTER) + compiler->last_flags = 0; +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]); + sljit_verbose_param(compiler, dst, dstw); + fprintf(compiler->verbose, "\n"); + } #endif CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_s32 reg) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { + SLJIT_UNUSED_ARG(type); SLJIT_UNUSED_ARG(reg); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + if (type == SLJIT_GP_REGISTER) { + CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS) + || (reg >= SLJIT_TMP_REGISTER_BASE && reg <= (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS))); + } else { + CHECK_ARGUMENT(type == SLJIT_FLOAT_REGISTER || ((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6))); + CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS) + || (reg >= SLJIT_TMP_FREGISTER_BASE && reg <= (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS))); + } #endif CHECK_RETURN_OK; } @@ -1583,8 +1780,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); - FUNCTION_FCHECK(src, srcw); - FUNCTION_FCHECK(dst, dstw); + FUNCTION_FCHECK(src, srcw, op & SLJIT_32); + FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { @@ -1623,8 +1820,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com CHECK_ARGUMENT(!(op & SLJIT_SET_Z)); CHECK_ARGUMENT((op & VARIABLE_FLAG_MASK) || (GET_FLAG_TYPE(op) >= SLJIT_F_EQUAL && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_LESS_EQUAL)); - FUNCTION_FCHECK(src1, src1w); - FUNCTION_FCHECK(src2, src2w); + FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); + FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { @@ -1653,15 +1850,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(str #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CONV_S32_FROM_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); - FUNCTION_FCHECK(src, srcw); + FUNCTION_FCHECK(src, srcw, op & SLJIT_32); FUNCTION_CHECK_DST(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], - (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? ".s32" : ".sw", + fop1_conv_types[GET_OPCODE(op) - SLJIT_CONV_SW_FROM_F64], (op & SLJIT_32) ? ".f32" : ".f64"); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", "); @@ -1672,7 +1868,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(str CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { @@ -1683,16 +1879,15 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(str #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_SW && GET_OPCODE(op) <= SLJIT_CONV_F64_FROM_S32); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); FUNCTION_CHECK_SRC(src, srcw); - FUNCTION_FCHECK(dst, dstw); + FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], + fprintf(compiler->verbose, " %s%s.from.%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], (op & SLJIT_32) ? ".f32" : ".f64", - (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? ".s32" : ".sw"); + fop1_conv_types[GET_OPCODE(op) - SLJIT_CONV_SW_FROM_F64]); sljit_verbose_fparam(compiler, dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src, srcw); @@ -1707,13 +1902,18 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) { + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); - FUNCTION_FCHECK(src1, src1w); - FUNCTION_FCHECK(src2, src2w); - FUNCTION_FCHECK(dst, dstw); + FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); + FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); + FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { @@ -1729,6 +1929,138 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile CHECK_RETURN_OK; } +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); + CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_COPYSIGN_F64); + FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); + FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, op & SLJIT_32)); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s%s ", fop2r_names[GET_OPCODE(op) - SLJIT_FOP2R_BASE], (op & SLJIT_32) ? ".f32" : ".f64"); + sljit_verbose_freg(compiler, dst_freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src2, src2w); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) +{ + SLJIT_UNUSED_ARG(value); + + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 1)); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fset32 "); + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", %f\n", value); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + SLJIT_UNUSED_ARG(value); + + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fset64 "); + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", %f\n", value); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_COPY_TO_F64 && GET_OPCODE(op) <= SLJIT_COPY_FROM_F64); + CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, op & SLJIT_32)); + +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg)); +#else /* !SLJIT_64BIT_ARCHITECTURE */ + switch (op) { + case SLJIT_COPY32_TO_F32: + case SLJIT_COPY32_FROM_F32: + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg)); + break; + case SLJIT_COPY_TO_F64: + case SLJIT_COPY_FROM_F64: + if (reg & REG_PAIR_MASK) { + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_FIRST(reg))); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_SECOND(reg))); + + if (op == SLJIT_COPY_TO_F64) + break; + + CHECK_ARGUMENT(REG_PAIR_FIRST(reg) != REG_PAIR_SECOND(reg)); + break; + } + + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg)); + break; + } +#endif /* SLJIT_64BIT_ARCHITECTURE */ +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " copy%s_%s_f%s ", (op & SLJIT_32) ? "32" : "", + GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? "to" : "from", (op & SLJIT_32) ? "32" : "64"); + + sljit_verbose_freg(compiler, freg); + + if (reg & REG_PAIR_MASK) { + fprintf(compiler->verbose, ", {"); + sljit_verbose_reg(compiler, REG_PAIR_FIRST(reg)); + fprintf(compiler->verbose, ", "); + sljit_verbose_reg(compiler, REG_PAIR_SECOND(reg)); + fprintf(compiler->verbose, "}\n"); + } else { + fprintf(compiler->verbose, ", "); + sljit_verbose_reg(compiler, reg); + fprintf(compiler->verbose, "\n"); + } + } +#endif + CHECK_RETURN_OK; +} + static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler) { SLJIT_UNUSED_ARG(compiler); @@ -1753,7 +2085,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compil #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ || (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) #define CHECK_UNORDERED(type, last_flags) \ - ((((type) & 0xff) == SLJIT_UNORDERED || ((type) & 0xff) == SLJIT_ORDERED) && \ + ((((type) & 0xfe) == SLJIT_ORDERED) && \ ((last_flags) & 0xff) >= SLJIT_UNORDERED && ((last_flags) & 0xff) <= SLJIT_ORDERED_LESS_EQUAL) #else #define CHECK_UNORDERED(type, last_flags) 0 @@ -1775,11 +2107,10 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compile if ((type & 0xff) <= SLJIT_NOT_ZERO) CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z); else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) { - CHECK_ARGUMENT((type & 0xff) == SLJIT_CARRY || (type & 0xff) == SLJIT_NOT_CARRY); + CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY); compiler->last_flags = 0; } else - CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff) - || ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW) + CHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(type, compiler->last_flags)); } #endif @@ -1863,10 +2194,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compile #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_F_EQUAL && (type & 0xff) <= SLJIT_ORDERED_LESS_EQUAL - && ((type & 0xff) <= SLJIT_ORDERED || sljit_cmp_info(type & 0xff))); - FUNCTION_FCHECK(src1, src1w); - FUNCTION_FCHECK(src2, src2w); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_F_EQUAL && (type & 0xff) <= SLJIT_ORDERED_LESS_EQUAL); + FUNCTION_FCHECK(src1, src1w, type & SLJIT_32); + FUNCTION_FCHECK(src2, src2w, type & SLJIT_32); compiler->last_flags = 0; #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) @@ -1961,9 +2291,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com if (type <= SLJIT_NOT_ZERO) CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z); else - CHECK_ARGUMENT(type == (compiler->last_flags & 0xff) - || (type == SLJIT_NOT_CARRY && (compiler->last_flags & 0xff) == SLJIT_CARRY) - || (type == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW) + CHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(type, compiler->last_flags)); FUNCTION_CHECK_DST(dst, dstw); @@ -1975,7 +2303,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " flags.%s%s%s ", GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], - GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_32) ? "32" : ""), + GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_32) ? "32" : ""), !(op & SLJIT_SET_Z) ? "" : ".z"); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", %s\n", jump_names[type]); @@ -1984,9 +2312,10 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) sljit_s32 cond = type & ~SLJIT_32; @@ -1995,27 +2324,68 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmov(struct sljit_compile CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg)); - if (src != SLJIT_IMM) { - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src)); - CHECK_ARGUMENT(srcw == 0); - } + FUNCTION_CHECK_SRC(src1, src1w); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg)); if (cond <= SLJIT_NOT_ZERO) CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z); - else - CHECK_ARGUMENT(cond == (compiler->last_flags & 0xff) - || (cond == SLJIT_NOT_CARRY && (compiler->last_flags & 0xff) == SLJIT_CARRY) - || (cond == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW) + else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) { + CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY); + compiler->last_flags = 0; + } else + CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(cond, compiler->last_flags)); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " cmov%s %s, ", + fprintf(compiler->verbose, " select%s %s, ", !(type & SLJIT_32) ? "" : "32", jump_names[type & ~SLJIT_32]); sljit_verbose_reg(compiler, dst_reg); fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src, srcw); + sljit_verbose_param(compiler, src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_reg(compiler, src2_reg); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + sljit_s32 cond = type & ~SLJIT_32; + + CHECK_ARGUMENT(cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL); + + CHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, type & SLJIT_32)); + FUNCTION_FCHECK(src1, src1w, type & SLJIT_32); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src2_freg, type & SLJIT_32)); + + if (cond <= SLJIT_NOT_ZERO) + CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z); + else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) { + CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY); + compiler->last_flags = 0; + } else + CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff) + || CHECK_UNORDERED(cond, compiler->last_flags)); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fselect%s %s, ", + !(type & SLJIT_32) ? "" : "32", + jump_names[type & ~SLJIT_32]); + sljit_verbose_freg(compiler, dst_freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_freg(compiler, src2_freg); fprintf(compiler->verbose, "\n"); } #endif @@ -2026,33 +2396,35 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler sljit_s32 reg, sljit_s32 mem, sljit_sw memw) { +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + sljit_s32 allowed_flags; +#endif /* SLJIT_ARGUMENT_CHECKS */ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; CHECK_RETURN_OK; } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - sljit_s32 allowed_flags; - if (type & SLJIT_MEM_UNALIGNED) { - CHECK_ARGUMENT(!(type & (SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32))); - } else if (type & SLJIT_MEM_UNALIGNED_16) { - CHECK_ARGUMENT(!(type & SLJIT_MEM_UNALIGNED_32)); + CHECK_ARGUMENT(!(type & (SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32))); + } else if (type & SLJIT_MEM_ALIGNED_16) { + CHECK_ARGUMENT(!(type & SLJIT_MEM_ALIGNED_32)); } else { - CHECK_ARGUMENT((reg & REG_PAIR_MASK) || (type & SLJIT_MEM_UNALIGNED_32)); + CHECK_ARGUMENT((reg & REG_PAIR_MASK) || (type & SLJIT_MEM_ALIGNED_32)); } allowed_flags = SLJIT_MEM_UNALIGNED; switch (type & 0xff) { + case SLJIT_MOV_P: + case SLJIT_MOV: + allowed_flags |= SLJIT_MEM_ALIGNED_32; + /* fallthrough */ case SLJIT_MOV_U32: case SLJIT_MOV_S32: case SLJIT_MOV32: - allowed_flags = SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16; - break; - case SLJIT_MOV: - case SLJIT_MOV_P: - allowed_flags = SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32; + allowed_flags |= SLJIT_MEM_ALIGNED_16; break; } @@ -2079,15 +2451,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler else fprintf(compiler->verbose, " %s%s%s", (type & SLJIT_MEM_STORE) ? "store" : "load", - !(type & SLJIT_32) ? "" : "32", - op1_names[(type & 0xff) - SLJIT_OP1_BASE]); + !(type & SLJIT_32) ? "" : "32", op1_types[(type & 0xff) - SLJIT_OP1_BASE]); if (type & SLJIT_MEM_UNALIGNED) - printf(".un"); - else if (type & SLJIT_MEM_UNALIGNED_16) - printf(".un16"); - else if (type & SLJIT_MEM_UNALIGNED_32) - printf(".un32"); + printf(".unal"); + else if (type & SLJIT_MEM_ALIGNED_16) + printf(".al16"); + else if (type & SLJIT_MEM_ALIGNED_32) + printf(".al32"); if (reg & REG_PAIR_MASK) { fprintf(compiler->verbose, " {"); @@ -2140,7 +2511,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem_update(struct sljit_c fprintf(compiler->verbose, " %s%s%s.%s ", (type & SLJIT_MEM_STORE) ? "store" : "load", !(type & SLJIT_32) ? "" : "32", - op1_names[(type & 0xff) - SLJIT_OP1_BASE], + op1_types[(type & 0xff) - SLJIT_OP1_BASE], (type & SLJIT_MEM_POST) ? "post" : "pre"); sljit_verbose_reg(compiler, reg); @@ -2157,19 +2528,20 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compile sljit_s32 mem, sljit_sw memw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64); if (type & SLJIT_MEM_UNALIGNED) { - CHECK_ARGUMENT(!(type & (SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32))); - } else if (type & SLJIT_MEM_UNALIGNED_16) { - CHECK_ARGUMENT(!(type & SLJIT_MEM_UNALIGNED_32)); + CHECK_ARGUMENT(!(type & (SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32))); + } else if (type & SLJIT_MEM_ALIGNED_16) { + CHECK_ARGUMENT(!(type & SLJIT_MEM_ALIGNED_32)); } else { - CHECK_ARGUMENT(type & SLJIT_MEM_UNALIGNED_32); + CHECK_ARGUMENT(type & SLJIT_MEM_ALIGNED_32); CHECK_ARGUMENT(!(type & SLJIT_32)); } - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32))); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg)); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32))); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32)); FUNCTION_CHECK_SRC_MEM(mem, memw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) @@ -2179,11 +2551,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compile !(type & SLJIT_32) ? "f64" : "f32"); if (type & SLJIT_MEM_UNALIGNED) - printf(".un"); - else if (type & SLJIT_MEM_UNALIGNED_16) - printf(".un16"); - else if (type & SLJIT_MEM_UNALIGNED_32) - printf(".un32"); + printf(".unal"); + else if (type & SLJIT_MEM_ALIGNED_16) + printf(".al16"); + else if (type & SLJIT_MEM_ALIGNED_32) + printf(".al32"); fprintf(compiler->verbose, " "); sljit_verbose_freg(compiler, freg); @@ -2200,10 +2572,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_ sljit_s32 mem, sljit_sw memw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64); CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0); FUNCTION_CHECK_SRC_MEM(mem, memw); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32)); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { @@ -2226,7 +2599,297 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_ } #endif CHECK_RETURN_OK; +} +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(SLJIT_SIMD_STORE)) == 0); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (srcdst & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + FUNCTION_FCHECK(srcdst, srcdstw, 0); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_mov(compiler, type | SLJIT_SIMD_TEST, freg, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_mem: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_%s.%d.%s%d", + (type & SLJIT_SIMD_STORE) ? "store" : "load", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + if ((type & 0x3f000000) == SLJIT_SIMD_MEM_UNALIGNED) + fprintf(compiler->verbose, ".unal "); + else + fprintf(compiler->verbose, ".al%d ", (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, srcdst, srcdstw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + + if (type & SLJIT_SIMD_FLOAT) { + if (src == SLJIT_IMM) { + CHECK_ARGUMENT(srcw == 0); + } else { + FUNCTION_FCHECK(src, srcw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2); + } + } else if (src != SLJIT_IMM) { + FUNCTION_CHECK_DST(src, srcw); + } +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_dup: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_replicate.%d.%s%d ", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", "); + if (type & SLJIT_SIMD_FLOAT) + sljit_verbose_fparam(compiler, src, srcw); + else + sljit_verbose_param(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO | SLJIT_SIMD_LANE_SIGNED | SLJIT_32)) == 0); + CHECK_ARGUMENT((type & (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO)) != (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO)); + CHECK_ARGUMENT((type & (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_SIGNED)) != SLJIT_SIMD_LANE_SIGNED); + CHECK_ARGUMENT(!(type & SLJIT_SIMD_FLOAT) || !(type & (SLJIT_SIMD_LANE_SIGNED | SLJIT_32))); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(!(type & SLJIT_32) || SLJIT_SIMD_GET_ELEM_SIZE(type) <= 2); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + CHECK_ARGUMENT(lane_index >= 0 && lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type)))); + + if (type & SLJIT_SIMD_FLOAT) { + FUNCTION_FCHECK(srcdst, srcdstw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2); + } else if ((type & SLJIT_SIMD_STORE) || srcdst != SLJIT_IMM) { + FUNCTION_CHECK_DST(srcdst, srcdstw); + } +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_lane_mov(compiler, type | SLJIT_SIMD_TEST, freg, lane_index, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_move_lane: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_%s_lane%s%s%s.%d.%s%d ", + (type & SLJIT_SIMD_STORE) ? "store" : "load", + (type & SLJIT_32) ? "32" : "", + (type & SLJIT_SIMD_LANE_ZERO) ? "_z" : "", + (type & SLJIT_SIMD_LANE_SIGNED) ? "_s" : "", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, "[%d], ", lane_index); + if (type & SLJIT_SIMD_FLOAT) + sljit_verbose_fparam(compiler, srcdst, srcdstw); + else + sljit_verbose_param(compiler, srcdst, srcdstw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src, 0)); + CHECK_ARGUMENT(src_lane_index >= 0 && src_lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type)))); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_lane_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, src_lane_index) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_lane_replicate: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_lane_replicate.%d.%s%d ", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_freg(compiler, src); + fprintf(compiler->verbose, "[%d]\n", src_lane_index); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(SLJIT_SIMD_EXTEND_SIGNED)) == 0); + CHECK_ARGUMENT((type & (SLJIT_SIMD_EXTEND_SIGNED | SLJIT_SIMD_FLOAT)) != (SLJIT_SIMD_EXTEND_SIGNED | SLJIT_SIMD_FLOAT)); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_ELEM2_SIZE(type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + FUNCTION_FCHECK(src, srcw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_extend(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_extend: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_load_extend%s.%d.%s%d.%s%d ", + (type & SLJIT_SIMD_EXTEND_SIGNED) ? "_s" : "", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_32)) == SLJIT_SIMD_STORE); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_sign(compiler, type | SLJIT_SIMD_TEST, freg, dst, dstw) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_sign: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_store_sign%s.%d.%s%d ", + (type & SLJIT_32) ? "32" : "", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, dst, dstw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) >= SLJIT_SIMD_OP2_AND && (type & SLJIT_SIMD_TYPE_MASK(0)) <= SLJIT_SIMD_OP2_XOR); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src1_freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src2_freg, 0)); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_op2(compiler, type | SLJIT_SIMD_TEST, dst_freg, src1_freg, src2_freg) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_op2: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_%s.%d.%s%d ", + simd_op2_names[SLJIT_SIMD_GET_OPCODE(type) - 1], + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, dst_freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_freg(compiler, src1_freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_freg(compiler, src2_freg); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) @@ -2286,7 +2949,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_co #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ #define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \ - SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1), \ + SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1) && !(SLJIT_CONV_F64_FROM_UW & 0x1), \ invalid_float_opcodes); \ if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \ if (GET_OPCODE(op) == SLJIT_CMP_F64) { \ @@ -2301,48 +2964,22 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_co ADJUST_LOCAL_OFFSET(src, srcw); \ return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \ } \ - CHECK(check_sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw)); \ + if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_F64_FROM_S32) { \ + CHECK(check_sljit_emit_fop1_conv_f64_from_w(compiler, op, dst, dstw, src, srcw)); \ + ADJUST_LOCAL_OFFSET(dst, dstw); \ + ADJUST_LOCAL_OFFSET(src, srcw); \ + return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \ + } \ + CHECK(check_sljit_emit_fop1_conv_f64_from_w(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); \ - return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \ + return sljit_emit_fop1_conv_f64_from_uw(compiler, op, dst, dstw, src, srcw); \ } \ CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ - || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \ - || ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)) \ - || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ - || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) - -static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) -{ - struct sljit_label *label; - struct sljit_jump *jump; - sljit_s32 op = (type & SLJIT_32) ? SLJIT_MOV32 : SLJIT_MOV; - - SLJIT_SKIP_CHECKS(compiler); - jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1); - FAIL_IF(!jump); - - SLJIT_SKIP_CHECKS(compiler); - FAIL_IF(sljit_emit_op1(compiler, op, dst_reg, 0, src, srcw)); - - SLJIT_SKIP_CHECKS(compiler); - label = sljit_emit_label(compiler); - FAIL_IF(!label); - - sljit_set_label(jump, label); - return SLJIT_SUCCESS; -} - -#endif - -#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) \ - && !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) static sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, @@ -2355,7 +2992,7 @@ static sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit return sljit_emit_op1(compiler, type & (0xff | SLJIT_32), reg, 0, mem, memw); } -#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) && !SLJIT_CONFIG_ARM_V5 */ +#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) */ #if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) \ && !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) @@ -2401,7 +3038,7 @@ static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, slji #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) # include "sljitNativeX86_common.c" -#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#elif (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) # include "sljitNativeARM_32.c" #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) # include "sljitNativeARM_32.c" @@ -2417,6 +3054,8 @@ static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, slji # include "sljitNativeRISCV_common.c" #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) # include "sljitNativeS390X.c" +#elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) +# include "sljitNativeLOONGARCH_64.c" #endif static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) @@ -2463,8 +3102,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp return sljit_emit_return_void(compiler); } +#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ + && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + && !(defined(SLJIT_CONFIG_LOONGARCH_64) && SLJIT_CONFIG_LOONGARCH_64) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + SLJIT_SKIP_CHECKS(compiler); + return sljit_emit_fop2(compiler, op, dst_freg, 0, src1, src1w, src2, src2w); +} + +#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X && !SLJIT_CONFIG_LOONGARCH_64 */ + #if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \ - && !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) + && !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ + && !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src1, sljit_sw src1w, @@ -2480,18 +3140,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler condition = type & 0xff; #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) { - if ((src1 & SLJIT_IMM) && !src1w) { + if (src1 == SLJIT_IMM && !src1w) { src1 = src2; src1w = src2w; src2 = SLJIT_IMM; src2w = 0; } - if ((src2 & SLJIT_IMM) && !src2w) + if (src2 == SLJIT_IMM && !src2w) return emit_cmp_to0(compiler, type, src1, src1w); } #endif - if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) { + if (SLJIT_UNLIKELY(src1 == SLJIT_IMM && src2 != SLJIT_IMM)) { /* Immediate is preferred as second argument by most architectures. */ switch (condition) { case SLJIT_LESS: @@ -2532,7 +3192,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler if (condition <= SLJIT_NOT_ZERO) flags = SLJIT_SET_Z; else - flags = condition << VARIABLE_FLAG_SHIFT; + flags = (condition & 0xfe) << VARIABLE_FLAG_SHIFT; SLJIT_SKIP_CHECKS(compiler); PTR_FAIL_IF(sljit_emit_op2u(compiler, @@ -2544,20 +3204,17 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler #endif /* !SLJIT_CONFIG_MIPS */ -#if (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) +#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - if (type < SLJIT_UNORDERED || type > SLJIT_ORDERED_LESS_EQUAL) - return 0; - switch (type) { case SLJIT_UNORDERED_OR_EQUAL: case SLJIT_ORDERED_NOT_EQUAL: - return 0; + return 1; } - return 1; + return 0; } #endif /* SLJIT_CONFIG_ARM */ @@ -2570,7 +3227,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); SLJIT_SKIP_CHECKS(compiler); - sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xff) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_32), src1, src1w, src2, src2w); + sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xfe) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_32), src1, src1w, src2, src2w); SLJIT_SKIP_CHECKS(compiler); return sljit_emit_jump(compiler, type); @@ -2629,6 +3286,158 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler #endif /* !SLJIT_CONFIG_ARM_64 && !SLJIT_CONFIG_PPC */ +#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ + && !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \ + && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(srcdst); + SLJIT_UNUSED_ARG(srcdstw); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(lane_index); + SLJIT_UNUSED_ARG(srcdst); + SLJIT_UNUSED_ARG(srcdstw); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(src_lane_index); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(dst_freg); + SLJIT_UNUSED_ARG(src1_freg); + SLJIT_UNUSED_ARG(src2_freg); + + return SLJIT_ERR_UNSUPPORTED; +} + +#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM */ + +#if !(defined(SLJIT_CONFIG_X86) && SLJIT_CONFIG_X86) \ + && !(defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM) \ + && !(defined(SLJIT_CONFIG_S390X) && SLJIT_CONFIG_S390X) \ + && !(defined(SLJIT_CONFIG_LOONGARCH) && SLJIT_CONFIG_LOONGARCH) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, + sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst_reg); + SLJIT_UNUSED_ARG(mem_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, + sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(src_reg); + SLJIT_UNUSED_ARG(mem_reg); + SLJIT_UNUSED_ARG(temp_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + + return SLJIT_ERR_UNSUPPORTED; +} + +#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM && !SLJIT_CONFIG_S390X && !SLJIT_CONFIG_LOONGARCH */ + #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) @@ -2646,491 +3455,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *c return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0); } -#endif - -#else /* SLJIT_CONFIG_UNSUPPORTED */ - -/* Empty function bodies for those machines, which are not (yet) supported. */ - -SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) -{ - return "unsupported"; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data) -{ - SLJIT_UNUSED_ARG(allocator_data); - SLJIT_UNUSED_ARG(exec_allocator_data); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(size); - SLJIT_UNREACHABLE(); - return NULL; -} - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) -SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(verbose); - SLJIT_UNREACHABLE(); -} -#endif - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) -{ - SLJIT_UNUSED_ARG(feature_type); - SLJIT_UNREACHABLE(); - return 0; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) -{ - SLJIT_UNUSED_ARG(type); - SLJIT_UNREACHABLE(); - return 0; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data) -{ - SLJIT_UNUSED_ARG(code); - SLJIT_UNUSED_ARG(exec_allocator_data); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(options); - SLJIT_UNUSED_ARG(arg_types); - SLJIT_UNUSED_ARG(scratches); - SLJIT_UNUSED_ARG(saveds); - SLJIT_UNUSED_ARG(fscratches); - SLJIT_UNUSED_ARG(fsaveds); - SLJIT_UNUSED_ARG(local_size); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(options); - SLJIT_UNUSED_ARG(arg_types); - SLJIT_UNUSED_ARG(scratches); - SLJIT_UNUSED_ARG(saveds); - SLJIT_UNUSED_ARG(fscratches); - SLJIT_UNUSED_ARG(fsaveds); - SLJIT_UNUSED_ARG(local_size); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(src_dst); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) -{ - SLJIT_UNREACHABLE(); - return reg; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_u32 size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(instruction); - SLJIT_UNUSED_ARG(size); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(current_flags); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 arg_types) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(arg_types); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) -{ - SLJIT_UNUSED_ARG(jump); - SLJIT_UNUSED_ARG(label); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) -{ - SLJIT_UNUSED_ARG(jump); - SLJIT_UNUSED_ARG(target); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label) -{ - SLJIT_UNUSED_ARG(put_label); - SLJIT_UNUSED_ARG(label); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 arg_types, - sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(arg_types); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 type) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(type); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(dst_reg); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(reg); - SLJIT_UNUSED_ARG(mem); - SLJIT_UNUSED_ARG(memw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(reg); - SLJIT_UNUSED_ARG(mem); - SLJIT_UNUSED_ARG(memw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(freg); - SLJIT_UNUSED_ARG(mem); - SLJIT_UNUSED_ARG(memw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(freg); - SLJIT_UNUSED_ARG(mem); - SLJIT_UNUSED_ARG(memw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(offset); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw initval) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(initval); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) -{ - SLJIT_UNUSED_ARG(addr); - SLJIT_UNUSED_ARG(new_target); - SLJIT_UNUSED_ARG(executable_offset); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) -{ - SLJIT_UNUSED_ARG(addr); - SLJIT_UNUSED_ARG(new_constant); - SLJIT_UNUSED_ARG(executable_offset); - SLJIT_UNREACHABLE(); -} +#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM_64 */ #endif /* !SLJIT_CONFIG_UNSUPPORTED */ diff --git a/src/3rdparty/pcre2/src/sljit/sljitLir.h b/src/3rdparty/pcre2/src/sljit/sljitLir.h index c6a0832ef87..2ba6683c74b 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitLir.h +++ b/src/3rdparty/pcre2/src/sljit/sljitLir.h @@ -72,6 +72,7 @@ #include "sljitConfigPre.h" #endif /* SLJIT_HAVE_CONFIG_PRE */ +#include "sljitConfigCPU.h" #include "sljitConfig.h" /* The following header file defines useful macros for fine tuning @@ -107,9 +108,9 @@ extern "C" { /* Cannot allocate executable memory. Only sljit_generate_code() returns with this error code. */ #define SLJIT_ERR_EX_ALLOC_FAILED 3 -/* Return value for SLJIT_CONFIG_UNSUPPORTED placeholder architecture. */ +/* Unsupported instruction form. */ #define SLJIT_ERR_UNSUPPORTED 4 -/* An ivalid argument is passed to any SLJIT function. */ +/* An invalid argument is passed to any SLJIT function. */ #define SLJIT_ERR_BAD_ARGUMENT 5 /* --------------------------------------------------------------------- */ @@ -127,40 +128,40 @@ extern "C" { is the first saved register, the one before the last is the second saved register, and so on. - If an architecture provides two scratch and three saved registers, - its scratch and saved register sets are the following: + For example, in an architecture with only five registers (A-E), if two + are scratch and three saved registers, they will be defined as follows: - R0 | | R0 is always a scratch register - R1 | | R1 is always a scratch register - [R2] | S2 | R2 and S2 represent the same physical register - [R3] | S1 | R3 and S1 represent the same physical register - [R4] | S0 | R4 and S0 represent the same physical register + A | R0 | | R0 always represent scratch register A + B | R1 | | R1 always represent scratch register B + C | [R2] | S2 | R2 and S2 represent the same physical register C + D | [R3] | S1 | R3 and S1 represent the same physical register D + E | [R4] | S0 | R4 and S0 represent the same physical register E - Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS would be 2 and - SLJIT_NUMBER_OF_SAVED_REGISTERS would be 3 for this architecture. + Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS will be 2 and + SLJIT_NUMBER_OF_SAVED_REGISTERS will be 3. - Note: On all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 12 + Note: For all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 12 and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 6. However, 6 registers are virtual on x86-32. See below. The purpose of this definition is convenience: saved registers can - be used as extra scratch registers. For example four registers can - be specified as scratch registers and the fifth one as saved register - on the CPU above and any user code which requires four scratch - registers can run unmodified. The SLJIT compiler automatically saves - the content of the two extra scratch register on the stack. Scratch - registers can also be preserved by saving their value on the stack - but this needs to be done manually. + be used as extra scratch registers. For example, building in the + previous example, four registers can be specified as scratch registers + and the fifth one as saved register, allowing any user code which requires + four scratch registers to run unmodified. The SLJIT compiler automatically + saves the content of the two extra scratch register on the stack. Scratch + registers can also be preserved by saving their value on the stack but + that needs to be done manually. Note: To emphasize that registers assigned to R2-R4 are saved registers, they are enclosed by square brackets. - Note: sljit_emit_enter and sljit_set_context defines whether a register - is S or R register. E.g: when 3 scratches and 1 saved is mapped - by sljit_emit_enter, the allowed register set will be: R0-R2 and - S0. Although S2 is mapped to the same position as R2, it does not - available in the current configuration. Furthermore the S1 register - is not available at all. + Note: sljit_emit_enter and sljit_set_context define whether a register + is S or R register. E.g: if in the previous example 3 scratches and + 1 saved are mapped by sljit_emit_enter, the allowed register set + will be: R0-R2 and S0. Although S2 is mapped to the same register + than R2, it is not available in that configuration. Furthermore + the S1 register cannot be used at all. */ /* Scratch registers. */ @@ -209,7 +210,7 @@ extern "C" { /* The SLJIT_SP provides direct access to the linear stack space allocated by sljit_emit_enter. It can only be used in the following form: SLJIT_MEM1(SLJIT_SP). The immediate offset is extended by the relative stack offset automatically. - The sljit_get_local_base can be used to obtain the real address of a value. */ + sljit_get_local_base can be used to obtain the real address of a value. */ #define SLJIT_SP (SLJIT_NUMBER_OF_REGISTERS + 1) /* Return with machine word. */ @@ -221,7 +222,7 @@ extern "C" { /* --------------------------------------------------------------------- */ /* Each floating point register can store a 32 or a 64 bit precision - value. The FR and FS register sets are overlap in the same way as R + value. The FR and FS register sets overlap in the same way as R and S register sets. See above. */ /* Floating point scratch registers. */ @@ -231,6 +232,10 @@ extern "C" { #define SLJIT_FR3 4 #define SLJIT_FR4 5 #define SLJIT_FR5 6 +#define SLJIT_FR6 7 +#define SLJIT_FR7 8 +#define SLJIT_FR8 9 +#define SLJIT_FR9 10 /* All FR registers provided by the architecture can be accessed by SLJIT_FR(i) The i parameter must be >= 0 and < SLJIT_NUMBER_OF_FLOAT_REGISTERS. */ #define SLJIT_FR(i) (1 + (i)) @@ -242,6 +247,10 @@ extern "C" { #define SLJIT_FS3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 3) #define SLJIT_FS4 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 4) #define SLJIT_FS5 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 5) +#define SLJIT_FS6 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 6) +#define SLJIT_FS7 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 7) +#define SLJIT_FS8 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 8) +#define SLJIT_FS9 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 9) /* All S registers provided by the architecture can be accessed by SLJIT_FS(i) The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */ #define SLJIT_FS(i) (SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i)) @@ -260,23 +269,39 @@ extern "C" { /* The following argument type definitions are used by sljit_emit_enter, sljit_set_context, sljit_emit_call, and sljit_emit_icall functions. - As for sljit_emit_call and sljit_emit_icall, the first integer argument + For sljit_emit_call and sljit_emit_icall, the first integer argument must be placed into SLJIT_R0, the second one into SLJIT_R1, and so on. Similarly the first floating point argument must be placed into SLJIT_FR0, the second one into SLJIT_FR1, and so on. - As for sljit_emit_enter, the integer arguments can be stored in scratch - or saved registers. The first integer argument without _R postfix is - stored in SLJIT_S0, the next one in SLJIT_S1, and so on. The integer - arguments with _R postfix are placed into scratch registers. The index - of the scratch register is the count of the previous integer arguments - starting from SLJIT_R0. The floating point arguments are always placed - into SLJIT_FR0, SLJIT_FR1, and so on. + For sljit_emit_enter, the integer arguments can be stored in scratch + or saved registers. Scratch registers are identified by a _R suffix. - Note: if a function is called by sljit_emit_call/sljit_emit_icall and - an argument is stored in a scratch register by sljit_emit_enter, - that argument uses the same scratch register index for both - integer and floating point arguments. + If only saved registers are used, then the allocation mirrors what is + done for the "call" functions but using saved registers, meaning that + the first integer argument goes to SLJIT_S0, the second one goes into + SLJIT_S1, and so on. + + If scratch registers are used, then the way the integer registers are + allocated changes so that SLJIT_S0, SLJIT_S1, etc; will be assigned + only for the arguments not using scratch registers, while SLJIT_R + will be used for the ones using scratch registers. + + Furthermore, the index (shown as "n" above) that will be used for the + scratch register depends on how many previous integer registers + (scratch or saved) were used already, starting with SLJIT_R0. + Eventhough some indexes will be likely skipped, they still need to be + accounted for in the scratches parameter of sljit_emit_enter. See below + for some examples. + + The floating point arguments always use scratch registers (but not the + _R suffix like the integer arguments) and must use SLJIT_FR0, SLJIT_FR1, + just like in the "call" functions. + + Note: the mapping for scratch registers is part of the compiler context + and therefore a new context after sljit_emit_call/sljit_emit_icall + could remove access to some scratch registers that were used as + arguments. Example function definition: sljit_f32 SLJIT_FUNC example_c_callback(void *arg_a, @@ -288,29 +313,33 @@ extern "C" { | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_32, 3) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F32, 4) Short form of argument type definition: - SLJIT_ARGS4(32, P, F64, 32, F32) + SLJIT_ARGS4(F32, P, F64, 32, F32) Argument passing: arg_a must be placed in SLJIT_R0 - arg_c must be placed in SLJIT_R1 arg_b must be placed in SLJIT_FR0 + arg_c must be placed in SLJIT_R1 arg_d must be placed in SLJIT_FR1 Examples for argument processing by sljit_emit_enter: - SLJIT_ARGS4(VOID, P, 32_R, F32, W) + SLJIT_ARGS4V(P, 32_R, F32, W) Arguments are placed into: SLJIT_S0, SLJIT_R1, SLJIT_FR0, SLJIT_S1 + The type of the result is void. - SLJIT_ARGS4(VOID, W, W_R, W, W_R) + SLJIT_ARGS4(F32, W, W_R, W, W_R) Arguments are placed into: SLJIT_S0, SLJIT_R1, SLJIT_S1, SLJIT_R3 + The type of the result is sljit_f32. - SLJIT_ARGS4(VOID, F64, W, F32, W_R) + SLJIT_ARGS4(P, W, F32, P_R) Arguments are placed into: SLJIT_FR0, SLJIT_S0, SLJIT_FR1, SLJIT_R1 + The type of the result is pointer. Note: it is recommended to pass the scratch arguments first followed by the saved arguments: - SLJIT_ARGS4(VOID, W_R, W_R, W, W) + SLJIT_ARGS4(W, W_R, W_R, W, W) Arguments are placed into: SLJIT_R0, SLJIT_R1, SLJIT_S0, SLJIT_S1 + The type of the result is sljit_sw / sljit_uw. */ /* The following flag is only allowed for the integer arguments of @@ -318,21 +347,21 @@ extern "C" { stored in a scratch register instead of a saved register. */ #define SLJIT_ARG_TYPE_SCRATCH_REG 0x8 -/* Void result, can only be used by SLJIT_ARG_RETURN. */ -#define SLJIT_ARG_TYPE_VOID 0 +/* No return value, only supported by SLJIT_ARG_RETURN. */ +#define SLJIT_ARG_TYPE_RET_VOID 0 /* Machine word sized integer argument or result. */ -#define SLJIT_ARG_TYPE_W 1 +#define SLJIT_ARG_TYPE_W 1 #define SLJIT_ARG_TYPE_W_R (SLJIT_ARG_TYPE_W | SLJIT_ARG_TYPE_SCRATCH_REG) /* 32 bit integer argument or result. */ -#define SLJIT_ARG_TYPE_32 2 +#define SLJIT_ARG_TYPE_32 2 #define SLJIT_ARG_TYPE_32_R (SLJIT_ARG_TYPE_32 | SLJIT_ARG_TYPE_SCRATCH_REG) /* Pointer sized integer argument or result. */ -#define SLJIT_ARG_TYPE_P 3 +#define SLJIT_ARG_TYPE_P 3 #define SLJIT_ARG_TYPE_P_R (SLJIT_ARG_TYPE_P | SLJIT_ARG_TYPE_SCRATCH_REG) /* 64 bit floating point argument or result. */ -#define SLJIT_ARG_TYPE_F64 4 +#define SLJIT_ARG_TYPE_F64 4 /* 32 bit floating point argument or result. */ -#define SLJIT_ARG_TYPE_F32 5 +#define SLJIT_ARG_TYPE_F32 5 #define SLJIT_ARG_SHIFT 4 #define SLJIT_ARG_RETURN(type) (type) @@ -345,24 +374,40 @@ extern "C" { can be shortened to: SLJIT_ARGS1(W, F32) + + Another example where no value is returned: + SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_RET_VOID) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_W_R, 1) + + can be shortened to: + SLJIT_ARGS1V(W_R) */ #define SLJIT_ARG_TO_TYPE(type) SLJIT_ARG_TYPE_ ## type #define SLJIT_ARGS0(ret) \ SLJIT_ARG_RETURN(SLJIT_ARG_TO_TYPE(ret)) +#define SLJIT_ARGS0V() \ + SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_RET_VOID) #define SLJIT_ARGS1(ret, arg1) \ (SLJIT_ARGS0(ret) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg1), 1)) +#define SLJIT_ARGS1V(arg1) \ + (SLJIT_ARGS0V() | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg1), 1)) #define SLJIT_ARGS2(ret, arg1, arg2) \ (SLJIT_ARGS1(ret, arg1) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg2), 2)) +#define SLJIT_ARGS2V(arg1, arg2) \ + (SLJIT_ARGS1V(arg1) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg2), 2)) #define SLJIT_ARGS3(ret, arg1, arg2, arg3) \ (SLJIT_ARGS2(ret, arg1, arg2) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg3), 3)) +#define SLJIT_ARGS3V(arg1, arg2, arg3) \ + (SLJIT_ARGS2V(arg1, arg2) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg3), 3)) #define SLJIT_ARGS4(ret, arg1, arg2, arg3, arg4) \ (SLJIT_ARGS3(ret, arg1, arg2, arg3) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg4), 4)) +#define SLJIT_ARGS4V(arg1, arg2, arg3, arg4) \ + (SLJIT_ARGS3V(arg1, arg2, arg3) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg4), 4)) /* --------------------------------------------------------------------- */ /* Main structures and functions */ @@ -457,7 +502,7 @@ struct sljit_compiler { sljit_s32 mode32; #endif -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) /* Constant pool handling. */ sljit_uw *cpool; sljit_u8 *cpool_unique; @@ -468,10 +513,10 @@ struct sljit_compiler { sljit_uw patches; #endif -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Temporary fields. */ sljit_uw shift_imm; -#endif /* SLJIT_CONFIG_ARM_V5 || SLJIT_CONFIG_ARM_V7 */ +#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V6 */ #if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__) sljit_uw args_size; @@ -501,6 +546,11 @@ struct sljit_compiler { sljit_s32 mode; #endif +#if (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) + sljit_s32 cache_arg; + sljit_sw cache_argw; +#endif + #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) FILE* verbose; #endif @@ -558,8 +608,7 @@ static SLJIT_INLINE sljit_s32 sljit_get_compiler_error(struct sljit_compiler *co after the code is compiled. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler); -/* - Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit, +/* Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit, and <= 128 bytes on 64 bit architectures. The memory area is owned by the compiler, and freed by sljit_free_compiler. The returned pointer is sizeof(sljit_sw) aligned. Excellent for allocating small blocks during @@ -567,19 +616,21 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi to contain at most 16 pointers. If the size is outside of the range, the function will return with NULL. However, this return value does not indicate that there is no more memory (does not set the current error code - of the compiler to out-of-memory status). -*/ + of the compiler to out-of-memory status). */ SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size); +/* Returns the allocator data passed to sljit_create_compiler. These pointers + may contain context data even if the normal/exec allocator ignores it. */ +static SLJIT_INLINE void* sljit_get_allocator_data(struct sljit_compiler *compiler) { return compiler->allocator_data; } +static SLJIT_INLINE void* sljit_get_exec_allocator_data(struct sljit_compiler *compiler) { return compiler->exec_allocator_data; } + #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) /* Passing NULL disables verbose. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose); #endif -/* - Create executable code from the instruction stream. This is the final step - of the code generation so no more instructions can be emitted after this call. -*/ +/* Create executable code from the instruction stream. This is the final step + of the code generation so no more instructions can be emitted after this call. */ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler); @@ -587,8 +638,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data); -/* - When the protected executable allocator is used the JIT code is mapped +/* When the protected executable allocator is used the JIT code is mapped twice. The first mapping has read/write and the second mapping has read/exec permissions. This function returns with the relative offset of the executable mapping using the writable mapping as the base after the machine code is @@ -596,16 +646,13 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_d allocator, since it uses only one mapping with read/write/exec permissions. Dynamic code modifications requires this value. - Before a successful code generation, this function returns with 0. -*/ + Before a successful code generation, this function returns with 0. */ static SLJIT_INLINE sljit_sw sljit_get_executable_offset(struct sljit_compiler *compiler) { return compiler->executable_offset; } -/* - The executable memory consumption of the generated code can be retrieved by +/* The executable memory consumption of the generated code can be retrieved by this function. The returned value can be used for statistical purposes. - Before a successful code generation, this function returns with 0. -*/ + Before a successful code generation, this function returns with 0. */ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; } /* Returns with non-zero if the feature or limitation type passed as its @@ -628,30 +675,49 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler #define SLJIT_HAS_CLZ 3 /* [Emulated] Count trailing zero is supported. */ #define SLJIT_HAS_CTZ 4 +/* [Emulated] Reverse the order of bytes is supported. */ +#define SLJIT_HAS_REV 5 /* [Emulated] Rotate left/right is supported. */ -#define SLJIT_HAS_ROT 5 +#define SLJIT_HAS_ROT 6 /* [Emulated] Conditional move is supported. */ -#define SLJIT_HAS_CMOV 6 +#define SLJIT_HAS_CMOV 7 /* [Emulated] Prefetch instruction is available (emulated as a nop). */ -#define SLJIT_HAS_PREFETCH 7 +#define SLJIT_HAS_PREFETCH 8 +/* [Emulated] Copy from/to f32 operation is available (see sljit_emit_fcopy). */ +#define SLJIT_HAS_COPY_F32 9 +/* [Emulated] Copy from/to f64 operation is available (see sljit_emit_fcopy). */ +#define SLJIT_HAS_COPY_F64 10 +/* [Not emulated] The 64 bit floating point registers can be used as + two separate 32 bit floating point registers (e.g. ARM32). The + second 32 bit part can be accessed by SLJIT_F64_SECOND. */ +#define SLJIT_HAS_F64_AS_F32_PAIR 11 +/* [Not emulated] Some SIMD operations are supported by the compiler. */ +#define SLJIT_HAS_SIMD 12 +/* [Not emulated] SIMD registers are mapped to a pair of double precision + floating point registers. E.g. passing either SLJIT_FR0 or SLJIT_FR1 to + a simd operation represents the same 128 bit register, and both SLJIT_FR0 + and SLJIT_FR1 are overwritten. */ +#define SLJIT_SIMD_REGS_ARE_PAIRS 13 +/* [Not emulated] Atomic support is available (fine-grained). */ +#define SLJIT_HAS_ATOMIC 14 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) -/* [Not emulated] SSE2 support is available on x86. */ -#define SLJIT_HAS_SSE2 100 +/* [Not emulated] AVX support is available on x86. */ +#define SLJIT_HAS_AVX 100 +/* [Not emulated] AVX2 support is available on x86. */ +#define SLJIT_HAS_AVX2 101 #endif SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type); /* If type is between SLJIT_ORDERED_EQUAL and SLJIT_ORDERED_LESS_EQUAL, - sljit_cmp_info returns one, if the cpu supports the passed floating - point comparison type. + sljit_cmp_info returns with: + zero - if the cpu supports the floating point comparison type + one - if the comparison requires two machine instructions + two - if the comparison requires more than two machine instructions - If type is SLJIT_UNORDERED or SLJIT_ORDERED, sljit_cmp_info returns - one, if the cpu supports checking the unordered comparison result - regardless of the comparison type passed to the comparison instruction. - The returned value is always one, if there is at least one type between - SLJIT_ORDERED_EQUAL and SLJIT_ORDERED_LESS_EQUAL where sljit_cmp_info - returns with a zero value. + When the result is non-zero, it is recommended to avoid + using the specified comparison type if it is easy to do so. Otherwise it returns zero. */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); @@ -662,7 +728,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); /* The executable code is a function from the viewpoint of the C - language. The function calls must obey to the ABI (Application + language. The function calls must conform to the ABI (Application Binary Interface) of the platform, which specify the purpose of machine registers and stack handling among other things. The sljit_emit_enter function emits the necessary instructions for @@ -721,7 +787,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); #define SLJIT_ENTER_REG_ARG 0x00000004 /* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */ -#define SLJIT_MAX_LOCAL_SIZE 65536 +#define SLJIT_MAX_LOCAL_SIZE 1048576 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, @@ -732,9 +798,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi by sljit_emit_enter. Several functions (such as sljit_emit_return) requires this context to be able to generate the appropriate code. However, some code fragments (compiled separately) may have no - normal entry point so their context is unknown for the compiler. + normal entry point so their context is unknown to the compiler. - The sljit_set_context and sljit_emit_enter have the same arguments, + sljit_set_context and sljit_emit_enter have the same arguments, but sljit_set_context does not generate any machine code. Note: every call of sljit_emit_enter and sljit_set_context overwrites @@ -767,28 +833,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw); -/* Generating entry and exit points for fast call functions (see SLJIT_FAST_CALL). - Both sljit_emit_fast_enter and SLJIT_FAST_RETURN operations preserve the - values of all registers and stack frame. The return address is stored in the - dst argument of sljit_emit_fast_enter, and this return address can be passed - to SLJIT_FAST_RETURN to continue the execution after the fast call. - - Fast calls are cheap operations (usually only a single call instruction is - emitted) but they do not preserve any registers. However the callee function - can freely use / update any registers and the local area which can be - efficiently exploited by various optimizations. Registers can be saved - and restored manually if needed. - - Although returning to different address by SLJIT_FAST_RETURN is possible, - this address usually cannot be predicted by the return address predictor of - modern CPUs which may reduce performance. Furthermore certain security - enhancement technologies such as Intel Control-flow Enforcement Technology - (CET) may disallow returning to a different address. - - Flags: - (does not modify flags). */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw); - /* Source and destination operands for arithmetical instructions imm - a simple immediate value (cannot be used as a destination) @@ -816,7 +860,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * Note: Different architectures have different addressing limitations. A single instruction is enough for the following addressing - modes. Other adrressing modes are emulated by instruction + modes. Other addressing modes are emulated by instruction sequences. This information could help to improve those code generators which focuses only a few architectures. @@ -847,6 +891,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * s390x: [reg+imm], -2^19 <= imm < 2^19 [reg+reg] is supported Write-back is not supported + loongarch: [reg+imm], -2048 <= imm <= 2047 + [reg+reg] is supported + Write-back is not supported */ /* Macros for specifying operand types. */ @@ -854,9 +901,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * #define SLJIT_MEM0() (SLJIT_MEM) #define SLJIT_MEM1(r1) (SLJIT_MEM | (r1)) #define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 8)) -#define SLJIT_IMM 0x40 +#define SLJIT_IMM 0x7f #define SLJIT_REG_PAIR(r1, r2) ((r1) | ((r2) << 8)) +/* Macros for checking operand types (only for valid arguments). */ +#define SLJIT_IS_REG(arg) ((arg) > 0 && (arg) < SLJIT_IMM) +#define SLJIT_IS_MEM(arg) ((arg) & SLJIT_MEM) +#define SLJIT_IS_MEM0(arg) ((arg) == SLJIT_MEM) +#define SLJIT_IS_MEM1(arg) ((arg) > SLJIT_MEM && (arg) < (SLJIT_MEM << 1)) +#define SLJIT_IS_MEM2(arg) (((arg) & SLJIT_MEM) && (arg) >= (SLJIT_MEM << 1)) +#define SLJIT_IS_IMM(arg) ((arg) == SLJIT_IMM) +#define SLJIT_IS_REG_PAIR(arg) (!((arg) & SLJIT_MEM) && (arg) >= (SLJIT_MEM << 1)) + /* Sets 32 bit operation mode on 64 bit CPUs. This option is ignored on 32 bit CPUs. When this option is set for an arithmetic operation, only the lower 32 bits of the input registers are used, and the CPU status @@ -1057,27 +1113,57 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile Note: loads a pointer sized data, useful on x32 mode (a 64 bit mode on x86-64 which uses 32 bit pointers) or similar compiling modes */ #define SLJIT_MOV_P (SLJIT_OP1_BASE + 8) -/* Flags: Z - Note: immediate source argument is not supported */ -#define SLJIT_NOT (SLJIT_OP1_BASE + 9) -#define SLJIT_NOT32 (SLJIT_NOT | SLJIT_32) /* Count leading zeroes Flags: - (may destroy flags) Note: immediate source argument is not supported */ -#define SLJIT_CLZ (SLJIT_OP1_BASE + 10) +#define SLJIT_CLZ (SLJIT_OP1_BASE + 9) #define SLJIT_CLZ32 (SLJIT_CLZ | SLJIT_32) /* Count trailing zeroes Flags: - (may destroy flags) Note: immediate source argument is not supported */ -#define SLJIT_CTZ (SLJIT_OP1_BASE + 11) +#define SLJIT_CTZ (SLJIT_OP1_BASE + 10) #define SLJIT_CTZ32 (SLJIT_CTZ | SLJIT_32) +/* Reverse the order of bytes + Flags: - (may destroy flags) + Note: converts between little and big endian formats + Note: immediate source argument is not supported */ +#define SLJIT_REV (SLJIT_OP1_BASE + 11) +#define SLJIT_REV32 (SLJIT_REV | SLJIT_32) +/* Reverse the order of bytes in the lower 16 bit and extend as unsigned + Flags: - (may destroy flags) + Note: converts between little and big endian formats + Note: immediate source argument is not supported */ +#define SLJIT_REV_U16 (SLJIT_OP1_BASE + 12) +#define SLJIT_REV32_U16 (SLJIT_REV_U16 | SLJIT_32) +/* Reverse the order of bytes in the lower 16 bit and extend as signed + Flags: - (may destroy flags) + Note: converts between little and big endian formats + Note: immediate source argument is not supported */ +#define SLJIT_REV_S16 (SLJIT_OP1_BASE + 13) +#define SLJIT_REV32_S16 (SLJIT_REV_S16 | SLJIT_32) +/* Reverse the order of bytes in the lower 32 bit and extend as unsigned + Flags: - (may destroy flags) + Note: converts between little and big endian formats + Note: immediate source argument is not supported */ +#define SLJIT_REV_U32 (SLJIT_OP1_BASE + 14) +/* Reverse the order of bytes in the lower 32 bit and extend as signed + Flags: - (may destroy flags) + Note: converts between little and big endian formats + Note: immediate source argument is not supported */ +#define SLJIT_REV_S32 (SLJIT_OP1_BASE + 15) + +/* The following unary operations are supported by using sljit_emit_op2: + - binary not: SLJIT_XOR with immedate -1 as src1 or src2 + - negate: SLJIT_SUB with immedate 0 as src1 + Note: these operations are optimized by the compiler if the + target CPU has specialized instruction forms for them. */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw); /* Starting index of opcodes for sljit_emit_op2. */ -#define SLJIT_OP2_BASE 96 +#define SLJIT_OP2_BASE 64 /* Flags: Z | OVERFLOW | CARRY */ #define SLJIT_ADD (SLJIT_OP2_BASE + 0) @@ -1174,80 +1260,97 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil op must be one of the following operations: SLJIT_SHL or SLJIT_SHL32: - src_dst <<= src2 - src_dst |= ((src1 >> 1) >> (src2 ^ value_mask)) + dst_reg = src1_reg << src3_reg + dst_reg |= ((src2_reg >> 1) >> (src3 ^ value_mask)) SLJIT_MSHL or SLJIT_MSHL32: - src2 &= value_mask + src3 &= value_mask perform the SLJIT_SHL or SLJIT_SHL32 operation SLJIT_LSHR or SLJIT_LSHR32: - src_dst >>= src2 - src_dst |= ((src1 << 1) << (src2 ^ value_mask)) + dst_reg = src1_reg >> src3_reg + dst_reg |= ((src2_reg << 1) << (src3 ^ value_mask)) SLJIT_MLSHR or SLJIT_MLSHR32: - src2 &= value_mask + src3 &= value_mask perform the SLJIT_LSHR or SLJIT_LSHR32 operation op can be combined (or'ed) with SLJIT_SHIFT_INTO_NON_ZERO - src_dst must be a register which content is updated after - the operation is completed - src1 / src1w contains the bits which shifted into src_dst - src2 / src2w contains the shift amount + dst_reg specifies the destination register, where dst_reg + and src2_reg cannot be the same registers + src1_reg specifies the source register + src2_reg specifies the register which is shifted into src1_reg + src3 / src3w contains the shift amount - Note: a rotate operation can be performed if src_dst and - src1 are set to the same register + Note: a rotate operation is performed if src1_reg and + src2_reg are the same registers Flags: - (may destroy flags) */ -/* The src2 contains a non-zero value. Improves the generated - code on certain architectures, which provides a small - performance improvement. */ +/* The src3 operand contains a non-zero value. Improves + the generated code on certain architectures, which + provides a small performance improvement. */ #define SLJIT_SHIFT_INTO_NON_ZERO 0x200 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w); + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w); -/* Starting index of opcodes for sljit_emit_op2. */ -#define SLJIT_OP_SRC_BASE 128 +/* Starting index of opcodes for sljit_emit_op_src + and sljit_emit_op_dst. */ +#define SLJIT_OP_SRC_DST_BASE 96 -/* Note: src cannot be an immedate value +/* Fast return, see SLJIT_FAST_CALL for more details. + Note: src cannot be an immedate value Flags: - (does not modify flags) */ -#define SLJIT_FAST_RETURN (SLJIT_OP_SRC_BASE + 0) +#define SLJIT_FAST_RETURN (SLJIT_OP_SRC_DST_BASE + 0) /* Skip stack frames before fast return. Note: src cannot be an immedate value Flags: may destroy flags. */ -#define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN (SLJIT_OP_SRC_BASE + 1) +#define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN (SLJIT_OP_SRC_DST_BASE + 1) /* Prefetch value into the level 1 data cache Note: if the target CPU does not support data prefetch, no instructions are emitted. Note: this instruction never fails, even if the memory address is invalid. Flags: - (does not modify flags) */ -#define SLJIT_PREFETCH_L1 (SLJIT_OP_SRC_BASE + 2) +#define SLJIT_PREFETCH_L1 (SLJIT_OP_SRC_DST_BASE + 2) /* Prefetch value into the level 2 data cache Note: same as SLJIT_PREFETCH_L1 if the target CPU does not support this instruction form. Note: this instruction never fails, even if the memory address is invalid. Flags: - (does not modify flags) */ -#define SLJIT_PREFETCH_L2 (SLJIT_OP_SRC_BASE + 3) +#define SLJIT_PREFETCH_L2 (SLJIT_OP_SRC_DST_BASE + 3) /* Prefetch value into the level 3 data cache Note: same as SLJIT_PREFETCH_L2 if the target CPU does not support this instruction form. Note: this instruction never fails, even if the memory address is invalid. Flags: - (does not modify flags) */ -#define SLJIT_PREFETCH_L3 (SLJIT_OP_SRC_BASE + 4) +#define SLJIT_PREFETCH_L3 (SLJIT_OP_SRC_DST_BASE + 4) /* Prefetch a value which is only used once (and can be discarded afterwards) Note: same as SLJIT_PREFETCH_L1 if the target CPU does not support this instruction form. Note: this instruction never fails, even if the memory address is invalid. Flags: - (does not modify flags) */ -#define SLJIT_PREFETCH_ONCE (SLJIT_OP_SRC_BASE + 5) +#define SLJIT_PREFETCH_ONCE (SLJIT_OP_SRC_DST_BASE + 5) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw); +/* Fast enter, see SLJIT_FAST_CALL for more details. + Flags: - (does not modify flags) */ +#define SLJIT_FAST_ENTER (SLJIT_OP_SRC_DST_BASE + 6) + +/* Copies the return address into dst. The return address is the + address where the execution continues after the called function + returns (see: sljit_emit_return / sljit_emit_return_void). + Flags: - (does not modify flags) */ +#define SLJIT_GET_RETURN_ADDRESS (SLJIT_OP_SRC_DST_BASE + 7) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw); + /* Starting index of opcodes for sljit_emit_fop1. */ -#define SLJIT_FOP1_BASE 160 +#define SLJIT_FOP1_BASE 128 /* Flags: - (does not modify flags) */ #define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0) @@ -1270,15 +1373,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp /* Flags: - (may destroy flags) */ #define SLJIT_CONV_F64_FROM_S32 (SLJIT_FOP1_BASE + 5) #define SLJIT_CONV_F32_FROM_S32 (SLJIT_CONV_F64_FROM_S32 | SLJIT_32) +/* Flags: - (may destroy flags) */ +#define SLJIT_CONV_F64_FROM_UW (SLJIT_FOP1_BASE + 6) +#define SLJIT_CONV_F32_FROM_UW (SLJIT_CONV_F64_FROM_UW | SLJIT_32) +/* Flags: - (may destroy flags) */ +#define SLJIT_CONV_F64_FROM_U32 (SLJIT_FOP1_BASE + 7) +#define SLJIT_CONV_F32_FROM_U32 (SLJIT_CONV_F64_FROM_U32 | SLJIT_32) /* Note: dst is the left and src is the right operand for SLJIT_CMP_F32/64. Flags: EQUAL_F | LESS_F | GREATER_EQUAL_F | GREATER_F | LESS_EQUAL_F */ -#define SLJIT_CMP_F64 (SLJIT_FOP1_BASE + 6) +#define SLJIT_CMP_F64 (SLJIT_FOP1_BASE + 8) #define SLJIT_CMP_F32 (SLJIT_CMP_F64 | SLJIT_32) /* Flags: - (may destroy flags) */ -#define SLJIT_NEG_F64 (SLJIT_FOP1_BASE + 7) +#define SLJIT_NEG_F64 (SLJIT_FOP1_BASE + 9) #define SLJIT_NEG_F32 (SLJIT_NEG_F64 | SLJIT_32) /* Flags: - (may destroy flags) */ -#define SLJIT_ABS_F64 (SLJIT_FOP1_BASE + 8) +#define SLJIT_ABS_F64 (SLJIT_FOP1_BASE + 10) #define SLJIT_ABS_F32 (SLJIT_ABS_F64 | SLJIT_32) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, @@ -1286,7 +1395,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil sljit_s32 src, sljit_sw srcw); /* Starting index of opcodes for sljit_emit_fop2. */ -#define SLJIT_FOP2_BASE 192 +#define SLJIT_FOP2_BASE 160 /* Flags: - (may destroy flags) */ #define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0) @@ -1306,10 +1415,90 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w); +/* Starting index of opcodes for sljit_emit_fop2r. */ +#define SLJIT_FOP2R_BASE 168 + +/* Flags: - (may destroy flags) */ +#define SLJIT_COPYSIGN_F64 (SLJIT_FOP2R_BASE + 0) +#define SLJIT_COPYSIGN_F32 (SLJIT_COPYSIGN_F64 | SLJIT_32) + +/* Similar to sljit_emit_fop2, except the destination is always a register. */ +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); + +/* Sets a floating point register to an immediate value. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value); + +/* The following opcodes are used by sljit_emit_fcopy(). */ + +/* 64 bit: copy a 64 bit value from an integer register into a + 64 bit floating point register without any modifications. + 32 bit: copy a 32 bit register or register pair into a 64 bit + floating point register without any modifications. The + register, or the first register of the register pair + replaces the high order 32 bit of the floating point + register. If a register pair is passed, the low + order 32 bit is replaced by the second register. + Otherwise, the low order 32 bit is unchanged. */ +#define SLJIT_COPY_TO_F64 1 +/* Copy a 32 bit value from an integer register into a 32 bit + floating point register without any modifications. */ +#define SLJIT_COPY32_TO_F32 (SLJIT_COPY_TO_F64 | SLJIT_32) +/* 64 bit: copy the value of a 64 bit floating point register into + an integer register without any modifications. + 32 bit: copy a 64 bit floating point register into a 32 bit register + or a 32 bit register pair without any modifications. The + high order 32 bit of the floating point register is copied + into the register, or the first register of the register + pair. If a register pair is passed, the low order 32 bit + is copied into the second register. */ +#define SLJIT_COPY_FROM_F64 2 +/* Copy the value of a 32 bit floating point register into an integer + register without any modifications. The register should be processed + with 32 bit operations later. */ +#define SLJIT_COPY32_FROM_F32 (SLJIT_COPY_FROM_F64 | SLJIT_32) + +/* Special data copy which involves floating point registers. + + op must be between SLJIT_COPY_TO_F64 and SLJIT_COPY32_FROM_F32 + freg must be a floating point register + reg must be a register or register pair */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg); + /* Label and jump instructions. */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler); +/* The SLJIT_FAST_CALL is a calling method for creating lightweight function + calls. This type of calls preserve the values of all registers and stack + frame. Unlike normal function calls, the enter and return operations must + be performed by the SLJIT_FAST_ENTER and SLJIT_FAST_RETURN operations + respectively. The return address is stored in the dst argument of the + SLJIT_FAST_ENTER operation, and this return address should be passed as + the src argument for the SLJIT_FAST_RETURN operation to return from the + called function. + + Fast calls are cheap operations (usually only a single call instruction is + emitted) but they do not preserve any registers. However the callee function + can freely use / update any registers and the locals area which can be + efficiently exploited by various optimizations. Registers can be saved + and restored manually if needed. + + Although returning to different address by SLJIT_FAST_RETURN is possible, + this address usually cannot be predicted by the return address predictor of + modern CPUs which may reduce performance. Furthermore certain security + enhancement technologies such as Intel Control-flow Enforcement Technology + (CET) may disallow returning to a different address (indirect jumps + can be used instead, see SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN). */ + /* Invert (negate) conditional type: xor (^) with 0x1 */ /* Integer comparison types. */ @@ -1321,19 +1510,19 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #define SLJIT_LESS 2 #define SLJIT_SET_LESS SLJIT_SET(SLJIT_LESS) #define SLJIT_GREATER_EQUAL 3 -#define SLJIT_SET_GREATER_EQUAL SLJIT_SET(SLJIT_GREATER_EQUAL) +#define SLJIT_SET_GREATER_EQUAL SLJIT_SET(SLJIT_LESS) #define SLJIT_GREATER 4 #define SLJIT_SET_GREATER SLJIT_SET(SLJIT_GREATER) #define SLJIT_LESS_EQUAL 5 -#define SLJIT_SET_LESS_EQUAL SLJIT_SET(SLJIT_LESS_EQUAL) +#define SLJIT_SET_LESS_EQUAL SLJIT_SET(SLJIT_GREATER) #define SLJIT_SIG_LESS 6 #define SLJIT_SET_SIG_LESS SLJIT_SET(SLJIT_SIG_LESS) #define SLJIT_SIG_GREATER_EQUAL 7 -#define SLJIT_SET_SIG_GREATER_EQUAL SLJIT_SET(SLJIT_SIG_GREATER_EQUAL) +#define SLJIT_SET_SIG_GREATER_EQUAL SLJIT_SET(SLJIT_SIG_LESS) #define SLJIT_SIG_GREATER 8 #define SLJIT_SET_SIG_GREATER SLJIT_SET(SLJIT_SIG_GREATER) #define SLJIT_SIG_LESS_EQUAL 9 -#define SLJIT_SET_SIG_LESS_EQUAL SLJIT_SET(SLJIT_SIG_LESS_EQUAL) +#define SLJIT_SET_SIG_LESS_EQUAL SLJIT_SET(SLJIT_SIG_GREATER) #define SLJIT_OVERFLOW 10 #define SLJIT_SET_OVERFLOW SLJIT_SET(SLJIT_OVERFLOW) @@ -1344,70 +1533,74 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #define SLJIT_SET_CARRY SLJIT_SET(SLJIT_CARRY) #define SLJIT_NOT_CARRY 13 +#define SLJIT_ATOMIC_STORED 14 +#define SLJIT_SET_ATOMIC_STORED SLJIT_SET(SLJIT_ATOMIC_STORED) +#define SLJIT_ATOMIC_NOT_STORED 15 + /* Basic floating point comparison types. Note: when the comparison result is unordered, their behaviour is unspecified. */ -#define SLJIT_F_EQUAL 14 +#define SLJIT_F_EQUAL 16 #define SLJIT_SET_F_EQUAL SLJIT_SET(SLJIT_F_EQUAL) -#define SLJIT_F_NOT_EQUAL 15 -#define SLJIT_SET_F_NOT_EQUAL SLJIT_SET(SLJIT_F_NOT_EQUAL) -#define SLJIT_F_LESS 16 +#define SLJIT_F_NOT_EQUAL 17 +#define SLJIT_SET_F_NOT_EQUAL SLJIT_SET(SLJIT_F_EQUAL) +#define SLJIT_F_LESS 18 #define SLJIT_SET_F_LESS SLJIT_SET(SLJIT_F_LESS) -#define SLJIT_F_GREATER_EQUAL 17 -#define SLJIT_SET_F_GREATER_EQUAL SLJIT_SET(SLJIT_F_GREATER_EQUAL) -#define SLJIT_F_GREATER 18 +#define SLJIT_F_GREATER_EQUAL 19 +#define SLJIT_SET_F_GREATER_EQUAL SLJIT_SET(SLJIT_F_LESS) +#define SLJIT_F_GREATER 20 #define SLJIT_SET_F_GREATER SLJIT_SET(SLJIT_F_GREATER) -#define SLJIT_F_LESS_EQUAL 19 -#define SLJIT_SET_F_LESS_EQUAL SLJIT_SET(SLJIT_F_LESS_EQUAL) +#define SLJIT_F_LESS_EQUAL 21 +#define SLJIT_SET_F_LESS_EQUAL SLJIT_SET(SLJIT_F_GREATER) /* Jumps when either argument contains a NaN value. */ -#define SLJIT_UNORDERED 20 +#define SLJIT_UNORDERED 22 #define SLJIT_SET_UNORDERED SLJIT_SET(SLJIT_UNORDERED) /* Jumps when neither argument contains a NaN value. */ -#define SLJIT_ORDERED 21 -#define SLJIT_SET_ORDERED SLJIT_SET(SLJIT_ORDERED) +#define SLJIT_ORDERED 23 +#define SLJIT_SET_ORDERED SLJIT_SET(SLJIT_UNORDERED) /* Ordered / unordered floating point comparison types. Note: each comparison type has an ordered and unordered form. Some architectures supports only either of them (see: sljit_cmp_info). */ -#define SLJIT_ORDERED_EQUAL 22 +#define SLJIT_ORDERED_EQUAL 24 #define SLJIT_SET_ORDERED_EQUAL SLJIT_SET(SLJIT_ORDERED_EQUAL) -#define SLJIT_UNORDERED_OR_NOT_EQUAL 23 -#define SLJIT_SET_UNORDERED_OR_NOT_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_NOT_EQUAL) -#define SLJIT_ORDERED_LESS 24 +#define SLJIT_UNORDERED_OR_NOT_EQUAL 25 +#define SLJIT_SET_UNORDERED_OR_NOT_EQUAL SLJIT_SET(SLJIT_ORDERED_EQUAL) +#define SLJIT_ORDERED_LESS 26 #define SLJIT_SET_ORDERED_LESS SLJIT_SET(SLJIT_ORDERED_LESS) -#define SLJIT_UNORDERED_OR_GREATER_EQUAL 25 -#define SLJIT_SET_UNORDERED_OR_GREATER_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_GREATER_EQUAL) -#define SLJIT_ORDERED_GREATER 26 +#define SLJIT_UNORDERED_OR_GREATER_EQUAL 27 +#define SLJIT_SET_UNORDERED_OR_GREATER_EQUAL SLJIT_SET(SLJIT_ORDERED_LESS) +#define SLJIT_ORDERED_GREATER 28 #define SLJIT_SET_ORDERED_GREATER SLJIT_SET(SLJIT_ORDERED_GREATER) -#define SLJIT_UNORDERED_OR_LESS_EQUAL 27 -#define SLJIT_SET_UNORDERED_OR_LESS_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_LESS_EQUAL) +#define SLJIT_UNORDERED_OR_LESS_EQUAL 29 +#define SLJIT_SET_UNORDERED_OR_LESS_EQUAL SLJIT_SET(SLJIT_ORDERED_GREATER) -#define SLJIT_UNORDERED_OR_EQUAL 28 +#define SLJIT_UNORDERED_OR_EQUAL 30 #define SLJIT_SET_UNORDERED_OR_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_EQUAL) -#define SLJIT_ORDERED_NOT_EQUAL 29 -#define SLJIT_SET_ORDERED_NOT_EQUAL SLJIT_SET(SLJIT_ORDERED_NOT_EQUAL) -#define SLJIT_UNORDERED_OR_LESS 30 +#define SLJIT_ORDERED_NOT_EQUAL 31 +#define SLJIT_SET_ORDERED_NOT_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_EQUAL) +#define SLJIT_UNORDERED_OR_LESS 32 #define SLJIT_SET_UNORDERED_OR_LESS SLJIT_SET(SLJIT_UNORDERED_OR_LESS) -#define SLJIT_ORDERED_GREATER_EQUAL 31 -#define SLJIT_SET_ORDERED_GREATER_EQUAL SLJIT_SET(SLJIT_ORDERED_GREATER_EQUAL) -#define SLJIT_UNORDERED_OR_GREATER 32 +#define SLJIT_ORDERED_GREATER_EQUAL 33 +#define SLJIT_SET_ORDERED_GREATER_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_LESS) +#define SLJIT_UNORDERED_OR_GREATER 34 #define SLJIT_SET_UNORDERED_OR_GREATER SLJIT_SET(SLJIT_UNORDERED_OR_GREATER) -#define SLJIT_ORDERED_LESS_EQUAL 33 -#define SLJIT_SET_ORDERED_LESS_EQUAL SLJIT_SET(SLJIT_ORDERED_LESS_EQUAL) +#define SLJIT_ORDERED_LESS_EQUAL 35 +#define SLJIT_SET_ORDERED_LESS_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_GREATER) /* Unconditional jump types. */ -#define SLJIT_JUMP 34 -/* Fast calling method. See sljit_emit_fast_enter / SLJIT_FAST_RETURN. */ -#define SLJIT_FAST_CALL 35 +#define SLJIT_JUMP 36 +/* Fast calling method. See the description above. */ +#define SLJIT_FAST_CALL 37 /* Default C calling convention. */ -#define SLJIT_CALL 36 +#define SLJIT_CALL 38 /* Called function must be compiled by SLJIT. See SLJIT_ENTER_REG_ARG option. */ -#define SLJIT_CALL_REG_ARG 37 +#define SLJIT_CALL_REG_ARG 39 /* The target can be changed during runtime (see: sljit_set_jump_addr). */ #define SLJIT_REWRITABLE_JUMP 0x1000 @@ -1497,19 +1690,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_s32 dst, sljit_sw dstw, sljit_s32 type); -/* Emit a conditional mov instruction which moves source to destination, - if the condition is satisfied. Unlike other arithmetic operations this - instruction does not support memory access. +/* Emit a conditional select instruction which moves src1 to dst_reg, + if the condition is satisfied, or src2_reg to dst_reg otherwise. type must be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL - type can be combined (or'ed) with SLJIT_32 - dst_reg must be a valid register - src must be a valid register or immediate (SLJIT_IMM) + type can be combined (or'ed) with SLJIT_32 to move 32 bit + register values instead of word sized ones + dst_reg and src2_reg must be valid registers + src1 must be valid operand + + Note: if src1 is a memory operand, its value + might be loaded even if the condition is false. Flags: - (does not modify flags) */ -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw); + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg); + +/* Emit a conditional floating point select instruction which moves + src1 to dst_reg, if the condition is satisfied, or src2_reg to + dst_reg otherwise. + + type must be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL + type can be combined (or'ed) with SLJIT_32 to move 32 bit + floating point values instead of 64 bit ones + dst_freg and src2_freg must be valid floating point registers + src1 must be valid operand + + Note: if src1 is a memory operand, its value + might be loaded even if the condition is false. + + Flags: - (does not modify flags) */ +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg); /* The following flags are used by sljit_emit_mem(), sljit_emit_mem_update(), sljit_emit_fmem(), and sljit_emit_fmem_update(). */ @@ -1524,9 +1740,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil /* Load or stora data from an unaligned (byte aligned) address. */ #define SLJIT_MEM_UNALIGNED 0x000400 /* Load or stora data from a 16 bit aligned address. */ -#define SLJIT_MEM_UNALIGNED_16 0x000800 +#define SLJIT_MEM_ALIGNED_16 0x000800 /* Load or stora data from a 32 bit aligned address. */ -#define SLJIT_MEM_UNALIGNED_32 0x001000 +#define SLJIT_MEM_ALIGNED_32 0x001000 /* The following flags are used by sljit_emit_mem_update(), and sljit_emit_fmem_update(). */ @@ -1544,8 +1760,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil /* The sljit_emit_mem emits instructions for various memory operations: - When SLJIT_MEM_UNALIGNED / SLJIT_MEM_UNALIGNED_16 / - SLJIT_MEM_UNALIGNED_32 is set in type argument: + When SLJIT_MEM_UNALIGNED / SLJIT_MEM_ALIGNED_16 / + SLJIT_MEM_ALIGNED_32 is set in type argument: Emit instructions for unaligned memory loads or stores. When SLJIT_UNALIGNED is not defined, the only way to access unaligned memory data is using sljit_emit_mem. Otherwise all operations (e.g. @@ -1560,8 +1776,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil location specified by the mem/memw arguments, and the end address of this operation is the starting address of the data transfer between the second register and memory. The type argument must - be SLJIT_MOV. The SLJIT_MEM_UNALIGNED* options are allowed for - this operation. + be SLJIT_MOV. The SLJIT_MEM_UNALIGNED / SLJIT_MEM_ALIGNED_* + options are allowed for this operation. type must be between SLJIT_MOV and SLJIT_MOV_P and can be combined (or'ed) with SLJIT_MEM_* flags @@ -1625,6 +1841,286 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler sljit_s32 freg, sljit_s32 mem, sljit_sw memw); +/* The following options are used by several simd operations. */ + +/* Load data into a simd register, this is the default */ +#define SLJIT_SIMD_LOAD 0x000000 +/* Store data from a simd register */ +#define SLJIT_SIMD_STORE 0x000001 +/* The simd register contains floating point values */ +#define SLJIT_SIMD_FLOAT 0x000400 +/* Tests whether the operation is available */ +#define SLJIT_SIMD_TEST 0x000800 +/* Move data to/from a 64 bit (8 byte) long SIMD register */ +#define SLJIT_SIMD_REG_64 (3 << 12) +/* Move data to/from a 128 bit (16 byte) long SIMD register */ +#define SLJIT_SIMD_REG_128 (4 << 12) +/* Move data to/from a 256 bit (32 byte) long SIMD register */ +#define SLJIT_SIMD_REG_256 (5 << 12) +/* Move data to/from a 512 bit (64 byte) long SIMD register */ +#define SLJIT_SIMD_REG_512 (6 << 12) +/* Element size is 8 bit long (this is the default), usually cannot be combined with SLJIT_SIMD_FLOAT */ +#define SLJIT_SIMD_ELEM_8 (0 << 18) +/* Element size is 16 bit long, usually cannot be combined with SLJIT_SIMD_FLOAT */ +#define SLJIT_SIMD_ELEM_16 (1 << 18) +/* Element size is 32 bit long */ +#define SLJIT_SIMD_ELEM_32 (2 << 18) +/* Element size is 64 bit long */ +#define SLJIT_SIMD_ELEM_64 (3 << 18) +/* Element size is 128 bit long */ +#define SLJIT_SIMD_ELEM_128 (4 << 18) +/* Element size is 256 bit long */ +#define SLJIT_SIMD_ELEM_256 (5 << 18) + +/* The following options are used by sljit_emit_simd_mov(). */ + +/* Memory address is unaligned (this is the default) */ +#define SLJIT_SIMD_MEM_UNALIGNED (0 << 24) +/* Memory address is 16 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_16 (1 << 24) +/* Memory address is 32 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_32 (2 << 24) +/* Memory address is 64 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_64 (3 << 24) +/* Memory address is 128 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_128 (4 << 24) +/* Memory address is 256 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_256 (5 << 24) +/* Memory address is 512 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_512 (6 << 24) + +/* Moves data between a simd register and memory. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* and + SLJIT_SIMD_MEM_* options + freg is the source or destination simd register + of the operation + srcdst must be a memory operand or a simd register + + Note: + The alignment and element size must be + less or equal than simd register size. + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw); + +/* Replicates a scalar value to all lanes of a simd + register. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* options + except SLJIT_SIMD_STORE. + freg is the destination simd register of the operation + src is the value which is replicated + + Note: + The src == SLJIT_IMM and srcw == 0 can be used to + clear a register even when SLJIT_SIMD_FLOAT is set. + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw); + +/* The following options are used by sljit_emit_simd_lane_mov(). */ + +/* Clear all bits of the simd register before loading the lane. */ +#define SLJIT_SIMD_LANE_ZERO 0x000002 +/* Sign extend the integer value stored from the lane. */ +#define SLJIT_SIMD_LANE_SIGNED 0x000004 + +/* Moves data between a simd register lane and a register or + memory. If the srcdst argument is a register, it must be + a floating point register when SLJIT_SIMD_FLOAT is specified, + or a general purpose register otherwise. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* options + Further options: + SLJIT_32 - when SLJIT_SIMD_FLOAT is not set + SLJIT_SIMD_LANE_SIGNED - when SLJIT_SIMD_STORE + is set and SLJIT_SIMD_FLOAT is not set + SLJIT_SIMD_LANE_ZERO - when SLJIT_SIMD_LOAD + is specified + freg is the source or destination simd register + of the operation + lane_index is the index of the lane + srcdst is the destination operand for loads, and + source operand for stores + + Note: + The elem size must be lower than register size. + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw); + +/* Replicates a scalar value from a lane to all lanes + of a simd register. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* options + except SLJIT_SIMD_STORE. + freg is the destination simd register of the operation + src is the simd register which lane is replicated + src_lane_index is the lane index of the src register + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index); + +/* The following options are used by sljit_emit_simd_load_extend(). */ + +/* Sign extend the integer elements */ +#define SLJIT_SIMD_EXTEND_SIGNED 0x000002 +/* Extend data to 16 bit */ +#define SLJIT_SIMD_EXTEND_16 (1 << 24) +/* Extend data to 32 bit */ +#define SLJIT_SIMD_EXTEND_32 (2 << 24) +/* Extend data to 64 bit */ +#define SLJIT_SIMD_EXTEND_64 (3 << 24) + +/* Extend elements and stores them in a simd register. + The extension operation increases the size of the + elements (e.g. from 16 bit to 64 bit). For integer + values, the extension can be signed or unsigned. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_*, and + SLJIT_SIMD_EXTEND_* options except SLJIT_SIMD_STORE + freg is the destination simd register of the operation + src must be a memory operand or a simd register. + In the latter case, the source elements are stored + in the lower half of the register. + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw); + +/* Extract the highest bit (usually the sign bit) from + each elements of a vector. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* and SLJIT_32 + options except SLJIT_SIMD_LOAD + freg is the source simd register of the operation + dst is the destination operand + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw); + +/* The following options are used by sljit_emit_simd_op2(). */ + +/* Binary 'and' operation */ +#define SLJIT_SIMD_OP2_AND 0x000001 +/* Binary 'or' operation */ +#define SLJIT_SIMD_OP2_OR 0x000002 +/* Binary 'xor' operation */ +#define SLJIT_SIMD_OP2_XOR 0x000003 + +/* Perform simd operations using simd registers. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* and SLJIT_SIMD_OP2_ + options except SLJIT_SIMD_LOAD and SLJIT_SIMD_STORE + dst_freg is the destination register of the operation + src1_freg is the first source register of the operation + src1_freg is the second source register of the operation + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg); + +/* The sljit_emit_atomic_load and sljit_emit_atomic_store operation pair + can perform an atomic read-modify-write operation. First, an unsigned + value must be loaded from memory using sljit_emit_atomic_load. Then, + the updated value must be written back to the same memory location by + sljit_emit_atomic_store. A thread can only perform a single atomic + operation at a time. + + Note: atomic operations are experimental, and not implemented + for all cpus. + + The following conditions must be satisfied, or the operation + is undefined: + - the address provided in mem_reg must be divisible by the size of + the value (only naturally aligned updates are supported) + - no memory writes are allowed between the load and store operations + regardless of its target address (currently read operations are + allowed, but this might change in the future) + - the memory operation (op) and the base address (stored in mem_reg) + passed to the load/store operations must be the same (the mem_reg + can be a different register, only its value must be the same) + - an store must always follow a load for the same transaction. + + op must be between SLJIT_MOV and SLJIT_MOV_P, excluding all + signed loads such as SLJIT_MOV32_S16 + dst_reg is the register where the data will be loaded into + mem_reg is the base address of the memory load (it cannot be + SLJIT_SP or a virtual register on x86-32) + + Flags: - (does not modify flags) */ +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg); + +/* The sljit_emit_atomic_load and sljit_emit_atomic_store operations + allows performing an atomic read-modify-write operation. See the + description of sljit_emit_atomic_load. + + op must be between SLJIT_MOV and SLJIT_MOV_P, excluding all signed + loads such as SLJIT_MOV32_S16 + src_reg is the register which value is stored into the memory + mem_reg is the base address of the memory store (it cannot be + SLJIT_SP or a virtual register on x86-32) + temp_reg is a not preserved scratch register, which must be + initialized with the value loaded into the dst_reg during the + corresponding sljit_emit_atomic_load operation, or the operation + is undefined + + Flags: ATOMIC_STORED is set if the operation is successful, + otherwise the memory remains unchanged. */ +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg); + /* Copies the base address of SLJIT_SP + offset to dst. The offset can represent the starting address of a value in the local data (stack). The offset is not limited by the local data limits, it can be any value. @@ -1665,30 +2161,39 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta /* CPU specific functions */ /* --------------------------------------------------------------------- */ -/* The following function is a helper function for sljit_emit_op_custom. - It returns with the real machine register index ( >=0 ) of any SLJIT_R, - SLJIT_S and SLJIT_SP registers. +/* Types for sljit_get_register_index */ - Note: it returns with -1 for virtual registers (only on x86-32). */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg); +/* General purpose (integer) registers. */ +#define SLJIT_GP_REGISTER 0 +/* Floating point registers. */ +#define SLJIT_FLOAT_REGISTER 1 /* The following function is a helper function for sljit_emit_op_custom. - It returns with the real machine register ( >= 0 ) index of any SLJIT_FR, - and SLJIT_FS register. + It returns with the real machine register index ( >=0 ) of any registers. - Note: the index is always an even number on ARM-32, MIPS. */ + When type is SLJIT_GP_REGISTER: + reg must be an SLJIT_R(i), SLJIT_S(i), or SLJIT_SP register -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg); + When type is SLJIT_FLOAT_REGISTER: + reg must be an SLJIT_FR(i) or SLJIT_FS(i) register + + When type is SLJIT_SIMD_REG_64 / 128 / 256 / 512 : + reg must be an SLJIT_FR(i) or SLJIT_FS(i) register + + Note: it returns with -1 for unknown registers, such as virtual + registers on x86-32 or unsupported simd registers. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg); /* Any instruction can be inserted into the instruction stream by sljit_emit_op_custom. It has a similar purpose as inline assembly. The size parameter must match to the instruction size of the target architecture: - x86: 0 < size <= 15. The instruction argument can be byte aligned. + x86: 0 < size <= 15, the instruction argument can be byte aligned. Thumb2: if size == 2, the instruction argument must be 2 byte aligned. if size == 4, the instruction argument must be 4 byte aligned. + s390x: size can be 2, 4, or 6, the instruction argument can be byte aligned. Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -1725,7 +2230,8 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *com to know the type of the code generator. */ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void); -/* Portable helper function to get an offset of a member. */ +/* Portable helper function to get an offset of a member. + Same as offsetof() macro defined in stddef.h */ #define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10) #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_32.c index 54b8ade0636..d44616d800f 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_32.c @@ -34,13 +34,16 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) return "ARMv7" SLJIT_CPUINFO ARM_ABI_INFO; -#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - return "ARMv5" SLJIT_CPUINFO ARM_ABI_INFO; +#elif (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + return "ARMv6" SLJIT_CPUINFO ARM_ABI_INFO; #else #error "Internal error: Unknown ARM architecture" #endif } +/* Length of an instruction word. */ +typedef sljit_u32 sljit_ins; + /* Last register + 1. */ #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) @@ -55,27 +58,39 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) #define CONST_POOL_EMPTY 0xffffffff #define ALIGN_INSTRUCTION(ptr) \ - (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1)) + (sljit_ins*)(((sljit_ins)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_ins)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_ins)) - 1)) #define MAX_DIFFERENCE(max_diff) \ - (((max_diff) / (sljit_s32)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) + (((max_diff) / (sljit_s32)sizeof(sljit_ins)) - (CONST_POOL_ALIGNMENT - 1)) /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15 }; -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { - 0, 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, 6, 7 +static const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = { + 0, + 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, + 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6 }; -#define RM(rm) ((sljit_uw)reg_map[rm]) -#define RM8(rm) ((sljit_uw)reg_map[rm] << 8) -#define RD(rd) ((sljit_uw)reg_map[rd] << 12) -#define RN(rn) ((sljit_uw)reg_map[rn] << 16) +static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = { + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1 +}; -#define VM(rm) ((sljit_uw)freg_map[rm]) -#define VD(rd) ((sljit_uw)freg_map[rd] << 12) -#define VN(rn) ((sljit_uw)freg_map[rn] << 16) +#define RM(rm) ((sljit_ins)reg_map[rm]) +#define RM8(rm) ((sljit_ins)reg_map[rm] << 8) +#define RD(rd) ((sljit_ins)reg_map[rd] << 12) +#define RN(rn) ((sljit_ins)reg_map[rn] << 16) + +#define VM(vm) (((sljit_ins)freg_map[vm]) | ((sljit_ins)freg_ebit_map[vm] << 5)) +#define VD(vd) (((sljit_ins)freg_map[vd] << 12) | ((sljit_ins)freg_ebit_map[vd] << 22)) +#define VN(vn) (((sljit_ins)freg_map[vn] << 16) | ((sljit_ins)freg_ebit_map[vn] << 7)) /* --------------------------------------------------------------------- */ /* Instrucion forms */ @@ -92,16 +107,19 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define AND 0xe0000000 #define B 0xea000000 #define BIC 0xe1c00000 +#define BKPT 0xe1200070 #define BL 0xeb000000 #define BLX 0xe12fff30 #define BX 0xe12fff10 #define CLZ 0xe16f0f10 #define CMN 0xe1600000 #define CMP 0xe1400000 -#define BKPT 0xe1200070 #define EOR 0xe0200000 #define LDR 0xe5100000 #define LDR_POST 0xe4100000 +#define LDREX 0xe1900f9f +#define LDREXB 0xe1d00f9f +#define LDREXH 0xe1f00f9f #define MOV 0xe1a00000 #define MUL 0xe0000090 #define MVN 0xe1e00000 @@ -109,50 +127,89 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define ORR 0xe1800000 #define PUSH 0xe92d0000 #define POP 0xe8bd0000 -#define RBIT 0xe6ff0f30 +#define REV 0xe6bf0f30 +#define REV16 0xe6bf0fb0 #define RSB 0xe0600000 #define RSC 0xe0e00000 #define SBC 0xe0c00000 #define SMULL 0xe0c00090 #define STR 0xe5000000 +#define STREX 0xe1800f90 +#define STREXB 0xe1c00f90 +#define STREXH 0xe1e00f90 #define SUB 0xe0400000 +#define SXTB 0xe6af0070 +#define SXTH 0xe6bf0070 #define TST 0xe1000000 #define UMULL 0xe0800090 +#define UXTB 0xe6ef0070 +#define UXTH 0xe6ff0070 #define VABS_F32 0xeeb00ac0 #define VADD_F32 0xee300a00 +#define VAND 0xf2000110 #define VCMP_F32 0xeeb40a40 #define VCVT_F32_S32 0xeeb80ac0 +#define VCVT_F32_U32 0xeeb80a40 #define VCVT_F64_F32 0xeeb70ac0 #define VCVT_S32_F32 0xeebd0ac0 #define VDIV_F32 0xee800a00 +#define VDUP 0xee800b10 +#define VDUP_s 0xf3b00c00 +#define VEOR 0xf3000110 +#define VLD1 0xf4200000 +#define VLD1_r 0xf4a00c00 +#define VLD1_s 0xf4a00000 #define VLDR_F32 0xed100a00 #define VMOV_F32 0xeeb00a40 #define VMOV 0xee000a10 #define VMOV2 0xec400a10 +#define VMOV_i 0xf2800010 +#define VMOV_s 0xee000b10 +#define VMOVN 0xf3b20200 #define VMRS 0xeef1fa10 #define VMUL_F32 0xee200a00 #define VNEG_F32 0xeeb10a40 +#define VORR 0xf2200110 #define VPOP 0xecbd0b00 #define VPUSH 0xed2d0b00 +#define VSHLL 0xf2800a10 +#define VSHR 0xf2800010 +#define VSRA 0xf2800110 +#define VST1 0xf4000000 +#define VST1_s 0xf4800000 #define VSTR_F32 0xed000a00 #define VSUB_F32 0xee300a40 #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Arm v7 specific instructions. */ -#define MOVW 0xe3000000 #define MOVT 0xe3400000 -#define SXTB 0xe6af0070 -#define SXTH 0xe6bf0070 -#define UXTB 0xe6ef0070 -#define UXTH 0xe6ff0070 +#define MOVW 0xe3000000 +#define RBIT 0xe6ff0f30 #endif -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + +static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32) +{ + if (compiler->scratches == -1) + return 0; + + if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) + fr -= SLJIT_F64_SECOND(0); + + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) + || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); +} + +#endif /* SLJIT_ARGUMENT_CHECKS */ + +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) static sljit_s32 push_cpool(struct sljit_compiler *compiler) { /* Pushing the constant pool into the instruction stream. */ - sljit_uw* inst; + sljit_ins* inst; sljit_uw* cpool_ptr; sljit_uw* cpool_end; sljit_s32 i; @@ -162,13 +219,13 @@ static sljit_s32 push_cpool(struct sljit_compiler *compiler) compiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1; SLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE); - inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + inst = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!inst); compiler->size++; *inst = 0xff000000 | compiler->cpool_fill; for (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) { - inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + inst = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!inst); compiler->size++; *inst = 0; @@ -177,7 +234,7 @@ static sljit_s32 push_cpool(struct sljit_compiler *compiler) cpool_ptr = compiler->cpool; cpool_end = cpool_ptr + compiler->cpool_fill; while (cpool_ptr < cpool_end) { - inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + inst = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!inst); compiler->size++; *inst = *cpool_ptr++; @@ -187,23 +244,23 @@ static sljit_s32 push_cpool(struct sljit_compiler *compiler) return SLJIT_SUCCESS; } -static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins inst) { - sljit_uw* ptr; + sljit_ins* ptr; if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) FAIL_IF(push_cpool(compiler)); - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); compiler->size++; *ptr = inst; return SLJIT_SUCCESS; } -static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_ins inst, sljit_uw literal) { - sljit_uw* ptr; + sljit_ins* ptr; sljit_uw cpool_index = CPOOL_SIZE; sljit_uw* cpool_ptr; sljit_uw* cpool_end; @@ -239,7 +296,7 @@ static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_u } SLJIT_ASSERT((inst & 0xfff) == 0); - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); compiler->size++; *ptr = inst | cpool_index; @@ -251,14 +308,15 @@ static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_u return SLJIT_SUCCESS; } -static sljit_s32 push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +static sljit_s32 push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_ins inst, sljit_uw literal) { - sljit_uw* ptr; + sljit_ins* ptr; + if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE)) FAIL_IF(push_cpool(compiler)); SLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0); - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); compiler->size++; *ptr = inst | compiler->cpool_fill; @@ -305,7 +363,7 @@ static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ while (last_pc_patch < code_ptr) { /* Data transfer instruction with Rn == r15. */ - if ((*last_pc_patch & 0x0c0f0000) == 0x040f0000) { + if ((*last_pc_patch & 0x0e0f0000) == 0x040f0000) { diff = (sljit_uw)(const_pool - last_pc_patch); ind = (*last_pc_patch) & 0xfff; @@ -395,11 +453,11 @@ static sljit_s32 resolve_const_pool_index(struct sljit_compiler *compiler, struc #else -static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins inst) { - sljit_uw* ptr; + sljit_ins* ptr; - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); compiler->size++; *ptr = inst; @@ -421,7 +479,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw if (jump->flags & SLJIT_REWRITABLE_JUMP) return 0; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (jump->flags & IS_BL) code_ptr--; @@ -449,7 +507,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw jump->flags |= PATCH_B; } } -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ if (jump->flags & JUMP_ADDR) diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr - executable_offset); else { @@ -467,16 +525,16 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw jump->flags |= PATCH_B; return 1; } -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ return 0; } static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw executable_offset, sljit_uw new_addr, sljit_s32 flush_cache) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_uw *ptr = (sljit_uw *)jump_ptr; - sljit_uw *inst = (sljit_uw *)ptr[0]; - sljit_uw mov_pc = ptr[1]; +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + sljit_ins *ptr = (sljit_ins*)jump_ptr; + sljit_ins *inst = (sljit_ins*)ptr[0]; + sljit_ins mov_pc = ptr[1]; sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC); sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2); @@ -491,7 +549,7 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff); if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } else { @@ -502,7 +560,7 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut inst[1] = NOP; if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } } @@ -521,14 +579,14 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut if (!bl) { if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } else { inst[1] = BLX | RM(TMP_REG1); if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } } @@ -544,8 +602,8 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1); } } -#else - sljit_uw *inst = (sljit_uw*)jump_ptr; +#else /* !SLJIT_CONFIG_ARM_V6 */ + sljit_ins *inst = (sljit_ins*)jump_ptr; SLJIT_UNUSED_ARG(executable_offset); @@ -560,10 +618,10 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ } static sljit_uw get_imm(sljit_uw imm); @@ -572,9 +630,9 @@ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, s static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_offset, sljit_uw new_constant, sljit_s32 flush_cache) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_uw *ptr = (sljit_uw*)addr; - sljit_uw *inst = (sljit_uw*)ptr[0]; +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + sljit_ins *ptr = (sljit_ins*)addr; + sljit_ins *inst = (sljit_ins*)ptr[0]; sljit_uw ldr_literal = ptr[1]; sljit_uw src2; @@ -590,7 +648,7 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } return; @@ -606,7 +664,7 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } return; @@ -626,7 +684,7 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } @@ -640,8 +698,8 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1); } -#else - sljit_uw *inst = (sljit_uw*)addr; +#else /* !SLJIT_CONFIG_ARM_V6 */ + sljit_ins *inst = (sljit_ins*)addr; SLJIT_UNUSED_ARG(executable_offset); @@ -656,30 +714,30 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ } SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; - sljit_uw *code; - sljit_uw *code_ptr; - sljit_uw *buf_ptr; - sljit_uw *buf_end; + sljit_ins *code; + sljit_ins *code_ptr; + sljit_ins *buf_ptr; + sljit_ins *buf_end; sljit_uw size; sljit_uw word_count; sljit_uw next_addr; sljit_sw executable_offset; sljit_uw addr; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) sljit_uw cpool_size; sljit_uw cpool_skip_alignment; sljit_uw cpool_current_index; - sljit_uw *cpool_start_address; - sljit_uw *last_pc_patch; + sljit_ins *cpool_start_address; + sljit_ins *last_pc_patch; struct future_patch *first_patch; #endif @@ -693,25 +751,25 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil reverse_buf(compiler); /* Second code generation pass. */ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) size = compiler->size + (compiler->patches << 1); if (compiler->cpool_fill > 0) size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ size = compiler->size; -#endif - code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw), compiler->exec_allocator_data); +#endif /* SLJIT_CONFIG_ARM_V6 */ + code = (sljit_ins*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_ins), compiler->exec_allocator_data); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) cpool_size = 0; cpool_skip_alignment = 0; cpool_current_index = 0; cpool_start_address = NULL; first_patch = NULL; last_pc_patch = code; -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ code_ptr = code; word_count = 0; @@ -729,11 +787,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } do { - buf_ptr = (sljit_uw*)buf->memory; + buf_ptr = (sljit_ins*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); do { word_count++; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (cpool_size > 0) { if (cpool_skip_alignment > 0) { buf_ptr++; @@ -761,7 +819,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } } else if ((*buf_ptr & 0xff000000) != PUSH_POOL) { -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ *code_ptr = *buf_ptr++; if (next_addr == word_count) { SLJIT_ASSERT(!label || label->size >= word_count); @@ -771,15 +829,15 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* These structures are ordered by their address. */ if (jump && jump->addr == word_count) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (detect_jump_type(jump, code_ptr, code, executable_offset)) code_ptr--; jump->addr = (sljit_uw)code_ptr; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ jump->addr = (sljit_uw)(code_ptr - 2); if (detect_jump_type(jump, code_ptr, code, executable_offset)) code_ptr -= 2; -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ jump = jump->next; } if (label && label->size == word_count) { @@ -789,11 +847,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = label->next; } if (const_ && const_->addr == word_count) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) const_->addr = (sljit_uw)code_ptr; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ const_->addr = (sljit_uw)(code_ptr - 1); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ const_ = const_->next; } if (put_label && put_label->addr == word_count) { @@ -804,9 +862,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil next_addr = compute_next_addr(label, jump, const_, put_label); } code_ptr++; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - } - else { +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + } else { /* Fortunately, no need to shift. */ cpool_size = *buf_ptr++ & ~PUSH_POOL; SLJIT_ASSERT(cpool_size > 0); @@ -814,14 +871,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size); if (cpool_current_index > 0) { /* Unconditional branch. */ - *code_ptr = B | (((sljit_uw)(cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL); - code_ptr = (sljit_uw*)(cpool_start_address + cpool_current_index); + *code_ptr = B | (((sljit_ins)(cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL); + code_ptr = (sljit_ins*)(cpool_start_address + cpool_current_index); } cpool_skip_alignment = CONST_POOL_ALIGNMENT - 1; cpool_current_index = 0; last_pc_patch = code_ptr; } -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ } while (buf_ptr < buf_end); buf = buf->next; } while (buf); @@ -831,13 +888,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!const_); SLJIT_ASSERT(!put_label); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) SLJIT_ASSERT(cpool_size == 0); if (compiler->cpool_fill > 0) { cpool_start_address = ALIGN_INSTRUCTION(code_ptr); cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill); if (cpool_current_index > 0) - code_ptr = (sljit_uw*)(cpool_start_address + cpool_current_index); + code_ptr = (sljit_ins*)(cpool_start_address + cpool_current_index); buf_ptr = compiler->cpool; buf_end = buf_ptr + compiler->cpool_fill; @@ -857,7 +914,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = compiler->jumps; while (jump) { - buf_ptr = (sljit_uw *)jump->addr; + buf_ptr = (sljit_ins*)jump->addr; if (jump->flags & PATCH_B) { addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset); @@ -872,18 +929,17 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } } else if (jump->flags & SLJIT_REWRITABLE_JUMP) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) jump->addr = (sljit_uw)code_ptr; - code_ptr[0] = (sljit_uw)buf_ptr; + code_ptr[0] = (sljit_ins)buf_ptr; code_ptr[1] = *buf_ptr; inline_set_jump_addr((sljit_uw)code_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); code_ptr += 2; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); -#endif - } - else { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#endif /* SLJIT_CONFIG_ARM_V6 */ + } else { +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (jump->flags & IS_BL) buf_ptr--; if (*buf_ptr & (1 << 23)) @@ -891,20 +947,20 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil else buf_ptr += 1; *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ } jump = jump->next; } -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) const_ = compiler->consts; while (const_) { - buf_ptr = (sljit_uw*)const_->addr; + buf_ptr = (sljit_ins*)const_->addr; const_->addr = (sljit_uw)code_ptr; - code_ptr[0] = (sljit_uw)buf_ptr; + code_ptr[0] = (sljit_ins)buf_ptr; code_ptr[1] = *buf_ptr; if (*buf_ptr & (1 << 23)) buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; @@ -916,21 +972,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil const_ = const_->next; } -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ put_label = compiler->put_labels; while (put_label) { addr = put_label->label->addr; - buf_ptr = (sljit_uw*)put_label->addr; + buf_ptr = (sljit_ins*)put_label->addr; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) SLJIT_ASSERT((buf_ptr[0] & 0xffff0000) == 0xe59f0000); buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ SLJIT_ASSERT((buf_ptr[-1] & 0xfff00000) == MOVW && (buf_ptr[0] & 0xfff00000) == MOVT); buf_ptr[-1] |= ((addr << 4) & 0xf0000) | (addr & 0xfff); buf_ptr[0] |= ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ put_label = put_label->next; } @@ -940,8 +996,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil compiler->executable_offset = executable_offset; compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_uw); - code = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); - code_ptr = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + code = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); + code_ptr = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); SLJIT_CACHE_FLUSH(code, code_ptr); SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1); @@ -952,26 +1008,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) { switch (feature_type) { case SLJIT_HAS_FPU: + case SLJIT_HAS_F64_AS_F32_PAIR: #ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; + return (SLJIT_IS_FPU_AVAILABLE) != 0; #else /* Available by default. */ return 1; -#endif +#endif /* SLJIT_IS_FPU_AVAILABLE */ + case SLJIT_HAS_SIMD: +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + return 0; +#else +#ifdef SLJIT_IS_FPU_AVAILABLE + return (SLJIT_IS_FPU_AVAILABLE) != 0; +#else + /* Available by default. */ + return 1; +#endif /* SLJIT_IS_FPU_AVAILABLE */ +#endif /* SLJIT_CONFIG_ARM_V6 */ + case SLJIT_SIMD_REGS_ARE_PAIRS: case SLJIT_HAS_CLZ: case SLJIT_HAS_ROT: case SLJIT_HAS_CMOV: -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - case SLJIT_HAS_CTZ: + case SLJIT_HAS_REV: case SLJIT_HAS_PREFETCH: -#endif + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: + case SLJIT_HAS_ATOMIC: return 1; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) case SLJIT_HAS_CTZ: +#if defined(SLJIT_CONFIG_ARM_V6) && SLJIT_CONFIG_ARM_V6 return 2; -#endif +#else + return 1; +#endif /* SLJIT_CONFIG_ARM_V6 */ default: return 0; @@ -991,17 +1063,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) #define LOAD_DATA 0x08 /* Flag bits for emit_op. */ -#define ALLOW_IMM 0x10 -#define ALLOW_INV_IMM 0x20 -#define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM) -#define ALLOW_NEG_IMM 0x40 +#define ALLOW_IMM 0x10 +#define ALLOW_INV_IMM 0x20 +#define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM) +#define ALLOW_NEG_IMM 0x40 +#define ALLOW_DOUBLE_IMM 0x80 /* s/l - store/load (1 bit) u/s - signed/unsigned (1 bit) w/b/h/N - word/byte/half/NOT allowed (2 bit) Storing signed and unsigned values are the same operations. */ -static const sljit_uw data_transfer_insts[16] = { +static const sljit_ins data_transfer_insts[16] = { /* s u w */ 0xe5000000 /* str */, /* s u b */ 0xe5400000 /* strb */, /* s u h */ 0xe10000b0 /* strh */, @@ -1022,7 +1095,7 @@ static const sljit_uw data_transfer_insts[16] = { }; #define EMIT_DATA_TRANSFER(type, add, target_reg, base_reg, arg) \ - (data_transfer_insts[(type) & 0xf] | ((add) << 23) | RD(target_reg) | RN(base_reg) | (sljit_uw)(arg)) + (data_transfer_insts[(type) & 0xf] | ((add) << 23) | RD(target_reg) | RN(base_reg) | (sljit_ins)(arg)) /* Normal ldr/str instruction. Type2: ldrsb, ldrh, ldrsh */ @@ -1032,7 +1105,7 @@ static const sljit_uw data_transfer_insts[16] = { (((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22)) #define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \ - ((sljit_uw)(opcode) | (sljit_uw)(mode) | VD(dst) | VM(src1) | VN(src2)) + ((sljit_ins)(opcode) | (sljit_ins)(mode) | VD(dst) | VM(src1) | VN(src2)) /* Flags for emit_op: */ /* Arguments are swapped. */ @@ -1104,12 +1177,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) { - FAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); + FAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_ins)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); } else { if (fsaveds > 0) - FAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); + FAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_ins)fsaveds << 1))); if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) - FAIL_IF(push_inst(compiler, VPUSH | VD(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); + FAIL_IF(push_inst(compiler, VPUSH | VD(fscratches) | ((sljit_ins)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); } } @@ -1138,7 +1211,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi FAIL_IF(push_inst(compiler, VMOV2 | (offset << 10) | ((offset + sizeof(sljit_sw)) << 14) | float_arg_count)); else FAIL_IF(push_inst(compiler, VLDR_F32 | 0x800100 | RN(SLJIT_SP) - | (float_arg_count << 12) | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2))); + | (float_arg_count << 12) | ((offset + (sljit_ins)size - 4 * sizeof(sljit_sw)) >> 2))); float_arg_count++; offset += sizeof(sljit_f64) - sizeof(sljit_sw); break; @@ -1147,7 +1220,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi FAIL_IF(push_inst(compiler, VMOV | (float_arg_count << 16) | (offset << 10))); else FAIL_IF(push_inst(compiler, VLDR_F32 | 0x800000 | RN(SLJIT_SP) - | (float_arg_count << 12) | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2))); + | (float_arg_count << 12) | ((offset + (sljit_ins)size - 4 * sizeof(sljit_sw)) >> 2))); float_arg_count++; break; default: @@ -1164,7 +1237,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (offset < 4 * sizeof(sljit_sw)) FAIL_IF(push_inst(compiler, MOV | RD(tmp) | (offset >> 2))); else - FAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(tmp) | (offset + (sljit_uw)size - 4 * sizeof(sljit_sw)))); + FAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(tmp) | (offset + (sljit_ins)size - 4 * sizeof(sljit_sw)))); break; } @@ -1217,7 +1290,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #endif if (local_size > 0) - FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size)); + FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM | ALLOW_DOUBLE_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size)); return SLJIT_SUCCESS; } @@ -1234,6 +1307,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); + /* Doubles are saved, so alignment is unaffected. */ if ((size & SSIZE_OF(sw)) != 0 && (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)) size += SSIZE_OF(sw); @@ -1245,13 +1319,8 @@ static sljit_s32 emit_add_sp(struct sljit_compiler *compiler, sljit_uw imm) { sljit_uw imm2 = get_imm(imm); - if (imm2 == 0) { - imm2 = (imm & ~(sljit_uw)0x3ff) >> 10; - imm = (imm & 0x3ff) >> 2; - - FAIL_IF(push_inst(compiler, ADD | SRC2_IMM | RD(SLJIT_SP) | RN(SLJIT_SP) | 0xb00 | imm2)); - return push_inst(compiler, ADD | SRC2_IMM | RD(SLJIT_SP) | RN(SLJIT_SP) | 0xf00 | (imm & 0xff)); - } + if (imm2 == 0) + return emit_op(compiler, SLJIT_ADD, ALLOW_IMM | ALLOW_DOUBLE_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, (sljit_sw)imm); return push_inst(compiler, ADD | RD(SLJIT_SP) | RN(SLJIT_SP) | imm2); } @@ -1274,12 +1343,12 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit FAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size)); if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) { - FAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); + FAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_ins)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); } else { if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) - FAIL_IF(push_inst(compiler, VPOP | VD(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); + FAIL_IF(push_inst(compiler, VPOP | VD(fscratches) | ((sljit_ins)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); if (fsaveds > 0) - FAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); + FAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_ins)fsaveds << 1))); } local_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1) & 0x7; @@ -1330,10 +1399,10 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit if (frame_size == 0) return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | 0x800008); if (frame_size > 2 * SSIZE_OF(sw)) - return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)(frame_size - (2 * SSIZE_OF(sw)))); + return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)(frame_size - (2 * SSIZE_OF(sw)))); } - FAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)local_size)); + FAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)local_size)); tmp = 1; } else if (frame_size == 0) { frame_size = (restored_reg == TMP_REG2) ? SSIZE_OF(sw) : 2 * SSIZE_OF(sw); @@ -1349,7 +1418,7 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit local_size += SSIZE_OF(sw); if (frame_size > local_size) - FAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | (sljit_uw)(frame_size - local_size))); + FAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | (sljit_ins)(frame_size - local_size))); else if (frame_size < local_size) FAIL_IF(emit_add_sp(compiler, (sljit_uw)(local_size - frame_size))); @@ -1361,11 +1430,11 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit if (restored_reg != TMP_REG2) frame_size -= SSIZE_OF(sw); - return push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)frame_size); + return push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)frame_size); } tmp = (restored_reg == TMP_REG2) ? 0x800004 : 0x800008; - return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)tmp); + return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)tmp); } if (local_size > 0) @@ -1384,7 +1453,7 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit FAIL_IF(push_inst(compiler, POP | reg_list)); if (frame_size > 0) - return push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | ((sljit_uw)frame_size - sizeof(sljit_sw))); + return push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | ((sljit_ins)frame_size - sizeof(sljit_sw))); if (lr_dst != 0) return SLJIT_SUCCESS; @@ -1432,7 +1501,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl sljit_s32 is_masked; sljit_uw shift_type; - switch (GET_OPCODE(op)) { + switch (op) { case SLJIT_MOV: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); if (dst != src2) { @@ -1446,17 +1515,10 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl case SLJIT_MOV_U8: case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); - if (flags & MOVE_REG_CONV) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (op == SLJIT_MOV_U8) - return push_inst(compiler, AND | RD(dst) | RN(src2) | SRC2_IMM | 0xff); - FAIL_IF(push_inst(compiler, MOV | RD(dst) | (24 << 7) | RM(src2))); - return push_inst(compiler, MOV | RD(dst) | (24 << 7) | (op == SLJIT_MOV_U8 ? 0x20 : 0x40) | RM(dst)); -#else + if (flags & MOVE_REG_CONV) return push_inst(compiler, (op == SLJIT_MOV_U8 ? UXTB : SXTB) | RD(dst) | RM(src2)); -#endif - } - else if (dst != src2) { + + if (dst != src2) { SLJIT_ASSERT(src2 & SRC2_IMM); return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2); } @@ -1465,26 +1527,15 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl case SLJIT_MOV_U16: case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); - if (flags & MOVE_REG_CONV) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - FAIL_IF(push_inst(compiler, MOV | RD(dst) | (16 << 7) | RM(src2))); - return push_inst(compiler, MOV | RD(dst) | (16 << 7) | (op == SLJIT_MOV_U16 ? 0x20 : 0x40) | RM(dst)); -#else + if (flags & MOVE_REG_CONV) return push_inst(compiler, (op == SLJIT_MOV_U16 ? UXTH : SXTH) | RD(dst) | RM(src2)); -#endif - } - else if (dst != src2) { + + if (dst != src2) { SLJIT_ASSERT(src2 & SRC2_IMM); return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2); } return SLJIT_SUCCESS; - case SLJIT_NOT: - if (src2 & SRC2_IMM) - return push_inst(compiler, ((flags & INV_IMM) ? MOV : MVN) | (flags & SET_FLAGS) | RD(dst) | src2); - - return push_inst(compiler, MVN | (flags & SET_FLAGS) | RD(dst) | RM(src2)); - case SLJIT_CLZ: SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2))); @@ -1493,17 +1544,30 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl case SLJIT_CTZ: SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) FAIL_IF(push_inst(compiler, RSB | SRC2_IMM | RD(TMP_REG1) | RN(src2) | 0)); FAIL_IF(push_inst(compiler, AND | RD(TMP_REG2) | RN(src2) | RM(TMP_REG1))); FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(TMP_REG2))); FAIL_IF(push_inst(compiler, CMP | SET_FLAGS | SRC2_IMM | RN(dst) | 32)); return push_inst(compiler, (EOR ^ 0xf0000000) | SRC2_IMM | RD(dst) | RN(dst) | 0x1f); -#else /* !SLJIT_CONFIG_ARM_V5 */ +#else /* !SLJIT_CONFIG_ARM_V6 */ FAIL_IF(push_inst(compiler, RBIT | RD(dst) | RM(src2))); return push_inst(compiler, CLZ | RD(dst) | RM(dst)); -#endif /* SLJIT_CONFIG_ARM_V5 */ +#endif /* SLJIT_CONFIG_ARM_V6 */ + case SLJIT_REV: + case SLJIT_REV_U32: + case SLJIT_REV_S32: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); + return push_inst(compiler, REV | RD(dst) | RM(src2)); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED) && src2 != TMP_REG1 && dst != TMP_REG1); + FAIL_IF(push_inst(compiler, REV16 | RD(dst) | RM(src2))); + if (dst == TMP_REG2 || (src2 == TMP_REG2 && op == SLJIT_REV_U16)) + return SLJIT_SUCCESS; + return push_inst(compiler, (op == SLJIT_REV_U16 ? UXTH : SXTH) | RD(dst) | RM(dst)); case SLJIT_ADD: SLJIT_ASSERT(!(flags & INV_IMM)); @@ -1534,7 +1598,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(!(src2 & SRC2_IMM)); compiler->status_flags_state = 0; - if (!HAS_FLAGS(op)) + if (!(flags & SET_FLAGS)) return push_inst(compiler, MUL | RN(dst) | RM8(src2) | RM(src1)); FAIL_IF(push_inst(compiler, SMULL | RN(TMP_REG1) | RD(dst) | RM8(src2) | RM(src1))); @@ -1553,25 +1617,28 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return push_inst(compiler, ORR | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2))); case SLJIT_XOR: - SLJIT_ASSERT(!(flags & INV_IMM)); + if (flags & INV_IMM) { + SLJIT_ASSERT(src2 == SRC2_IMM); + return push_inst(compiler, MVN | (flags & SET_FLAGS) | RD(dst) | RM(src1)); + } return push_inst(compiler, EOR | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2))); case SLJIT_SHL: case SLJIT_MSHL: shift_type = 0; - is_masked = GET_OPCODE(op) == SLJIT_MSHL; + is_masked = op == SLJIT_MSHL; break; case SLJIT_LSHR: case SLJIT_MLSHR: shift_type = 1; - is_masked = GET_OPCODE(op) == SLJIT_MLSHR; + is_masked = op == SLJIT_MLSHR; break; case SLJIT_ASHR: case SLJIT_MASHR: shift_type = 2; - is_masked = GET_OPCODE(op) == SLJIT_MASHR; + is_masked = op == SLJIT_MASHR; break; case SLJIT_ROTL: @@ -1611,7 +1678,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } return push_inst(compiler, MOV | (flags & SET_FLAGS) | RD(dst) - | RM8(src2) | (sljit_uw)(shift_type << 5) | 0x10 | RM(src1)); + | RM8(src2) | (sljit_ins)(shift_type << 5) | 0x10 | RM(src1)); } #undef EMIT_SHIFT_INS_AND_RETURN @@ -1628,8 +1695,7 @@ static sljit_uw get_imm(sljit_uw imm) if (!(imm & 0xff000000)) { imm <<= 8; rol = 8; - } - else { + } else { imm = (imm << 24) | (imm >> 8); rol = 0; } @@ -1651,22 +1717,19 @@ static sljit_uw get_imm(sljit_uw imm) if (!(imm & 0x00ffffff)) return SRC2_IMM | (imm >> 24) | (rol << 8); - else - return 0; + return 0; } -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm, sljit_s32 positive) +static sljit_uw compute_imm(sljit_uw imm, sljit_uw* imm2) { sljit_uw mask; sljit_uw imm1; - sljit_uw imm2; sljit_uw rol; /* Step1: Search a zero byte (8 continous zero bit). */ mask = 0xff000000; rol = 8; - while(1) { + while (1) { if (!(imm & mask)) { /* Rol imm by rol. */ imm = (imm << rol) | (imm >> (32 - rol)); @@ -1674,6 +1737,7 @@ static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sl rol = 4 + (rol >> 1); break; } + rol += 2; mask >>= 2; if (mask & 0x3) { @@ -1703,9 +1767,8 @@ static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sl if (!(imm & 0xff000000)) { imm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8); - imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8); - } - else if (imm & 0xc0000000) { + *imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8); + } else if (imm & 0xc0000000) { imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8); imm <<= 8; rol += 4; @@ -1726,11 +1789,10 @@ static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sl } if (!(imm & 0x00ffffff)) - imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); + *imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); else return 0; - } - else { + } else { if (!(imm & 0xf0000000)) { imm <<= 4; rol += 2; @@ -1756,25 +1818,23 @@ static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sl } if (!(imm & 0x00ffffff)) - imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); + *imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); else return 0; } - FAIL_IF(push_inst(compiler, (positive ? MOV : MVN) | RD(reg) | imm1)); - FAIL_IF(push_inst(compiler, (positive ? ORR : BIC) | RD(reg) | RN(reg) | imm2)); - return 1; + return imm1; } -#endif static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm) { sljit_uw tmp; - -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + sljit_uw imm1, imm2; +#else /* !SLJIT_CONFIG_ARM_V6 */ if (!(imm & ~(sljit_uw)0xffff)) return push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ /* Create imm by 1 inst. */ tmp = get_imm(imm); @@ -1785,19 +1845,28 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, if (tmp) return push_inst(compiler, MVN | RD(reg) | tmp); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) /* Create imm by 2 inst. */ - FAIL_IF(generate_int(compiler, reg, imm, 1)); - FAIL_IF(generate_int(compiler, reg, ~imm, 0)); + imm1 = compute_imm(imm, &imm2); + if (imm1 != 0) { + FAIL_IF(push_inst(compiler, MOV | RD(reg) | imm1)); + return push_inst(compiler, ORR | RD(reg) | RN(reg) | imm2); + } + + imm1 = compute_imm(~imm, &imm2); + if (imm1 != 0) { + FAIL_IF(push_inst(compiler, MVN | RD(reg) | imm1)); + return push_inst(compiler, BIC | RD(reg) | RN(reg) | imm2); + } /* Load integer. */ return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), imm); -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff))); if (imm <= 0xffff) return SLJIT_SUCCESS; return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff)); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ } static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, @@ -1834,13 +1903,13 @@ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, s argw &= 0x3; if (argw != 0 && (mask == 0xff)) { - FAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg) | RM(offset_reg) | ((sljit_uw)argw << 7))); + FAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg) | RM(offset_reg) | ((sljit_ins)argw << 7))); return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, tmp_reg, TYPE2_TRANSFER_IMM(0))); } /* Bit 25: RM is offset. */ return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg, - RM(offset_reg) | (mask == 0xff ? 0 : (1 << 25)) | ((sljit_uw)argw << 7))); + RM(offset_reg) | (mask == 0xff ? 0 : (1 << 25)) | ((sljit_ins)argw << 7))); } arg &= REG_MASK; @@ -1902,10 +1971,16 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 /* We prefers register and simple consts. */ sljit_s32 dst_reg; - sljit_s32 src1_reg; + sljit_s32 src1_reg = 0; sljit_s32 src2_reg = 0; sljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0; sljit_s32 neg_op = 0; + sljit_u32 imm2; + + op = GET_OPCODE(op); + + if (flags & SET_FLAGS) + inp_flags &= ~ALLOW_DOUBLE_IMM; if (dst == TMP_REG2) flags |= UNUSED_RETURN; @@ -1913,7 +1988,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 SLJIT_ASSERT(!(inp_flags & ALLOW_INV_IMM) || (inp_flags & ALLOW_IMM)); if (inp_flags & ALLOW_NEG_IMM) { - switch (GET_OPCODE(op)) { + switch (op) { case SLJIT_ADD: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; neg_op = SLJIT_SUB; @@ -1937,10 +2012,11 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 if (!(inp_flags & ALLOW_IMM)) break; - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { src2_reg = (sljit_s32)get_imm((sljit_uw)src2w); if (src2_reg) break; + if (inp_flags & ALLOW_INV_IMM) { src2_reg = (sljit_s32)get_imm(~(sljit_uw)src2w); if (src2_reg) { @@ -1948,8 +2024,9 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 break; } } + if (neg_op != 0) { - src2_reg = (sljit_s32)get_imm((sljit_uw)-src2w); + src2_reg = (sljit_s32)get_imm((neg_op == SLJIT_ADD || neg_op == SLJIT_SUB) ? (sljit_uw)-src2w : ~(sljit_uw)src2w); if (src2_reg) { op = neg_op | GET_ALL_FLAGS(op); break; @@ -1957,7 +2034,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 } } - if (src1 & SLJIT_IMM) { + if (src1 == SLJIT_IMM) { src2_reg = (sljit_s32)get_imm((sljit_uw)src1w); if (src2_reg) { flags |= ARGS_SWAPPED; @@ -1965,6 +2042,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 src1w = src2w; break; } + if (inp_flags & ALLOW_INV_IMM) { src2_reg = (sljit_s32)get_imm(~(sljit_uw)src1w); if (src2_reg) { @@ -1974,8 +2052,11 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 break; } } + if (neg_op >= SLJIT_SUB) { /* Note: additive operation (commutative). */ + SLJIT_ASSERT(op == SLJIT_ADD || op == SLJIT_ADDC); + src2_reg = (sljit_s32)get_imm((sljit_uw)-src1w); if (src2_reg) { src1 = src2; @@ -1993,8 +2074,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 else if (src1 & SLJIT_MEM) { FAIL_IF(emit_op_mem(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1)); src1_reg = TMP_REG1; - } - else { + } else if (!(inp_flags & ALLOW_DOUBLE_IMM) || src2_reg != 0 || op == SLJIT_SUB || op == SLJIT_SUBC) { FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); src1_reg = TMP_REG1; } @@ -2023,8 +2103,62 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 src2_reg = src2; else if (src2 & SLJIT_MEM) FAIL_IF(emit_op_mem(compiler, inp_flags | LOAD_DATA, src2_reg, src2, src2w, TMP_REG2)); - else + else if (!(inp_flags & ALLOW_DOUBLE_IMM)) FAIL_IF(load_immediate(compiler, src2_reg, (sljit_uw)src2w)); + else { + SLJIT_ASSERT(!(flags & SET_FLAGS)); + + if (src1_reg == 0) { + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); + src1_reg = TMP_REG1; + } + + src2_reg = (sljit_s32)compute_imm((sljit_uw)src2w, &imm2); + + if (src2_reg == 0 && neg_op != 0) { + src2_reg = (sljit_s32)compute_imm((sljit_uw)-src2w, &imm2); + if (src2_reg != 0) + op = neg_op; + } + + if (src2_reg == 0) { + FAIL_IF(load_immediate(compiler, TMP_REG2, (sljit_uw)src2w)); + src2_reg = TMP_REG2; + } else { + FAIL_IF(emit_single_op(compiler, op, flags, (sljit_uw)dst_reg, (sljit_uw)src1_reg, (sljit_uw)src2_reg)); + src1_reg = dst_reg; + src2_reg = (sljit_s32)imm2; + + if (op == SLJIT_ADDC) + op = SLJIT_ADD; + else if (op == SLJIT_SUBC) + op = SLJIT_SUB; + } + } + } + + if (src1_reg == 0) { + SLJIT_ASSERT((inp_flags & ALLOW_DOUBLE_IMM) && !(flags & SET_FLAGS)); + + src1_reg = (sljit_s32)compute_imm((sljit_uw)src1w, &imm2); + + if (src1_reg == 0 && neg_op != 0) { + src1_reg = (sljit_s32)compute_imm((sljit_uw)-src1w, &imm2); + if (src1_reg != 0) + op = neg_op; + } + + if (src1_reg == 0) { + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); + src1_reg = TMP_REG1; + } else { + FAIL_IF(emit_single_op(compiler, op, flags, (sljit_uw)dst_reg, (sljit_uw)src2_reg, (sljit_uw)src1_reg)); + src1_reg = dst_reg; + src2_reg = (sljit_s32)imm2; + + if (op == SLJIT_ADDC) + op = SLJIT_ADD; + } } FAIL_IF(emit_single_op(compiler, op, flags, (sljit_uw)dst_reg, (sljit_uw)src1_reg, (sljit_uw)src2_reg)); @@ -2114,7 +2248,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile SLJIT_ASSERT(saved_reg_list[1] < 8); FAIL_IF(push_inst(compiler, LDR | 0x8d0004 | (saved_reg_list[1] << 12) /* ldr rX, [sp, #4] */)); } - return push_inst(compiler, (LDR ^ (1 << 24)) | 0x8d0000 | (sljit_uw)(saved_reg_count >= 3 ? 16 : 8) + return push_inst(compiler, (LDR ^ (1 << 24)) | 0x8d0000 | (sljit_ins)(saved_reg_count >= 3 ? 16 : 8) | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */); } return SLJIT_SUCCESS; @@ -2144,23 +2278,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_U8: - return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw); case SLJIT_MOV_S8: - return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw); case SLJIT_MOV_U16: - return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw); case SLJIT_MOV_S16: - return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); - - case SLJIT_NOT: - return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_CLZ: case SLJIT_CTZ: + case SLJIT_REV: + case SLJIT_REV_U32: + case SLJIT_REV_S32: return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + return emit_op(compiler, op, HALF_SIZE, dst, dstw, TMP_REG1, 0, src, srcw); } return SLJIT_SUCCESS; @@ -2171,6 +2309,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) { + sljit_s32 inp_flags; + CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -2182,11 +2322,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile case SLJIT_ADDC: case SLJIT_SUB: case SLJIT_SUBC: - return emit_op(compiler, op, ALLOW_IMM | ALLOW_NEG_IMM, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, op, ALLOW_IMM | ALLOW_NEG_IMM | ALLOW_DOUBLE_IMM, dst, dstw, src1, src1w, src2, src2w); case SLJIT_OR: + return emit_op(compiler, op, ALLOW_IMM | ALLOW_DOUBLE_IMM, dst, dstw, src1, src1w, src2, src2w); + case SLJIT_XOR: - return emit_op(compiler, op, ALLOW_IMM, dst, dstw, src1, src1w, src2, src2w); + inp_flags = ALLOW_IMM | ALLOW_DOUBLE_IMM; + if ((src1 == SLJIT_IMM && src1w == -1) || (src2 == SLJIT_IMM && src2w == -1)) { + inp_flags |= ALLOW_INV_IMM; + } + return emit_op(compiler, op, inp_flags, dst, dstw, src1, src1w, src2, src2w); case SLJIT_MUL: return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w); @@ -2202,7 +2348,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile case SLJIT_MASHR: case SLJIT_ROTL: case SLJIT_ROTR: - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { compiler->shift_imm = src2w & 0x1f; return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w); } else { @@ -2226,60 +2372,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_left; CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); op = GET_OPCODE(op); is_left = (op == SLJIT_SHL || op == SLJIT_MSHL); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); /* Shift type of ROR is 3. */ - if (src2 & SLJIT_IMM) { - src2w &= 0x1f; + if (src3 == SLJIT_IMM) { + src3w &= 0x1f; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src2, src2w, TMP_REG2)); - src2 = TMP_REG2; + + FAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | RM(src1_reg) | ((sljit_ins)(is_left ? 0 : 1) << 5) | ((sljit_ins)src3w << 7))); + src3w = (src3w ^ 0x1f) + 1; + return push_inst(compiler, ORR | RD(dst_reg) | RN(dst_reg) | RM(src2_reg) | ((sljit_ins)(is_left ? 1 : 0) << 5) | ((sljit_ins)src3w << 7)); } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); - src1 = TMP_REG1; + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src3, src3w, TMP_REG2)); + src3 = TMP_REG2; } - if (src2 & SLJIT_IMM) { - FAIL_IF(push_inst(compiler, MOV | RD(src_dst) | RM(src_dst) | ((sljit_uw)(is_left ? 0 : 1) << 5) | ((sljit_uw)src2w << 7))); - src2w = (src2w ^ 0x1f) + 1; - return push_inst(compiler, ORR | RD(src_dst) | RN(src_dst) | RM(src1) | ((sljit_uw)(is_left ? 1 : 0) << 5) | ((sljit_uw)src2w << 7)); + if (op == SLJIT_MSHL || op == SLJIT_MLSHR || dst_reg == src3) { + FAIL_IF(push_inst(compiler, AND | SRC2_IMM | RD(TMP_REG2) | RN(src3) | 0x1f)); + src3 = TMP_REG2; } - if (op == SLJIT_MSHL || op == SLJIT_MLSHR) { - FAIL_IF(push_inst(compiler, AND | SRC2_IMM | RD(TMP_REG2) | RN(src2) | 0x1f)); - src2 = TMP_REG2; - } - - FAIL_IF(push_inst(compiler, MOV | RD(src_dst) | RM8(src2) | ((sljit_uw)(is_left ? 0 : 1) << 5) | 0x10 | RM(src_dst))); - FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src1) | ((sljit_uw)(is_left ? 1 : 0) << 5) | (1 << 7))); - FAIL_IF(push_inst(compiler, EOR | SRC2_IMM | RD(TMP_REG2) | RN(src2) | 0x1f)); - return push_inst(compiler, ORR | RD(src_dst) | RN(src_dst) | RM(TMP_REG1) | ((sljit_uw)(is_left ? 1 : 0) << 5) | 0x10 | RM8(TMP_REG2)); + FAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | RM8(src3) | ((sljit_ins)(is_left ? 0 : 1) << 5) | 0x10 | RM(src1_reg))); + FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src2_reg) | ((sljit_ins)(is_left ? 1 : 0) << 5) | (1 << 7))); + FAIL_IF(push_inst(compiler, EOR | SRC2_IMM | RD(TMP_REG2) | RN(src3) | 0x1f)); + return push_inst(compiler, ORR | RD(dst_reg) | RN(dst_reg) | RM8(TMP_REG2) | ((sljit_ins)(is_left ? 1 : 0) << 5) | 0x10 | RM(TMP_REG1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, @@ -2305,27 +2443,67 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp case SLJIT_PREFETCH_L2: case SLJIT_PREFETCH_L3: case SLJIT_PREFETCH_ONCE: -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) SLJIT_ASSERT(src & SLJIT_MEM); return emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1); -#else /* !SLJIT_CONFIG_ARM_V7 */ - return SLJIT_SUCCESS; -#endif /* SLJIT_CONFIG_ARM_V7 */ } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 size, dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + SLJIT_ASSERT(reg_map[TMP_REG2] == 14); + + if (FAST_IS_REG(dst)) + return push_inst(compiler, MOV | RD(dst) | RM(TMP_REG2)); + break; + case SLJIT_GET_RETURN_ADDRESS: + size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 0); + + if (compiler->fsaveds > 0 || compiler->fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { + /* The size of pc is not added above. */ + if ((size & SSIZE_OF(sw)) == 0) + size += SSIZE_OF(sw); + + size += GET_SAVED_FLOAT_REGISTERS_SIZE(compiler->fscratches, compiler->fsaveds, f64); + } + + SLJIT_ASSERT(((compiler->local_size + size + SSIZE_OF(sw)) & 0x7) == 0); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + size, TMP_REG1)); + break; + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return (freg_map[reg] << 1); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type == SLJIT_FLOAT_REGISTER || type == SLJIT_SIMD_REG_64) + return freg_map[reg]; + + if (type != SLJIT_SIMD_REG_128) + return freg_map[reg] & ~0x1; + + return -1; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -2335,7 +2513,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - return push_inst(compiler, *(sljit_uw*)instruction); + return push_inst(compiler, *(sljit_ins*)instruction); } /* --------------------------------------------------------------------- */ @@ -2344,18 +2522,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c #define FPU_LOAD (1 << 20) #define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \ - ((inst) | (sljit_uw)((add) << 23) | RN(base) | VD(freg) | (sljit_uw)(offs)) + ((inst) | (sljit_ins)((add) << 23) | RN(base) | VD(freg) | (sljit_ins)(offs)) static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { sljit_uw imm; - sljit_uw inst = VSTR_F32 | (flags & (SLJIT_32 | FPU_LOAD)); + sljit_ins inst = VSTR_F32 | (flags & (SLJIT_32 | FPU_LOAD)); SLJIT_ASSERT(arg & SLJIT_MEM); arg &= ~SLJIT_MEM; if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { - FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (((sljit_uw)argw & 0x3) << 7))); + FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (((sljit_ins)argw & 0x3) << 7))); arg = TMP_REG2; argw = 0; } @@ -2410,14 +2588,12 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - op ^= SLJIT_32; - if (FAST_IS_REG(src)) FAIL_IF(push_inst(compiler, VMOV | RD(src) | VN(TMP_FREG1))); else if (src & SLJIT_MEM) { @@ -2429,13 +2605,27 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp FAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | VN(TMP_FREG1))); } - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_32, dst_r, TMP_FREG1, 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(ins, ins & SLJIT_32, dst_r, TMP_FREG1, 0))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, (ins & SLJIT_32), TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + return sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_S32 | (~op & SLJIT_32), dst, dstw, src, srcw); +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + return sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_U32 | (~op & SLJIT_32), dst, dstw, src, srcw); +} + static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) @@ -2453,7 +2643,12 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile } FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_32, src1, src2, 0))); - return push_inst(compiler, VMRS); + FAIL_IF(push_inst(compiler, VMRS)); + + if (GET_FLAG_TYPE(op) != SLJIT_UNORDERED_OR_EQUAL) + return SLJIT_SUCCESS; + + return push_inst(compiler, (CMP - CONDITIONAL) | (0x60000000 /* VS */) | SET_FLAGS | RN(TMP_REG1) | RM(TMP_REG1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, @@ -2534,18 +2729,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_32, dst_r, src2, src1))); break; - case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_32, dst_r, src2, src1))); break; - case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_32, dst_r, src2, src1))); break; - case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_32, dst_r, src2, src1))); break; + case SLJIT_COPYSIGN_F64: + FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(src2) | RD(TMP_REG1) | ((op & SLJIT_32) ? (1 << 7) : 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_32, dst_r, src1, 0))); + FAIL_IF(push_inst(compiler, CMP | SET_FLAGS | RN(TMP_REG1) | SRC2_IMM | 0)); + return push_inst(compiler, EMIT_FPU_OPERATION((VNEG_F32 & ~COND_MASK) | 0xb0000000, op & SLJIT_32, dst_r, dst_r, 0)); } if (dst_r == TMP_FREG1) @@ -2556,42 +2753,120 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil #undef EMIT_FPU_DATA_TRANSFER -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { +#if defined(__ARM_NEON) && __ARM_NEON + sljit_u32 exp; + sljit_ins ins; +#endif /* NEON */ + union { + sljit_u32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - SLJIT_ASSERT(reg_map[TMP_REG2] == 14); + u.value = value; - if (FAST_IS_REG(dst)) - return push_inst(compiler, MOV | RD(dst) | RM(TMP_REG2)); +#if defined(__ARM_NEON) && __ARM_NEON + if ((u.imm << (32 - 19)) == 0) { + exp = (u.imm >> (23 + 2)) & 0x3f; - /* Memory. */ - return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1); + if (exp == 0x20 || exp == 0x1f) { + ins = ((u.imm >> 24) & 0x80) | ((u.imm >> 19) & 0x7f); + return push_inst(compiler, (VMOV_F32 ^ (1 << 6)) | ((ins & 0xf0) << 12) | VD(freg) | (ins & 0xf)); + } + } +#endif /* NEON */ + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm)); + return push_inst(compiler, VMOV | VN(freg) | RD(TMP_REG1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ +#if defined(__ARM_NEON) && __ARM_NEON + sljit_u32 exp; + sljit_ins ins; +#endif /* NEON */ + union { + sljit_u32 imm[2]; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + +#if defined(__ARM_NEON) && __ARM_NEON + if (u.imm[0] == 0 && (u.imm[1] << (64 - 48)) == 0) { + exp = (u.imm[1] >> ((52 - 32) + 2)) & 0x1ff; + + if (exp == 0x100 || exp == 0xff) { + ins = ((u.imm[1] >> (56 - 32)) & 0x80) | ((u.imm[1] >> (48 - 32)) & 0x7f); + return push_inst(compiler, (VMOV_F32 ^ (1 << 6)) | (1 << 8) | ((ins & 0xf0) << 12) | VD(freg) | (ins & 0xf)); + } + } +#endif /* NEON */ + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0])); + if (u.imm[0] == u.imm[1]) + return push_inst(compiler, VMOV2 | RN(TMP_REG1) | RD(TMP_REG1) | VM(freg)); + + FAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1])); + return push_inst(compiler, VMOV2 | RN(TMP_REG2) | RD(TMP_REG1) | VM(freg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_s32 reg2; + sljit_ins inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + + inst = VMOV2 | RN(reg) | RD(reg2) | VM(freg); + } else { + inst = VMOV | VN(freg) | RD(reg); + + if (!(op & SLJIT_32)) + inst |= 1 << 7; + } + + if (GET_OPCODE(op) == SLJIT_COPY_FROM_F64) + inst |= 1 << 20; + + return push_inst(compiler, inst); } /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ -static sljit_uw get_cc(struct sljit_compiler *compiler, sljit_s32 type) +static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type) { switch (type) { case SLJIT_EQUAL: + case SLJIT_ATOMIC_STORED: case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: - case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */ + case SLJIT_UNORDERED_OR_EQUAL: return 0x00000000; case SLJIT_NOT_EQUAL: + case SLJIT_ATOMIC_NOT_STORED: case SLJIT_F_NOT_EQUAL: case SLJIT_UNORDERED_OR_NOT_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */ + case SLJIT_ORDERED_NOT_EQUAL: return 0x10000000; case SLJIT_CARRY: @@ -2696,7 +2971,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile SLJIT_ASSERT(reg_map[TMP_REG1] != 14); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (type >= SLJIT_FAST_CALL) PTR_FAIL_IF(prepare_blx(compiler)); PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, @@ -2714,13 +2989,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) jump->addr = compiler->size; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ if (type >= SLJIT_FAST_CALL) jump->flags |= IS_BL; PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(compiler, type))); jump->addr = compiler->size; -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ return jump; } @@ -2738,7 +3013,7 @@ static sljit_s32 softfloat_call_with_args(struct sljit_compiler *compiler, sljit sljit_u8 *offset_ptr = offsets; if (src && FAST_IS_REG(*src)) - src_offset = (sljit_uw)reg_map[*src] * sizeof(sljit_sw); + src_offset = (sljit_u32)reg_map[*src] * sizeof(sljit_sw); arg_types >>= SLJIT_ARG_SHIFT; @@ -2773,7 +3048,7 @@ static sljit_s32 softfloat_call_with_args(struct sljit_compiler *compiler, sljit if (is_tail_call) offset += sizeof(sljit_sw); - offset = ((offset - 4 * sizeof(sljit_sw)) + 0x7) & ~(sljit_uw)0x7; + offset = ((offset - 4 * sizeof(sljit_sw)) + 0x7) & ~(sljit_u32)0x7; *extra_space = offset; @@ -2903,8 +3178,6 @@ static sljit_s32 hardfloat_call_with_args(struct sljit_compiler *compiler, sljit #endif /* __SOFTFP__ */ -#undef EMIT_FPU_OPERATION - SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types) { @@ -2971,7 +3244,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi SLJIT_ASSERT(reg_map[TMP_REG1] != 14); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { if (FAST_IS_REG(src)) { SLJIT_ASSERT(reg_map[src] != 14); return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src)); @@ -2988,16 +3261,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); jump->u.target = (sljit_uw)srcw; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (type >= SLJIT_FAST_CALL) FAIL_IF(prepare_blx(compiler)); FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0)); if (type >= SLJIT_FAST_CALL) FAIL_IF(emit_blx(compiler)); -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1))); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ jump->addr = compiler->size; return SLJIT_SUCCESS; } @@ -3096,7 +3369,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_s32 type) { sljit_s32 dst_reg, flags = GET_ALL_FLAGS(op); - sljit_uw cc, ins; + sljit_ins cc, ins; CHECK_ERROR(); CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type)); @@ -3132,61 +3405,114 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { - sljit_uw cc, tmp; + sljit_ins cc, tmp; CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (src2_reg != dst_reg && src1 == dst_reg) { + src1 = src2_reg; + src1w = 0; + src2_reg = dst_reg; + type ^= 0x1; + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, (src2_reg != dst_reg) ? dst_reg : TMP_REG1, src1, src1w, TMP_REG2)); + + if (src2_reg != dst_reg) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + src1 = TMP_REG1; + src1w = 0; + } + } else if (dst_reg != src2_reg) + FAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | RM(src2_reg))); cc = get_cc(compiler, type & ~SLJIT_32); - if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { - tmp = get_imm((sljit_uw)srcw); + if (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) { + tmp = get_imm((sljit_uw)src1w); if (tmp) return push_inst(compiler, ((MOV | RD(dst_reg) | tmp) & ~COND_MASK) | cc); - tmp = get_imm(~(sljit_uw)srcw); + tmp = get_imm(~(sljit_uw)src1w); if (tmp) return push_inst(compiler, ((MVN | RD(dst_reg) | tmp) & ~COND_MASK) | cc); #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - tmp = (sljit_uw)srcw; + tmp = (sljit_ins)src1w; FAIL_IF(push_inst(compiler, (MOVW & ~COND_MASK) | cc | RD(dst_reg) | ((tmp << 4) & 0xf0000) | (tmp & 0xfff))); if (tmp <= 0xffff) return SLJIT_SUCCESS; return push_inst(compiler, (MOVT & ~COND_MASK) | cc | RD(dst_reg) | ((tmp >> 12) & 0xf0000) | ((tmp >> 16) & 0xfff)); -#else - FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); - src = TMP_REG1; -#endif +#else /* !SLJIT_CONFIG_ARM_V7 */ + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); + src1 = TMP_REG1; +#endif /* SLJIT_CONFIG_ARM_V7 */ } - return push_inst(compiler, ((MOV | RD(dst_reg) | RM(src)) & ~COND_MASK) | cc); + return push_inst(compiler, ((MOV | RD(dst_reg) | RM(src1)) & ~COND_MASK) | cc); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_ins cc; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + type ^= SLJIT_32; + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, (type & SLJIT_32), dst_freg, src2_freg, 0))); + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w)); + src1 = TMP_FREG1; + } + + cc = get_cc(compiler, type & ~SLJIT_32); + return push_inst(compiler, EMIT_FPU_OPERATION((VMOV_F32 & ~COND_MASK) | cc, (type & SLJIT_32), dst_freg, src1, 0)); +} + +#undef EMIT_FPU_OPERATION + static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s32 max_offset) { sljit_s32 arg = *mem; sljit_sw argw = *memw; sljit_uw imm, tmp; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_sw mask = max_offset >= 0xf00 ? 0xfff : 0xff; - sljit_sw sign = max_offset >= 0xf00 ? 0x1000 : 0x100; -#else /* !SLJIT_CONFIG_ARM_V5 */ sljit_sw mask = 0xfff; sljit_sw sign = 0x1000; SLJIT_ASSERT(max_offset >= 0xf00); -#endif /* SLJIT_CONFIG_ARM_V5 */ *mem = TMP_REG1; if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { *memw = 0; - return push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_uw)(argw & 0x3) << 7)); + return push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_ins)(argw & 0x3) << 7)); } arg &= REG_MASK; @@ -3234,158 +3560,6 @@ static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem return push_inst(compiler, ADD | RD(TMP_REG1) | RN(TMP_REG1) | RM(arg)); } -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - -static sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 reg, - sljit_s32 mem, sljit_sw memw) -{ - sljit_s32 flags, steps, tmp_reg; - sljit_uw add, shift; - - switch (type & 0xff) { - case SLJIT_MOV_U8: - case SLJIT_MOV_S8: - flags = BYTE_SIZE; - if (!(type & SLJIT_MEM_STORE)) - flags |= LOAD_DATA; - if ((type & 0xff) == SLJIT_MOV_S8) - flags |= SIGNED; - - return emit_op_mem(compiler, flags, reg, mem, memw, TMP_REG1); - - case SLJIT_MOV_U16: - FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 1)); - flags = BYTE_SIZE; - steps = 1; - break; - - case SLJIT_MOV_S16: - FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xff - 1)); - flags = BYTE_SIZE | SIGNED; - steps = 1; - break; - - default: - if (type & SLJIT_MEM_UNALIGNED_32) { - flags = WORD_SIZE; - if (!(type & SLJIT_MEM_STORE)) - flags |= LOAD_DATA; - - return emit_op_mem(compiler, flags, reg, mem, memw, TMP_REG1); - } - - if (!(type & SLJIT_MEM_UNALIGNED_16)) { - FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 3)); - flags = BYTE_SIZE; - steps = 3; - break; - } - - FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xff - 2)); - - add = 1; - if (memw < 0) { - add = 0; - memw = -memw; - } - - tmp_reg = reg; - - if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE, add, reg, mem, TYPE2_TRANSFER_IMM(memw)))); - FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(reg) | (16 << 7) | (2 << 4))); - } else { - if (reg == mem) { - SLJIT_ASSERT(reg != TMP_REG1); - tmp_reg = TMP_REG1; - } - - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE | LOAD_DATA, add, tmp_reg, mem, TYPE2_TRANSFER_IMM(memw)))); - } - - if (!add) { - memw -= 2; - if (memw <= 0) { - memw = -memw; - add = 1; - } - } else - memw += 2; - - if (type & SLJIT_MEM_STORE) - return push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE, add, TMP_REG2, mem, TYPE2_TRANSFER_IMM(memw))); - - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE | LOAD_DATA, add, TMP_REG2, mem, TYPE2_TRANSFER_IMM(memw)))); - return push_inst(compiler, ORR | RD(reg) | RN(tmp_reg) | RM(TMP_REG2) | (16 << 7)); - } - - SLJIT_ASSERT(steps > 0); - - add = 1; - if (memw < 0) { - add = 0; - memw = -memw; - } - - if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE, add, reg, mem, memw))); - FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(reg) | (8 << 7) | (2 << 4))); - - while (1) { - if (!add) { - memw -= 1; - if (memw == 0) - add = 1; - } else - memw += 1; - - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE, add, TMP_REG2, mem, memw))); - - if (--steps == 0) - return SLJIT_SUCCESS; - - FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(TMP_REG2) | (8 << 7) | (2 << 4))); - } - } - - tmp_reg = reg; - - if (reg == mem) { - SLJIT_ASSERT(reg != TMP_REG1); - tmp_reg = TMP_REG1; - } - - shift = 8; - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE | LOAD_DATA, add, tmp_reg, mem, memw))); - - do { - if (!add) { - memw -= 1; - if (memw == 0) - add = 1; - } else - memw += 1; - - if (steps > 1) { - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE | LOAD_DATA, add, TMP_REG2, mem, memw))); - FAIL_IF(push_inst(compiler, ORR | RD(tmp_reg) | RN(tmp_reg) | RM(TMP_REG2) | (shift << 7))); - shift += 8; - } - } while (--steps != 0); - - flags |= LOAD_DATA; - - if (flags & SIGNED) - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(flags, add, TMP_REG2, mem, TYPE2_TRANSFER_IMM(memw)))); - else - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(flags, add, TMP_REG2, mem, memw))); - - return push_inst(compiler, ORR | RD(reg) | RN(tmp_reg) | RM(TMP_REG2) | (shift << 7)); -} - -#endif /* SLJIT_CONFIG_ARM_V5 */ - SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw) @@ -3395,30 +3569,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile CHECK_ERROR(); CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw)); - if (!(reg & REG_PAIR_MASK)) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - ADJUST_LOCAL_OFFSET(mem, memw); -#endif /* SLJIT_CONFIG_ARM_V5 */ - + if (!(reg & REG_PAIR_MASK)) return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw); - } ADJUST_LOCAL_OFFSET(mem, memw); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (type & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16)) { - FAIL_IF(update_mem_addr(compiler, &mem, &memw, (type & SLJIT_MEM_UNALIGNED_16) ? 0xfff - 6 : 0xfff - 7)); - - if (!(type & SLJIT_MEM_STORE) && REG_PAIR_FIRST(reg) == (mem & REG_MASK)) { - FAIL_IF(sljit_emit_mem_unaligned(compiler, type, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), memw + SSIZE_OF(sw))); - return sljit_emit_mem_unaligned(compiler, type, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw); - } - - FAIL_IF(sljit_emit_mem_unaligned(compiler, type, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw)); - return sljit_emit_mem_unaligned(compiler, type, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), memw + SSIZE_OF(sw)); - } -#endif /* SLJIT_CONFIG_ARM_V5 */ - FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4)); flags = WORD_SIZE; @@ -3441,7 +3596,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler * sljit_s32 mem, sljit_sw memw) { sljit_s32 flags; - sljit_uw is_type1_transfer, inst; + sljit_ins is_type1_transfer, inst; CHECK_ERROR(); CHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw)); @@ -3500,7 +3655,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler * if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { memw &= 0x3; - inst = EMIT_DATA_TRANSFER(flags, 1, reg, mem & REG_MASK, RM(OFFS_REG(mem)) | ((sljit_uw)memw << 7)); + inst = EMIT_DATA_TRANSFER(flags, 1, reg, mem & REG_MASK, RM(OFFS_REG(mem)) | ((sljit_ins)memw << 7)); if (is_type1_transfer) inst |= (1 << 25); @@ -3526,7 +3681,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler * else memw = -memw; - return push_inst(compiler, inst | (sljit_uw)memw); + return push_inst(compiler, inst | (sljit_ins)memw); } if (memw >= 0) @@ -3534,76 +3689,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler * else memw = -memw; - return push_inst(compiler, inst | TYPE2_TRANSFER_IMM((sljit_uw)memw)); + return push_inst(compiler, inst | TYPE2_TRANSFER_IMM((sljit_ins)memw)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_s32 max_offset; - sljit_s32 dst; -#endif /* SLJIT_CONFIG_ARM_V5 */ - CHECK_ERROR(); CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw)); - if (type & SLJIT_MEM_UNALIGNED_32) + if (type & SLJIT_MEM_ALIGNED_32) return emit_fop_mem(compiler, ((type ^ SLJIT_32) & SLJIT_32) | ((type & SLJIT_MEM_STORE) ? 0 : FPU_LOAD), freg, mem, memw); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | RD(TMP_REG2))); - - if (type & SLJIT_32) - return sljit_emit_mem_unaligned(compiler, SLJIT_MOV | SLJIT_MEM_STORE | (type & SLJIT_MEM_UNALIGNED_16), TMP_REG2, mem, memw); - - max_offset = 0xfff - 7; - if (type & SLJIT_MEM_UNALIGNED_16) - max_offset++; - - FAIL_IF(update_mem_addr(compiler, &mem, &memw, max_offset)); - mem |= SLJIT_MEM; - - FAIL_IF(sljit_emit_mem_unaligned(compiler, SLJIT_MOV | SLJIT_MEM_STORE | (type & SLJIT_MEM_UNALIGNED_16), TMP_REG2, mem, memw)); - - FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | 0x80 | RD(TMP_REG2))); - return sljit_emit_mem_unaligned(compiler, SLJIT_MOV | SLJIT_MEM_STORE | (type & SLJIT_MEM_UNALIGNED_16), TMP_REG2, mem, memw + 4); - } - - max_offset = (type & SLJIT_32) ? 0xfff - 3 : 0xfff - 7; - if (type & SLJIT_MEM_UNALIGNED_16) - max_offset++; - - FAIL_IF(update_mem_addr(compiler, &mem, &memw, max_offset)); - - dst = TMP_REG1; - - /* Stack offset adjustment is not needed because dst - is not stored on the stack when mem is SLJIT_SP. */ - - if (mem == TMP_REG1) { - dst = SLJIT_R3; - - if (compiler->scratches >= 4) - FAIL_IF(push_inst(compiler, STR | (1 << 21) | RN(SLJIT_SP) | RD(SLJIT_R3) | 8)); - } - - mem |= SLJIT_MEM; - - FAIL_IF(sljit_emit_mem_unaligned(compiler, SLJIT_MOV | (type & SLJIT_MEM_UNALIGNED_16), dst, mem, memw)); - FAIL_IF(push_inst(compiler, VMOV | VN(freg) | RD(dst))); - - if (!(type & SLJIT_32)) { - FAIL_IF(sljit_emit_mem_unaligned(compiler, SLJIT_MOV | (type & SLJIT_MEM_UNALIGNED_16), dst, mem, memw + 4)); - FAIL_IF(push_inst(compiler, VMOV | VN(freg) | 0x80 | RD(dst))); - } - - if (dst == SLJIT_R3 && compiler->scratches >= 4) - FAIL_IF(push_inst(compiler, (LDR ^ (0x1 << 24)) | (0x1 << 23) | RN(SLJIT_SP) | RD(SLJIT_R3) | 8)); - return SLJIT_SUCCESS; -#else /* !SLJIT_CONFIG_ARM_V5 */ if (type & SLJIT_MEM_STORE) { FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | RD(TMP_REG2))); @@ -3629,11 +3727,714 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, mem, memw, TMP_REG1)); FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, mem, memw + 4, TMP_REG1)); return push_inst(compiler, VMOV2 | VM(freg) | RD(TMP_REG2) | RN(TMP_REG1)); -#endif /* SLJIT_CONFIG_ARM_V5 */ +} + +static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, sljit_s32 *mem_ptr, sljit_sw memw) +{ + sljit_s32 mem = *mem_ptr; + sljit_uw imm; + + if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { + *mem_ptr = TMP_REG1; + return push_inst(compiler, ADD | RD(TMP_REG1) | RN(mem & REG_MASK) | RM(OFFS_REG(mem)) | ((sljit_ins)(memw & 0x3) << 7)); + } + + if (SLJIT_UNLIKELY(!(mem & REG_MASK))) { + *mem_ptr = TMP_REG1; + return load_immediate(compiler, TMP_REG1, (sljit_uw)memw); + } + + mem &= REG_MASK; + + if (memw == 0) { + *mem_ptr = mem; + return SLJIT_SUCCESS; + } + + *mem_ptr = TMP_REG1; + imm = get_imm((sljit_uw)(memw < 0 ? -memw : memw)); + + if (imm != 0) + return push_inst(compiler, ((memw < 0) ? SUB : ADD) | RD(TMP_REG1) | RN(mem) | imm); + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw)); + return push_inst(compiler, ADD | RD(TMP_REG1) | RN(TMP_REG1) | RM(mem)); +} + +static SLJIT_INLINE sljit_s32 simd_get_quad_reg_index(sljit_s32 freg) +{ + freg += freg & 0x1; + + SLJIT_ASSERT((freg_map[freg] & 0x1) == (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)); + + if (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS) + freg--; + + return freg; +} + +#define SLJIT_QUAD_OTHER_HALF(freg) ((((freg) & 0x1) << 1) - 1) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (!(srcdst & SLJIT_MEM)) { + if (reg_size == 4) + srcdst = simd_get_quad_reg_index(srcdst); + + if (type & SLJIT_SIMD_STORE) + ins = VD(srcdst) | VN(freg) | VM(freg); + else + ins = VD(freg) | VN(srcdst) | VM(srcdst); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst(compiler, VORR | ins); + } + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + if (elem_size > 3) + elem_size = 3; + + ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD(freg) + | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); + + SLJIT_ASSERT(reg_size >= alignment); + + if (alignment == 3) + ins |= 0x10; + else if (alignment >= 3) + ins |= 0x20; + + return push_inst(compiler, ins | RN(srcdst) | ((sljit_ins)elem_size) << 6 | 0xf); +} + +static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) +{ + sljit_ins result; + + if (elem_size > 1 && (sljit_u16)value == (value >> 16)) { + elem_size = 1; + value = (sljit_u16)value; + } + + if (elem_size == 1 && (sljit_u8)value == (value >> 8)) { + elem_size = 0; + value = (sljit_u8)value; + } + + switch (elem_size) { + case 0: + SLJIT_ASSERT(value <= 0xff); + result = 0xe00; + break; + case 1: + SLJIT_ASSERT(value <= 0xffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x800; + break; + } + + if ((value & 0xff) == 0) { + value >>= 8; + result |= 0xa00; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value ^= (sljit_uw)0xffff; + result = (1 << 5); + } + break; + default: + SLJIT_ASSERT(value <= 0xffffffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x000; + break; + } + + if ((value & ~(sljit_uw)0xff00) == 0) { + value >>= 8; + result |= 0x200; + break; + } + + if ((value & ~(sljit_uw)0xff0000) == 0) { + value >>= 16; + result |= 0x400; + break; + } + + if ((value & ~(sljit_uw)0xff000000) == 0) { + value >>= 24; + result |= 0x600; + break; + } + + if ((value & (sljit_uw)0xff) == 0xff && (value >> 16) == 0) { + value >>= 8; + result |= 0xc00; + break; + } + + if ((value & (sljit_uw)0xffff) == 0xffff && (value >> 24) == 0) { + value >>= 16; + result |= 0xd00; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value = ~value; + result = (1 << 5); + } + break; + } + + return ((sljit_ins)value & 0xf) | (((sljit_ins)value & 0x70) << 12) | (((sljit_ins)value & 0x80) << 17) | result; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imm; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (src == SLJIT_IMM && srcw == 0) + return push_inst(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD(freg)); + + if (SLJIT_UNLIKELY(elem_size == 3)) { + SLJIT_ASSERT(type & SLJIT_SIMD_FLOAT); + + if (src & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, freg, src, srcw)); + src = freg; + } else if (freg != src) + FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (freg != src) + return push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src)); + return SLJIT_SUCCESS; + } + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + + ins = (sljit_ins)(elem_size << 6); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 5; + + return push_inst(compiler, VLD1_r | ins | VD(freg) | RN(src) | 0xf); + } + + if (type & SLJIT_SIMD_FLOAT) { + SLJIT_ASSERT(elem_size == 2); + ins = ((sljit_ins)freg_ebit_map[src] << (16 + 2 + 1)) | ((sljit_ins)1 << (16 + 2)); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst(compiler, VDUP_s | ins | VD(freg) | (sljit_ins)freg_map[src]); + } + + if (src == SLJIT_IMM) { + if (elem_size < 2) + srcw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + imm = simd_get_imm(elem_size, (sljit_uw)srcw); + + if (imm != ~(sljit_ins)0) { + if (reg_size == 4) + imm |= (sljit_ins)1 << 6; + + return push_inst(compiler, VMOV_i | imm | VD(freg)); + } + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); + src = TMP_REG1; + } + + switch (elem_size) { + case 0: + ins = 1 << 22; + break; + case 1: + ins = 1 << 5; + break; + default: + ins = 0; + break; + } + + if (reg_size == 4) + ins |= (sljit_ins)1 << 21; + + return push_inst(compiler, VDUP | ins | VN(freg) | RD(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (type & SLJIT_SIMD_LANE_ZERO) { + ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 6); + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 3 && !(srcdst & SLJIT_MEM)) { + if (lane_index == 1) + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (srcdst != freg) + FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(srcdst) | VM(srcdst))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst(compiler, VMOV_i | VD(freg)); + } + + if (srcdst == freg || (elem_size == 3 && srcdst == (freg + SLJIT_QUAD_OTHER_HALF(freg)))) { + FAIL_IF(push_inst(compiler, VORR | ins | VD(TMP_FREG2) | VN(freg) | VM(freg))); + srcdst = TMP_FREG2; + srcdstw = 0; + } + } + + FAIL_IF(push_inst(compiler, VMOV_i | ins | VD(freg))); + } + + if (reg_size == 4 && lane_index >= (0x8 >> elem_size)) { + lane_index -= (0x8 >> elem_size); + freg += SLJIT_QUAD_OTHER_HALF(freg); + } + + if (srcdst & SLJIT_MEM) { + if (elem_size == 3) + return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, freg, srcdst, srcdstw); + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + lane_index = lane_index << elem_size; + ins = (sljit_ins)((elem_size << 10) | (lane_index << 5)); + return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD(freg) | RN(srcdst) | 0xf); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 3) { + if (type & SLJIT_SIMD_STORE) + return push_inst(compiler, VORR | VD(srcdst) | VN(freg) | VM(freg)); + return push_inst(compiler, VMOV_F32 | SLJIT_32 | VD(freg) | VM(srcdst)); + } + + if (type & SLJIT_SIMD_STORE) { + if (freg_ebit_map[freg] == 0) { + if (lane_index == 1) + freg = SLJIT_F64_SECOND(freg); + + return push_inst(compiler, VMOV_F32 | VD(srcdst) | VM(freg)); + } + + FAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN(freg) | RD(TMP_REG1))); + return push_inst(compiler, VMOV | VN(srcdst) | RD(TMP_REG1)); + } + + FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(srcdst) | RD(TMP_REG1))); + return push_inst(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN(freg) | RD(TMP_REG1)); + } + + if (srcdst == SLJIT_IMM) { + if (elem_size < 2) + srcdstw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcdstw)); + srcdst = TMP_REG1; + } + + if (elem_size == 0) + ins = 0x400000; + else if (elem_size == 1) + ins = 0x20; + else + ins = 0; + + lane_index = lane_index << elem_size; + ins |= (sljit_ins)(((lane_index & 0x4) << 19) | ((lane_index & 0x3) << 5)); + + if (type & SLJIT_SIMD_STORE) { + ins |= (1 << 20); + + if (elem_size < 2 && !(type & SLJIT_SIMD_LANE_SIGNED)) + ins |= (1 << 23); + } + + return push_inst(compiler, VMOV_s | ins | VN(freg) | RD(srcdst)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) { + freg = simd_get_quad_reg_index(freg); + src = simd_get_quad_reg_index(src); + + if (src_lane_index >= (0x8 >> elem_size)) { + src_lane_index -= (0x8 >> elem_size); + src += SLJIT_QUAD_OTHER_HALF(src); + } + } + + if (elem_size == 3) { + if (freg != src) + FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (freg != src) + return push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src)); + return SLJIT_SUCCESS; + } + + ins = ((((sljit_ins)src_lane_index << 1) | 1) << (16 + elem_size)); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst(compiler, VDUP_s | ins | VD(freg) | VM(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_s32 dst_reg; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size != 2 || elem2_size != 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + if (reg_size == 4 && elem2_size - elem_size == 1) + FAIL_IF(push_inst(compiler, VLD1 | (0x7 << 8) | VD(freg) | RN(src) | 0xf)); + else + FAIL_IF(push_inst(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD(freg) | RN(src) | 0xf)); + src = freg; + } else if (reg_size == 4) + src = simd_get_quad_reg_index(src); + + if (!(type & SLJIT_SIMD_FLOAT)) { + dst_reg = (reg_size == 4) ? freg : TMP_FREG2; + + do { + FAIL_IF(push_inst(compiler, VSHLL | ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0 : (1 << 24)) + | ((sljit_ins)1 << (19 + elem_size)) | VD(dst_reg) | VM(src))); + src = dst_reg; + } while (++elem_size < elem2_size); + + if (dst_reg == TMP_FREG2) + return push_inst(compiler, VORR | VD(freg) | VN(TMP_FREG2) | VM(TMP_FREG2)); + return SLJIT_SUCCESS; + } + + /* No SIMD variant, must use VFP instead. */ + SLJIT_ASSERT(reg_size == 4); + + if (freg == src) { + freg += SLJIT_QUAD_OTHER_HALF(freg); + FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src) | 0x20)); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src)); + } + + FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src))); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src) | 0x20); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imms; + sljit_s32 dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + switch (elem_size) { + case 0: + imms = 0x243219; + ins = VSHR | (1 << 24) | (0x9 << 16); + break; + case 1: + imms = (reg_size == 4) ? 0x243219 : 0x2231; + ins = VSHR | (1 << 24) | (0x11 << 16); + break; + case 2: + imms = (reg_size == 4) ? 0x2231 : 0x21; + ins = VSHR | (1 << 24) | (0x21 << 16); + break; + default: + imms = 0x21; + ins = VSHR | (1 << 24) | (0x1 << 16) | (1 << 7); + break; + } + + if (reg_size == 4) { + freg = simd_get_quad_reg_index(freg); + ins |= (sljit_ins)1 << 6; + } + + SLJIT_ASSERT((freg_map[TMP_FREG2] & 0x1) == 0); + FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG2) | VM(freg))); + + if (reg_size == 4 && elem_size > 0) + FAIL_IF(push_inst(compiler, VMOVN | ((sljit_ins)(elem_size - 1) << 18) | VD(TMP_FREG2) | VM(TMP_FREG2))); + + ins = (reg_size == 4 && elem_size == 0) ? (1 << 6) : 0; + + while (imms >= 0x100) { + FAIL_IF(push_inst(compiler, VSRA | (1 << 24) | ins | ((imms & 0xff) << 16) | VD(TMP_FREG2) | VM(TMP_FREG2))); + imms >>= 8; + } + + FAIL_IF(push_inst(compiler, VSRA | (1 << 24) | ins | (1 << 7) | (imms << 16) | VD(TMP_FREG2) | VM(TMP_FREG2))); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + FAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RD(dst_r) | VN(TMP_FREG2))); + + if (reg_size == 4 && elem_size == 0) { + SLJIT_ASSERT(freg_map[TMP_FREG2] + 1 == freg_map[TMP_FREG1]); + FAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RD(TMP_REG2) | VN(TMP_FREG1))); + FAIL_IF(push_inst(compiler, ORR | RD(dst_r) | RN(dst_r) | RM(TMP_REG2) | (0x8 << 7))); + } + + if (dst_r == TMP_REG1) + return emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + switch (SLJIT_SIMD_GET_OPCODE(type)) { + case SLJIT_SIMD_OP2_AND: + ins = VAND; + break; + case SLJIT_SIMD_OP2_OR: + ins = VORR; + break; + case SLJIT_SIMD_OP2_XOR: + ins = VEOR; + break; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) { + dst_freg = simd_get_quad_reg_index(dst_freg); + src1_freg = simd_get_quad_reg_index(src1_freg); + src2_freg = simd_get_quad_reg_index(src2_freg); + ins |= (sljit_ins)1 << 6; + } + + return push_inst(compiler, ins | VD(dst_freg) | VN(src1_freg) | VM(src2_freg)); } #undef FPU_LOAD +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + sljit_u32 ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV_U8: + ins = LDREXB; + break; + case SLJIT_MOV_U16: + ins = LDREXH; + break; + default: + ins = LDREX; + break; + } + + return push_inst(compiler, ins | RN(mem_reg) | RD(dst_reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_u32 ins; + + /* temp_reg == mem_reg is undefined so use another temp register */ + SLJIT_UNUSED_ARG(temp_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV_U8: + ins = STREXB; + break; + case SLJIT_MOV_U16: + ins = STREXH; + break; + default: + ins = STREX; + break; + } + + FAIL_IF(push_inst(compiler, ins | RN(mem_reg) | RD(TMP_REG1) | RM(src_reg))); + if (op & SLJIT_SET_ATOMIC_STORED) + return push_inst(compiler, CMP | SET_FLAGS | SRC2_IMM | RN(TMP_REG1)); + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; @@ -3645,13 +4446,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) PTR_FAIL_IF(push_inst_with_unique_literal(compiler, - EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), (sljit_uw)init_value)); + EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), (sljit_ins)init_value)); compiler->patches++; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value)); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); PTR_FAIL_IF(!const_); @@ -3673,12 +4474,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), 0)); compiler->patches++; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ PTR_FAIL_IF(emit_imm(compiler, dst_r, 0)); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); PTR_FAIL_IF(!put_label); diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c index 89f747e7c89..b268582f42c 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c @@ -67,79 +67,123 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { /* Instrucion forms */ /* --------------------------------------------------------------------- */ -#define ADC 0x9a000000 -#define ADD 0x8b000000 -#define ADDE 0x8b200000 -#define ADDI 0x91000000 -#define AND 0x8a000000 -#define ANDI 0x92000000 -#define ASRV 0x9ac02800 -#define B 0x14000000 -#define B_CC 0x54000000 -#define BL 0x94000000 -#define BLR 0xd63f0000 -#define BR 0xd61f0000 -#define BRK 0xd4200000 -#define CBZ 0xb4000000 -#define CLZ 0xdac01000 -#define CSEL 0x9a800000 -#define CSINC 0x9a800400 -#define EOR 0xca000000 -#define EORI 0xd2000000 -#define EXTR 0x93c00000 -#define FABS 0x1e60c000 -#define FADD 0x1e602800 -#define FCMP 0x1e602000 -#define FCVT 0x1e224000 -#define FCVTZS 0x9e780000 -#define FDIV 0x1e601800 -#define FMOV 0x1e604000 -#define FMUL 0x1e600800 -#define FNEG 0x1e614000 -#define FSUB 0x1e603800 -#define LDRI 0xf9400000 -#define LDRI_F64 0xfd400000 -#define LDRI_POST 0xf8400400 -#define LDP 0xa9400000 -#define LDP_F64 0x6d400000 -#define LDP_POST 0xa8c00000 -#define LDR_PRE 0xf8400c00 -#define LSLV 0x9ac02000 -#define LSRV 0x9ac02400 -#define MADD 0x9b000000 -#define MOVK 0xf2800000 -#define MOVN 0x92800000 -#define MOVZ 0xd2800000 -#define NOP 0xd503201f -#define ORN 0xaa200000 -#define ORR 0xaa000000 -#define ORRI 0xb2000000 -#define RBIT 0xdac00000 -#define RET 0xd65f0000 -#define RORV 0x9ac02c00 -#define SBC 0xda000000 -#define SBFM 0x93000000 -#define SCVTF 0x9e620000 -#define SDIV 0x9ac00c00 -#define SMADDL 0x9b200000 -#define SMULH 0x9b403c00 -#define STP 0xa9000000 -#define STP_F64 0x6d000000 -#define STP_PRE 0xa9800000 -#define STRB 0x38206800 -#define STRBI 0x39000000 -#define STRI 0xf9000000 -#define STRI_F64 0xfd000000 -#define STR_FI 0x3d000000 -#define STR_FR 0x3c206800 -#define STUR_FI 0x3c000000 -#define STURBI 0x38000000 -#define SUB 0xcb000000 -#define SUBI 0xd1000000 -#define SUBS 0xeb000000 -#define UBFM 0xd3000000 -#define UDIV 0x9ac00800 -#define UMULH 0x9bc03c00 +#define ADC 0x9a000000 +#define ADD 0x8b000000 +#define ADDE 0x8b200000 +#define ADDI 0x91000000 +#define AND 0x8a000000 +#define ANDI 0x92000000 +#define AND_v 0x0e201c00 +#define ASRV 0x9ac02800 +#define B 0x14000000 +#define B_CC 0x54000000 +#define BL 0x94000000 +#define BLR 0xd63f0000 +#define BR 0xd61f0000 +#define BRK 0xd4200000 +#define CAS 0xc8a07c00 +#define CASB 0x08a07c00 +#define CASH 0x48a07c00 +#define CBZ 0xb4000000 +#define CCMPI 0xfa400800 +#define CLZ 0xdac01000 +#define CSEL 0x9a800000 +#define CSINC 0x9a800400 +#define DUP_e 0x0e000400 +#define DUP_g 0x0e000c00 +#define EOR 0xca000000 +#define EOR_v 0x2e201c00 +#define EORI 0xd2000000 +#define EXTR 0x93c00000 +#define FABS 0x1e60c000 +#define FADD 0x1e602800 +#define FCMP 0x1e602000 +#define FCSEL 0x1e600c00 +#define FCVT 0x1e224000 +#define FCVTL 0x0e217800 +#define FCVTZS 0x9e780000 +#define FDIV 0x1e601800 +#define FMOV 0x1e604000 +#define FMOV_R 0x9e660000 +#define FMOV_I 0x1e601000 +#define FMUL 0x1e600800 +#define FNEG 0x1e614000 +#define FSUB 0x1e603800 +#define INS 0x4e001c00 +#define INS_e 0x6e000400 +#define LD1 0x0c407000 +#define LD1_s 0x0d400000 +#define LD1R 0x0d40c000 +#define LDRI 0xf9400000 +#define LDRI_F64 0xfd400000 +#define LDRI_POST 0xf8400400 +#define LDP 0xa9400000 +#define LDP_F64 0x6d400000 +#define LDP_POST 0xa8c00000 +#define LDR_PRE 0xf8400c00 +#define LDXR 0xc85f7c00 +#define LDXRB 0x085f7c00 +#define LDXRH 0x485f7c00 +#define LSLV 0x9ac02000 +#define LSRV 0x9ac02400 +#define MADD 0x9b000000 +#define MOVI 0x0f000400 +#define MOVK 0xf2800000 +#define MOVN 0x92800000 +#define MOVZ 0xd2800000 +#define NOP 0xd503201f +#define ORN 0xaa200000 +#define ORR 0xaa000000 +#define ORR_v 0x0ea01c00 +#define ORRI 0xb2000000 +#define RBIT 0xdac00000 +#define RET 0xd65f0000 +#define REV 0xdac00c00 +#define REV16 0xdac00400 +#define RORV 0x9ac02c00 +#define SBC 0xda000000 +#define SBFM 0x93400000 +#define SCVTF 0x9e620000 +#define SDIV 0x9ac00c00 +#define SMADDL 0x9b200000 +#define SMOV 0x0e002c00 +#define SMULH 0x9b403c00 +#define SSHLL 0x0f00a400 +#define ST1 0x0c007000 +#define ST1_s 0x0d000000 +#define STP 0xa9000000 +#define STP_F64 0x6d000000 +#define STP_PRE 0xa9800000 +#define STRB 0x38206800 +#define STRBI 0x39000000 +#define STRI 0xf9000000 +#define STRI_F64 0xfd000000 +#define STR_FI 0x3d000000 +#define STR_FR 0x3c206800 +#define STUR_FI 0x3c000000 +#define STURBI 0x38000000 +#define STXR 0xc8007c00 +#define STXRB 0x8007c00 +#define STXRH 0x48007c00 +#define SUB 0xcb000000 +#define SUBI 0xd1000000 +#define SUBS 0xeb000000 +#define TBZ 0x36000000 +#define UBFM 0xd3400000 +#define UCVTF 0x9e630000 +#define UDIV 0x9ac00800 +#define UMOV 0x0e003c00 +#define UMULH 0x9bc03c00 +#define USHLL 0x2f00a400 +#define USHR 0x2f000400 +#define USRA 0x2f001400 +#define XTN 0x0e212800 + +#define CSET (CSINC | RM(TMP_ZERO) | RN(TMP_ZERO)) +#define LDR (STRI | (1 << 22)) +#define LDRB (STRBI | (1 << 22)) +#define LDRH (LDRB | (1 << 30)) +#define MOV (ORR | RN(TMP_ZERO)) static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) { @@ -175,7 +219,7 @@ static SLJIT_INLINE sljit_sw detect_jump_type(struct sljit_jump *jump, sljit_ins target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; } - diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4) - executable_offset; + diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr - 4) - executable_offset; if (jump->flags & IS_COND) { diff += SSIZE_OF(ins); @@ -385,8 +429,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) { switch (feature_type) { case SLJIT_HAS_FPU: + case SLJIT_HAS_SIMD: #ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; + return (SLJIT_IS_FPU_AVAILABLE) != 0; #else /* Available by default. */ return 1; @@ -394,9 +439,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_CLZ: case SLJIT_HAS_CTZ: + case SLJIT_HAS_REV: case SLJIT_HAS_ROT: case SLJIT_HAS_CMOV: case SLJIT_HAS_PREFETCH: + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: + case SLJIT_HAS_ATOMIC: return 1; default: @@ -404,6 +453,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) } } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) +{ + switch (type) { + case SLJIT_UNORDERED_OR_EQUAL: + case SLJIT_ORDERED_NOT_EQUAL: + return 2; + } + + return 0; +} + /* --------------------------------------------------------------------- */ /* Core code generator functions. */ /* --------------------------------------------------------------------- */ @@ -636,6 +696,11 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s case SLJIT_MUL: case SLJIT_CLZ: case SLJIT_CTZ: + case SLJIT_REV: + case SLJIT_REV_U16: + case SLJIT_REV_S16: + case SLJIT_REV_U32: + case SLJIT_REV_S32: case SLJIT_ADDC: case SLJIT_SUBC: /* No form with immediate operand (except imm 0, which @@ -644,10 +709,6 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s case SLJIT_MOV: SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1); return load_immediate(compiler, dst, imm); - case SLJIT_NOT: - SLJIT_ASSERT(flags & ARG2_IMM); - FAIL_IF(load_immediate(compiler, dst, (flags & INT_OP) ? (~imm & 0xffffffff) : ~imm)); - goto set_flags; case SLJIT_SUB: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB; if (flags & ARG1_IMM) @@ -694,8 +755,13 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s break; CHECK_FLAGS(3 << 29); return push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits); - case SLJIT_OR: case SLJIT_XOR: + if (imm == -1) { + FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(reg))); + goto set_flags; + } + /* fallthrough */ + case SLJIT_OR: inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32)); if (!inst_bits) break; @@ -718,6 +784,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s inst_bits = ((sljit_ins)1 << 22) | (((sljit_ins)-imm & 0x3f) << 16) | ((63 - (sljit_ins)imm) << 10); } + inv_bits |= inv_bits >> 9; FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | inst_bits)); goto set_flags; case SLJIT_LSHR: @@ -727,6 +794,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s if (flags & ARG1_IMM) break; + inv_bits |= inv_bits >> 9; if (op >= SLJIT_ASHR) inv_bits |= 1 << 30; @@ -780,22 +848,22 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (dst == arg2) return SLJIT_SUCCESS; - return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2)); + return push_inst(compiler, MOV | RD(dst) | RM(arg2)); case SLJIT_MOV_U8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - return push_inst(compiler, (UBFM ^ W_OP) | RD(dst) | RN(arg2) | (7 << 10)); + inv_bits |= inv_bits >> 9; + return push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10)); case SLJIT_MOV_S8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (!(flags & INT_OP)) - inv_bits |= 1 << 22; + inv_bits |= inv_bits >> 9; return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10)); case SLJIT_MOV_U16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - return push_inst(compiler, (UBFM ^ W_OP) | RD(dst) | RN(arg2) | (15 << 10)); + inv_bits |= inv_bits >> 9; + return push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10)); case SLJIT_MOV_S16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (!(flags & INT_OP)) - inv_bits |= 1 << 22; + inv_bits |= inv_bits >> 9; return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10)); case SLJIT_MOV32: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); @@ -804,14 +872,10 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s /* fallthrough */ case SLJIT_MOV_U32: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - return push_inst(compiler, (ORR ^ W_OP) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); + return push_inst(compiler, (MOV ^ W_OP) | RD(dst) | RM(arg2)); case SLJIT_MOV_S32: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10)); - case SLJIT_NOT: - SLJIT_ASSERT(arg1 == TMP_REG1); - FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2))); - break; /* Set flags. */ case SLJIT_CLZ: SLJIT_ASSERT(arg1 == TMP_REG1); return push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2)); @@ -819,6 +883,25 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s SLJIT_ASSERT(arg1 == TMP_REG1); FAIL_IF(push_inst(compiler, (RBIT ^ inv_bits) | RD(dst) | RN(arg2))); return push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(dst)); + case SLJIT_REV: + SLJIT_ASSERT(arg1 == TMP_REG1); + inv_bits |= inv_bits >> 21; + return push_inst(compiler, (REV ^ inv_bits) | RD(dst) | RN(arg2)); + case SLJIT_REV_U16: + case SLJIT_REV_S16: + SLJIT_ASSERT(arg1 == TMP_REG1 && dst != TMP_REG2); + FAIL_IF(push_inst(compiler, (REV16 ^ (sljit_ins)0x80000000) | RD(dst) | RN(arg2))); + if (dst == TMP_REG1 || (arg2 == TMP_REG2 && op == SLJIT_REV_U16)) + return SLJIT_SUCCESS; + inv_bits |= inv_bits >> 9; + return push_inst(compiler, ((op == SLJIT_REV_U16 ? UBFM : SBFM) ^ inv_bits) | RD(dst) | RN(dst) | (15 << 10)); + case SLJIT_REV_U32: + case SLJIT_REV_S32: + SLJIT_ASSERT(arg1 == TMP_REG1 && dst != TMP_REG2); + FAIL_IF(push_inst(compiler, (REV ^ (sljit_ins)0x80000400) | RD(dst) | RN(arg2))); + if (op == SLJIT_REV_U32 || dst == TMP_REG1) + return SLJIT_SUCCESS; + return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(dst) | (31 << 10)); case SLJIT_ADD: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; CHECK_FLAGS(1 << 29); @@ -980,7 +1063,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 2); - saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, SSIZE_OF(f64)); + saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); local_size = (local_size + saved_regs_size + 0xf) & ~0xf; compiler->local_size = local_size; @@ -1065,7 +1148,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi while (arg_types) { if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) { if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) { - FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S0 - saved_arg_count) | RN(TMP_ZERO) | RM(tmp))); + FAIL_IF(push_inst(compiler, MOV | RD(SLJIT_S0 - saved_arg_count) | RM(tmp))); saved_arg_count++; } tmp++; @@ -1153,7 +1236,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 2); - saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, SSIZE_OF(f64)); + saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); compiler->local_size = (local_size + saved_regs_size + 0xf) & ~0xf; return SLJIT_SUCCESS; @@ -1272,7 +1355,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c src = TMP_REG1; srcw = 0; } else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) { - FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(src))); + FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src))); src = TMP_REG1; srcw = 0; } @@ -1302,12 +1385,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return push_inst(compiler, NOP); case SLJIT_LMUL_UW: case SLJIT_LMUL_SW: - FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); + FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(SLJIT_R0))); FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); case SLJIT_DIVMOD_UW: case SLJIT_DIVMOD_SW: - FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); + FAIL_IF(push_inst(compiler, (MOV ^ inv_bits) | RD(TMP_REG1) | RM(SLJIT_R0))); FAIL_IF(push_inst(compiler, ((op == SLJIT_DIVMOD_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1))); FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); @@ -1349,33 +1432,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile break; case SLJIT_MOV_U8: mem_flags = BYTE_SIZE; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_u8)srcw; break; case SLJIT_MOV_S8: mem_flags = BYTE_SIZE | SIGNED; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_s8)srcw; break; case SLJIT_MOV_U16: mem_flags = HALF_SIZE; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_u16)srcw; break; case SLJIT_MOV_S16: mem_flags = HALF_SIZE | SIGNED; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_s16)srcw; break; case SLJIT_MOV_U32: mem_flags = INT_SIZE; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_u32)srcw; break; case SLJIT_MOV_S32: case SLJIT_MOV32: mem_flags = INT_SIZE | SIGNED; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_s32)srcw; break; default: @@ -1384,7 +1467,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile break; } - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw)); else if (!(src & SLJIT_MEM)) dst_r = src; @@ -1397,11 +1480,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile } flags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0; - mem_flags = WORD_SIZE; - if (op_flags & SLJIT_32) { - flags |= INT_OP; + switch (op) { + case SLJIT_REV_U16: + case SLJIT_REV_S16: + mem_flags = HALF_SIZE; + break; + case SLJIT_REV_U32: + case SLJIT_REV_S32: mem_flags = INT_SIZE; + break; + default: + mem_flags = WORD_SIZE; + + if (op_flags & SLJIT_32) { + flags |= INT_OP; + mem_flags = INT_SIZE; + } + break; } if (src & SLJIT_MEM) { @@ -1451,12 +1547,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile src2 = TMP_REG2; } - if (src1 & SLJIT_IMM) + if (src1 == SLJIT_IMM) flags |= ARG1_IMM; else src1w = src1; - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) flags |= ARG2_IMM; else src2w = src2; @@ -1480,57 +1576,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_ins inv_bits, imm; sljit_s32 is_left; sljit_sw mask; CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); inv_bits = (op & SLJIT_32) ? W_OP : 0; - mask = inv_bits ? 0x1f : 0x3f; - if (src2 & SLJIT_IMM) { - src2w &= mask; + if (src3 == SLJIT_IMM) { + mask = inv_bits ? 0x1f : 0x3f; + src3w &= mask; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG2, src2, src2w, TMP_REG2)); - src2 = TMP_REG2; - } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); - src1 = TMP_REG1; - } - - if (src2 & SLJIT_IMM) { if (is_left) - src2w = (src2w ^ mask) + 1; + src3w = (src3w ^ mask) + 1; - return push_inst(compiler, (EXTR ^ (inv_bits | (inv_bits >> 9))) | RD(src_dst) - | RN(is_left ? src_dst : src1) | RM(is_left ? src1 : src_dst) | ((sljit_ins)src2w << 10)); + return push_inst(compiler, (EXTR ^ (inv_bits | (inv_bits >> 9))) | RD(dst_reg) + | RN(is_left ? src1_reg : src2_reg) | RM(is_left ? src2_reg : src1_reg) | ((sljit_ins)src3w << 10)); } - FAIL_IF(push_inst(compiler, ((is_left ? LSLV : LSRV) ^ inv_bits) | RD(src_dst) | RN(src_dst) | RM(src2))); + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG2, src3, src3w, TMP_REG2)); + src3 = TMP_REG2; + } else if (dst_reg == src3) { + FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src3))); + src3 = TMP_REG2; + } + + FAIL_IF(push_inst(compiler, ((is_left ? LSLV : LSRV) ^ inv_bits) | RD(dst_reg) | RN(src1_reg) | RM(src3))); if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) { /* Shift left/right by 1. */ @@ -1539,18 +1630,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * else imm = (sljit_ins)(inv_bits ? ((31 << 16) | (30 << 10)) : ((63 << 16) | (62 << 10) | (1 << 22))); - FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(TMP_REG1) | RN(src1) | imm)); + FAIL_IF(push_inst(compiler, (UBFM ^ (inv_bits | (inv_bits >> 9))) | RD(TMP_REG1) | RN(src2_reg) | imm)); /* Set imm to mask. */ imm = (sljit_ins)(inv_bits ? (4 << 10) : ((5 << 10) | (1 << 22))); - FAIL_IF(push_inst(compiler, (EORI ^ inv_bits) | RD(TMP_REG2) | RN(src2) | imm)); + FAIL_IF(push_inst(compiler, (EORI ^ inv_bits) | RD(TMP_REG2) | RN(src3) | imm)); - src1 = TMP_REG1; + src2_reg = TMP_REG1; } else - FAIL_IF(push_inst(compiler, (SUB ^ inv_bits) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(src2))); + FAIL_IF(push_inst(compiler, (SUB ^ inv_bits) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(src3))); - FAIL_IF(push_inst(compiler, ((is_left ? LSRV : LSLV) ^ inv_bits) | RD(TMP_REG1) | RN(src1) | RM(TMP_REG2))); - return push_inst(compiler, (ORR ^ inv_bits) | RD(src_dst) | RN(src_dst) | RM(TMP_REG1)); + FAIL_IF(push_inst(compiler, ((is_left ? LSRV : LSLV) ^ inv_bits) | RD(TMP_REG1) | RN(src2_reg) | RM(TMP_REG2))); + return push_inst(compiler, (ORR ^ inv_bits) | RD(dst_reg) | RN(dst_reg) | RM(TMP_REG1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, @@ -1563,7 +1654,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp switch (op) { case SLJIT_FAST_RETURN: if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src))); + FAIL_IF(push_inst(compiler, MOV | RD(TMP_LR) | RM(src))); else FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1)); @@ -1593,15 +1684,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 dst_r = TMP_LR; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + if (FAST_IS_REG(dst)) + return push_inst(compiler, MOV | RD(dst) | RM(TMP_LR)); + break; + case SLJIT_GET_RETURN_ADDRESS: + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, dst_r, SLJIT_MEM1(SLJIT_SP), 0x8, TMP_REG2)); + break; + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type != SLJIT_FLOAT_REGISTER && type != SLJIT_SIMD_REG_64 && type != SLJIT_SIMD_REG_128) + return -1; + return freg_map[reg]; } @@ -1679,7 +1797,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp inv_bits |= W_OP; if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw)); src = TMP_FREG1; } @@ -1690,34 +1808,59 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0; - - if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) - inv_bits |= W_OP; if (src & SLJIT_MEM) { - emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw, TMP_REG1); + emit_op_mem(compiler, (ins & W_OP) ? WORD_SIZE : INT_SIZE, TMP_REG1, src, srcw, TMP_REG1); src = TMP_REG1; - } else if (src & SLJIT_IMM) { - if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) - srcw = (sljit_s32)srcw; - + } else if (src == SLJIT_IMM) { FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); src = TMP_REG1; } - FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src))); + FAIL_IF(push_inst(compiler, ins | VD(dst_r) | RN(src))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, ((op & SLJIT_32) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, ((ins & (1 << 22)) ? WORD_SIZE : INT_SIZE) | STORE, TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0; + + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) { + inv_bits |= W_OP; + + if (src == SLJIT_IMM) + srcw = (sljit_s32)srcw; + } + + return sljit_emit_fop1_conv_f64_from_w(compiler, SCVTF ^ inv_bits, dst, dstw, src, srcw); +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0; + + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) { + inv_bits |= W_OP; + + if (src == SLJIT_IMM) + srcw = (sljit_u32)srcw; + } + + return sljit_emit_fop1_conv_f64_from_w(compiler, UCVTF ^ inv_bits, dst, dstw, src, srcw); +} + static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) @@ -1726,16 +1869,22 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0; if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); + FAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w); + FAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } - return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2)); + FAIL_IF(push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2))); + + if (GET_FLAG_TYPE(op) != SLJIT_UNORDERED_OR_EQUAL) + return SLJIT_SUCCESS; + + FAIL_IF(push_inst(compiler, CSINC | (0x0 << 12) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(TMP_ZERO))); + return push_inst(compiler, CCMPI | (0x0 << 16) | (0x7 << 12) | RN(TMP_REG1) | 0x4); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, @@ -1754,7 +1903,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x1) : mem_flags, dst_r, src, srcw); + FAIL_IF(emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x1) : mem_flags, dst_r, src, srcw)); src = dst_r; } @@ -1799,11 +1948,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); + FAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w); + FAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } @@ -1820,6 +1969,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); break; + case SLJIT_COPYSIGN_F64: + FAIL_IF(push_inst(compiler, (FMOV_R ^ ((op & SLJIT_32) ? (W_OP | (1 << 22)) : 0)) | VN(src2) | RD(TMP_REG1))); + FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src1))); + FAIL_IF(push_inst(compiler, TBZ | ((op & SLJIT_32) ? 0 : ((sljit_ins)1 << 31)) | (0x1f << 19) | (2 << 5) | RT(TMP_REG1))); + return push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(dst_r)); } if (!(dst & SLJIT_MEM)) @@ -1827,21 +1981,79 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw); } -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { + sljit_u32 exp; + union { + sljit_u32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - if (FAST_IS_REG(dst)) - return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR)); + u.value = value; - /* Memory. */ - return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw, TMP_REG1); + if (u.imm == 0) + return push_inst(compiler, (FMOV_R ^ (W_OP | (1 << 22))) | RN(TMP_ZERO) | VD(freg) | (1 << 16)); + + if ((u.imm << (32 - 19)) == 0) { + exp = (u.imm >> (23 + 2)) & 0x3f; + + if (exp == 0x20 || exp == 0x1f) + return push_inst(compiler, (FMOV_I ^ (1 << 22)) | (sljit_ins)((((u.imm >> 24) & 0x80) | ((u.imm >> 19) & 0x7f)) << 13) | VD(freg)); + } + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_s32)u.imm)); + return push_inst(compiler, (FMOV_R ^ (W_OP | (1 << 22))) | RN(TMP_REG1) | VD(freg) | (1 << 16)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + sljit_uw exp; + union { + sljit_uw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm == 0) + return push_inst(compiler, FMOV_R | RN(TMP_ZERO) | VD(freg) | (sljit_ins)1 << 16); + + if ((u.imm << (64 - 48)) == 0) { + exp = (u.imm >> (52 + 2)) & 0x1ff; + + if (exp == 0x100 || exp == 0xff) + return push_inst(compiler, FMOV_I | (sljit_ins)((((u.imm >> 56) & 0x80) | ((u.imm >> 48) & 0x7f)) << 13) | VD(freg)); + } + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_sw)u.imm)); + return push_inst(compiler, FMOV_R | RN(TMP_REG1) | VD(freg) | (1 << 16)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_ins inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) + inst = FMOV_R | RN(reg) | VD(freg) | (1 << 16); + else + inst = FMOV_R | VN(freg) | RD(reg); + + if (op & SLJIT_32) + inst ^= W_OP | (1 << 22); + + return push_inst(compiler, inst); } /* --------------------------------------------------------------------- */ @@ -1852,15 +2064,17 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type) { switch (type) { case SLJIT_EQUAL: + case SLJIT_ATOMIC_STORED: case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: - case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */ + case SLJIT_UNORDERED_OR_EQUAL: return 0x1; case SLJIT_NOT_EQUAL: + case SLJIT_ATOMIC_NOT_STORED: case SLJIT_F_NOT_EQUAL: case SLJIT_UNORDERED_OR_NOT_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */ + case SLJIT_ORDERED_NOT_EQUAL: return 0x0; case SLJIT_CARRY: @@ -2011,7 +2225,7 @@ static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compi PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1)); src = TMP_REG1; } - else if (src & SLJIT_IMM) { + else if (src == SLJIT_IMM) { PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); src = TMP_REG1; } @@ -2035,7 +2249,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { if (src & SLJIT_MEM) { ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1)); @@ -2071,7 +2285,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi if (type & SLJIT_CALL_RETURN) { if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) { - FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(src))); + FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src))); src = TMP_REG1; } @@ -2131,27 +2345,53 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { sljit_ins inv_bits = (type & SLJIT_32) ? W_OP : 0; sljit_ins cc; CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); - if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (src1 == SLJIT_IMM) { if (type & SLJIT_32) - srcw = (sljit_s32)srcw; - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - srcw = 0; + src1w = (sljit_s32)src1w; + FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); + src1 = TMP_REG1; + } else if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG2)); + src1 = TMP_REG1; } cc = get_cc(compiler, type & ~SLJIT_32); + return push_inst(compiler, (CSEL ^ inv_bits) | (cc << 12) | RD(dst_reg) | RN(src2_reg) | RM(src1)); +} - return push_inst(compiler, (CSEL ^ inv_bits) | (cc << 12) | RD(dst_reg) | RN(dst_reg) | RM(src)); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_ins inv_bits = (type & SLJIT_32) ? (1 << 22) : 0; + sljit_ins cc; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src1, src1w)); + src1 = TMP_FREG1; + } + + cc = get_cc(compiler, type & ~SLJIT_32); + return push_inst(compiler, (FCSEL ^ inv_bits) | (cc << 12) | VD(dst_freg) | VN(src2_freg) | VM(src1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, @@ -2308,6 +2548,661 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler return push_inst(compiler, inst | VT(freg) | RN(mem & REG_MASK) | (sljit_ins)((memw & 0x1ff) << 12)); } +static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, sljit_s32 *mem_ptr, sljit_sw memw) +{ + sljit_ins ins; + sljit_s32 mem = *mem_ptr; + + if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { + *mem_ptr = TMP_REG1; + return push_inst(compiler, ADD | RD(TMP_REG1) | RN(mem & REG_MASK) | RM(OFFS_REG(mem)) | ((sljit_ins)(memw & 0x3) << 10)); + } + + if (!(mem & REG_MASK)) { + *mem_ptr = TMP_REG1; + return load_immediate(compiler, TMP_REG1, memw); + } + + mem &= REG_MASK; + + if (memw == 0) { + *mem_ptr = mem; + return SLJIT_SUCCESS; + } + + *mem_ptr = TMP_REG1; + + if (memw < -0xffffff || memw > 0xffffff) { + FAIL_IF(load_immediate(compiler, TMP_REG1, memw)); + return push_inst(compiler, ADD | RD(TMP_REG1) | RN(TMP_REG1) | RM(mem)); + } + + ins = ADDI; + + if (memw < 0) { + memw = -memw; + ins = SUBI; + } + + if (memw > 0xfff) { + FAIL_IF(push_inst(compiler, ins | (1 << 22) | RD(TMP_REG1) | RN(mem) | ((sljit_ins)(memw >> 12) << 10))); + + memw &= 0xfff; + if (memw == 0) + return SLJIT_SUCCESS; + + mem = TMP_REG1; + } + + return push_inst(compiler, ins | RD(TMP_REG1) | RN(mem) | ((sljit_ins)memw << 10)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (!(srcdst & SLJIT_MEM)) { + if (type & SLJIT_SIMD_STORE) + ins = VD(srcdst) | VN(freg) | VM(freg); + else + ins = VD(freg) | VN(srcdst) | VM(srcdst); + + if (reg_size == 4) + ins |= (1 << 30); + + return push_inst(compiler, ORR_v | ins); + } + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + if (elem_size > 3) + elem_size = 3; + + ins = (type & SLJIT_SIMD_STORE) ? ST1 : LD1; + + if (reg_size == 4) + ins |= (1 << 30); + + return push_inst(compiler, ins | ((sljit_ins)elem_size << 10) | RN(srcdst) | VT(freg)); +} + +static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) +{ + sljit_ins result; + + if (elem_size > 2 && (sljit_u32)value == (value >> 32)) { + elem_size = 2; + value = (sljit_u32)value; + } + + if (elem_size == 2 && (sljit_u16)value == (value >> 16)) { + elem_size = 1; + value = (sljit_u16)value; + } + + if (elem_size == 1 && (sljit_u8)value == (value >> 8)) { + elem_size = 0; + value = (sljit_u8)value; + } + + switch (elem_size) { + case 0: + SLJIT_ASSERT(value <= 0xff); + result = 0xe000; + break; + case 1: + SLJIT_ASSERT(value <= 0xffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x8000; + break; + } + + if ((value & 0xff) == 0) { + value >>= 8; + result |= 0xa000; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value ^= (sljit_uw)0xffff; + result = (1 << 29); + } + break; + case 2: + SLJIT_ASSERT(value <= 0xffffffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x0000; + break; + } + + if ((value & ~(sljit_uw)0xff00) == 0) { + value >>= 8; + result |= 0x2000; + break; + } + + if ((value & ~(sljit_uw)0xff0000) == 0) { + value >>= 16; + result |= 0x4000; + break; + } + + if ((value & ~(sljit_uw)0xff000000) == 0) { + value >>= 24; + result |= 0x6000; + break; + } + + if ((value & (sljit_uw)0xff) == 0xff && (value >> 16) == 0) { + value >>= 8; + result |= 0xc000; + break; + } + + if ((value & (sljit_uw)0xffff) == 0xffff && (value >> 24) == 0) { + value >>= 16; + result |= 0xd000; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value ^= (sljit_uw)0xffffffff; + result = (1 << 29); + } + break; + default: + return ~(sljit_ins)0; + } + + return (((sljit_ins)value & 0x1f) << 5) | (((sljit_ins)value & 0xe0) << 11) | result; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imm; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + + ins = (sljit_ins)elem_size << 10; + + if (reg_size == 4) + ins |= (sljit_ins)1 << 30; + + return push_inst(compiler, LD1R | ins | RN(src) | VT(freg)); + } + + ins = (sljit_ins)1 << (16 + elem_size); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 30; + + if (type & SLJIT_SIMD_FLOAT) { + if (src == SLJIT_IMM) + return push_inst(compiler, MOVI | (ins & ((sljit_ins)1 << 30)) | VD(freg)); + + return push_inst(compiler, DUP_e | ins | VD(freg) | VN(src)); + } + + if (src == SLJIT_IMM) { + if (elem_size < 3) + srcw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + imm = simd_get_imm(elem_size, (sljit_uw)srcw); + + if (imm != ~(sljit_ins)0) { + imm |= ins & ((sljit_ins)1 << 30); + + return push_inst(compiler, MOVI | imm | VD(freg)); + } + + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } + + return push_inst(compiler, DUP_g | ins | VD(freg) | RN(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (type & SLJIT_SIMD_LANE_ZERO) { + ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 30); + + if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { + FAIL_IF(push_inst(compiler, ORR_v | ins | VD(TMP_FREG1) | VN(freg) | VM(freg))); + srcdst = TMP_FREG1; + srcdstw = 0; + } + + FAIL_IF(push_inst(compiler, MOVI | ins | VD(freg))); + } + + if (srcdst & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + if (elem_size == 3) + ins = 0x8400; + else if (elem_size == 0) + ins = 0; + else + ins = (sljit_ins)0x2000 << elem_size; + + lane_index = lane_index << elem_size; + ins |= (sljit_ins)(((lane_index & 0x8) << 27) | ((lane_index & 0x7) << 10)); + + return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? ST1_s : LD1_s) | ins | RN(srcdst) | VT(freg)); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (type & SLJIT_SIMD_STORE) + ins = INS_e | ((sljit_ins)1 << (16 + elem_size)) | ((sljit_ins)lane_index << (11 + elem_size)) | VD(srcdst) | VN(freg); + else + ins = INS_e | ((((sljit_ins)lane_index << 1) | 1) << (16 + elem_size)) | VD(freg) | VN(srcdst); + + return push_inst(compiler, ins); + } + + if (srcdst == SLJIT_IMM) { + if (elem_size < 3) + srcdstw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + FAIL_IF(load_immediate(compiler, TMP_REG1, srcdstw)); + srcdst = TMP_REG1; + } + + if (type & SLJIT_SIMD_STORE) { + ins = RD(srcdst) | VN(freg); + + if ((type & SLJIT_SIMD_LANE_SIGNED) && (elem_size < 2 || (elem_size == 2 && !(type & SLJIT_32)))) { + ins |= SMOV; + + if (!(type & SLJIT_32)) + ins |= (sljit_ins)1 << 30; + } else + ins |= UMOV; + } else + ins = INS | VD(freg) | RN(srcdst); + + if (elem_size == 3) + ins |= (sljit_ins)1 << 30; + + return push_inst(compiler, ins | ((((sljit_ins)lane_index << 1) | 1) << (16 + elem_size))); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + ins = (((sljit_ins)src_lane_index << 1) | 1) << (16 + elem_size); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 30; + + return push_inst(compiler, DUP_e | ins | VD(freg) | VN(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size != 2 || elem2_size != 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + + if (reg_size == 4 && elem2_size - elem_size == 1) + FAIL_IF(push_inst(compiler, LD1 | ((sljit_ins)elem_size << 10) | RN(src) | VT(freg))); + else + FAIL_IF(push_inst(compiler, LD1_s | ((sljit_ins)0x2000 << (reg_size - elem2_size + elem_size)) | RN(src) | VT(freg))); + src = freg; + } + + if (type & SLJIT_SIMD_FLOAT) { + SLJIT_ASSERT(reg_size == 4); + return push_inst(compiler, FCVTL | (1 << 22) | VD(freg) | VN(src)); + } + + do { + FAIL_IF(push_inst(compiler, ((type & SLJIT_SIMD_EXTEND_SIGNED) ? SSHLL : USHLL) + | ((sljit_ins)1 << (19 + elem_size)) | VD(freg) | VN(src))); + src = freg; + } while (++elem_size < elem2_size); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imms; + sljit_s32 dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + switch (elem_size) { + case 0: + imms = 0x643219; + ins = USHR | (0x9 << 16); + break; + case 1: + imms = (reg_size == 4) ? 0x643219 : 0x6231; + ins = USHR | (0x11 << 16); + break; + case 2: + imms = (reg_size == 4) ? 0x6231 : 0x61; + ins = USHR | (0x21 << 16); + break; + default: + imms = 0x61; + ins = USHR | (0x41 << 16); + break; + } + + if (reg_size == 4) + ins |= (1 << 30); + + FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG1) | VN(freg))); + + if (reg_size == 4 && elem_size > 0) + FAIL_IF(push_inst(compiler, XTN | ((sljit_ins)(elem_size - 1) << 22) | VD(TMP_FREG1) | VN(TMP_FREG1))); + + if (imms >= 0x100) { + ins = (reg_size == 4 && elem_size == 0) ? (1 << 30) : 0; + + do { + FAIL_IF(push_inst(compiler, USRA | ins | ((imms & 0xff) << 16) | VD(TMP_FREG1) | VN(TMP_FREG1))); + imms >>= 8; + } while (imms >= 0x100); + } + + FAIL_IF(push_inst(compiler, USRA | (1 << 30) | (imms << 16) | VD(TMP_FREG1) | VN(TMP_FREG1))); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + ins = (0x1 << 16); + + if (reg_size == 4 && elem_size == 0) { + FAIL_IF(push_inst(compiler, INS_e | (0x3 << 16) | (0x8 << 11) | VD(TMP_FREG1) | VN(TMP_FREG1))); + ins = (0x2 << 16); + } + + FAIL_IF(push_inst(compiler, UMOV | ins | RD(dst_r) | VN(TMP_FREG1))); + + if (dst_r == TMP_REG1) + return emit_op_mem(compiler, STORE | ((type & SLJIT_32) ? INT_SIZE : WORD_SIZE), TMP_REG1, dst, dstw, TMP_REG2); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + switch (SLJIT_SIMD_GET_OPCODE(type)) { + case SLJIT_SIMD_OP2_AND: + ins = AND_v; + break; + case SLJIT_SIMD_OP2_OR: + ins = ORR_v; + break; + case SLJIT_SIMD_OP2_XOR: + ins = EOR_v; + break; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + ins |= (sljit_ins)1 << 30; + + return push_inst(compiler, ins | VD(dst_freg) | VN(src1_freg) | VM(src2_freg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + +#ifdef __ARM_FEATURE_ATOMICS + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + ins = LDR ^ (1 << 30); + break; + case SLJIT_MOV_U16: + ins = LDRH; + break; + case SLJIT_MOV_U8: + ins = LDRB; + break; + default: + ins = LDR; + break; + } +#else /* !__ARM_FEATURE_ATOMICS */ + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + ins = LDXR ^ (1 << 30); + break; + case SLJIT_MOV_U8: + ins = LDXRB; + break; + case SLJIT_MOV_U16: + ins = LDXRH; + break; + default: + ins = LDXR; + break; + } +#endif /* ARM_FEATURE_ATOMICS */ + return push_inst(compiler, ins | RN(mem_reg) | RT(dst_reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_ins ins; + sljit_s32 tmp = temp_reg; + sljit_ins cmp = 0; + sljit_ins inv_bits = W_OP; + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + +#ifdef __ARM_FEATURE_ATOMICS + if (op & SLJIT_SET_ATOMIC_STORED) + cmp = (SUBS ^ W_OP) | RD(TMP_ZERO); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + ins = CAS ^ (1 << 30); + break; + case SLJIT_MOV_U16: + ins = CASH; + break; + case SLJIT_MOV_U8: + ins = CASB; + break; + default: + ins = CAS; + inv_bits = 0; + if (cmp) + cmp ^= W_OP; + break; + } + + if (cmp) { + FAIL_IF(push_inst(compiler, (MOV ^ inv_bits) | RM(temp_reg) | RD(TMP_REG1))); + tmp = TMP_REG1; + } + FAIL_IF(push_inst(compiler, ins | RM(tmp) | RN(mem_reg) | RD(src_reg))); + if (!cmp) + return SLJIT_SUCCESS; + + FAIL_IF(push_inst(compiler, cmp | RM(tmp) | RN(temp_reg))); + FAIL_IF(push_inst(compiler, (CSET ^ inv_bits) | RD(tmp))); + return push_inst(compiler, cmp | RM(tmp) | RN(TMP_ZERO)); +#else /* !__ARM_FEATURE_ATOMICS */ + SLJIT_UNUSED_ARG(tmp); + SLJIT_UNUSED_ARG(inv_bits); + + if (op & SLJIT_SET_ATOMIC_STORED) + cmp = (SUBI ^ W_OP) | (1 << 29); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + ins = STXR ^ (1 << 30); + break; + case SLJIT_MOV_U8: + ins = STXRB; + break; + case SLJIT_MOV_U16: + ins = STXRH; + break; + default: + ins = STXR; + break; + } + + FAIL_IF(push_inst(compiler, ins | RM(TMP_REG1) | RN(mem_reg) | RT(src_reg))); + return cmp ? push_inst(compiler, cmp | RD(TMP_ZERO) | RN(TMP_REG1)) : SLJIT_SUCCESS; +#endif /* __ARM_FEATURE_ATOMICS */ +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) { sljit_s32 dst_reg; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c index 7d6bac077e2..c27c50ddb3a 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c @@ -49,8 +49,20 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15 }; -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { - 0, 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, 6, 7 +static const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = { + 0, + 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, + 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6 +}; + +static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = { + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1 }; #define COPY_BITS(src, from, to, bits) \ @@ -75,13 +87,15 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { (reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7) /* Thumb32 encodings. */ -#define RD4(rd) ((sljit_ins)reg_map[rd] << 8) -#define RN4(rn) ((sljit_ins)reg_map[rn] << 16) #define RM4(rm) ((sljit_ins)reg_map[rm]) +#define RD4(rd) ((sljit_ins)reg_map[rd] << 8) #define RT4(rt) ((sljit_ins)reg_map[rt] << 12) -#define DD4(dd) ((sljit_ins)freg_map[dd] << 12) -#define DN4(dn) ((sljit_ins)freg_map[dn] << 16) -#define DM4(dm) ((sljit_ins)freg_map[dm]) +#define RN4(rn) ((sljit_ins)reg_map[rn] << 16) + +#define VM4(vm) (((sljit_ins)freg_map[vm]) | ((sljit_ins)freg_ebit_map[vm] << 5)) +#define VD4(vd) (((sljit_ins)freg_map[vd] << 12) | ((sljit_ins)freg_ebit_map[vd] << 22)) +#define VN4(vn) (((sljit_ins)freg_map[vn] << 16) | ((sljit_ins)freg_ebit_map[vn] << 7)) + #define IMM5(imm) \ (COPY_BITS(imm, 2, 12, 3) | (((sljit_ins)imm & 0x3) << 6)) #define IMM12(imm) \ @@ -128,9 +142,12 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define EORS 0x4040 #define EOR_W 0xea800000 #define IT 0xbf00 -#define LDR_SP 0x9800 #define LDR 0xf8d00000 +#define LDR_SP 0x9800 #define LDRD 0xe9500000 +#define LDREX 0xe8500f00 +#define LDREXB 0xe8d00f4f +#define LDREXH 0xe8d00f5f #define LDRI 0xf8500800 #define LSLS 0x4080 #define LSLSI 0x0000 @@ -160,6 +177,10 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define POP_W 0xe8bd0000 #define PUSH 0xb400 #define PUSH_W 0xe92d0000 +#define REV 0xba00 +#define REV_W 0xfa90f080 +#define REV16 0xba40 +#define REV16_W 0xfa90f090 #define RBIT 0xfa90f0a0 #define RORS 0x41c0 #define ROR_W 0xfa60f000 @@ -171,8 +192,11 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define SBC_W 0xeb600000 #define SDIV 0xfb90f0f0 #define SMULL 0xfb800000 -#define STRD 0xe9400000 #define STR_SP 0x9000 +#define STRD 0xe9400000 +#define STREX 0xe8400000 +#define STREXB 0xe8c00f40 +#define STREXH 0xe8c00f50 #define SUBS 0x1a00 #define SUBSI3 0x1e00 #define SUBSI8 0x3800 @@ -195,23 +219,57 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define UXTH_W 0xfa1ff080 #define VABS_F32 0xeeb00ac0 #define VADD_F32 0xee300a00 +#define VAND 0xef000110 #define VCMP_F32 0xeeb40a40 #define VCVT_F32_S32 0xeeb80ac0 +#define VCVT_F32_U32 0xeeb80a40 #define VCVT_F64_F32 0xeeb70ac0 #define VCVT_S32_F32 0xeebd0ac0 #define VDIV_F32 0xee800a00 +#define VDUP 0xee800b10 +#define VDUP_s 0xffb00c00 +#define VEOR 0xff000110 +#define VLD1 0xf9200000 +#define VLD1_r 0xf9a00c00 +#define VLD1_s 0xf9a00000 #define VLDR_F32 0xed100a00 #define VMOV_F32 0xeeb00a40 #define VMOV 0xee000a10 #define VMOV2 0xec400a10 +#define VMOV_i 0xef800010 +#define VMOV_s 0xee000b10 +#define VMOVN 0xffb20200 #define VMRS 0xeef1fa10 #define VMUL_F32 0xee200a00 #define VNEG_F32 0xeeb10a40 +#define VORR 0xef200110 #define VPOP 0xecbd0b00 #define VPUSH 0xed2d0b00 +#define VSHLL 0xef800a10 +#define VSHR 0xef800010 +#define VSRA 0xef800110 +#define VST1 0xf9000000 +#define VST1_s 0xf9800000 #define VSTR_F32 0xed000a00 #define VSUB_F32 0xee300a40 +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + +static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32) +{ + if (compiler->scratches == -1) + return 0; + + if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) + fr -= SLJIT_F64_SECOND(0); + + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) + || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); +} + +#endif /* SLJIT_ARGUMENT_CHECKS */ + static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst) { sljit_u16 *ptr; @@ -488,18 +546,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) { switch (feature_type) { case SLJIT_HAS_FPU: + case SLJIT_HAS_F64_AS_F32_PAIR: + case SLJIT_HAS_SIMD: #ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; + return (SLJIT_IS_FPU_AVAILABLE) != 0; #else /* Available by default. */ return 1; #endif + case SLJIT_SIMD_REGS_ARE_PAIRS: case SLJIT_HAS_CLZ: case SLJIT_HAS_CTZ: + case SLJIT_HAS_REV: case SLJIT_HAS_ROT: case SLJIT_HAS_CMOV: case SLJIT_HAS_PREFETCH: + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: + case SLJIT_HAS_ATOMIC: return 1; default: @@ -615,18 +680,17 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s switch (flags & 0xffff) { case SLJIT_CLZ: case SLJIT_CTZ: + case SLJIT_REV: + case SLJIT_REV_U16: + case SLJIT_REV_S16: + case SLJIT_REV_U32: + case SLJIT_REV_S32: case SLJIT_MUL: /* No form with immediate operand. */ break; case SLJIT_MOV: SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG2); return load_immediate(compiler, dst, imm); - case SLJIT_NOT: - if (!(flags & SET_FLAGS)) - return load_immediate(compiler, dst, ~imm); - /* Since the flags should be set, we just fallback to the register mode. - Although some clever things could be done here, "NOT IMM" does not worth the efforts. */ - break; case SLJIT_ADD: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; imm2 = NEGATE(imm); @@ -657,9 +721,14 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s break; case SLJIT_ADDC: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; - imm = get_imm(imm); - if (imm != INVALID_IMM) - return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + imm2 = get_imm(imm); + if (imm2 != INVALID_IMM) + return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2); + if (flags & ARG2_IMM) { + imm = get_imm(~imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + } break; case SLJIT_SUB: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB; @@ -712,9 +781,12 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB; if (flags & ARG1_IMM) break; - imm = get_imm(imm); + imm2 = get_imm(imm); + if (imm2 != INVALID_IMM) + return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2); + imm = get_imm(~imm); if (imm != INVALID_IMM) - return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); break; case SLJIT_AND: imm2 = get_imm(imm); @@ -733,6 +805,11 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s return push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); break; case SLJIT_XOR: + if (imm == (sljit_uw)-1) { + if (IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, MVNS | RD3(dst) | RN3(reg)); + return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(reg)); + } imm = get_imm(imm); if (imm != INVALID_IMM) return push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); @@ -788,8 +865,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s imm = arg2; arg2 = (arg1 == TMP_REG1) ? TMP_REG2 : TMP_REG1; FAIL_IF(load_immediate(compiler, (sljit_s32)arg2, imm)); - } - else { + } else { imm = arg1; arg1 = (arg2 == TMP_REG1) ? TMP_REG2 : TMP_REG1; FAIL_IF(load_immediate(compiler, (sljit_s32)arg1, imm)); @@ -829,11 +905,6 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2)); return push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2)); - case SLJIT_NOT: - SLJIT_ASSERT(arg1 == TMP_REG2); - if (IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, MVNS | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(arg2)); case SLJIT_CLZ: SLJIT_ASSERT(arg1 == TMP_REG2); return push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2)); @@ -841,6 +912,29 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s SLJIT_ASSERT(arg1 == TMP_REG2); FAIL_IF(push_inst32(compiler, RBIT | RN4(arg2) | RD4(dst) | RM4(arg2))); return push_inst32(compiler, CLZ | RN4(dst) | RD4(dst) | RM4(dst)); + case SLJIT_REV: + case SLJIT_REV_U32: + case SLJIT_REV_S32: + SLJIT_ASSERT(arg1 == TMP_REG2); + if (IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, REV | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, REV_W | RN4(arg2) | RD4(dst) | RM4(arg2)); + case SLJIT_REV_U16: + case SLJIT_REV_S16: + SLJIT_ASSERT(arg1 == TMP_REG2 && dst != TMP_REG2); + + flags &= 0xffff; + if (IS_2_LO_REGS(dst, arg2)) + FAIL_IF(push_inst16(compiler, REV16 | RD3(dst) | RN3(arg2))); + else + FAIL_IF(push_inst32(compiler, REV16_W | RN4(arg2) | RD4(dst) | RM4(arg2))); + + if (dst == TMP_REG1 || (arg2 == TMP_REG1 && flags == SLJIT_REV_U16)) + return SLJIT_SUCCESS; + + if (reg_map[dst] <= 7) + return push_inst16(compiler, (flags == SLJIT_REV_U16 ? UXTH : SXTH) | RD3(dst) | RN3(dst)); + return push_inst32(compiler, (flags == SLJIT_REV_U16 ? UXTH_W : SXTH_W) | RD4(dst) | RM4(dst)); case SLJIT_ADD: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; if (IS_3_LO_REGS(dst, arg1, arg2)) @@ -1176,12 +1270,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) { - FAIL_IF(push_inst32(compiler, VPUSH | DD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); + FAIL_IF(push_inst32(compiler, VPUSH | VD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); } else { if (fsaveds > 0) - FAIL_IF(push_inst32(compiler, VPUSH | DD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); + FAIL_IF(push_inst32(compiler, VPUSH | VD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) - FAIL_IF(push_inst32(compiler, VPUSH | DD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); + FAIL_IF(push_inst32(compiler, VPUSH | VD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); } } @@ -1258,17 +1352,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi switch (arg_types & SLJIT_ARG_MASK) { case SLJIT_ARG_TYPE_F64: if (offset != old_offset) - *remap_ptr++ = VMOV_F32 | SLJIT_32 | DD4(offset) | DM4(old_offset); + *remap_ptr++ = VMOV_F32 | SLJIT_32 | VD4(offset) | VM4(old_offset); old_offset++; offset++; break; case SLJIT_ARG_TYPE_F32: if (f32_offset != 0) { - *remap_ptr++ = VMOV_F32 | 0x20 | DD4(offset) | DM4(f32_offset); + *remap_ptr++ = VMOV_F32 | 0x20 | VD4(offset) | VM4(f32_offset); f32_offset = 0; } else { if (offset != old_offset) - *remap_ptr++ = VMOV_F32 | DD4(offset) | DM4(old_offset); + *remap_ptr++ = VMOV_F32 | VD4(offset) | VM4(old_offset); f32_offset = old_offset; old_offset++; } @@ -1356,6 +1450,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); + /* Doubles are saved, so alignment is unaffected. */ if ((size & SSIZE_OF(sw)) != 0 && (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)) size += SSIZE_OF(sw); @@ -1401,12 +1496,12 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit FAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size)); if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) { - FAIL_IF(push_inst32(compiler, VPOP | DD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); + FAIL_IF(push_inst32(compiler, VPOP | VD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); } else { if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) - FAIL_IF(push_inst32(compiler, VPOP | DD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); + FAIL_IF(push_inst32(compiler, VPOP | VD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); if (fsaveds > 0) - FAIL_IF(push_inst32(compiler, VPOP | DD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); + FAIL_IF(push_inst32(compiler, VPOP | VD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); } local_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1) & 0x7; @@ -1705,22 +1800,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile break; case SLJIT_MOV_U8: flags = BYTE_SIZE; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_u8)srcw; break; case SLJIT_MOV_S8: flags = BYTE_SIZE | SIGNED; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_s8)srcw; break; case SLJIT_MOV_U16: flags = HALF_SIZE; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_u16)srcw; break; case SLJIT_MOV_S16: flags = HALF_SIZE | SIGNED; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_s16)srcw; break; default: @@ -1729,7 +1824,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile break; } - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG2, (sljit_uw)srcw)); else if (src & SLJIT_MEM) { FAIL_IF(emit_op_mem(compiler, flags, dst_r, src, srcw, TMP_REG1)); @@ -1745,10 +1840,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2); } + SLJIT_COMPILE_ASSERT(WORD_SIZE == 0, word_size_must_be_0); flags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0; + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) + flags |= HALF_SIZE; + if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1)); + FAIL_IF(emit_op_mem(compiler, flags, TMP_REG1, src, srcw, TMP_REG1)); src = TMP_REG1; } @@ -1778,7 +1877,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile if (dst == TMP_REG1) flags |= UNUSED_RETURN; - if (src1 & SLJIT_IMM) + if (src1 == SLJIT_IMM) flags |= ARG1_IMM; else if (src1 & SLJIT_MEM) { emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1); @@ -1787,7 +1886,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile else src1w = src1; - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) flags |= ARG2_IMM; else if (src2 & SLJIT_MEM) { src2_reg = (!(flags & ARG1_IMM) && (src1w == TMP_REG1)) ? TMP_REG2 : TMP_REG1; @@ -1816,68 +1915,60 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_left; CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); op = GET_OPCODE(op); is_left = (op == SLJIT_SHL || op == SLJIT_MSHL); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); - if (src2 & SLJIT_IMM) { - src2w &= 0x1f; + if (src3 == SLJIT_IMM) { + src3w &= 0x1f; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src2, src2w, TMP_REG2)); - src2 = TMP_REG2; - } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); - src1 = TMP_REG1; - } - - if (src2 & SLJIT_IMM) { - if (reg_map[src_dst] <= 7) - FAIL_IF(push_inst16(compiler, (is_left ? LSLSI : LSRSI) | RD3(src_dst) | RN3(src_dst) | ((sljit_ins)src2w << 6))); + if (IS_2_LO_REGS(dst_reg, src1_reg)) + FAIL_IF(push_inst16(compiler, (is_left ? LSLSI : LSRSI) | RD3(dst_reg) | RN3(src1_reg) | ((sljit_ins)src3w << 6))); else - FAIL_IF(push_inst32(compiler, (is_left ? LSL_WI : LSR_WI) | RD4(src_dst) | RM4(src_dst) | IMM5(src2w))); + FAIL_IF(push_inst32(compiler, (is_left ? LSL_WI : LSR_WI) | RD4(dst_reg) | RM4(src1_reg) | IMM5(src3w))); - src2w = (src2w ^ 0x1f) + 1; - return push_inst32(compiler, ORR_W | RD4(src_dst) | RN4(src_dst) | RM4(src1) | (is_left ? 0x10 : 0x0) | IMM5(src2w)); + src3w = (src3w ^ 0x1f) + 1; + return push_inst32(compiler, ORR_W | RD4(dst_reg) | RN4(dst_reg) | RM4(src2_reg) | (is_left ? 0x10 : 0x0) | IMM5(src3w)); } - if (op == SLJIT_MSHL || op == SLJIT_MLSHR) { - FAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(src2) | 0x1f)); - src2 = TMP_REG2; + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src3, src3w, TMP_REG2)); + src3 = TMP_REG2; } - if (IS_2_LO_REGS(src_dst, src2)) - FAIL_IF(push_inst16(compiler, (is_left ? LSLS : LSRS) | RD3(src_dst) | RN3(src2))); + if (op == SLJIT_MSHL || op == SLJIT_MLSHR || dst_reg == src3) { + FAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(src3) | 0x1f)); + src3 = TMP_REG2; + } + + if (dst_reg == src1_reg && IS_2_LO_REGS(dst_reg, src3)) + FAIL_IF(push_inst16(compiler, (is_left ? LSLS : LSRS) | RD3(dst_reg) | RN3(src3))); else - FAIL_IF(push_inst32(compiler, (is_left ? LSL_W : LSR_W) | RD4(src_dst) | RN4(src_dst) | RM4(src2))); + FAIL_IF(push_inst32(compiler, (is_left ? LSL_W : LSR_W) | RD4(dst_reg) | RN4(src1_reg) | RM4(src3))); - FAIL_IF(push_inst32(compiler, (is_left ? LSR_WI : LSL_WI) | RD4(TMP_REG1) | RM4(src1) | (1 << 6))); - FAIL_IF(push_inst32(compiler, EORI | RD4(TMP_REG2) | RN4(src2) | 0x1f)); + FAIL_IF(push_inst32(compiler, (is_left ? LSR_WI : LSL_WI) | RD4(TMP_REG1) | RM4(src2_reg) | (1 << 6))); + FAIL_IF(push_inst32(compiler, EORI | RD4(TMP_REG2) | RN4(src3) | 0x1f)); FAIL_IF(push_inst32(compiler, (is_left ? LSR_W : LSL_W) | RD4(TMP_REG1) | RN4(TMP_REG1) | RM4(TMP_REG2))); - return push_inst32(compiler, ORR_W | RD4(src_dst) | RN4(src_dst) | RM4(TMP_REG1)); + return push_inst32(compiler, ORR_W | RD4(dst_reg) | RN4(dst_reg) | RM4(TMP_REG1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, @@ -1909,16 +2000,60 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 size, dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + SLJIT_ASSERT(reg_map[TMP_REG2] == 14); + + if (FAST_IS_REG(dst)) + return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2)); + break; + case SLJIT_GET_RETURN_ADDRESS: + size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 0); + + if (compiler->fsaveds > 0 || compiler->fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { + /* The size of pc is not added above. */ + if ((size & SSIZE_OF(sw)) == 0) + size += SSIZE_OF(sw); + + size += GET_SAVED_FLOAT_REGISTERS_SIZE(compiler->fscratches, compiler->fsaveds, f64); + } + + SLJIT_ASSERT(((compiler->local_size + size + SSIZE_OF(sw)) & 0x7) == 0); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + size, TMP_REG1)); + break; + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, TMP_REG1); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return (freg_map[reg] << 1); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type == SLJIT_FLOAT_REGISTER || type == SLJIT_SIMD_REG_64) + return freg_map[reg]; + + if (type != SLJIT_SIMD_REG_128) + return freg_map[reg] & ~0x1; + + return -1; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -1954,35 +2089,35 @@ static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, if ((arg & REG_MASK) && (argw & 0x3) == 0) { if (!(argw & ~0x3fc)) - return push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | DD4(reg) | ((sljit_uw)argw >> 2)); + return push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | VD4(reg) | ((sljit_uw)argw >> 2)); if (!(-argw & ~0x3fc)) - return push_inst32(compiler, inst | RN4(arg & REG_MASK) | DD4(reg) | ((sljit_uw)-argw >> 2)); + return push_inst32(compiler, inst | RN4(arg & REG_MASK) | VD4(reg) | ((sljit_uw)-argw >> 2)); } if (arg & REG_MASK) { if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) { FAIL_IF(compiler->error); - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg)); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | VD4(reg)); } imm = get_imm((sljit_uw)argw & ~(sljit_uw)0x3fc); if (imm != INVALID_IMM) { FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm)); - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2)); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | VD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2)); } imm = get_imm((sljit_uw)-argw & ~(sljit_uw)0x3fc); if (imm != INVALID_IMM) { argw = -argw; FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm)); - return push_inst32(compiler, inst | RN4(TMP_REG1) | DD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2)); + return push_inst32(compiler, inst | RN4(TMP_REG1) | VD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2)); } } FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)argw)); if (arg & REG_MASK) FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, (arg & REG_MASK)))); - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg)); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | VD4(reg)); } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, @@ -1996,41 +2131,53 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp src = TMP_FREG1; } - FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_32) | DD4(TMP_FREG1) | DM4(src))); + FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_32) | VD4(TMP_FREG1) | VM4(src))); if (FAST_IS_REG(dst)) - return push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | DN4(TMP_FREG1)); + return push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | VN4(TMP_FREG1)); /* Store the integer value from a VFP register. */ return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - op ^= SLJIT_32; - if (FAST_IS_REG(src)) - FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | DN4(TMP_FREG1))); + FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | VN4(TMP_FREG1))); else if (src & SLJIT_MEM) { /* Load the integer value into a VFP register. */ FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw)); } else { FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); - FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | DN4(TMP_FREG1))); + FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | VN4(TMP_FREG1))); } - FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_32) | DD4(dst_r) | DM4(TMP_FREG1))); + FAIL_IF(push_inst32(compiler, ins | VD4(dst_r) | VM4(TMP_FREG1))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, (ins & SLJIT_32), TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + return sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_S32 | (~op & SLJIT_32), dst, dstw, src, srcw); +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + return sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_U32 | (~op & SLJIT_32), dst, dstw, src, srcw); +} + static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) @@ -2038,17 +2185,23 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile op ^= SLJIT_32; if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } - FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_32) | DD4(src1) | DM4(src2))); - return push_inst32(compiler, VMRS); + FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_32) | VD4(src1) | VM4(src2))); + FAIL_IF(push_inst32(compiler, VMRS)); + + if (GET_FLAG_TYPE(op) != SLJIT_UNORDERED_OR_EQUAL) + return SLJIT_SUCCESS; + + FAIL_IF(push_inst16(compiler, IT | (0x6 << 4) | 0x8)); + return push_inst16(compiler, CMP /* Rm, Rn = r0 */); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, @@ -2068,7 +2221,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil op ^= SLJIT_32; if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, dst_r, src, srcw); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, dst_r, src, srcw)); src = dst_r; } @@ -2076,19 +2229,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) - FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src))); + FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src))); else dst_r = src; } break; case SLJIT_NEG_F64: - FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src))); + FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src))); break; case SLJIT_ABS_F64: - FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src))); + FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src))); break; case SLJIT_CONV_F64_FROM_F32: - FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src))); + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src))); op ^= SLJIT_32; break; } @@ -2115,27 +2268,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } switch (GET_OPCODE(op)) { case SLJIT_ADD_F64: - FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2))); + FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2))); break; case SLJIT_SUB_F64: - FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2))); + FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2))); break; case SLJIT_MUL_F64: - FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2))); + FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2))); break; case SLJIT_DIV_F64: - FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2))); + FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2))); break; + case SLJIT_COPYSIGN_F64: + FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(src2) | RT4(TMP_REG1) | ((op & SLJIT_32) ? (1 << 7) : 0))); + FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src1))); + FAIL_IF(push_inst32(compiler, CMPI_W | RN4(TMP_REG1) | 0)); + FAIL_IF(push_inst16(compiler, IT | (0xb << 4) | 0x8)); + return push_inst32(compiler, VNEG_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(dst_r)); } if (!(dst & SLJIT_MEM)) @@ -2143,23 +2302,99 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw); } -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { +#if defined(__ARM_NEON) && __ARM_NEON + sljit_u32 exp; + sljit_ins ins; +#endif /* NEON */ + union { + sljit_u32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - SLJIT_ASSERT(reg_map[TMP_REG2] == 14); + u.value = value; - if (FAST_IS_REG(dst)) - return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2)); +#if defined(__ARM_NEON) && __ARM_NEON + if ((u.imm << (32 - 19)) == 0) { + exp = (u.imm >> (23 + 2)) & 0x3f; - /* Memory. */ - return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, TMP_REG1); + if (exp == 0x20 || exp == 0x1f) { + ins = ((u.imm >> 24) & 0x80) | ((u.imm >> 19) & 0x7f); + return push_inst32(compiler, (VMOV_F32 ^ (1 << 6)) | ((ins & 0xf0) << 12) | VD4(freg) | (ins & 0xf)); + } + } +#endif /* NEON */ + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm)); + return push_inst32(compiler, VMOV | VN4(freg) | RT4(TMP_REG1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ +#if defined(__ARM_NEON) && __ARM_NEON + sljit_u32 exp; + sljit_ins ins; +#endif /* NEON */ + union { + sljit_u32 imm[2]; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + +#if defined(__ARM_NEON) && __ARM_NEON + if (u.imm[0] == 0 && (u.imm[1] << (64 - 48)) == 0) { + exp = (u.imm[1] >> ((52 - 32) + 2)) & 0x1ff; + + if (exp == 0x100 || exp == 0xff) { + ins = ((u.imm[1] >> (56 - 32)) & 0x80) | ((u.imm[1] >> (48 - 32)) & 0x7f); + return push_inst32(compiler, (VMOV_F32 ^ (1 << 6)) | (1 << 8) | ((ins & 0xf0) << 12) | VD4(freg) | (ins & 0xf)); + } + } +#endif /* NEON */ + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0])); + if (u.imm[0] == u.imm[1]) + return push_inst32(compiler, VMOV2 | RN4(TMP_REG1) | RT4(TMP_REG1) | VM4(freg)); + + FAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1])); + return push_inst32(compiler, VMOV2 | RN4(TMP_REG2) | RT4(TMP_REG1) | VM4(freg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_s32 reg2; + sljit_ins inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + + inst = VMOV2 | RN4(reg) | RT4(reg2) | VM4(freg); + } else { + inst = VMOV | VN4(freg) | RT4(reg); + + if (!(op & SLJIT_32)) + inst |= 1 << 7; + } + + if (GET_OPCODE(op) == SLJIT_COPY_FROM_F64) + inst |= 1 << 20; + + return push_inst32(compiler, inst); } /* --------------------------------------------------------------------- */ @@ -2170,15 +2405,17 @@ static sljit_uw get_cc(struct sljit_compiler *compiler, sljit_s32 type) { switch (type) { case SLJIT_EQUAL: + case SLJIT_ATOMIC_STORED: case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: - case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */ + case SLJIT_UNORDERED_OR_EQUAL: return 0x0; case SLJIT_NOT_EQUAL: + case SLJIT_ATOMIC_NOT_STORED: case SLJIT_F_NOT_EQUAL: case SLJIT_UNORDERED_OR_NOT_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */ + case SLJIT_ORDERED_NOT_EQUAL: return 0x1; case SLJIT_CARRY: @@ -2453,18 +2690,18 @@ static sljit_s32 hardfloat_call_with_args(struct sljit_compiler *compiler, sljit switch (arg_types & SLJIT_ARG_MASK) { case SLJIT_ARG_TYPE_F64: if (offset != new_offset) - FAIL_IF(push_inst32(compiler, VMOV_F32 | SLJIT_32 | DD4(new_offset) | DM4(offset))); + FAIL_IF(push_inst32(compiler, VMOV_F32 | SLJIT_32 | VD4(new_offset) | VM4(offset))); new_offset++; offset++; break; case SLJIT_ARG_TYPE_F32: if (f32_offset != 0) { - FAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | DD4(f32_offset) | DM4(offset))); + FAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | VD4(f32_offset) | VM4(offset))); f32_offset = 0; } else { if (offset != new_offset) - FAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | DD4(new_offset) | DM4(offset))); + FAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | VD4(new_offset) | VM4(offset))); f32_offset = new_offset; new_offset++; } @@ -2546,7 +2783,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi SLJIT_ASSERT(reg_map[TMP_REG1] != 14); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { if (FAST_IS_REG(src)) { SLJIT_ASSERT(reg_map[src] != 14); return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src)); @@ -2645,8 +2882,8 @@ static SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *com if (FAST_IS_REG(src)) { if (op & SLJIT_32) - return push_inst32(compiler, VMOV | (1 << 20) | DN4(src) | RT4(SLJIT_R0)); - return push_inst32(compiler, VMOV2 | (1 << 20) | DM4(src) | RT4(SLJIT_R0) | RN4(SLJIT_R1)); + return push_inst32(compiler, VMOV | (1 << 20) | VN4(src) | RT4(SLJIT_R0)); + return push_inst32(compiler, VMOV2 | (1 << 20) | VM4(src) | RT4(SLJIT_R0) | RN4(SLJIT_R1)); } SLJIT_SKIP_CHECKS(compiler); @@ -2711,23 +2948,47 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { sljit_uw cc, tmp; CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (src2_reg != dst_reg && src1 == dst_reg) { + src1 = src2_reg; + src1w = 0; + src2_reg = dst_reg; + type ^= 0x1; + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, (src2_reg != dst_reg) ? dst_reg : TMP_REG1, src1, src1w, TMP_REG2)); + + if (src2_reg != dst_reg) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + src1 = TMP_REG1; + src1w = 0; + } + } else if (dst_reg != src2_reg) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(dst_reg, src2_reg))); cc = get_cc(compiler, type & ~SLJIT_32); - if (!(src & SLJIT_IMM)) { + if (src1 != SLJIT_IMM) { FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); - return push_inst16(compiler, MOV | SET_REGS44(dst_reg, src)); + return push_inst16(compiler, MOV | SET_REGS44(dst_reg, src1)); } - tmp = (sljit_uw) srcw; + tmp = (sljit_uw)src1w; if (tmp < 0x10000) { /* set low 16 bits, set hi 16 bits to 0. */ @@ -2736,13 +2997,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil | COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff)); } - tmp = get_imm((sljit_uw)srcw); + tmp = get_imm((sljit_uw)src1w); if (tmp != INVALID_IMM) { FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); return push_inst32(compiler, MOV_WI | RD4(dst_reg) | tmp); } - tmp = get_imm(~(sljit_uw)srcw); + tmp = get_imm(~(sljit_uw)src1w); if (tmp != INVALID_IMM) { FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); return push_inst32(compiler, MVN_WI | RD4(dst_reg) | tmp); @@ -2750,13 +3011,43 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil FAIL_IF(push_inst16(compiler, IT | (cc << 4) | ((cc & 0x1) << 3) | 0x4)); - tmp = (sljit_uw) srcw; + tmp = (sljit_uw)src1w; FAIL_IF(push_inst32(compiler, MOVW | RD4(dst_reg) | COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff))); return push_inst32(compiler, MOVT | RD4(dst_reg) | COPY_BITS(tmp, 12 + 16, 16, 4) | COPY_BITS(tmp, 11 + 16, 26, 1) | COPY_BITS(tmp, 8 + 16, 12, 3) | ((tmp & 0xff0000) >> 16)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + type ^= SLJIT_32; + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst32(compiler, VMOV_F32 | (type & SLJIT_32) | VD4(dst_freg) | VM4(src2_freg))); + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w)); + src1 = TMP_FREG1; + } + + FAIL_IF(push_inst16(compiler, IT | (get_cc(compiler, type & ~SLJIT_32) << 4) | 0x8)); + return push_inst32(compiler, VMOV_F32 | (type & SLJIT_32) | VD4(dst_freg) | VM4(src1)); +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw) @@ -2770,7 +3061,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile if (!(reg & REG_PAIR_MASK)) return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw); - if (type & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32)) { + if (type & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)) { if ((mem & REG_MASK) == 0) { if ((memw & 0xfff) >= (0x1000 - SSIZE_OF(sw))) { imm = get_imm((sljit_uw)((memw + 0x1000) & ~0xfff)); @@ -2781,7 +3072,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile imm = get_imm((sljit_uw)(memw & ~0xfff)); if (imm != INVALID_IMM) - memw &= 0xff; + memw &= 0xfff; } if (imm == INVALID_IMM) { @@ -3058,11 +3349,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil CHECK_ERROR(); CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw)); - if (type & SLJIT_MEM_UNALIGNED_32) + if (type & SLJIT_MEM_ALIGNED_32) return emit_fop_mem(compiler, ((type ^ SLJIT_32) & SLJIT_32) | ((type & SLJIT_MEM_STORE) ? 0 : FPU_LOAD), freg, mem, memw); if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | DN4(freg) | RT4(TMP_REG2))); + FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(freg) | RT4(TMP_REG2))); if (type & SLJIT_32) return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw, TMP_REG1); @@ -3071,13 +3362,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil mem |= SLJIT_MEM; FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw, TMP_REG1)); - FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | DN4(freg) | 0x80 | RT4(TMP_REG2))); + FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(freg) | 0x80 | RT4(TMP_REG2))); return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw + 4, TMP_REG1); } if (type & SLJIT_32) { FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1)); - return push_inst32(compiler, VMOV | DN4(freg) | RT4(TMP_REG2)); + return push_inst32(compiler, VMOV | VN4(freg) | RT4(TMP_REG2)); } FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4)); @@ -3085,11 +3376,715 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1)); FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, mem, memw + 4, TMP_REG1)); - return push_inst32(compiler, VMOV2 | DM4(freg) | RT4(TMP_REG2) | RN4(TMP_REG1)); + return push_inst32(compiler, VMOV2 | VM4(freg) | RT4(TMP_REG2) | RN4(TMP_REG1)); +} + +static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, sljit_s32 *mem_ptr, sljit_sw memw) +{ + sljit_uw imm; + sljit_s32 mem = *mem_ptr; + + if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { + *mem_ptr = TMP_REG1; + return push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(mem & REG_MASK) | RM4(OFFS_REG(mem)) | ((sljit_uw)(memw & 0x3) << 6)); + } + + if (SLJIT_UNLIKELY(!(mem & REG_MASK))) { + *mem_ptr = TMP_REG1; + return load_immediate(compiler, TMP_REG1, (sljit_uw)memw); + } + + mem &= REG_MASK; + + if (memw == 0) { + *mem_ptr = mem; + return SLJIT_SUCCESS; + } + + *mem_ptr = TMP_REG1; + imm = get_imm((sljit_uw)(memw < 0 ? -memw : memw)); + + if (imm != INVALID_IMM) + return push_inst32(compiler, ((memw < 0) ? SUB_WI : ADD_WI) | RD4(TMP_REG1) | RN4(mem) | imm); + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw)); + return push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, mem)); +} + +static SLJIT_INLINE sljit_s32 simd_get_quad_reg_index(sljit_s32 freg) +{ + freg += freg & 0x1; + + SLJIT_ASSERT((freg_map[freg] & 0x1) == (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)); + + if (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS) + freg--; + + return freg; +} + +#define SLJIT_QUAD_OTHER_HALF(freg) ((((freg) & 0x1) << 1) - 1) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (!(srcdst & SLJIT_MEM)) { + if (reg_size == 4) + srcdst = simd_get_quad_reg_index(srcdst); + + if (type & SLJIT_SIMD_STORE) + ins = VD4(srcdst) | VN4(freg) | VM4(freg); + else + ins = VD4(freg) | VN4(srcdst) | VM4(srcdst); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst32(compiler, VORR | ins); + } + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + if (elem_size > 3) + elem_size = 3; + + ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD4(freg) + | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); + + SLJIT_ASSERT(reg_size >= alignment); + + if (alignment == 3) + ins |= 0x10; + else if (alignment >= 4) + ins |= 0x20; + + return push_inst32(compiler, ins | RN4(srcdst) | ((sljit_ins)elem_size) << 6 | 0xf); +} + +static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) +{ + sljit_ins result; + + if (elem_size > 1 && (sljit_u16)value == (value >> 16)) { + elem_size = 1; + value = (sljit_u16)value; + } + + if (elem_size == 1 && (sljit_u8)value == (value >> 8)) { + elem_size = 0; + value = (sljit_u8)value; + } + + switch (elem_size) { + case 0: + SLJIT_ASSERT(value <= 0xff); + result = 0xe00; + break; + case 1: + SLJIT_ASSERT(value <= 0xffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x800; + break; + } + + if ((value & 0xff) == 0) { + value >>= 8; + result |= 0xa00; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value ^= (sljit_uw)0xffff; + result = (1 << 5); + } + break; + default: + SLJIT_ASSERT(value <= 0xffffffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x000; + break; + } + + if ((value & ~(sljit_uw)0xff00) == 0) { + value >>= 8; + result |= 0x200; + break; + } + + if ((value & ~(sljit_uw)0xff0000) == 0) { + value >>= 16; + result |= 0x400; + break; + } + + if ((value & ~(sljit_uw)0xff000000) == 0) { + value >>= 24; + result |= 0x600; + break; + } + + if ((value & (sljit_uw)0xff) == 0xff && (value >> 16) == 0) { + value >>= 8; + result |= 0xc00; + break; + } + + if ((value & (sljit_uw)0xffff) == 0xffff && (value >> 24) == 0) { + value >>= 16; + result |= 0xd00; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value = ~value; + result = (1 << 5); + } + break; + } + + return ((sljit_ins)value & 0xf) | (((sljit_ins)value & 0x70) << 12) | (((sljit_ins)value & 0x80) << 21) | result; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imm; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (src == SLJIT_IMM && srcw == 0) + return push_inst32(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD4(freg)); + + if (SLJIT_UNLIKELY(elem_size == 3)) { + SLJIT_ASSERT(type & SLJIT_SIMD_FLOAT); + + if (src & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, freg, src, srcw)); + src = freg; + } else if (freg != src) + FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (freg != src) + return push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src)); + return SLJIT_SUCCESS; + } + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + + ins = (sljit_ins)(elem_size << 6); + + if (reg_size == 4) + ins |= 1 << 5; + + return push_inst32(compiler, VLD1_r | ins | VD4(freg) | RN4(src) | 0xf); + } + + if (type & SLJIT_SIMD_FLOAT) { + SLJIT_ASSERT(elem_size == 2); + ins = ((sljit_ins)freg_ebit_map[src] << (16 + 2 + 1)) | ((sljit_ins)1 << (16 + 2)); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst32(compiler, VDUP_s | ins | VD4(freg) | (sljit_ins)freg_map[src]); + } + + if (src == SLJIT_IMM) { + if (elem_size < 2) + srcw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + imm = simd_get_imm(elem_size, (sljit_uw)srcw); + + if (imm != ~(sljit_ins)0) { + if (reg_size == 4) + imm |= (sljit_ins)1 << 6; + + return push_inst32(compiler, VMOV_i | imm | VD4(freg)); + } + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); + src = TMP_REG1; + } + + switch (elem_size) { + case 0: + ins = 1 << 22; + break; + case 1: + ins = 1 << 5; + break; + default: + ins = 0; + break; + } + + if (reg_size == 4) + ins |= (sljit_ins)1 << 21; + + return push_inst32(compiler, VDUP | ins | VN4(freg) | RT4(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (type & SLJIT_SIMD_LANE_ZERO) { + ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 6); + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 3 && !(srcdst & SLJIT_MEM)) { + if (lane_index == 1) + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (srcdst != freg) + FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(srcdst) | VM4(srcdst))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst32(compiler, VMOV_i | VD4(freg)); + } + + if (srcdst == freg || (elem_size == 3 && srcdst == (freg + SLJIT_QUAD_OTHER_HALF(freg)))) { + FAIL_IF(push_inst32(compiler, VORR | ins | VD4(TMP_FREG2) | VN4(freg) | VM4(freg))); + srcdst = TMP_FREG2; + srcdstw = 0; + } + } + + FAIL_IF(push_inst32(compiler, VMOV_i | ins | VD4(freg))); + } + + if (reg_size == 4 && lane_index >= (0x8 >> elem_size)) { + lane_index -= (0x8 >> elem_size); + freg += SLJIT_QUAD_OTHER_HALF(freg); + } + + if (srcdst & SLJIT_MEM) { + if (elem_size == 3) + return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, freg, srcdst, srcdstw); + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + lane_index = lane_index << elem_size; + ins = (sljit_ins)((elem_size << 10) | (lane_index << 5)); + return push_inst32(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD4(freg) | RN4(srcdst) | 0xf); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 3) { + if (type & SLJIT_SIMD_STORE) + return push_inst32(compiler, VORR | VD4(srcdst) | VN4(freg) | VM4(freg)); + return push_inst32(compiler, VMOV_F32 | SLJIT_32 | VD4(freg) | VM4(srcdst)); + } + + if (type & SLJIT_SIMD_STORE) { + if (freg_ebit_map[freg] == 0) { + if (lane_index == 1) + freg = SLJIT_F64_SECOND(freg); + + return push_inst32(compiler, VMOV_F32 | VD4(srcdst) | VM4(freg)); + } + + FAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN4(freg) | RT4(TMP_REG1))); + return push_inst32(compiler, VMOV | VN4(srcdst) | RT4(TMP_REG1)); + } + + FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(srcdst) | RT4(TMP_REG1))); + return push_inst32(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN4(freg) | RT4(TMP_REG1)); + } + + if (srcdst == SLJIT_IMM) { + if (elem_size < 2) + srcdstw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcdstw)); + srcdst = TMP_REG1; + } + + if (elem_size == 0) + ins = 0x400000; + else if (elem_size == 1) + ins = 0x20; + else + ins = 0; + + lane_index = lane_index << elem_size; + ins |= (sljit_ins)(((lane_index & 0x4) << 19) | ((lane_index & 0x3) << 5)); + + if (type & SLJIT_SIMD_STORE) { + ins |= (1 << 20); + + if (elem_size < 2 && !(type & SLJIT_SIMD_LANE_SIGNED)) + ins |= (1 << 23); + } + + return push_inst32(compiler, VMOV_s | ins | VN4(freg) | RT4(srcdst)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) { + freg = simd_get_quad_reg_index(freg); + src = simd_get_quad_reg_index(src); + + if (src_lane_index >= (0x8 >> elem_size)) { + src_lane_index -= (0x8 >> elem_size); + src += SLJIT_QUAD_OTHER_HALF(src); + } + } + + if (elem_size == 3) { + if (freg != src) + FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (freg != src) + return push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src)); + return SLJIT_SUCCESS; + } + + ins = ((((sljit_ins)src_lane_index << 1) | 1) << (16 + elem_size)); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst32(compiler, VDUP_s | ins | VD4(freg) | VM4(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_s32 dst_reg; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size != 2 || elem2_size != 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + if (reg_size == 4 && elem2_size - elem_size == 1) + FAIL_IF(push_inst32(compiler, VLD1 | (0x7 << 8) | VD4(freg) | RN4(src) | 0xf)); + else + FAIL_IF(push_inst32(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD4(freg) | RN4(src) | 0xf)); + src = freg; + } else if (reg_size == 4) + src = simd_get_quad_reg_index(src); + + if (!(type & SLJIT_SIMD_FLOAT)) { + dst_reg = (reg_size == 4) ? freg : TMP_FREG2; + + do { + FAIL_IF(push_inst32(compiler, VSHLL | ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0 : (1 << 28)) + | ((sljit_ins)1 << (19 + elem_size)) | VD4(dst_reg) | VM4(src))); + src = dst_reg; + } while (++elem_size < elem2_size); + + if (dst_reg == TMP_FREG2) + return push_inst32(compiler, VORR | VD4(freg) | VN4(TMP_FREG2) | VM4(TMP_FREG2)); + return SLJIT_SUCCESS; + } + + /* No SIMD variant, must use VFP instead. */ + SLJIT_ASSERT(reg_size == 4); + + if (freg == src) { + freg += SLJIT_QUAD_OTHER_HALF(freg); + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src) | 0x20)); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src)); + } + + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src))); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src) | 0x20); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imms; + sljit_s32 dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + switch (elem_size) { + case 0: + imms = 0x243219; + ins = VSHR | (1 << 28) | (0x9 << 16); + break; + case 1: + imms = (reg_size == 4) ? 0x243219 : 0x2231; + ins = VSHR | (1 << 28) | (0x11 << 16); + break; + case 2: + imms = (reg_size == 4) ? 0x2231 : 0x21; + ins = VSHR | (1 << 28) | (0x21 << 16); + break; + default: + imms = 0x21; + ins = VSHR | (1 << 28) | (0x1 << 16) | (1 << 7); + break; + } + + if (reg_size == 4) { + freg = simd_get_quad_reg_index(freg); + ins |= (sljit_ins)1 << 6; + } + + SLJIT_ASSERT((freg_map[TMP_FREG2] & 0x1) == 0); + FAIL_IF(push_inst32(compiler, ins | VD4(TMP_FREG2) | VM4(freg))); + + if (reg_size == 4 && elem_size > 0) + FAIL_IF(push_inst32(compiler, VMOVN | ((sljit_ins)(elem_size - 1) << 18) | VD4(TMP_FREG2) | VM4(TMP_FREG2))); + + ins = (reg_size == 4 && elem_size == 0) ? (1 << 6) : 0; + + while (imms >= 0x100) { + FAIL_IF(push_inst32(compiler, VSRA | (1 << 28) | ins | ((imms & 0xff) << 16) | VD4(TMP_FREG2) | VM4(TMP_FREG2))); + imms >>= 8; + } + + FAIL_IF(push_inst32(compiler, VSRA | (1 << 28) | ins | (1 << 7) | (imms << 16) | VD4(TMP_FREG2) | VM4(TMP_FREG2))); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + FAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RT4(dst_r) | VN4(TMP_FREG2))); + + if (reg_size == 4 && elem_size == 0) { + SLJIT_ASSERT(freg_map[TMP_FREG2] + 1 == freg_map[TMP_FREG1]); + FAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RT4(TMP_REG2)| VN4(TMP_FREG1))); + FAIL_IF(push_inst32(compiler, ORR_W | RD4(dst_r) | RN4(dst_r) | RM4(TMP_REG2) | (0x2 << 12))); + } + + if (dst_r == TMP_REG1) + return emit_op_mem(compiler, STORE | WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + switch (SLJIT_SIMD_GET_OPCODE(type)) { + case SLJIT_SIMD_OP2_AND: + ins = VAND; + break; + case SLJIT_SIMD_OP2_OR: + ins = VORR; + break; + case SLJIT_SIMD_OP2_XOR: + ins = VEOR; + break; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) { + dst_freg = simd_get_quad_reg_index(dst_freg); + src1_freg = simd_get_quad_reg_index(src1_freg); + src2_freg = simd_get_quad_reg_index(src2_freg); + ins |= (sljit_ins)1 << 6; + } + + return push_inst32(compiler, ins | VD4(dst_freg) | VN4(src1_freg) | VM4(src2_freg)); } #undef FPU_LOAD +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV_U8: + ins = LDREXB; + break; + case SLJIT_MOV_U16: + ins = LDREXH; + break; + default: + ins = LDREX; + break; + } + + return push_inst32(compiler, ins | RN4(mem_reg) | RT4(dst_reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_ins ins; + + /* temp_reg == mem_reg is undefined so use another temp register */ + SLJIT_UNUSED_ARG(temp_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV_U8: + ins = STREXB | RM4(TMP_REG1); + break; + case SLJIT_MOV_U16: + ins = STREXH | RM4(TMP_REG1); + break; + default: + ins = STREX | RD4(TMP_REG1); + break; + } + + FAIL_IF(push_inst32(compiler, ins | RN4(mem_reg) | RT4(src_reg))); + if (op & SLJIT_SET_ATOMIC_STORED) + return push_inst32(compiler, CMPI_W | RN4(TMP_REG1)); + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c index e6853c98f67..9620b945f65 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c @@ -26,6 +26,49 @@ /* mips 32-bit arch dependent functions. */ +static sljit_s32 emit_copysign(struct sljit_compiler *compiler, sljit_s32 op, + sljit_sw src1, sljit_sw src2, sljit_sw dst) +{ + int is_32 = (op & SLJIT_32); + sljit_ins mfhc = MFC1, mthc = MTC1; + sljit_ins src1_r = FS(src1), src2_r = FS(src2), dst_r = FS(dst); + + if (!is_32) { + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + mfhc = MFHC1; + mthc = MTHC1; + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + src1_r |= (1 << 11); + src2_r |= (1 << 11); + dst_r |= (1 << 11); + break; + } + } + + FAIL_IF(push_inst(compiler, mfhc | T(TMP_REG1) | src1_r, DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, mfhc | T(TMP_REG2) | src2_r, DR(TMP_REG2))); + if (!is_32 && src1 != dst) + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(src1) | FD(dst), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + else + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + FAIL_IF(push_inst(compiler, XOR | T(TMP_REG1) | D(TMP_REG2) | S(TMP_REG2), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SRL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SLL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, XOR | T(TMP_REG2) | D(TMP_REG1) | S(TMP_REG1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, mthc | T(TMP_REG1) | dst_r, MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + if (mthc == MTC1) + return push_inst(compiler, NOP, UNMOVABLE_INS); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) { if (!(imm & ~0xffff)) @@ -44,6 +87,108 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + struct { +#if defined(SLJIT_LITTLE_ENDIAN) && SLJIT_LITTLE_ENDIAN + sljit_s32 lo; + sljit_s32 hi; +#else /* !SLJIT_LITTLE_ENDIAN */ + sljit_s32 hi; + sljit_s32 lo; +#endif /* SLJIT_LITTLE_ENDIAN */ + } bin; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.bin.lo != 0) + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.bin.lo)); + if (u.bin.hi != 0) + FAIL_IF(load_immediate(compiler, DR(TMP_REG2), u.bin.hi)); + + FAIL_IF(push_inst(compiler, MTC1 | (u.bin.lo != 0 ? T(TMP_REG1) : TA(0)) | FS(freg), MOVABLE_INS)); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + return push_inst(compiler, MTHC1 | (u.bin.hi != 0 ? T(TMP_REG2) : TA(0)) | FS(freg), MOVABLE_INS); +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + FAIL_IF(push_inst(compiler, MTC1 | (u.bin.hi != 0 ? T(TMP_REG2) : TA(0)) | FS(freg) | (1 << 11), MOVABLE_INS)); + break; + } +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_s32 reg2 = 0; + sljit_ins inst = FS(freg); + sljit_ins mthc = MTC1, mfhc = MFC1; + int is_32 = (op & SLJIT_32); + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + op = GET_OPCODE(op); + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + + inst |= T(reg2); + + if (op == SLJIT_COPY_TO_F64) + FAIL_IF(push_inst(compiler, MTC1 | inst, MOVABLE_INS)); + else + FAIL_IF(push_inst(compiler, MFC1 | inst, DR(reg2))); + + inst = FS(freg) | (1 << 11); +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + if (cpu_feature_list & CPU_FEATURE_FR) { + mthc = MTHC1; + mfhc = MFHC1; + inst = FS(freg); + } +#endif /* SLJIT_MIPS_REV >= 2 */ + } + + inst |= T(reg); + if (!is_32 && !reg2) { + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + mthc = MTHC1; + mfhc = MFHC1; + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + inst |= (1 << 11); + break; + } + } + + if (op == SLJIT_COPY_TO_F64) + FAIL_IF(push_inst(compiler, mthc | inst, MOVABLE_INS)); + else + FAIL_IF(push_inst(compiler, mfhc | inst, DR(reg))); + +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + if (mthc == MTC1 || mfhc == MFC1) + return push_inst(compiler, NOP, UNMOVABLE_INS); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins *)addr; @@ -74,6 +219,11 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t sljit_ins ins = NOP; sljit_u8 offsets[4]; sljit_u8 *offsets_ptr = offsets; +#if defined(SLJIT_LITTLE_ENDIAN) && SLJIT_LITTLE_ENDIAN + sljit_ins f64_hi = TA(7), f64_lo = TA(6); +#else + sljit_ins f64_hi = TA(6), f64_lo = TA(7); +#endif /* SLJIT_LITTLE_ENDIAN */ SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12); @@ -138,20 +288,28 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t switch (types & SLJIT_ARG_MASK) { case SLJIT_ARG_TYPE_F64: - if (*offsets_ptr < 4 * sizeof (sljit_sw)) { + if (*offsets_ptr < 4 * sizeof(sljit_sw)) { if (prev_ins != NOP) FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS)); /* Must be preceded by at least one other argument, * and its starting offset must be 8 because of alignment. */ SLJIT_ASSERT((*offsets_ptr >> 2) == 2); - - prev_ins = MFC1 | TA(6) | FS(float_arg_count) | (1 << 11); - ins = MFC1 | TA(7) | FS(float_arg_count); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + prev_ins = MFHC1 | f64_hi | FS(float_arg_count); + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + prev_ins = MFC1 | f64_hi | FS(float_arg_count) | (1 << 11); + break; + } + ins = MFC1 | f64_lo | FS(float_arg_count); } else if (*offsets_ptr < 254) ins = SDC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr); else if (*offsets_ptr == 254) - ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1); + ins = MOV_fmt(FMT_D) | FS(SLJIT_FR0) | FD(TMP_FREG1); float_arg_count--; break; @@ -161,7 +319,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t else if (*offsets_ptr < 254) ins = SWC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr); else if (*offsets_ptr == 254) - ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1); + ins = MOV_fmt(FMT_S) | FS(SLJIT_FR0) | FD(TMP_FREG1); float_arg_count--; break; @@ -285,7 +443,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw)); else if (src != PIC_ADDR_REG) FAIL_IF(push_inst(compiler, ADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG))); diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c index d2a5924f8e9..52a0d3fb7ad 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c @@ -26,6 +26,23 @@ /* mips 64-bit arch dependent functions. */ +static sljit_s32 emit_copysign(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_s32 src2, sljit_s32 dst) +{ + FAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | T(TMP_REG1) | FS(src1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | T(TMP_REG2) | FS(src2), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, XOR | S(TMP_REG2) | T(TMP_REG1) | D(TMP_REG2), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | T(TMP_REG2) | D(TMP_REG1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, SELECT_OP(DMTC1, MTC1) | T(TMP_REG1) | FS(dst), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + if (!(op & SLJIT_32)) + return push_inst(compiler, NOP, UNMOVABLE_INS); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) { sljit_s32 shift = 32; @@ -128,6 +145,57 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_sw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm == 0) { + FAIL_IF(push_inst(compiler, DMTC1 | TA(0) | FS(freg), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + return SLJIT_SUCCESS; + } + + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.imm)); + FAIL_IF(push_inst(compiler, DMTC1 | T(TMP_REG1) | FS(freg), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_ins inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + inst = T(reg) | FS(freg); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) + FAIL_IF(push_inst(compiler, SELECT_OP(DMTC1, MTC1) | inst, MOVABLE_INS)); + else + FAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | inst, DR(reg))); + +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + if (!(op & SLJIT_32)) + return push_inst(compiler, NOP, UNMOVABLE_INS); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins *)addr; @@ -183,17 +251,17 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t switch (types & SLJIT_ARG_MASK) { case SLJIT_ARG_TYPE_F64: if (arg_count != float_arg_count) - ins = MOV_S | FMT_D | FS(float_arg_count) | FD(arg_count); + ins = MOV_fmt(FMT_D) | FS(float_arg_count) | FD(arg_count); else if (arg_count == 1) - ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1); + ins = MOV_fmt(FMT_D) | FS(SLJIT_FR0) | FD(TMP_FREG1); arg_count--; float_arg_count--; break; case SLJIT_ARG_TYPE_F32: if (arg_count != float_arg_count) - ins = MOV_S | FMT_S | FS(float_arg_count) | FD(arg_count); + ins = MOV_fmt(FMT_S) | FS(float_arg_count) | FD(arg_count); else if (arg_count == 1) - ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1); + ins = MOV_fmt(FMT_S) | FS(SLJIT_FR0) | FD(TMP_FREG1); arg_count--; float_arg_count--; break; @@ -300,7 +368,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw)); else if (src != PIC_ADDR_REG) FAIL_IF(push_inst(compiler, DADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG))); diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c index 9afe901c382..807b3474ead 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c @@ -26,9 +26,12 @@ /* Latest MIPS architecture. */ -#ifndef __mips_hard_float +#ifdef HAVE_PRCTL +#include +#endif + +#if !defined(__mips_hard_float) || defined(__mips_single_float) /* Disable automatic detection, covers both -msoft-float and -mno-float */ -#undef SLJIT_IS_FPU_AVAILABLE #define SLJIT_IS_FPU_AVAILABLE 0 #endif @@ -42,6 +45,14 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) return "MIPS64-R6" SLJIT_CPUINFO; #endif /* SLJIT_CONFIG_MIPS_32 */ +#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 5) + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return "MIPS32-R5" SLJIT_CPUINFO; +#else /* !SLJIT_CONFIG_MIPS_32 */ + return "MIPS64-R5" SLJIT_CPUINFO; +#endif /* SLJIT_CONFIG_MIPS_32 */ + #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -83,27 +94,31 @@ typedef sljit_u32 sljit_ins; #define EQUAL_FLAG 3 #define OTHER_FLAG 1 +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = { + 0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31, 3, 1 +}; + #define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) #define TMP_FREG3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3) -static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { - 0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31 -}; - #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { - 0, 0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20, 12, 10, 16 +static const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3) << 1) + 1] = { + 0, + 0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20, + 12, 10, 16, + 1, 15, 3, 5, 7, 9, 19, 31, 29, 27, 25, 23, 21, + 13, 11, 17 }; -#else +#else /* !SLJIT_CONFIG_MIPS_32 */ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 31, 30, 29, 28, 27, 26, 25, 24, 12, 11, 10 }; -#endif +#endif /* SLJIT_CONFIG_MIPS_32 */ /* --------------------------------------------------------------------- */ /* Instrucion forms */ @@ -200,10 +215,18 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define DMULTU (HI(0) | LO(29)) #endif /* SLJIT_MIPS_REV >= 6 */ #define DIV_S (HI(17) | FMT_S | LO(3)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 #define DINSU (HI(31) | LO(6)) +#endif /* SLJIT_MIPS_REV >= 2 */ +#define DMFC1 (HI(17) | (1 << 21)) +#define DMTC1 (HI(17) | (5 << 21)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 #define DROTR (HI(0) | (1 << 21) | LO(58)) #define DROTR32 (HI(0) | (1 << 21) | LO(62)) #define DROTRV (HI(0) | (1 << 6) | LO(22)) +#define DSBH (HI(31) | (2 << 6) | LO(36)) +#define DSHD (HI(31) | (5 << 6) | LO(36)) +#endif /* SLJIT_MIPS_REV >= 2 */ #define DSLL (HI(0) | LO(56)) #define DSLL32 (HI(0) | LO(60)) #define DSLLV (HI(0) | LO(20)) @@ -232,6 +255,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define LWR (HI(38)) #define LWC1 (HI(49)) #define MFC1 (HI(17)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 +#define MFHC1 (HI(17) | (3 << 21)) +#endif /* SLJIT_MIPS_REV >= 2 */ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define MOD (HI(0) | (3 << 6) | LO(26)) #define MODU (HI(0) | (3 << 6) | LO(27)) @@ -239,8 +265,10 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define MFHI (HI(0) | LO(16)) #define MFLO (HI(0) | LO(18)) #endif /* SLJIT_MIPS_REV >= 6 */ -#define MOV_S (HI(17) | FMT_S | LO(6)) #define MTC1 (HI(17) | (4 << 21)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 +#define MTHC1 (HI(17) | (7 << 21)) +#endif /* SLJIT_MIPS_REV >= 2 */ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define MUH (HI(0) | (3 << 6) | LO(24)) #define MUHU (HI(0) | (3 << 6) | LO(25)) @@ -256,8 +284,10 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define NOR (HI(0) | LO(39)) #define OR (HI(0) | LO(37)) #define ORI (HI(13)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 #define ROTR (HI(0) | (1 << 21) | LO(2)) #define ROTRV (HI(0) | (1 << 6) | LO(6)) +#endif /* SLJIT_MIPS_REV >= 2 */ #define SD (HI(63)) #define SDL (HI(44)) #define SDR (HI(45)) @@ -279,6 +309,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define SWR (HI(46)) #define SWC1 (HI(57)) #define TRUNC_W_S (HI(17) | FMT_S | LO(13)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 +#define WSBH (HI(31) | (2 << 6) | LO(32)) +#endif /* SLJIT_MIPS_REV >= 2 */ #define XOR (HI(0) | LO(38)) #define XORI (HI(14)) @@ -289,15 +322,21 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #else /* SLJIT_MIPS_REV < 6 */ #define DCLZ (HI(28) | LO(36)) #define MOVF (HI(0) | (0 << 16) | LO(1)) +#define MOVF_S (HI(17) | FMT_S | (0 << 16) | LO(17)) #define MOVN (HI(0) | LO(11)) +#define MOVN_S (HI(17) | FMT_S | LO(19)) #define MOVT (HI(0) | (1 << 16) | LO(1)) +#define MOVT_S (HI(17) | FMT_S | (1 << 16) | LO(17)) #define MOVZ (HI(0) | LO(10)) +#define MOVZ_S (HI(17) | FMT_S | LO(18)) #define MUL (HI(28) | LO(2)) #endif /* SLJIT_MIPS_REV >= 6 */ #define PREF (HI(51)) #define PREFX (HI(19) | LO(15)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 #define SEB (HI(31) | (16 << 6) | LO(32)) #define SEH (HI(31) | (24 << 6) | LO(32)) +#endif /* SLJIT_MIPS_REV >= 2 */ #endif /* SLJIT_MIPS_REV >= 1 */ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -318,10 +357,107 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define LOAD_W LD #endif +#define MOV_fmt(f) (HI(17) | f | LO(6)) + #define SIMM_MAX (0x7fff) #define SIMM_MIN (-0x8000) #define UIMM_MAX (0xffff) +#define CPU_FEATURE_DETECTED (1 << 0) +#define CPU_FEATURE_FPU (1 << 1) +#define CPU_FEATURE_FP64 (1 << 2) +#define CPU_FEATURE_FR (1 << 3) + +static sljit_u32 cpu_feature_list = 0; + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + && (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + +static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32) +{ + if (compiler->scratches == -1) + return 0; + + if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) + fr -= SLJIT_F64_SECOND(0); + + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) + || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); +} + +#endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_ARGUMENT_CHECKS */ + +static void get_cpu_features(void) +{ +#if !defined(SLJIT_IS_FPU_AVAILABLE) && defined(__GNUC__) + sljit_u32 fir = 0; +#endif /* !SLJIT_IS_FPU_AVAILABLE && __GNUC__ */ + sljit_u32 feature_list = CPU_FEATURE_DETECTED; + +#if defined(SLJIT_IS_FPU_AVAILABLE) +#if SLJIT_IS_FPU_AVAILABLE + feature_list |= CPU_FEATURE_FPU; +#if SLJIT_IS_FPU_AVAILABLE == 64 + feature_list |= CPU_FEATURE_FP64; +#endif /* SLJIT_IS_FPU_AVAILABLE == 64 */ +#endif /* SLJIT_IS_FPU_AVAILABLE */ +#elif defined(__GNUC__) + __asm__ ("cfc1 %0, $0" : "=r"(fir)); + if ((fir & (0x3 << 16)) == (0x3 << 16)) + feature_list |= CPU_FEATURE_FPU; + +#if (defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64) \ + && (!defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV < 2) + if ((feature_list & CPU_FEATURE_FPU)) + feature_list |= CPU_FEATURE_FP64; +#else /* SLJIT_CONFIG_MIPS32 || SLJIT_MIPS_REV >= 2 */ + if ((fir & (1 << 22))) + feature_list |= CPU_FEATURE_FP64; +#endif /* SLJIT_CONFIG_MIPS_64 && SLJIT_MIPS_REV < 2 */ +#endif /* SLJIT_IS_FPU_AVAILABLE */ + + if ((feature_list & CPU_FEATURE_FPU) && (feature_list & CPU_FEATURE_FP64)) { +#if defined(SLJIT_CONFIG_MIPS_32) && SLJIT_CONFIG_MIPS_32 +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 6 + feature_list |= CPU_FEATURE_FR; +#elif defined(SLJIT_DETECT_FR) && SLJIT_DETECT_FR == 0 +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 5 + feature_list |= CPU_FEATURE_FR; +#endif /* SLJIT_MIPS_REV >= 5 */ +#else + sljit_s32 flag = -1; +#ifndef FR_GET_FP_MODE + sljit_f64 zero = 0.0; +#else /* PR_GET_FP_MODE */ + flag = prctl(PR_GET_FP_MODE); + + if (flag > 0) + feature_list |= CPU_FEATURE_FR; +#endif /* FP_GET_PR_MODE */ +#if ((defined(SLJIT_DETECT_FR) && SLJIT_DETECT_FR == 2) \ + || (!defined(PR_GET_FP_MODE) && (!defined(SLJIT_DETECT_FR) || SLJIT_DETECT_FR >= 1))) \ + && (defined(__GNUC__) && (defined(__mips) && __mips >= 2)) + if (flag < 0) { + __asm__ (".set oddspreg\n" + "lwc1 $f17, %0\n" + "ldc1 $f16, %1\n" + "swc1 $f17, %0\n" + : "+m" (flag) : "m" (zero) : "$f16", "$f17"); + if (flag) + feature_list |= CPU_FEATURE_FR; + } +#endif /* (!PR_GET_FP_MODE || (PR_GET_FP_MODE && SLJIT_DETECT_FR == 2)) && __GNUC__ */ +#endif /* SLJIT_MIPS_REV >= 6 */ +#else /* !SLJIT_CONFIG_MIPS_32 */ + /* StatusFR=1 is the only mode supported by the code in MIPS64 */ + feature_list |= CPU_FEATURE_FR; +#endif /* SLJIT_CONFIG_MIPS_32 */ + } + + cpu_feature_list = feature_list; +} + /* dest_reg is the absolute name of the register Useful for reordering instructions in the delay slot. */ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot) @@ -715,21 +851,23 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) { -#if defined(__GNUC__) && !defined(SLJIT_IS_FPU_AVAILABLE) - sljit_sw fir = 0; -#endif /* __GNUC__ && !SLJIT_IS_FPU_AVAILABLE */ - switch (feature_type) { +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + && (!defined(SLJIT_IS_FPU_AVAILABLE) || SLJIT_IS_FPU_AVAILABLE) + case SLJIT_HAS_F64_AS_F32_PAIR: + if (!cpu_feature_list) + get_cpu_features(); + + return (cpu_feature_list & CPU_FEATURE_FR) != 0; +#endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_IS_FPU_AVAILABLE */ case SLJIT_HAS_FPU: -#ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; -#elif defined(__GNUC__) - __asm__ ("cfc1 %0, $0" : "=r"(fir)); - return (fir >> 22) & 0x1; -#else -#error "FIR check is not implemented for this architecture" -#endif + if (!cpu_feature_list) + get_cpu_features(); + + return (cpu_feature_list & CPU_FEATURE_FPU) != 0; case SLJIT_HAS_ZERO_REGISTER: + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: return 1; #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) case SLJIT_HAS_CLZ: @@ -741,6 +879,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) return 2; #endif /* SLJIT_MIPS_REV >= 1 */ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) + case SLJIT_HAS_REV: case SLJIT_HAS_ROT: return 1; #endif /* SLJIT_MIPS_REV >= 2 */ @@ -751,7 +890,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - return (type >= SLJIT_ORDERED_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL); + SLJIT_UNUSED_ARG(type); + return 0; } /* --------------------------------------------------------------------- */ @@ -791,6 +931,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw); static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr); +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define SELECT_OP(a, b) (b) +#else +#define SELECT_OP(a, b) (!(op & SLJIT_32) ? a : b) +#endif + #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #include "sljitNativeMIPS_32.c" #else @@ -815,12 +961,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { if ((local_size & SSIZE_OF(sw)) != 0) local_size += SSIZE_OF(sw); - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; #else - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f; #endif compiler->local_size = local_size; @@ -918,10 +1064,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (word_arg_count == 0 && float_arg_count <= 2) { if (float_arg_count == 1) - FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); } else if (arg_count < 4) { FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS)); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + FAIL_IF(push_inst(compiler, MTHC1 | TA(5 + arg_count) | FS(float_arg_count), MOVABLE_INS)); + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + FAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS)); + break; + } } else FAIL_IF(push_inst(compiler, LDC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS)); arg_count++; @@ -931,7 +1086,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (word_arg_count == 0 && float_arg_count <= 2) { if (float_arg_count == 1) - FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); } else if (arg_count < 4) FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS)); else @@ -966,16 +1121,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi case SLJIT_ARG_TYPE_F64: float_arg_count++; if (arg_count != float_arg_count) - FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(arg_count) | FD(float_arg_count), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS)); else if (arg_count == 1) - FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); break; case SLJIT_ARG_TYPE_F32: float_arg_count++; if (arg_count != float_arg_count) - FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(arg_count) | FD(float_arg_count), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS)); else if (arg_count == 1) - FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); break; default: word_arg_count++; @@ -1011,12 +1166,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { if ((local_size & SSIZE_OF(sw)) != 0) local_size += SSIZE_OF(sw); - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; #else - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f; #endif return SLJIT_SUCCESS; @@ -1042,10 +1197,10 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { if ((tmp & SSIZE_OF(sw)) != 0) tmp += SSIZE_OF(sw); - tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } #else - tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); #endif if (local_size <= SIMM_MAX) { @@ -1138,7 +1293,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c FAIL_IF(emit_stack_frame_release(compiler, 1, &ins)); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS)); return push_inst(compiler, ins, UNMOVABLE_INS); } @@ -1388,16 +1543,12 @@ static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, slji #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#define SELECT_OP(a, b) (b) - #define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \ op_imm = (imm); \ op_v = (v); #else /* !SLJIT_CONFIG_MIPS_32 */ -#define SELECT_OP(a, b) \ - (!(op & SLJIT_32) ? a : b) #define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \ op_dimm = (dimm); \ @@ -1414,10 +1565,10 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj { sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ); #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - sljit_ins max = (op & SLJIT_32) ? 32 : 64; -#else /* !SLJIT_CONFIG_RISCV_64 */ - sljit_ins max = 32; -#endif /* SLJIT_CONFIG_RISCV_64 */ + sljit_ins word_size = (op & SLJIT_32) ? 32 : 64; +#else /* !SLJIT_CONFIG_MIPS_64 */ + sljit_ins word_size = 32; +#endif /* SLJIT_CONFIG_MIPS_64 */ /* The TMP_REG2 is the next value. */ if (src != TMP_REG2) @@ -1425,7 +1576,7 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(is_clz ? 13 : 14), UNMOVABLE_INS)); /* The OTHER_FLAG is the counter. Delay slot. */ - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(max), OTHER_FLAG)); + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(word_size), OTHER_FLAG)); if (!is_clz) { FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG2) | T(TMP_REG1) | IMM(1), DR(TMP_REG1))); @@ -1437,7 +1588,7 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(0), OTHER_FLAG)); /* The TMP_REG1 is the next shift. */ - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(TMP_REG1) | IMM(max), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(TMP_REG1) | IMM(word_size), DR(TMP_REG1))); FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(TMP_REG2) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG)); FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1))); @@ -1459,6 +1610,104 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj #endif /* SLJIT_MIPS_REV < 1 */ +static sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src) +{ +#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64 + int is_32 = (op & SLJIT_32); +#endif /* SLJIT_CONFIG_MIPS_64 */ + + op = GET_OPCODE(op); +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 +#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64 + if (!is_32 && (op == SLJIT_REV)) { + FAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst))); + return push_inst(compiler, DSHD | T(dst) | D(dst), DR(dst)); + } + if (op != SLJIT_REV && src != TMP_REG2) { + FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG1), DR(TMP_REG1))); + src = TMP_REG1; + } +#endif /* SLJIT_CONFIG_MIPS_64 */ + FAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst))); + FAIL_IF(push_inst(compiler, ROTR | T(dst) | D(dst) | SH_IMM(16), DR(dst))); +#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64 + if (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3) + FAIL_IF(push_inst(compiler, DINSU | T(dst) | SA(0) | (31 << 11), DR(dst))); +#endif /* SLJIT_CONFIG_MIPS_64 */ +#else /* SLJIT_MIPS_REV < 2 */ +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (!is_32) { + FAIL_IF(push_inst(compiler, DSRL32 | T(src) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, ORI | SA(0) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG)); + FAIL_IF(push_inst(compiler, DSLL32 | T(src) | D(dst) | SH_IMM(0), DR(dst))); + FAIL_IF(push_inst(compiler, DSLL32 | TA(OTHER_FLAG) | DA(OTHER_FLAG) | SH_IMM(0), OTHER_FLAG)); + FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst))); + + FAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG)); + FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst))); + FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, DSLL | TA(OTHER_FLAG) | DA(EQUAL_FLAG) | SH_IMM(8), EQUAL_FLAG)); + FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); + FAIL_IF(push_inst(compiler, XOR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG)); + FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst))); + + FAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst))); + FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(8), DR(dst))); + return push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)); + } + + if (op != SLJIT_REV && src != TMP_REG2) { + FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG2) | SH_IMM(0), DR(TMP_REG2))); + src = TMP_REG2; + } +#endif /* SLJIT_CONFIG_MIPS_64 */ + + FAIL_IF(push_inst(compiler, SRL | T(src) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, LUI | TA(OTHER_FLAG) | 0xff, OTHER_FLAG)); + FAIL_IF(push_inst(compiler, SLL | T(src) | D(dst) | SH_IMM(16), DR(dst))); + FAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xff, OTHER_FLAG)); + FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst))); + + FAIL_IF(push_inst(compiler, SRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst))); + FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, SLL | T(dst) | D(dst) | SH_IMM(8), DR(dst))); + FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst))); + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3) { + FAIL_IF(push_inst(compiler, DSLL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst))); + FAIL_IF(push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst))); + } +#endif /* SLJIT_CONFIG_MIPS_64 */ +#endif /* SLJIT_MIPR_REV >= 2 */ + return SLJIT_SUCCESS; +} + +static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src) +{ +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 +#if defined(SLJIT_CONFIG_MIPS_32) && SLJIT_CONFIG_MIPS_32 + FAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst))); +#else /* !SLJIT_CONFIG_MIPS_32 */ + FAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst))); +#endif /* SLJIT_CONFIG_MIPS_32 */ + if (GET_OPCODE(op) == SLJIT_REV_U16) + return push_inst(compiler, ANDI | S(dst) | T(dst) | 0xffff, DR(dst)); + else + return push_inst(compiler, SEH | T(dst) | D(dst), DR(dst)); +#else /* SLJIT_MIPS_REV < 2 */ + FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(src) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | T(src) | D(dst) | SH_IMM(24), DR(dst))); + FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG1) | T(TMP_REG1) | 0xff, DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SELECT_OP(DSRL32, SRL) : SELECT_OP(DSRA32, SRA)) | T(dst) | D(dst) | SH_IMM(16), DR(dst))); + return push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)); +#endif /* SLJIT_MIPS_REV >= 2 */ +} + static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_s32 src1, sljit_sw src2) { @@ -1486,17 +1735,17 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); -#else /* SLJIT_MIPS_REV < 1 */ +#else /* SLJIT_MIPS_REV < 2 */ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst))); return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst)); -#endif /* SLJIT_MIPS_REV >= 1 */ +#endif /* SLJIT_MIPS_REV >= 2 */ #else /* !SLJIT_CONFIG_MIPS_32 */ -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) if (op & SLJIT_32) return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); -#endif /* SLJIT_MIPS_REV >= 1 */ +#endif /* SLJIT_MIPS_REV >= 2 */ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst))); return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst)); #endif /* SLJIT_CONFIG_MIPS_32 */ @@ -1515,17 +1764,17 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); -#else /* SLJIT_MIPS_REV < 1 */ +#else /* SLJIT_MIPS_REV < 2 */ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst))); return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst)); -#endif /* SLJIT_MIPS_REV >= 1 */ +#endif /* SLJIT_MIPS_REV >= 2 */ #else /* !SLJIT_CONFIG_MIPS_32 */ -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) if (op & SLJIT_32) return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); -#endif /* SLJIT_MIPS_REV >= 1 */ +#endif /* SLJIT_MIPS_REV >= 2 */ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst))); return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst)); #endif /* SLJIT_CONFIG_MIPS_32 */ @@ -1539,7 +1788,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) if (dst == src2) - return push_inst(compiler, DINSU | T(src2) | SA(0) | (31 << 11) | (0 << 11), DR(dst)); + return push_inst(compiler, DINSU | T(src2) | SA(0) | (31 << 11), DR(dst)); #endif /* SLJIT_MIPS_REV >= 2 */ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst))); return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)); @@ -1556,14 +1805,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return SLJIT_SUCCESS; #endif /* SLJIT_CONFIG_MIPS_64 */ - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (op & SLJIT_SET_Z) - FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (!(flags & UNUSED_DEST)) - FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); - return SLJIT_SUCCESS; - #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) case SLJIT_CLZ: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); @@ -1591,10 +1832,21 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return emit_clz_ctz(compiler, op, dst, src2); #endif /* SLJIT_MIPS_REV >= 1 */ + case SLJIT_REV: + case SLJIT_REV_U32: + case SLJIT_REV_S32: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && src2 != TMP_REG1 && dst != TMP_REG1); + return emit_rev(compiler, op, dst, src2); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + return emit_rev16(compiler, op, dst, src2); + case SLJIT_ADD: /* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */ is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW; - carry_src_ar = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + carry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_overflow) { @@ -1650,7 +1902,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG); case SLJIT_ADDC: - carry_src_ar = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + carry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst))); @@ -1697,11 +1949,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl is_handled = 0; if (flags & SRC2_IMM) { - if (GET_FLAG_TYPE(op) == SLJIT_LESS || GET_FLAG_TYPE(op) == SLJIT_GREATER_EQUAL) { + if (GET_FLAG_TYPE(op) == SLJIT_LESS) { FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG)); is_handled = 1; } - else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS || GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER_EQUAL) { + else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) { FAIL_IF(push_inst(compiler, SLTI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG)); is_handled = 1; } @@ -1718,19 +1970,15 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl switch (GET_FLAG_TYPE(op)) { case SLJIT_LESS: - case SLJIT_GREATER_EQUAL: FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG)); break; case SLJIT_GREATER: - case SLJIT_LESS_EQUAL: FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG)); break; case SLJIT_SIG_LESS: - case SLJIT_SIG_GREATER_EQUAL: FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG)); break; case SLJIT_SIG_GREATER: - case SLJIT_SIG_LESS_EQUAL: FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG)); break; } @@ -1753,7 +2001,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW; - is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_overflow) { @@ -1802,7 +2050,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl flags &= ~SRC2_IMM; } - is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_carry) @@ -1868,6 +2116,14 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return SLJIT_SUCCESS; case SLJIT_XOR: + if (!(flags & LOGICAL_OP)) { + SLJIT_ASSERT((flags & SRC2_IMM) && src2 == -1); + if (op & SLJIT_SET_Z) + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (!(flags & UNUSED_DEST)) + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | D(dst), DR(dst))); + return SLJIT_SUCCESS; + } EMIT_LOGICAL(XORI, XOR); return SLJIT_SUCCESS; @@ -2034,9 +2290,10 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 compiler->cache_argw = 0; } - if (dst == TMP_REG2) { + if (dst == 0) { SLJIT_ASSERT(HAS_FLAGS(op)); flags |= UNUSED_DEST; + dst = TMP_REG2; } else if (FAST_IS_REG(dst)) { dst_r = dst; @@ -2048,10 +2305,10 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 flags |= SLOW_DEST; if (flags & IMM_OP) { - if ((src2 & SLJIT_IMM) && src2w != 0 && CHECK_IMM(flags, src2w)) { + if (src2 == SLJIT_IMM && src2w != 0 && CHECK_IMM(flags, src2w)) { flags |= SRC2_IMM; src2_r = src2w; - } else if ((flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w != 0 && CHECK_IMM(flags, src1w)) { + } else if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && CHECK_IMM(flags, src1w)) { flags |= SRC2_IMM; src2_r = src1w; @@ -2068,7 +2325,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 src1_r = src1; flags |= REG1_SOURCE; } - else if (src1 & SLJIT_IMM) { + else if (src1 == SLJIT_IMM) { if (src1w) { FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); src1_r = TMP_REG1; @@ -2091,7 +2348,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP) dst_r = (sljit_s32)src2_r; } - else if (src2 & SLJIT_IMM) { + else if (src2 == SLJIT_IMM) { if (!(flags & SRC2_IMM)) { if (src2w) { FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w)); @@ -2279,31 +2536,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) case SLJIT_MOV_U32: - return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u32)srcw : srcw); case SLJIT_MOV_S32: case SLJIT_MOV32: - return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw); #endif case SLJIT_MOV_U8: - return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); + return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw); case SLJIT_MOV_S8: - return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); + return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw); case SLJIT_MOV_U16: - return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); + return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw); case SLJIT_MOV_S16: - return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); - - case SLJIT_NOT: - return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_CLZ: case SLJIT_CTZ: + case SLJIT_REV: return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + return emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_REV_U32: + case SLJIT_REV_S32: + return emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); } SLJIT_UNREACHABLE(); @@ -2326,9 +2589,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) if (op & SLJIT_32) { flags |= INT_DATA | SIGNED_DATA; - if (src1 & SLJIT_IMM) + if (src1 == SLJIT_IMM) src1w = (sljit_s32)src1w; - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) src2w = (sljit_s32)src2w; } #endif @@ -2348,9 +2611,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile compiler->status_flags_state = 0; return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); + case SLJIT_XOR: + if ((src1 == SLJIT_IMM && src1w == -1) || (src2 == SLJIT_IMM && src2w == -1)) { + return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + } + /* fallthrough */ case SLJIT_AND: case SLJIT_OR: - case SLJIT_XOR: return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SHL: @@ -2362,10 +2629,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile case SLJIT_ROTL: case SLJIT_ROTR: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) src2w &= 0x1f; #else - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { if (op & SLJIT_32) src2w &= 0x1f; else @@ -2387,7 +2654,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w)); SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w); + return sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w); } #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) @@ -2399,9 +2666,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil #endif /* SLJIT_CONFIG_MIPS_64 */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_left; sljit_ins ins1, ins2, ins3; @@ -2414,50 +2682,44 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * #endif /* SLJIT_CONFIG_MIPS_64 */ CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); - if (src2 & SLJIT_IMM) { - src2w &= bit_length - 1; + if (src3 == SLJIT_IMM) { + src3w &= bit_length - 1; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src2, src2w)); - src2 = TMP_REG2; - } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); - src1 = TMP_REG1; - } - - if (src2 & SLJIT_IMM) { if (is_left) { - ins1 = SELECT_OP3(op, src2w, DSLL, DSLL32, SLL); - src2w = bit_length - src2w; - ins2 = SELECT_OP3(op, src2w, DSRL, DSRL32, SRL); + ins1 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL); + src3w = bit_length - src3w; + ins2 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL); } else { - ins1 = SELECT_OP3(op, src2w, DSRL, DSRL32, SRL); - src2w = bit_length - src2w; - ins2 = SELECT_OP3(op, src2w, DSLL, DSLL32, SLL); + ins1 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL); + src3w = bit_length - src3w; + ins2 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL); } - FAIL_IF(push_inst(compiler, ins1 | T(src_dst) | D(src_dst), DR(src_dst))); - FAIL_IF(push_inst(compiler, ins2 | T(src1) | D(TMP_REG1), DR(TMP_REG1))); - return push_inst(compiler, OR | S(src_dst) | T(TMP_REG1) | D(src_dst), DR(src_dst)); + FAIL_IF(push_inst(compiler, ins1 | T(src1_reg) | D(dst_reg), DR(dst_reg))); + FAIL_IF(push_inst(compiler, ins2 | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1))); + return push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg)); + } + + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src3, src3w)); + src3 = TMP_REG2; + } else if (dst_reg == src3) { + FAIL_IF(push_inst(compiler, SELECT_OP2(op, DADDU, ADDU) | S(src3) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); + src3 = TMP_REG2; } if (is_left) { @@ -2470,17 +2732,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * ins3 = SELECT_OP2(op, DSLLV, SLLV); } - FAIL_IF(push_inst(compiler, ins2 | S(src2) | T(src_dst) | D(src_dst), DR(src_dst))); + FAIL_IF(push_inst(compiler, ins2 | S(src3) | T(src1_reg) | D(dst_reg), DR(dst_reg))); if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) { - FAIL_IF(push_inst(compiler, ins1 | T(src1) | D(TMP_REG1) | (1 << 6), DR(TMP_REG1))); - FAIL_IF(push_inst(compiler, XORI | S(src2) | T(TMP_REG2) | ((sljit_ins)bit_length - 1), DR(TMP_REG2))); - src1 = TMP_REG1; + FAIL_IF(push_inst(compiler, ins1 | T(src2_reg) | D(TMP_REG1) | (1 << 6), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, XORI | S(src3) | T(TMP_REG2) | ((sljit_ins)bit_length - 1), DR(TMP_REG2))); + src2_reg = TMP_REG1; } else - FAIL_IF(push_inst(compiler, SELECT_OP2(op, DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG2), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SELECT_OP2(op, DSUBU, SUBU) | SA(0) | T(src3) | D(TMP_REG2), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, ins3 | S(TMP_REG2) | T(src1) | D(TMP_REG1), DR(TMP_REG1))); - return push_inst(compiler, OR | S(src_dst) | T(TMP_REG1) | D(src_dst), DR(src_dst)); + FAIL_IF(push_inst(compiler, ins3 | S(TMP_REG2) | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1))); + return push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg)); } #undef SELECT_OP3 @@ -2518,21 +2780,54 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 dst_ar = RETURN_ADDR_REG; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + if (FAST_IS_REG(dst)) + return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS); + break; + case SLJIT_GET_RETURN_ADDRESS: + dst_ar = DR(FAST_IS_REG(dst) ? dst : TMP_REG2); + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_ar, SLJIT_MEM1(SLJIT_SP), compiler->local_size - SSIZE_OF(sw))); + break; + } + + if (dst & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw)); + + if (op == SLJIT_FAST_ENTER) + compiler->delay_slot = UNMOVABLE_INS; + } + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type != SLJIT_FLOAT_REGISTER) + return -1; + return FR(reg); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_u32 size) { + SLJIT_UNUSED_ARG(size); + CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -2544,14 +2839,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c /* --------------------------------------------------------------------- */ #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7)) -#define FMT(op) ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) << (21 - 8)) +#define FMT(op) (FMT_S | (~(sljit_ins)op & SLJIT_32) << (21 - (5 + 3))) static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define flags (sljit_u32)0 + sljit_u32 flags = 0; #else sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21; #endif @@ -2565,18 +2860,13 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp if (FAST_IS_REG(dst)) { FAIL_IF(push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) +#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif +#endif /* MIPS III */ return SLJIT_SUCCESS; } - /* Store the integer value from a VFP register. */ return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, FR(TMP_FREG1), dst, dstw, 0, 0); - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# undef flags -#endif } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, @@ -2584,43 +2874,158 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define flags (sljit_u32)0 + sljit_u32 flags = 0; #else sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)) << 21; #endif - sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - if (FAST_IS_REG(src)) { - FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif - } else if (src & SLJIT_MEM) { - /* Load the integer value into a VFP register. */ + if (src & SLJIT_MEM) FAIL_IF(emit_op_mem2(compiler, (flags ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw)); - } else { + if (src == SLJIT_IMM) { #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) - srcw = (sljit_s32)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; #endif - FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); - FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); + src = TMP_REG1; + } + + FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif +#endif /* MIPS III */ } - FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); if (dst & SLJIT_MEM) return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0); return SLJIT_SUCCESS; +} +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# undef flags + sljit_u32 flags = 0; +#else + sljit_u32 flags = 1 << 21; #endif + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_UW ? WORD_DATA : INT_DATA) | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw)); + src = TMP_REG1; + } else if (src == SLJIT_IMM) { +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) + srcw = (sljit_u32)srcw; +#endif + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); + src = TMP_REG1; + } + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) { + if (src != TMP_REG1) { + FAIL_IF(push_inst(compiler, DSLL32 | T(src) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, DSRL32 | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1))); + } + + FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0); + return SLJIT_SUCCESS; + } +#else /* !SLJIT_CONFIG_MIPS_64 */ + if (!(op & SLJIT_32)) { + FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG2) | SH_IMM(1), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SRL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(1), DR(TMP_REG2))); + + FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG2) | FS(TMP_FREG1), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | 1 | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + +#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1) + FAIL_IF(push_inst(compiler, BGEZ | S(src) | 5, UNMOVABLE_INS)); +#else /* SLJIT_MIPS_REV >= 1 */ + FAIL_IF(push_inst(compiler, BGEZ | S(src) | 4, UNMOVABLE_INS)); +#endif /* SLJIT_MIPS_REV < 1 */ + + FAIL_IF(push_inst(compiler, LUI | T(TMP_REG2) | IMM(0x41e0), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, MTC1 | TA(0) | FS(TMP_FREG2), UNMOVABLE_INS)); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + FAIL_IF(push_inst(compiler, MTHC1 | T(TMP_REG2) | FS(TMP_FREG2), UNMOVABLE_INS)); + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(TMP_FREG2) | (1 << 11), UNMOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + break; + } + FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(TMP_FREG2) | FS(dst_r) | FD(dst_r), UNMOVABLE_INS)); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0); + return SLJIT_SUCCESS; + } +#endif /* SLJIT_CONFIG_MIPS_64 */ + +#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1) + FAIL_IF(push_inst(compiler, BLTZ | S(src) | 5, UNMOVABLE_INS)); +#else /* SLJIT_MIPS_REV >= 1 */ + FAIL_IF(push_inst(compiler, BLTZ | S(src) | 4, UNMOVABLE_INS)); +#endif /* SLJIT_MIPS_REV < 1 */ + FAIL_IF(push_inst(compiler, ANDI | S(src) | T(TMP_REG2) | IMM(1), DR(TMP_REG2))); + + FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* !SLJIT_MIPS_REV */ + + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + +#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1) + FAIL_IF(push_inst(compiler, BEQ | 6, UNMOVABLE_INS)); +#else /* SLJIT_MIPS_REV >= 1 */ + FAIL_IF(push_inst(compiler, BEQ | 5, UNMOVABLE_INS)); +#endif /* SLJIT_MIPS_REV < 1 */ + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + FAIL_IF(push_inst(compiler, DSRL | T(src) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1))); +#else /* !SLJIT_CONFIG_MIPS_64 */ + FAIL_IF(push_inst(compiler, SRL | T(src) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1))); +#endif /* SLJIT_CONFIG_MIPS_64 */ + + FAIL_IF(push_inst(compiler, OR | S(TMP_REG1) | T(TMP_REG2) | D(TMP_REG1), DR(TMP_REG1))); + + FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* !SLJIT_MIPS_REV */ + + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(dst_r) | FS(dst_r) | FD(dst_r), UNMOVABLE_INS)); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0); + return SLJIT_SUCCESS; } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, @@ -2642,36 +3047,30 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile switch (GET_FLAG_TYPE(op)) { case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: - case SLJIT_UNORDERED_OR_NOT_EQUAL: inst = C_EQ_S; break; case SLJIT_F_NOT_EQUAL: case SLJIT_UNORDERED_OR_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: inst = C_UEQ_S; break; case SLJIT_F_LESS: case SLJIT_ORDERED_LESS: - case SLJIT_UNORDERED_OR_GREATER_EQUAL: inst = C_OLT_S; break; case SLJIT_F_GREATER_EQUAL: case SLJIT_UNORDERED_OR_LESS: - case SLJIT_ORDERED_GREATER_EQUAL: inst = C_ULT_S; break; case SLJIT_F_GREATER: case SLJIT_ORDERED_GREATER: - case SLJIT_UNORDERED_OR_LESS_EQUAL: inst = C_ULE_S; break; case SLJIT_F_LESS_EQUAL: case SLJIT_UNORDERED_OR_GREATER: - case SLJIT_ORDERED_LESS_EQUAL: inst = C_OLE_S; break; default: - SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_UNORDERED || GET_FLAG_TYPE(op) == SLJIT_ORDERED); + SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_UNORDERED); inst = C_UN_S; break; } @@ -2705,7 +3104,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) - FAIL_IF(push_inst(compiler, MOV_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT(op)) | FS(src) | FD(dst_r), MOVABLE_INS)); else dst_r = src; } @@ -2786,18 +3185,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; + case SLJIT_COPYSIGN_F64: + return emit_copysign(compiler, op, src1, src2, dst_r); } if (dst_r == TMP_FREG2) @@ -2806,26 +3204,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return SLJIT_SUCCESS; } -#undef FLOAT_DATA -#undef FMT - -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { + union { + sljit_s32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - if (FAST_IS_REG(dst)) - return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS); + u.value = value; - /* Memory. */ - FAIL_IF(emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw)); - compiler->delay_slot = UNMOVABLE_INS; - return SLJIT_SUCCESS; + if (u.imm == 0) + return push_inst(compiler, MTC1 | TA(0) | FS(freg), MOVABLE_INS); + + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.imm)); + return push_inst(compiler, MTC1 | T(TMP_REG1) | FS(freg), MOVABLE_INS); } /* --------------------------------------------------------------------- */ @@ -2984,7 +3380,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile } #define RESOLVE_IMM1() \ - if (src1 & SLJIT_IMM) { \ + if (src1 == SLJIT_IMM) { \ if (src1w) { \ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \ src1 = TMP_REG1; \ @@ -2994,7 +3390,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile } #define RESOLVE_IMM2() \ - if (src2 & SLJIT_IMM) { \ + if (src2 == SLJIT_IMM) { \ if (src2w) { \ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \ src2 = TMP_REG2; \ @@ -3046,10 +3442,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2))) jump->flags |= IS_MOVABLE; PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | BRANCH_LENGTH, UNMOVABLE_INS)); - } - else if (type >= SLJIT_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) { + } else if (type >= SLJIT_SIG_LESS && ((src1 == SLJIT_IMM && src1w == 0) || (src2 == SLJIT_IMM && src2w == 0))) { inst = NOP; - if ((src1 & SLJIT_IMM) && (src1w == 0)) { + if (src1 == SLJIT_IMM && src1w == 0) { RESOLVE_IMM2(); switch (type) { case SLJIT_SIG_LESS: @@ -3097,7 +3492,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler else { if (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) { RESOLVE_IMM1(); - if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN) + if (src2 == SLJIT_IMM && src2w <= SIMM_MAX && src2w >= SIMM_MIN) PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1))); else { RESOLVE_IMM2(); @@ -3107,7 +3502,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler } else { RESOLVE_IMM2(); - if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN) + if (src1 == SLJIT_IMM && src1w <= SIMM_MAX && src1w >= SIMM_MIN) PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1))); else { RESOLVE_IMM1(); @@ -3142,9 +3537,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler #undef BR_T #undef BR_F -#undef FLOAT_DATA -#undef FMT - SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump = NULL; @@ -3152,7 +3544,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); FAIL_IF(!jump); set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0)); @@ -3184,8 +3576,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi #endif } - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); - return SLJIT_SUCCESS; + return push_inst(compiler, NOP, UNMOVABLE_INS); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, @@ -3287,50 +3678,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, TMP_REG2, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) + +static sljit_ins get_select_cc(sljit_s32 type, sljit_s32 is_float) { -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) - sljit_ins ins; -#endif /* SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6 */ - - CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); - -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) - - if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (type & SLJIT_32) - srcw = (sljit_s32)srcw; -#endif - FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); - src = TMP_REG1; - srcw = 0; - } - switch (type & ~SLJIT_32) { case SLJIT_EQUAL: - ins = MOVZ | TA(EQUAL_FLAG); - break; + return (is_float ? MOVZ_S : MOVZ) | TA(EQUAL_FLAG); case SLJIT_NOT_EQUAL: - ins = MOVN | TA(EQUAL_FLAG); - break; + return (is_float ? MOVN_S : MOVN) | TA(EQUAL_FLAG); case SLJIT_LESS: case SLJIT_GREATER: case SLJIT_SIG_LESS: case SLJIT_SIG_GREATER: case SLJIT_OVERFLOW: - ins = MOVN | TA(OTHER_FLAG); - break; + case SLJIT_CARRY: + return (is_float ? MOVN_S : MOVN) | TA(OTHER_FLAG); case SLJIT_GREATER_EQUAL: case SLJIT_LESS_EQUAL: case SLJIT_SIG_GREATER_EQUAL: case SLJIT_SIG_LESS_EQUAL: case SLJIT_NOT_OVERFLOW: - ins = MOVZ | TA(OTHER_FLAG); - break; + case SLJIT_NOT_CARRY: + return (is_float ? MOVZ_S : MOVZ) | TA(OTHER_FLAG); case SLJIT_F_EQUAL: case SLJIT_F_LESS: case SLJIT_F_LESS_EQUAL: @@ -3341,8 +3711,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil case SLJIT_UNORDERED_OR_LESS_EQUAL: case SLJIT_ORDERED_LESS_EQUAL: case SLJIT_UNORDERED: - ins = MOVT; - break; + return is_float ? MOVT_S : MOVT; case SLJIT_F_NOT_EQUAL: case SLJIT_F_GREATER_EQUAL: case SLJIT_F_GREATER: @@ -3353,21 +3722,159 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil case SLJIT_ORDERED_GREATER: case SLJIT_UNORDERED_OR_GREATER: case SLJIT_ORDERED: - ins = MOVF; - break; + return is_float ? MOVF_S : MOVF; default: - ins = MOVZ | TA(OTHER_FLAG); SLJIT_UNREACHABLE(); - break; + return (is_float ? MOVZ_S : MOVZ) | TA(OTHER_FLAG); + } +} + +#endif /* SLJIT_MIPS_REV >= 1 */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_reg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) +{ +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + sljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA; + sljit_ins mov_ins = (type & SLJIT_32) ? ADDU : DADDU; +#else /* !SLJIT_CONFIG_MIPS_64 */ + sljit_s32 inp_flags = WORD_DATA | LOAD_DATA; + sljit_ins mov_ins = ADDU; +#endif /* SLJIT_CONFIG_MIPS_64 */ + +#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) + struct sljit_label *label; + struct sljit_jump *jump; +#endif /* !(SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) */ + + CHECK_ERROR(); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); + ADJUST_LOCAL_OFFSET(src1, src1w); + +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src1, src1w)); + src1 = TMP_REG2; + } else if (src1 == SLJIT_IMM) { +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (type & SLJIT_32) + src1w = (sljit_s32)src1w; +#endif + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); + src1 = TMP_REG1; } - return push_inst(compiler, ins | S(src) | D(dst_reg), DR(dst_reg)); + if (dst_reg != src2_reg) { + if (dst_reg == src1) { + src1 = src2_reg; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, mov_ins | S(src2_reg) | TA(0) | D(dst_reg), DR(dst_reg))); + } + + return push_inst(compiler, get_select_cc(type, 0) | S(src1) | D(dst_reg), DR(dst_reg)); #else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */ - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw); + if (dst_reg != src2_reg) { + if (dst_reg == src1) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) { + FAIL_IF(push_inst(compiler, ADDU_W | S(dst_reg) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); + + if ((src1 & REG_MASK) == dst_reg) + src1 = (src1 & ~REG_MASK) | TMP_REG2; + + if (OFFS_REG(src1) == dst_reg) + src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG2); + } + + FAIL_IF(push_inst(compiler, mov_ins | S(src2_reg) | TA(0) | D(dst_reg), DR(dst_reg))); + } + } + + SLJIT_SKIP_CHECKS(compiler); + jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1); + FAIL_IF(!jump); + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, DR(dst_reg), src1, src1w)); + } else if (src1 == SLJIT_IMM) { +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (type & SLJIT_32) + src1w = (sljit_s32)src1w; +#endif /* SLJIT_CONFIG_MIPS_64 */ + FAIL_IF(load_immediate(compiler, DR(dst_reg), src1w)); + } else + FAIL_IF(push_inst(compiler, mov_ins | S(src1) | TA(0) | D(dst_reg), DR(dst_reg))); + + SLJIT_SKIP_CHECKS(compiler); + label = sljit_emit_label(compiler); + FAIL_IF(!label); + + sljit_set_label(jump, label); + return SLJIT_SUCCESS; #endif /* SLJIT_MIPS_REV >= 1 */ } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ +#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) + struct sljit_label *label; + struct sljit_jump *jump; +#endif /* !(SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) */ + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, MOV_fmt(FMT(type)) | FS(src2_freg) | FD(dst_freg), MOVABLE_INS)); + } + +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, FR(TMP_FREG1), src1, src1w)); + src1 = TMP_FREG1; + } + + return push_inst(compiler, get_select_cc(type, 1) | FMT(type) | FS(src1) | FD(dst_freg), MOVABLE_INS); + +#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */ + SLJIT_SKIP_CHECKS(compiler); + jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1); + FAIL_IF(!jump); + + if (src1 & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, FR(dst_freg), src1, src1w)); + else + FAIL_IF(push_inst(compiler, MOV_fmt(FMT(type)) | FS(src1) | FD(dst_freg), MOVABLE_INS)); + + SLJIT_SKIP_CHECKS(compiler); + label = sljit_emit_label(compiler); + FAIL_IF(!label); + + sljit_set_label(jump, label); + return SLJIT_SUCCESS; +#endif /* SLJIT_MIPS_REV >= 1 */ +} + +#undef FLOAT_DATA +#undef FMT + static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s16 max_offset) { sljit_s32 arg = *mem; @@ -3410,21 +3917,33 @@ static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem } #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) -#define MEM16_IMM_FIRST(memw) IMM((memw) + 1) -#define MEM16_IMM_SECOND(memw) IMM(memw) -#define MEMF64_FS_FIRST(freg) FS(freg) -#define MEMF64_FS_SECOND(freg) (FS(freg) | ((sljit_ins)1 << 11)) +#define IMM_LEFT(memw) IMM((memw) + SSIZE_OF(sw) - 1) +#define IMM_RIGHT(memw) IMM(memw) +#define IMM_32_LEFT(memw) IMM((memw) + SSIZE_OF(s32) - 1) +#define IMM_32_RIGHT(memw) IMM(memw) +#define IMM_F64_FIRST_LEFT(memw) IMM((memw) + SSIZE_OF(s32) - 1) +#define IMM_F64_FIRST_RIGHT(memw) IMM(memw) +#define IMM_F64_SECOND_LEFT(memw) IMM((memw) + SSIZE_OF(f64) - 1) +#define IMM_F64_SECOND_RIGHT(memw) IMM((memw) + SSIZE_OF(s32)) +#define IMM_16_FIRST(memw) IMM((memw) + 1) +#define IMM_16_SECOND(memw) IMM(memw) #else /* !SLJIT_LITTLE_ENDIAN */ -#define MEM16_IMM_FIRST(memw) IMM(memw) -#define MEM16_IMM_SECOND(memw) IMM((memw) + 1) -#define MEMF64_FS_FIRST(freg) (FS(freg) | ((sljit_ins)1 << 11)) -#define MEMF64_FS_SECOND(freg) FS(freg) +#define IMM_LEFT(memw) IMM(memw) +#define IMM_RIGHT(memw) IMM((memw) + SSIZE_OF(sw) - 1) +#define IMM_32_LEFT(memw) IMM(memw) +#define IMM_32_RIGHT(memw) IMM((memw) + SSIZE_OF(s32) - 1) +#define IMM_F64_FIRST_LEFT(memw) IMM((memw) + SSIZE_OF(s32)) +#define IMM_F64_FIRST_RIGHT(memw) IMM((memw) + SSIZE_OF(f64) - 1) +#define IMM_F64_SECOND_LEFT(memw) IMM(memw) +#define IMM_F64_SECOND_RIGHT(memw) IMM((memw) + SSIZE_OF(s32) - 1) +#define IMM_16_FIRST(memw) IMM(memw) +#define IMM_16_SECOND(memw) IMM((memw) + 1) #endif /* SLJIT_LITTLE_ENDIAN */ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16)) +#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16)) #else /* !SLJIT_CONFIG_MIPS_32 */ -#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32)) +#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)) #endif /* SLJIT_CONFIG_MIPS_32 */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, @@ -3461,10 +3980,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile ins_right = ((type & SLJIT_MEM_STORE) ? SDR : LDR) | S(mem); #endif /* SLJIT_CONFIG_MIPS_32 */ - FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg)))); - FAIL_IF(push_inst(compiler, ins_right | T(REG_PAIR_FIRST(reg)) | IMM(memw + (SSIZE_OF(sw) - 1)), DR(REG_PAIR_FIRST(reg)))); - FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)))); - return push_inst(compiler, ins_right | T(REG_PAIR_SECOND(reg)) | IMM((memw + 2 * SSIZE_OF(sw) - 1)), DR(REG_PAIR_SECOND(reg))); + FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM_LEFT(memw), DR(REG_PAIR_FIRST(reg)))); + FAIL_IF(push_inst(compiler, ins_right | T(REG_PAIR_FIRST(reg)) | IMM_RIGHT(memw), DR(REG_PAIR_FIRST(reg)))); + FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM_LEFT(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)))); + return push_inst(compiler, ins_right | T(REG_PAIR_SECOND(reg)) | IMM_RIGHT(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))); } #endif /* !(SLJIT_MIPS_REV >= 6) */ @@ -3505,8 +4024,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile if (type & SLJIT_MEM_STORE) { FAIL_IF(push_inst(compiler, SRA_W | T(reg) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(TMP_REG2) | MEM16_IMM_FIRST(memw), MOVABLE_INS)); - return push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(reg) | MEM16_IMM_SECOND(memw), MOVABLE_INS); + FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(TMP_REG2) | IMM_16_FIRST(memw), MOVABLE_INS)); + return push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(reg) | IMM_16_SECOND(memw), MOVABLE_INS); } flags = BYTE_DATA | LOAD_DATA; @@ -3514,15 +4033,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile if (op == SLJIT_MOV_S16) flags |= SIGNED_DATA; - FAIL_IF(push_inst(compiler, data_transfer_insts[flags] | S(mem) | T(TMP_REG2) | MEM16_IMM_FIRST(memw), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA | LOAD_DATA] | S(mem) | T(reg) | MEM16_IMM_SECOND(memw), DR(reg))); + FAIL_IF(push_inst(compiler, data_transfer_insts[flags] | S(mem) | T(TMP_REG2) | IMM_16_FIRST(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA | LOAD_DATA] | S(mem) | T(reg) | IMM_16_SECOND(memw), DR(reg))); FAIL_IF(push_inst(compiler, SLL_W | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2))); return push_inst(compiler, OR | S(reg) | T(TMP_REG2) | D(reg), DR(reg)); case SLJIT_MOV: case SLJIT_MOV_P: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - if (type & SLJIT_MEM_UNALIGNED_32) { + if (type & SLJIT_MEM_ALIGNED_32) { flags = WORD_DATA; if (!(type & SLJIT_MEM_STORE)) flags |= LOAD_DATA; @@ -3534,8 +4053,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2); if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst(compiler, SDL | S(mem) | T(reg) | IMM(memw), MOVABLE_INS)); - return push_inst(compiler, SDR | S(mem) | T(reg) | IMM(memw + 7), MOVABLE_INS); + FAIL_IF(push_inst(compiler, SDL | S(mem) | T(reg) | IMM_LEFT(memw), MOVABLE_INS)); + return push_inst(compiler, SDR | S(mem) | T(reg) | IMM_RIGHT(memw), MOVABLE_INS); } if (mem == reg) { @@ -3543,8 +4062,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile mem = TMP_REG1; } - FAIL_IF(push_inst(compiler, LDL | S(mem) | T(reg) | IMM(memw), DR(reg))); - return push_inst(compiler, LDR | S(mem) | T(reg) | IMM(memw + 7), DR(reg)); + FAIL_IF(push_inst(compiler, LDL | S(mem) | T(reg) | IMM_LEFT(memw), DR(reg))); + return push_inst(compiler, LDR | S(mem) | T(reg) | IMM_RIGHT(memw), DR(reg)); #endif /* SLJIT_CONFIG_MIPS_32 */ } @@ -3552,8 +4071,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2); if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst(compiler, SWL | S(mem) | T(reg) | IMM(memw), MOVABLE_INS)); - return push_inst(compiler, SWR | S(mem) | T(reg) | IMM(memw + 3), MOVABLE_INS); + FAIL_IF(push_inst(compiler, SWL | S(mem) | T(reg) | IMM_32_LEFT(memw), MOVABLE_INS)); + return push_inst(compiler, SWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), MOVABLE_INS); } if (mem == reg) { @@ -3561,18 +4080,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile mem = TMP_REG1; } - FAIL_IF(push_inst(compiler, LWL | S(mem) | T(reg) | IMM(memw), DR(reg))); + FAIL_IF(push_inst(compiler, LWL | S(mem) | T(reg) | IMM_32_LEFT(memw), DR(reg))); #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return push_inst(compiler, LWR | S(mem) | T(reg) | IMM(memw + 3), DR(reg)); + return push_inst(compiler, LWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), DR(reg)); #else /* !SLJIT_CONFIG_MIPS_32 */ - FAIL_IF(push_inst(compiler, LWR | S(mem) | T(reg) | IMM(memw + 3), DR(reg))); + FAIL_IF(push_inst(compiler, LWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), DR(reg))); if (op != SLJIT_MOV_U32) return SLJIT_SUCCESS; #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) - return push_inst(compiler, DINSU | T(reg) | SA(0) | (31 << 11) | (0 << 11), DR(reg)); -#else /* SLJIT_MIPS_REV < 1 */ + return push_inst(compiler, DINSU | T(reg) | SA(0) | (31 << 11), DR(reg)); +#else /* SLJIT_MIPS_REV < 2 */ FAIL_IF(push_inst(compiler, DSLL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg))); return push_inst(compiler, DSRL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg)); #endif /* SLJIT_MIPS_REV >= 2 */ @@ -3595,77 +4114,97 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil if (type & SLJIT_MEM_STORE) { if (type & SLJIT_32) { FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2))); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) +#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif - FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS)); - return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), MOVABLE_INS); +#endif /* MIPS III */ + FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_32_LEFT(memw), MOVABLE_INS)); + return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_32_RIGHT(memw), MOVABLE_INS); } #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | MEMF64_FS_FIRST(freg), DR(TMP_REG2))); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) + FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2))); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_LEFT(memw), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_RIGHT(memw), MOVABLE_INS)); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + FAIL_IF(push_inst(compiler, MFHC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2))); + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg) | (1 << 11), DR(TMP_REG2))); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); #endif - FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), MOVABLE_INS)); + break; + } - FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | MEMF64_FS_SECOND(freg), DR(TMP_REG2))); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif - FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw + 4), MOVABLE_INS)); - return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 7), MOVABLE_INS); + FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_LEFT(memw), MOVABLE_INS)); + return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_RIGHT(memw), MOVABLE_INS); #else /* !SLJIT_CONFIG_MIPS_32 */ - FAIL_IF(push_inst(compiler, MFC1 | (1 << 21) | T(TMP_REG2) | FS(freg), DR(TMP_REG2))); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) + FAIL_IF(push_inst(compiler, DMFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2))); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif - FAIL_IF(push_inst(compiler, SDL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS)); - return push_inst(compiler, SDR | S(mem) | T(TMP_REG2) | IMM(memw + 7), MOVABLE_INS); +#endif /* MIPS III */ + FAIL_IF(push_inst(compiler, SDL | S(mem) | T(TMP_REG2) | IMM_LEFT(memw), MOVABLE_INS)); + return push_inst(compiler, SDR | S(mem) | T(TMP_REG2) | IMM_RIGHT(memw), MOVABLE_INS); #endif /* SLJIT_CONFIG_MIPS_32 */ } if (type & SLJIT_32) { - FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_32_LEFT(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_32_RIGHT(memw), DR(TMP_REG2))); FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) +#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif +#endif /* MIPS III */ return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | MEMF64_FS_FIRST(freg), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_LEFT(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_RIGHT(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw + 4), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 7), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | MEMF64_FS_SECOND(freg), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif + FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_LEFT(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_RIGHT(memw), DR(TMP_REG2))); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + return push_inst(compiler, MTHC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS); +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg) | (1 << 11), MOVABLE_INS)); + break; + } #else /* !SLJIT_CONFIG_MIPS_32 */ - FAIL_IF(push_inst(compiler, LDL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, LDR | S(mem) | T(TMP_REG2) | IMM(memw + 7), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LDL | S(mem) | T(TMP_REG2) | IMM_LEFT(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LDR | S(mem) | T(TMP_REG2) | IMM_RIGHT(memw), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, MTC1 | (1 << 21) | T(TMP_REG2) | FS(freg), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif + FAIL_IF(push_inst(compiler, DMTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS)); #endif /* SLJIT_CONFIG_MIPS_32 */ +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ return SLJIT_SUCCESS; } #endif /* !SLJIT_MIPS_REV || SLJIT_MIPS_REV < 6 */ -#undef MEM16_IMM_FIRST -#undef MEM16_IMM_SECOND -#undef MEMF64_FS_FIRST -#undef MEMF64_FS_SECOND +#undef IMM_16_SECOND +#undef IMM_16_FIRST +#undef IMM_F64_SECOND_RIGHT +#undef IMM_F64_SECOND_LEFT +#undef IMM_F64_FIRST_RIGHT +#undef IMM_F64_FIRST_LEFT +#undef IMM_32_RIGHT +#undef IMM_32_LEFT +#undef IMM_RIGHT +#undef IMM_LEFT #undef MEM_CHECK_UNALIGNED #undef TO_ARGW_HI diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_32.c index 9449e4b9d76..2352fad5d47 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_32.c @@ -85,10 +85,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } return SLJIT_SUCCESS; - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1); - return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); - case SLJIT_CLZ: SLJIT_ASSERT(src1 == TMP_REG1); return push_inst(compiler, CNTLZW | S(src2) | A(dst)); @@ -246,6 +242,10 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(imm))); return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(imm >> 16)); } + if (flags & ALT_FORM4) { + SLJIT_ASSERT(src1 == TMP_REG1); + return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); + } return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_SHL: @@ -325,6 +325,151 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_s32 invert_sign = 1; + + if (src == SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ (sljit_sw)0x80000000)); + src = TMP_REG1; + invert_sign = 0; + } else if (!FAST_IS_REG(src)) { + FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); + src = TMP_REG1; + } + + /* First, a special double precision floating point value is constructed: + (2^53 + (src xor (2^31))) + The upper 32 bits of this number is a constant, and the lower 32 bits + is simply the value of the source argument. The xor 2^31 operation adds + 0x80000000 to the source argument, which moves it into the 0 - 0xffffffff + range. Finally we substract 2^53 + 2^31 to get the converted value. */ + FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330)); + if (invert_sign) + FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000)); + FAIL_IF(push_inst(compiler, STW | S(TMP_REG2) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI)); + FAIL_IF(push_inst(compiler, STW | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, STW | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG2) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + + FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2))); + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r))); + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src == SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } else if (!FAST_IS_REG(src)) { + FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); + src = TMP_REG1; + } + + /* First, a special double precision floating point value is constructed: + (2^53 + src) + The upper 32 bits of this number is a constant, and the lower 32 bits + is simply the value of the source argument. Finally we substract 2^53 + to get the converted value. */ + FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330)); + FAIL_IF(push_inst(compiler, STW | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + FAIL_IF(push_inst(compiler, STW | S(TMP_REG2) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI)); + + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, STW | S(TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG2) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + + FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2))); + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r))); + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_s32 imm[2]; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm[0] != 0) + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0])); + if (u.imm[1] != 0) + FAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1])); + + /* Saved in the same endianness. */ + FAIL_IF(push_inst(compiler, STW | S(u.imm[0] != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, STW | S(u.imm[1] != 0 ? TMP_REG2 : TMP_ZERO) | A(SLJIT_SP) | (TMP_MEM_OFFSET + sizeof(sljit_s32)))); + return push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_s32 reg2 = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (op & SLJIT_32) { + if (op == SLJIT_COPY32_TO_F32) { + FAIL_IF(push_inst(compiler, STW | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, LFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); + } + + FAIL_IF(push_inst(compiler, STFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, LWZ | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET); + } + + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + } + + if (op == SLJIT_COPY_TO_F64) { + FAIL_IF(push_inst(compiler, STW | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI)); + + if (reg2 != 0) + FAIL_IF(push_inst(compiler, STW | S(reg2) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + else + FAIL_IF(push_inst(compiler, STFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + + return push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); + } + + FAIL_IF(push_inst(compiler, STFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + + if (reg2 != 0) + FAIL_IF(push_inst(compiler, LWZ | S(reg2) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + + return push_inst(compiler, LWZ | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI); +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins *)addr; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_64.c index 80549108bfb..b3cf9d074d5 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_64.c @@ -49,7 +49,7 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); - if (!(imm & ~0xffff)) + if (((sljit_uw)imm >> 16) == 0) return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm)); if (imm <= 0x7fffffffl && imm >= -0x80000000l) { @@ -57,6 +57,11 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; } + if (((sljit_uw)imm >> 32) == 0) { + FAIL_IF(push_inst(compiler, ORIS | S(TMP_ZERO) | A(reg) | IMM(imm >> 16))); + return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; + } + /* Count leading zeroes. */ tmp = (sljit_uw)((imm >= 0) ? imm : ~imm); ASM_SLJIT_CLZ(tmp, shift); @@ -198,11 +203,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } return SLJIT_SUCCESS; - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1); - UN_EXTS(); - return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); - case SLJIT_CLZ: SLJIT_ASSERT(src1 == TMP_REG1); return push_inst(compiler, ((flags & ALT_FORM1) ? CNTLZW : CNTLZD) | S(src2) | A(dst)); @@ -399,6 +399,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(imm))); return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(imm >> 16)); } + if (flags & ALT_FORM4) { + SLJIT_ASSERT(src1 == TMP_REG1); + UN_EXTS(); + return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); + } return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_SHL: @@ -563,6 +568,141 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src == SLJIT_IMM) { + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; + + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) { + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1))); + else + FAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); + src = TMP_REG1; + } + + if (FAST_IS_REG(src)) { + FAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + } else + FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1)); + + FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r))); + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) { + if (src == SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_u32)srcw)); + src = TMP_REG1; + } else { + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, CLRLDI(TMP_REG1, src, 32))); + else + FAIL_IF(emit_op_mem(compiler, INT_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); + src = TMP_REG1; + } + + FAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); + } else { + if (src == SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } else if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); + src = TMP_REG1; + } + + FAIL_IF(push_inst(compiler, CMPI | CRD(0 | 1) | A(src) | 0)); + FAIL_IF(push_inst(compiler, BCx | (12 << 21) | (0 << 16) | 20)); + FAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); + FAIL_IF(push_inst(compiler, Bx | ((op & SLJIT_32) ? 36 : 32))); + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, RLWINM | S(src) | A(TMP_REG2) | RLWI_SH(10) | RLWI_MBE(10, 21))); + else + FAIL_IF(push_inst(compiler, ANDI | S(src) | A(TMP_REG2) | 0x1)); + + /* Shift right. */ + FAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(63) | RLDI_MB(1))); + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, RLDICR | S(TMP_REG1) | A(TMP_REG1) | RLDI_SH(0) | RLDI_ME(53))); + + FAIL_IF(push_inst(compiler, OR | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2))); + + FAIL_IF(push_inst(compiler, STD | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); + FAIL_IF(push_inst(compiler, FADD | FD(dst_r) | FA(dst_r) | FB(dst_r))); + } + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r))); + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_sw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm != 0) + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm)); + + FAIL_IF(push_inst(compiler, STD | S(u.imm != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) { + FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? STW : STD) | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, ((op & SLJIT_32) ? LFS : LFD) | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); + } + + FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? STFS : STFD) | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, ((op & SLJIT_32) ? LWZ : LD) | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET); +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins*)addr; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_common.c b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_common.c index f387114733b..54977f02e3e 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_common.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_common.c @@ -132,7 +132,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { OE and Rc flag (see ALT_SET_FLAGS). */ #define OE(flags) ((flags) & ALT_SET_FLAGS) /* Rc flag (see ALT_SET_FLAGS). */ -#define RC(flags) (((flags) & ALT_SET_FLAGS) >> 10) +#define RC(flags) ((sljit_ins)((flags) & ALT_SET_FLAGS) >> 10) #define HI(opcode) ((sljit_ins)(opcode) << 26) #define LO(opcode) ((sljit_ins)(opcode) << 1) @@ -150,6 +150,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define BCx (HI(16)) #define BCCTR (HI(19) | LO(528) | (3 << 11)) #define BLR (HI(19) | LO(16) | (0x14 << 21)) +#if defined(_ARCH_PWR10) && _ARCH_PWR10 +#define BRD (HI(31) | LO(187)) +#endif /* POWER10 */ #define CNTLZD (HI(31) | LO(58)) #define CNTLZW (HI(31) | LO(26)) #define CMP (HI(31) | LO(0)) @@ -183,6 +186,12 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define FSUBS (HI(59) | LO(20)) #define LD (HI(58) | 0) #define LFD (HI(50)) +#define LFS (HI(48)) +#if defined(_ARCH_PWR7) && _ARCH_PWR7 +#define LDBRX (HI(31) | LO(532)) +#endif /* POWER7 */ +#define LHBRX (HI(31) | LO(790)) +#define LWBRX (HI(31) | LO(534)) #define LWZ (HI(32)) #define MFCR (HI(31) | LO(19)) #define MFLR (HI(31) | LO(339) | 0x80000) @@ -219,11 +228,17 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define SRD (HI(31) | LO(539)) #define SRW (HI(31) | LO(536)) #define STD (HI(62) | 0) +#if defined(_ARCH_PWR7) && _ARCH_PWR7 +#define STDBRX (HI(31) | LO(660)) +#endif /* POWER7 */ #define STDU (HI(62) | 1) #define STDUX (HI(31) | LO(181)) #define STFD (HI(54)) #define STFIWX (HI(31) | LO(983)) +#define STFS (HI(52)) +#define STHBRX (HI(31) | LO(918)) #define STW (HI(36)) +#define STWBRX (HI(31) | LO(662)) #define STWU (HI(37)) #define STWUX (HI(31) | LO(183)) #define SUBF (HI(31) | LO(40)) @@ -253,10 +268,24 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) #define SLWI_W(shift) SLWI(shift) +#define TMP_MEM_OFFSET (2 * sizeof(sljit_sw)) #else /* !SLJIT_CONFIG_PPC_32 */ #define SLWI_W(shift) SLDI(shift) +#define TMP_MEM_OFFSET (6 * sizeof(sljit_sw)) #endif /* SLJIT_CONFIG_PPC_32 */ +#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#define TMP_MEM_OFFSET_LO (TMP_MEM_OFFSET) +#define TMP_MEM_OFFSET_HI (TMP_MEM_OFFSET + sizeof(sljit_s32)) +#define LWBRX_FIRST_REG S(TMP_REG1) +#define LWBRX_SECOND_REG S(dst) +#else /* !SLJIT_LITTLE_ENDIAN */ +#define TMP_MEM_OFFSET_LO (TMP_MEM_OFFSET + sizeof(sljit_s32)) +#define TMP_MEM_OFFSET_HI (TMP_MEM_OFFSET) +#define LWBRX_FIRST_REG S(dst) +#define LWBRX_SECOND_REG S(TMP_REG1) +#endif /* SLJIT_LITTLE_ENDIAN */ + #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_uw addr, void* func) { @@ -423,6 +452,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil reverse_buf(compiler); #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) + /* add to compiler->size additional instruction space to hold the trampoline and padding */ #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); #else @@ -623,7 +653,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; - compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins); code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); @@ -641,8 +670,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1); #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) + compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins) + sizeof(struct sljit_function_context); + return code_ptr; #else + compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins); + return code; #endif } @@ -652,12 +685,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) switch (feature_type) { case SLJIT_HAS_FPU: #ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; + return (SLJIT_IS_FPU_AVAILABLE) != 0; #else /* Available by default. */ return 1; #endif - + case SLJIT_HAS_REV: +#if defined(_ARCH_PWR10) && _ARCH_PWR10 + return 1; +#else /* !POWER10 */ + return 2; +#endif /* POWER10 */ /* A saved register is set to a zero value. */ case SLJIT_HAS_ZERO_REGISTER: case SLJIT_HAS_CLZ: @@ -675,7 +713,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - return (type >= SLJIT_UNORDERED && type <= SLJIT_ORDERED_LESS_EQUAL); + switch (type) { + case SLJIT_UNORDERED_OR_EQUAL: + case SLJIT_ORDERED_NOT_EQUAL: + case SLJIT_UNORDERED_OR_LESS: + case SLJIT_ORDERED_GREATER_EQUAL: + case SLJIT_UNORDERED_OR_GREATER: + case SLJIT_ORDERED_LESS_EQUAL: + return 1; + } + + return 0; } /* --------------------------------------------------------------------- */ @@ -699,6 +747,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) #define MEM_MASK 0x7f +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 6)) + /* Other inp_flags. */ /* Integer opertion and set flags -> requires exts on 64 bit systems. */ @@ -722,6 +772,9 @@ ALT_FORM1 0x001000 ... ALT_FORM5 0x010000 */ +static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, + sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg); + #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) #include "sljitNativePPC_32.c" #else @@ -737,16 +790,13 @@ ALT_FORM5 0x010000 */ #endif #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) -#define LR_SAVE_OFFSET 2 * SSIZE_OF(sw) +#define LR_SAVE_OFFSET (2 * SSIZE_OF(sw)) #else #define LR_SAVE_OFFSET SSIZE_OF(sw) #endif #define STACK_MAX_DISTANCE (0x8000 - SSIZE_OF(sw) - LR_SAVE_OFFSET) -static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, - sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg); - SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) @@ -763,7 +813,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 0) - + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); if (!(options & SLJIT_ENTER_REG_ARG)) local_size += SSIZE_OF(sw); @@ -873,7 +923,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 0) - + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); if (!(options & SLJIT_ENTER_REG_ARG)) local_size += SSIZE_OF(sw); @@ -1222,7 +1272,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 src1_r = src1; flags |= REG1_SOURCE; } - else if (src1 & SLJIT_IMM) { + else if (src1 == SLJIT_IMM) { src1_r = TMP_ZERO; if (src1w != 0) { FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); @@ -1242,7 +1292,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P) dst_r = src2_r; } - else if (src2 & SLJIT_IMM) { + else if (src2 == SLJIT_IMM) { src2_r = TMP_ZERO; if (src2w != 0) { FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); @@ -1312,29 +1362,161 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return SLJIT_SUCCESS; } -static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, - sljit_s32 src, sljit_sw srcw) +static sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - if (!(src & OFFS_REG_MASK)) { - if (srcw == 0 && (src & REG_MASK)) - return push_inst(compiler, DCBT | A(0) | B(src & REG_MASK)); + sljit_s32 mem, offs_reg, inp_flags; + sljit_sw memw; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_s32 is_32 = op & SLJIT_32; - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - /* Works with SLJIT_MEM0() case as well. */ - return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1)); + op = GET_OPCODE(op); +#endif /* SLJIT_CONFIG_PPC_64 */ + + if (!((dst | src) & SLJIT_MEM)) { + /* Both are registers. */ + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) { + if (src == dst) { + FAIL_IF(push_inst(compiler, RLWIMI | S(dst) | A(dst) | RLWI_SH(16) | RLWI_MBE(8, 15))); + FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | RLWI_SH(24) | RLWI_MBE(16, 31))); + } else { + FAIL_IF(push_inst(compiler, RLWINM | S(src) | A(dst) | RLWI_SH(8) | RLWI_MBE(16, 23))); + FAIL_IF(push_inst(compiler, RLWIMI | S(src) | A(dst) | RLWI_SH(24) | RLWI_MBE(24, 31))); + } + + if (op == SLJIT_REV_U16) + return SLJIT_SUCCESS; + return push_inst(compiler, EXTSH | S(dst) | A(dst)); + } + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (!is_32) { +#if defined(_ARCH_PWR10) && _ARCH_PWR10 + return push_inst(compiler, BRD | S(src) | A(dst)); +#else /* !POWER10 */ + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(0) | IMM(TMP_MEM_OFFSET_HI))); + FAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(32) | RLDI_MB(32))); + FAIL_IF(push_inst(compiler, STWBRX | S(src) | A(SLJIT_SP) | B(TMP_REG2))); + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(0) | IMM(TMP_MEM_OFFSET_LO))); + FAIL_IF(push_inst(compiler, STWBRX | S(TMP_REG1) | A(SLJIT_SP) | B(TMP_REG2))); + return push_inst(compiler, LD | D(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET); +#endif /* POWER10 */ + } +#endif /* SLJIT_CONFIG_PPC_64 */ + + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(0) | IMM(TMP_MEM_OFFSET))); + FAIL_IF(push_inst(compiler, STWBRX | S(src) | A(SLJIT_SP) | B(TMP_REG2))); + FAIL_IF(push_inst(compiler, LWZ | D(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op == SLJIT_REV_S32) + return push_inst(compiler, EXTSW | S(dst) | A(dst)); +#endif /* SLJIT_CONFIG_PPC_64 */ + return SLJIT_SUCCESS; } - srcw &= 0x3; + mem = src; + memw = srcw; - if (srcw == 0) - return push_inst(compiler, DCBT | A(src & REG_MASK) | B(OFFS_REG(src))); + if (dst & SLJIT_MEM) { + mem = dst; + memw = dstw; - FAIL_IF(push_inst(compiler, SLWI_W(srcw) | S(OFFS_REG(src)) | A(TMP_REG1))); - return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1)); + if (src & SLJIT_MEM) { + inp_flags = HALF_DATA | LOAD_DATA; + + if (op != SLJIT_REV_U16 && op != SLJIT_REV_S16) { +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + inp_flags = (is_32 ? INT_DATA : WORD_DATA) | LOAD_DATA; +#else /* !SLJIT_CONFIG_PPC_64 */ + inp_flags = WORD_DATA | LOAD_DATA; +#endif /* SLJIT_CONFIG_PPC_64 */ + } + + FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src, srcw, TMP_REG2)); + src = TMP_REG1; + } + } + + if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { + offs_reg = OFFS_REG(mem); + mem &= REG_MASK; + memw &= 0x3; + + if (memw != 0) { + FAIL_IF(push_inst(compiler, SLWI_W(memw) | S(offs_reg) | A(TMP_REG2))); + offs_reg = TMP_REG2; + } +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + } else if (memw > 0x7fff7fffl || memw < -0x80000000l) { + FAIL_IF(load_immediate(compiler, TMP_REG2, memw)); + offs_reg = TMP_REG2; + mem &= REG_MASK; +#endif /* SLJIT_CONFIG_PPC_64 */ + } else { + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(mem & REG_MASK) | IMM(memw))); + if (memw > SIMM_MAX || memw < SIMM_MIN) + FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(TMP_REG2) | IMM((memw + 0x8000) >> 16))); + + mem = 0; + offs_reg = TMP_REG2; + } + + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) { + if (dst & SLJIT_MEM) + return push_inst(compiler, STHBRX | S(src) | A(mem) | B(offs_reg)); + + FAIL_IF(push_inst(compiler, LHBRX | S(dst) | A(mem) | B(offs_reg))); + + if (op == SLJIT_REV_U16) + return SLJIT_SUCCESS; + return push_inst(compiler, EXTSH | S(dst) | A(dst)); + } + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (!is_32) { + if (dst & SLJIT_MEM) { +#if defined(_ARCH_PWR7) && _ARCH_PWR7 + return push_inst(compiler, STDBRX | S(src) | A(mem) | B(offs_reg)); +#else /* !POWER7 */ +#if defined(SLJIT_LITTLE_ENDIAN) && SLJIT_LITTLE_ENDIAN + FAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(32) | RLDI_MB(32))); + FAIL_IF(push_inst(compiler, STWBRX | S(TMP_REG1) | A(mem) | B(offs_reg))); + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(offs_reg) | IMM(SSIZE_OF(s32)))); + return push_inst(compiler, STWBRX | S(src) | A(mem) | B(TMP_REG2)); +#else /* !SLJIT_LITTLE_ENDIAN */ + FAIL_IF(push_inst(compiler, STWBRX | S(src) | A(mem) | B(offs_reg))); + FAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(32) | RLDI_MB(32))); + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(offs_reg) | IMM(SSIZE_OF(s32)))); + return push_inst(compiler, STWBRX | S(TMP_REG1) | A(mem) | B(TMP_REG2)); +#endif /* SLJIT_LITTLE_ENDIAN */ +#endif /* POWER7 */ + } +#if defined(_ARCH_PWR7) && _ARCH_PWR7 + return push_inst(compiler, LDBRX | S(dst) | A(mem) | B(offs_reg)); +#else /* !POWER7 */ + FAIL_IF(push_inst(compiler, LWBRX | LWBRX_FIRST_REG | A(mem) | B(offs_reg))); + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(offs_reg) | IMM(SSIZE_OF(s32)))); + FAIL_IF(push_inst(compiler, LWBRX | LWBRX_SECOND_REG | A(mem) | B(TMP_REG2))); + return push_inst(compiler, RLDIMI | S(TMP_REG1) | A(dst) | RLDI_SH(32) | RLDI_MB(0)); +#endif /* POWER7 */ + } +#endif /* SLJIT_CONFIG_PPC_64 */ + + if (dst & SLJIT_MEM) + return push_inst(compiler, STWBRX | S(src) | A(mem) | B(offs_reg)); + + FAIL_IF(push_inst(compiler, LWBRX | S(dst) | A(mem) | B(offs_reg))); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op == SLJIT_REV_S32) + return push_inst(compiler, EXTSW | S(dst) | A(dst)); +#endif /* SLJIT_CONFIG_PPC_64 */ + return SLJIT_SUCCESS; } #define EMIT_MOV(type, type_flags, type_cast) \ - emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw) + emit_op(compiler, (src == SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? type_cast srcw : srcw) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, @@ -1353,19 +1535,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile if (GET_FLAG_TYPE(op_flags) == SLJIT_OVERFLOW) FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); - if (op < SLJIT_NOT && FAST_IS_REG(src) && src == dst) { + if (op <= SLJIT_MOV_P && FAST_IS_REG(src) && src == dst) { if (!TYPE_CAST_NEEDED(op)) return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op_flags & SLJIT_32) { - if (op < SLJIT_NOT) { + if (op <= SLJIT_MOV_P) { if (src & SLJIT_MEM) { if (op == SLJIT_MOV_S32) op = SLJIT_MOV_U32; } - else if (src & SLJIT_IMM) { + else if (src == SLJIT_IMM) { if (op == SLJIT_MOV_U32) op = SLJIT_MOV_S32; } @@ -1410,16 +1592,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile case SLJIT_MOV_S16: return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16)); - case SLJIT_NOT: - return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_CLZ: case SLJIT_CTZ: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - return emit_op(compiler, op, flags | (!(op_flags & SLJIT_32) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); -#else + if (op_flags & SLJIT_32) + flags |= ALT_FORM1; +#endif /* SLJIT_CONFIG_PPC_64 */ return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); -#endif + case SLJIT_REV_U32: + case SLJIT_REV_S32: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + op |= SLJIT_32; +#endif /* SLJIT_CONFIG_PPC_64 */ + /* fallthrough */ + case SLJIT_REV: + case SLJIT_REV_U16: + case SLJIT_REV_S16: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + op |= (op_flags & SLJIT_32); +#endif /* SLJIT_CONFIG_PPC_64 */ + return emit_rev(compiler, op, dst, dstw, src, srcw); } return SLJIT_SUCCESS; @@ -1427,40 +1619,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile #undef EMIT_MOV +/* Macros for checking different operand types / values. */ #define TEST_SL_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN) - + ((src) == SLJIT_IMM && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN) #define TEST_UL_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & ~0xffff)) - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define TEST_SH_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l) -#else -#define TEST_SH_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & 0xffff)) -#endif - + ((src) == SLJIT_IMM && !((srcw) & ~0xffff)) #define TEST_UH_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & ~(sljit_sw)0xffff0000)) + ((src) == SLJIT_IMM && !((srcw) & ~(sljit_sw)0xffff0000)) #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define TEST_SH_IMM(src, srcw) \ + ((src) == SLJIT_IMM && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l) #define TEST_ADD_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l) -#else -#define TEST_ADD_IMM(src, srcw) \ - ((src) & SLJIT_IMM) -#endif - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + ((src) == SLJIT_IMM && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l) #define TEST_UI_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff)) -#else -#define TEST_UI_IMM(src, srcw) \ - ((src) & SLJIT_IMM) -#endif + ((src) == SLJIT_IMM && !((srcw) & ~0xffffffff)) -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define TEST_ADD_FORM1(op) \ (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \ || (op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_32 | SLJIT_SET_Z | SLJIT_SET_CARRY)) @@ -1470,14 +1644,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile #define TEST_SUB_FORM3(op) \ (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \ || (op & (SLJIT_32 | SLJIT_SET_Z)) == (SLJIT_32 | SLJIT_SET_Z)) -#else + +#else /* !SLJIT_CONFIG_PPC_64 */ +#define TEST_SH_IMM(src, srcw) \ + ((src) == SLJIT_IMM && !((srcw) & 0xffff)) +#define TEST_ADD_IMM(src, srcw) \ + ((src) == SLJIT_IMM) +#define TEST_UI_IMM(src, srcw) \ + ((src) == SLJIT_IMM) + #define TEST_ADD_FORM1(op) \ (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW) #define TEST_SUB_FORM2(op) \ (GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) #define TEST_SUB_FORM3(op) \ (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW) -#endif +#endif /* SLJIT_CONFIG_PPC_64 */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, @@ -1496,9 +1678,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile if (op & SLJIT_32) { /* Most operations expect sign extended arguments. */ flags |= INT_DATA | SIGNED_DATA; - if (src1 & SLJIT_IMM) + if (src1 == SLJIT_IMM) src1w = (sljit_s32)(src1w); - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) src2w = (sljit_s32)(src2w); if (HAS_FLAGS(op)) flags |= ALT_SIGN_EXT; @@ -1514,7 +1696,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile if (TEST_ADD_FORM1(op)) return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w); - if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { + if (!HAS_FLAGS(op) && (src1 == SLJIT_IMM || src2 == SLJIT_IMM)) { if (TEST_SL_IMM(src2, src2w)) { compiler->imm = (sljit_ins)src2w & 0xffff; return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); @@ -1565,7 +1747,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); } } - return emit_op(compiler, SLJIT_ADD, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, SLJIT_ADD, flags | ((GET_FLAG_TYPE(op) == SLJIT_CARRY) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); case SLJIT_ADDC: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; @@ -1583,7 +1765,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w); } - if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= (SIMM_MAX + 1)) { + if (src2 == SLJIT_IMM && src2w >= 0 && src2w <= (SIMM_MAX + 1)) { compiler->imm = (sljit_ins)src2w; return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } @@ -1599,7 +1781,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile } if (TEST_SUB_FORM2(op)) { - if ((src2 & SLJIT_IMM) && src2w >= -SIMM_MAX && src2w <= SIMM_MAX) { + if (src2 == SLJIT_IMM && src2w >= -SIMM_MAX && src2w <= SIMM_MAX) { compiler->imm = (sljit_ins)src2w & 0xffff; return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); } @@ -1632,7 +1814,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile } /* We know ALT_SIGN_EXT is set if it is an SLJIT_32 on 64 bit systems. */ - return emit_op(compiler, SLJIT_SUB, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, SLJIT_SUB, flags | ((GET_FLAG_TYPE(op) == SLJIT_CARRY) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUBC: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB; @@ -1657,9 +1839,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w); + case SLJIT_XOR: + if (src2 == SLJIT_IMM && src2w == -1) { + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM4, dst, dstw, TMP_REG1, 0, src1, src1w); + } + if (src1 == SLJIT_IMM && src1w == -1) { + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM4, dst, dstw, TMP_REG1, 0, src2, src2w); + } + /* fallthrough */ case SLJIT_AND: case SLJIT_OR: - case SLJIT_XOR: /* Commutative unsigned operations. */ if (!HAS_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) { if (TEST_UL_IMM(src2, src2w)) { @@ -1704,7 +1893,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile if (op & SLJIT_32) flags |= ALT_FORM2; #endif - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { compiler->imm = (sljit_ins)src2w; return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } @@ -1730,9 +1919,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil #undef TEST_SUB_FORM3 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_right; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -1744,85 +1934,97 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * #endif /* SLJIT_CONFIG_PPC_64 */ CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); is_right = (GET_OPCODE(op) == SLJIT_LSHR || GET_OPCODE(op) == SLJIT_MLSHR); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); - if (src2 & SLJIT_IMM) { - src2w &= bit_length - 1; + if (src3 == SLJIT_IMM) { + src3w &= bit_length - 1; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src2, src2w, TMP_REG2)); - src2 = TMP_REG2; - } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src1, src1w, TMP_REG1)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); - src1 = TMP_REG1; - } - - if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (!(op & SLJIT_32)) { if (is_right) { - FAIL_IF(push_inst(compiler, SRDI(src2w) | S(src_dst) | A(src_dst))); - return push_inst(compiler, RLDIMI | S(src1) | A(src_dst) | RLDI_SH(64 - src2w) | RLDI_MB(0)); + FAIL_IF(push_inst(compiler, SRDI(src3w) | S(src1_reg) | A(dst_reg))); + return push_inst(compiler, RLDIMI | S(src2_reg) | A(dst_reg) | RLDI_SH(64 - src3w) | RLDI_MB(0)); } - FAIL_IF(push_inst(compiler, SLDI(src2w) | S(src_dst) | A(src_dst))); + FAIL_IF(push_inst(compiler, SLDI(src3w) | S(src1_reg) | A(dst_reg))); /* Computes SRDI(64 - src2w). */ - FAIL_IF(push_inst(compiler, RLDICL | S(src1) | A(TMP_REG1) | RLDI_SH(src2w) | RLDI_MB(64 - src2w))); - return push_inst(compiler, OR | S(src_dst) | A(src_dst) | B(TMP_REG1)); + FAIL_IF(push_inst(compiler, RLDICL | S(src2_reg) | A(TMP_REG1) | RLDI_SH(src3w) | RLDI_MB(64 - src3w))); + return push_inst(compiler, OR | S(dst_reg) | A(dst_reg) | B(TMP_REG1)); } #endif /* SLJIT_CONFIG_PPC_64 */ if (is_right) { - FAIL_IF(push_inst(compiler, SRWI(src2w) | S(src_dst) | A(src_dst))); - return push_inst(compiler, RLWIMI | S(src1) | A(src_dst) | RLWI_SH(32 - src2w) | RLWI_MBE(0, src2w - 1)); + FAIL_IF(push_inst(compiler, SRWI(src3w) | S(src1_reg) | A(dst_reg))); + return push_inst(compiler, RLWIMI | S(src2_reg) | A(dst_reg) | RLWI_SH(32 - src3w) | RLWI_MBE(0, src3w - 1)); } - FAIL_IF(push_inst(compiler, SLWI(src2w) | S(src_dst) | A(src_dst))); - return push_inst(compiler, RLWIMI | S(src1) | A(src_dst) | RLWI_SH(src2w) | RLWI_MBE(32 - src2w, 31)); + FAIL_IF(push_inst(compiler, SLWI(src3w) | S(src1_reg) | A(dst_reg))); + return push_inst(compiler, RLWIMI | S(src2_reg) | A(dst_reg) | RLWI_SH(src3w) | RLWI_MBE(32 - src3w, 31)); + } + + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src3, src3w, TMP_REG2)); + src3 = TMP_REG2; } #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (!(op & SLJIT_32)) { - if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR) { - FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x3f)); - src2 = TMP_REG2; + if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR || dst_reg == src3) { + FAIL_IF(push_inst(compiler, ANDI | S(src3) | A(TMP_REG2) | 0x3f)); + src3 = TMP_REG2; } - FAIL_IF(push_inst(compiler, (is_right ? SRD : SLD) | S(src_dst) | A(src_dst) | B(src2))); - FAIL_IF(push_inst(compiler, (is_right ? SLDI(1) : SRDI(1)) | S(src1) | A(TMP_REG1))); - FAIL_IF(push_inst(compiler, XORI | S(src2) | A(TMP_REG2) | 0x3f)); + FAIL_IF(push_inst(compiler, (is_right ? SRD : SLD) | S(src1_reg) | A(dst_reg) | B(src3))); + FAIL_IF(push_inst(compiler, (is_right ? SLDI(1) : SRDI(1)) | S(src2_reg) | A(TMP_REG1))); + FAIL_IF(push_inst(compiler, XORI | S(src3) | A(TMP_REG2) | 0x3f)); FAIL_IF(push_inst(compiler, (is_right ? SLD : SRD) | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2))); - return push_inst(compiler, OR | S(src_dst) | A(src_dst) | B(TMP_REG1)); + return push_inst(compiler, OR | S(dst_reg) | A(dst_reg) | B(TMP_REG1)); } #endif /* SLJIT_CONFIG_PPC_64 */ - if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR) { - FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f)); - src2 = TMP_REG2; + if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR || dst_reg == src3) { + FAIL_IF(push_inst(compiler, ANDI | S(src3) | A(TMP_REG2) | 0x1f)); + src3 = TMP_REG2; } - FAIL_IF(push_inst(compiler, (is_right ? SRW : SLW) | S(src_dst) | A(src_dst) | B(src2))); - FAIL_IF(push_inst(compiler, (is_right ? SLWI(1) : SRWI(1)) | S(src1) | A(TMP_REG1))); - FAIL_IF(push_inst(compiler, XORI | S(src2) | A(TMP_REG2) | 0x1f)); + FAIL_IF(push_inst(compiler, (is_right ? SRW : SLW) | S(src1_reg) | A(dst_reg) | B(src3))); + FAIL_IF(push_inst(compiler, (is_right ? SLWI(1) : SRWI(1)) | S(src2_reg) | A(TMP_REG1))); + FAIL_IF(push_inst(compiler, XORI | S(src3) | A(TMP_REG2) | 0x1f)); FAIL_IF(push_inst(compiler, (is_right ? SLW : SRW) | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2))); - return push_inst(compiler, OR | S(src_dst) | A(src_dst) | B(TMP_REG1)); + return push_inst(compiler, OR | S(dst_reg) | A(dst_reg) | B(TMP_REG1)); +} + +static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, + sljit_s32 src, sljit_sw srcw) +{ + if (!(src & OFFS_REG_MASK)) { + if (srcw == 0 && (src & REG_MASK)) + return push_inst(compiler, DCBT | A(0) | B(src & REG_MASK)); + + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + /* Works with SLJIT_MEM0() case as well. */ + return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1)); + } + + srcw &= 0x3; + + if (srcw == 0) + return push_inst(compiler, DCBT | A(src & REG_MASK) | B(OFFS_REG(src))); + + FAIL_IF(push_inst(compiler, SLWI_W(srcw) | S(OFFS_REG(src)) | A(TMP_REG1))); + return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, @@ -1854,21 +2056,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + if (FAST_IS_REG(dst)) + return push_inst(compiler, MFLR | D(dst)); + + FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG1))); + break; + case SLJIT_GET_RETURN_ADDRESS: + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + LR_SAVE_OFFSET, TMP_REG2)); + break; + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_DATA, TMP_REG1, dst, dstw, TMP_REG2); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type != SLJIT_FLOAT_REGISTER) + return -1; + return freg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_u32 size) { + SLJIT_UNUSED_ARG(size); + CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -1879,24 +2112,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c /* Floating point operators */ /* --------------------------------------------------------------------- */ -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 6)) #define SELECT_FOP(op, single, double) ((sljit_ins)((op & SLJIT_32) ? single : double)) -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw)) -#else -#define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw)) - -#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) -#define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw)) -#define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw)) -#else -#define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw)) -#define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw)) -#endif - -#endif /* SLJIT_CONFIG_PPC_64 */ - static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) @@ -1913,19 +2130,19 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp if (op == SLJIT_CONV_SW_FROM_F64) { if (FAST_IS_REG(dst)) { - FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1)); - return emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1); + FAIL_IF(push_inst(compiler, STFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, LD | S(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET); } return emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, TMP_REG1); } -#else +#else /* !SLJIT_CONFIG_PPC_64 */ FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src))); -#endif +#endif /* SLJIT_CONFIG_PPC_64 */ if (FAST_IS_REG(dst)) { - FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET)); + FAIL_IF(load_immediate(compiler, TMP_REG1, TMP_MEM_OFFSET)); FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1))); - return emit_op_mem(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1); + return push_inst(compiler, LWZ | S(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET); } SLJIT_ASSERT(dst & SLJIT_MEM); @@ -1935,16 +2152,14 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp if (dstw) { FAIL_IF(push_inst(compiler, SLWI_W(dstw) | S(OFFS_REG(dst)) | A(TMP_REG1))); dstw = TMP_REG1; - } - else + } else dstw = OFFS_REG(dst); } else { if ((dst & REG_MASK) && !dstw) { dstw = dst & REG_MASK; dst = 0; - } - else { + } else { /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */ FAIL_IF(load_immediate(compiler, TMP_REG1, dstw)); dstw = TMP_REG1; @@ -1954,85 +2169,6 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw)); } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src, sljit_sw srcw) -{ -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - - sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - - if (src & SLJIT_IMM) { - if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) - srcw = (sljit_s32)srcw; - - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - } - else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) { - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1))); - else - FAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); - src = TMP_REG1; - } - - if (FAST_IS_REG(src)) { - FAIL_IF(emit_op_mem(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1)); - FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1)); - } - else - FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1)); - - FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); - - if (dst & SLJIT_MEM) - return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); - if (op & SLJIT_32) - return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); - return SLJIT_SUCCESS; - -#else - - sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_s32 invert_sign = 1; - - if (src & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ (sljit_sw)0x80000000)); - src = TMP_REG1; - invert_sign = 0; - } - else if (!FAST_IS_REG(src)) { - FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); - src = TMP_REG1; - } - - /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31))) - The double precision format has exactly 53 bit precision, so the lower 32 bit represents - the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000 - to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating - point value, we need to subtract 2^53 + 2^31 from the constructed value. */ - FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330)); - if (invert_sign) - FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000)); - FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, TMP_REG1)); - FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2)); - FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000)); - FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1)); - FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2)); - FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1)); - - FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2))); - - if (dst & SLJIT_MEM) - return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); - if (op & SLJIT_32) - return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); - return SLJIT_SUCCESS; - -#endif -} - static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) @@ -2051,13 +2187,10 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile switch (GET_FLAG_TYPE(op)) { case SLJIT_UNORDERED_OR_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: return push_inst(compiler, CROR | ((4 + 2) << 21) | ((4 + 2) << 16) | ((4 + 3) << 11)); case SLJIT_UNORDERED_OR_LESS: - case SLJIT_ORDERED_GREATER_EQUAL: return push_inst(compiler, CROR | ((4 + 0) << 21) | ((4 + 0) << 16) | ((4 + 3) << 11)); case SLJIT_UNORDERED_OR_GREATER: - case SLJIT_ORDERED_LESS_EQUAL: return push_inst(compiler, CROR | ((4 + 1) << 21) | ((4 + 1) << 16) | ((4 + 3) << 11)); } @@ -2143,18 +2276,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2))); break; - case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2))); break; - case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); break; - case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2))); break; + case SLJIT_COPYSIGN_F64: + FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? STFS : STFD) | FS(src2) | A(SLJIT_SP) | TMP_MEM_OFFSET)); +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + FAIL_IF(push_inst(compiler, LWZ | S(TMP_REG1) | A(SLJIT_SP) | ((op & SLJIT_32) ? TMP_MEM_OFFSET : TMP_MEM_OFFSET_HI))); +#else /* !SLJIT_CONFIG_PPC_32 */ + FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? LWZ : LD) | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); +#endif /* SLJIT_CONFIG_PPC_32 */ + FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src1))); +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(TMP_REG1) | 0)); +#else /* !SLJIT_CONFIG_PPC_32 */ + FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((op & SLJIT_32) ? 0 : 1)) | A(TMP_REG1) | 0)); +#endif /* SLJIT_CONFIG_PPC_32 */ + FAIL_IF(push_inst(compiler, BCx | (4 << 21) | (0 << 16) | 8)); + return push_inst(compiler, FNEG | FD(dst_r) | FB(dst_r)); } if (dst & SLJIT_MEM) @@ -2165,22 +2310,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil #undef SELECT_FOP -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { + union { + sljit_s32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - if (FAST_IS_REG(dst)) - return push_inst(compiler, MFLR | D(dst)); + u.value = value; - /* Memory. */ - FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2))); - return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); + if (u.imm != 0) + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm)); + + FAIL_IF(push_inst(compiler, STW | S(u.imm != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, LFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); } /* --------------------------------------------------------------------- */ @@ -2303,7 +2450,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile set_jump(jump, compiler, (sljit_u32)type & SLJIT_REWRITABLE_JUMP); type &= 0xff; - if (type == SLJIT_CARRY || type == SLJIT_NOT_CARRY) + if ((type | 0x1) == SLJIT_NOT_CARRY) PTR_FAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG1) | A(TMP_ZERO) | B(TMP_ZERO))); /* In PPC, we don't need to touch the arguments. */ @@ -2324,6 +2471,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types) { + SLJIT_UNUSED_ARG(arg_types); + CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types)); @@ -2360,7 +2509,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi #else /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */ src_r = src; #endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */ - } else if (src & SLJIT_IMM) { + } else if (src == SLJIT_IMM) { /* These jumps are converted to jump/call instructions when possible. */ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); FAIL_IF(!jump); @@ -2390,6 +2539,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi sljit_s32 arg_types, sljit_s32 src, sljit_sw srcw) { + SLJIT_UNUSED_ARG(arg_types); + CHECK_ERROR(); CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw)); @@ -2572,14 +2723,106 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return sljit_emit_op2(compiler, saved_op, dst, 0, dst, 0, TMP_REG2, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { - CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + sljit_ins *ptr; + sljit_uw size; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA; +#else /* !SLJIT_CONFIG_PPC_64 */ + sljit_s32 inp_flags = WORD_DATA | LOAD_DATA; +#endif /* SLJIT_CONFIG_PPC_64 */ - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);; + CHECK_ERROR(); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_reg != src2_reg) { + if (dst_reg == src1) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) { + FAIL_IF(push_inst(compiler, OR | S(dst_reg) | A(TMP_REG2) | B(dst_reg))); + + if ((src1 & REG_MASK) == dst_reg) + src1 = (src1 & ~REG_MASK) | TMP_REG2; + + if (OFFS_REG(src1) == dst_reg) + src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG2); + } + + FAIL_IF(push_inst(compiler, OR | S(src2_reg) | A(dst_reg) | B(src2_reg))); + } + } + + if (((type & ~SLJIT_32) | 0x1) == SLJIT_NOT_CARRY) + FAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG1) | A(TMP_ZERO) | B(TMP_ZERO))); + + size = compiler->size; + + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + compiler->size++; + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, dst_reg, src1, src1w, TMP_REG1)); + } else if (src1 == SLJIT_IMM) { +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + if (type & SLJIT_32) + src1w = (sljit_s32)src1w; +#endif /* SLJIT_CONFIG_RISCV_64 */ + FAIL_IF(load_immediate(compiler, dst_reg, src1w)); + } else + FAIL_IF(push_inst(compiler, OR | S(src1) | A(dst_reg) | B(src1))); + + *ptr = BCx | get_bo_bi_flags(compiler, (type ^ 0x1) & ~SLJIT_32) | (sljit_ins)((compiler->size - size) << 2); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_ins *ptr; + sljit_uw size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, FMR | FD(dst_freg) | FB(src2_freg))); + } + + if (((type & ~SLJIT_32) | 0x1) == SLJIT_NOT_CARRY) + FAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG1) | A(TMP_ZERO) | B(TMP_ZERO))); + + size = compiler->size; + + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + compiler->size++; + + if (src1 & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, dst_freg, src1, src1w, TMP_REG1)); + else + FAIL_IF(push_inst(compiler, FMR | FD(dst_freg) | FB(src1))); + + *ptr = BCx | get_bo_bi_flags(compiler, (type ^ 0x1) & ~SLJIT_32) | (sljit_ins)((compiler->size - size) << 2); + return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) @@ -2813,7 +3056,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(emit_const(compiler, dst_r, init_value)); if (dst & SLJIT_MEM) - PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, dst_r, dst, dstw, TMP_REG1)); return const_; } diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_32.c index b38e6924c80..396c956c197 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_32.c @@ -27,7 +27,6 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r) { SLJIT_UNUSED_ARG(tmp_r); - SLJIT_ASSERT(dst_r != tmp_r); if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)); @@ -43,6 +42,76 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_s32 imm[2]; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm[0] != 0) + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0], TMP_REG3)); + if (u.imm[1] != 0) + FAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1], TMP_REG3)); + + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-16))); + FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(u.imm[0] != 0 ? TMP_REG1 : TMP_ZERO) | (8 << 7))); + FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(u.imm[1] != 0 ? TMP_REG2 : TMP_ZERO) | (12 << 7))); + FAIL_IF(push_inst(compiler, FLD | FRD(freg) | RS1(SLJIT_SP) | IMM_I(8))); + return push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(16)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_ins inst; + sljit_s32 reg2 = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (op & SLJIT_32) { + if (op == SLJIT_COPY32_TO_F32) + inst = FMV_W_X | RS1(reg) | FRD(freg); + else + inst = FMV_X_W | FRS1(freg) | RD(reg); + + return push_inst(compiler, inst); + } + + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-16))); + + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + } + + if (op == SLJIT_COPY_TO_F64) { + if (reg2 != 0) + FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(reg2) | (8 << 7))); + else + FAIL_IF(push_inst(compiler, FSW | RS1(SLJIT_SP) | FRS2(freg) | (8 << 7))); + + FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(reg) | (12 << 7))); + FAIL_IF(push_inst(compiler, FLD | FRD(freg) | RS1(SLJIT_SP) | IMM_I(8))); + } else { + FAIL_IF(push_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(freg) | (8 << 7))); + + if (reg2 != 0) + FAIL_IF(push_inst(compiler, FMV_X_W | FRS1(freg) | RD(reg2))); + + FAIL_IF(push_inst(compiler, LW | RD(reg) | RS1(SLJIT_SP) | IMM_I(12))); + } + + return push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(16)); +} + static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins) { if ((init_value & 0x800) != 0) diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_64.c index 32cec7848d2..7fcf2c52730 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_64.c @@ -28,8 +28,6 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r { sljit_sw high; - SLJIT_ASSERT(dst_r != tmp_r); - if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)); @@ -81,6 +79,8 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r return SLJIT_SUCCESS; } + SLJIT_ASSERT(dst_r != tmp_r); + high = imm >> 32; imm = (sljit_s32)imm; @@ -126,6 +126,45 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r return push_inst(compiler, XOR | RD(dst_r) | RS1(dst_r) | RS2(tmp_r)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_sw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm == 0) + return push_inst(compiler, FMV_W_X | (1 << 25) | RS1(TMP_ZERO) | FRD(freg)); + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm, TMP_REG3)); + return push_inst(compiler, FMV_W_X | (1 << 25) | RS1(TMP_REG1) | FRD(freg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_ins inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) + inst = FMV_W_X | RS1(reg) | FRD(freg); + else + inst = FMV_X_W | FRS1(freg) | RD(reg); + + if (!(op & SLJIT_32)) + inst |= (sljit_ins)1 << 25; + + return push_inst(compiler, inst); +} + static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins) { sljit_sw high; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_common.c b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_common.c index 58a48c649c9..64bd411d9d3 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_common.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_common.c @@ -97,16 +97,20 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define FLD (F3(0x3) | OPC(0x7)) #define FLE_S (F7(0x50) | F3(0x0) | OPC(0x53)) #define FLT_S (F7(0x50) | F3(0x1) | OPC(0x53)) -#define FSD (F3(0x3) | OPC(0x27)) /* These conversion opcodes are partly defined. */ #define FCVT_S_D (F7(0x20) | OPC(0x53)) #define FCVT_S_W (F7(0x68) | OPC(0x53)) +#define FCVT_S_WU (F7(0x68) | F12(0x1) | OPC(0x53)) #define FCVT_W_S (F7(0x60) | F3(0x1) | OPC(0x53)) #define FMUL_S (F7(0x8) | F3(0x7) | OPC(0x53)) +#define FMV_X_W (F7(0x70) | F3(0x0) | OPC(0x53)) +#define FMV_W_X (F7(0x78) | F3(0x0) | OPC(0x53)) +#define FSD (F3(0x3) | OPC(0x27)) #define FSGNJ_S (F7(0x10) | F3(0x0) | OPC(0x53)) #define FSGNJN_S (F7(0x10) | F3(0x1) | OPC(0x53)) #define FSGNJX_S (F7(0x10) | F3(0x2) | OPC(0x53)) #define FSUB_S (F7(0x4) | F3(0x7) | OPC(0x53)) +#define FSW (F3(0x2) | OPC(0x27)) #define JAL (OPC(0x6f)) #define JALR (F3(0x0) | OPC(0x67)) #define LD (F3(0x3) | OPC(0x3)) @@ -344,13 +348,12 @@ static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg) if ((addr & 0x80000000l) != 0) high = ~high; - if ((high & 0x800) != 0) - high += 0x1000; - if (flags & PATCH_ABS52) { SLJIT_ASSERT(addr <= S52_MAX); inst[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high << 12); } else { + if ((high & 0x800) != 0) + high += 0x1000; inst[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff); inst[1] = ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high); inst++; @@ -531,7 +534,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) { switch (feature_type) { case SLJIT_HAS_FPU: +#ifdef SLJIT_IS_FPU_AVAILABLE + return (SLJIT_IS_FPU_AVAILABLE) != 0; +#elif defined(__riscv_float_abi_soft) + return 0; +#else + return 1; +#endif /* SLJIT_IS_FPU_AVAILABLE */ case SLJIT_HAS_ZERO_REGISTER: + case SLJIT_HAS_COPY_F32: +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + case SLJIT_HAS_COPY_F64: +#endif /* !SLJIT_CONFIG_RISCV_64 */ return 1; default: return 0; @@ -540,7 +554,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - return (type >= SLJIT_ORDERED_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL); + switch (type) { + case SLJIT_UNORDERED_OR_EQUAL: + case SLJIT_ORDERED_NOT_EQUAL: + return 2; + + case SLJIT_UNORDERED: + case SLJIT_ORDERED: + return 1; + } + + return 0; } /* --------------------------------------------------------------------- */ @@ -610,10 +634,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { if ((local_size & SSIZE_OF(sw)) != 0) local_size += SSIZE_OF(sw); - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } #else - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); #endif local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; compiler->local_size = local_size; @@ -704,10 +728,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { if ((local_size & SSIZE_OF(sw)) != 0) local_size += SSIZE_OF(sw); - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } #else - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); #endif compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; @@ -915,7 +939,7 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl /* Since tmp can be the same as base or offset registers, * these might be unavailable after modifying tmp. */ - if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) + if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA) && reg == TMP_REG2) tmp_r = reg; if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { @@ -1031,9 +1055,11 @@ static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, slji #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) #define WORD 0 +#define WORD_32 0 #define IMM_EXTEND(v) (IMM_I(v)) #else /* !SLJIT_CONFIG_RISCV_32 */ #define WORD word +#define WORD_32 0x08 #define IMM_EXTEND(v) (IMM_I((op & SLJIT_32) ? (v) : (32 + (v)))) #endif /* SLJIT_CONFIG_RISCV_32 */ @@ -1041,16 +1067,16 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj { sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ); #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - sljit_ins word = (op & SLJIT_32) >> 5; - sljit_ins max = (op & SLJIT_32) ? 32 : 64; + sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5; + sljit_ins word_size = (op & SLJIT_32) ? 32 : 64; #else /* !SLJIT_CONFIG_RISCV_64 */ - sljit_ins max = 32; + sljit_ins word_size = 32; #endif /* SLJIT_CONFIG_RISCV_64 */ SLJIT_ASSERT(WORD == 0 || WORD == 0x8); /* The OTHER_FLAG is the counter. */ - FAIL_IF(push_inst(compiler, ADDI | WORD | RD(OTHER_FLAG) | RS1(TMP_ZERO) | IMM_I(max))); + FAIL_IF(push_inst(compiler, ADDI | WORD | RD(OTHER_FLAG) | RS1(TMP_ZERO) | IMM_I(word_size))); /* The TMP_REG2 is the next value. */ if (src != TMP_REG2) @@ -1066,7 +1092,7 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj FAIL_IF(push_inst(compiler, BLT | RS1(TMP_REG2) | RS2(TMP_ZERO) | ((sljit_ins)(2 * SSIZE_OF(ins)) << 7) | ((sljit_ins)(8 * SSIZE_OF(ins)) << 20))); /* The TMP_REG1 is the next shift. */ - FAIL_IF(push_inst(compiler, ADDI | WORD | RD(TMP_REG1) | RS1(TMP_ZERO) | IMM_I(max))); + FAIL_IF(push_inst(compiler, ADDI | WORD | RD(TMP_REG1) | RS1(TMP_ZERO) | IMM_I(word_size))); FAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(TMP_REG2) | IMM_I(0))); FAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_I(1))); @@ -1081,6 +1107,65 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj return push_inst(compiler, ADDI | WORD | RD(dst) | RS1(OTHER_FLAG) | IMM_I(0)); } +static sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src) +{ + SLJIT_UNUSED_ARG(op); + +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + if (!(op & SLJIT_32)) { + FAIL_IF(push_inst(compiler, LUI | RD(OTHER_FLAG) | 0x10000)); + FAIL_IF(push_inst(compiler, SRLI | RD(TMP_REG1) | RS1(src) | IMM_I(32))); + FAIL_IF(push_inst(compiler, ADDI | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | IMM_I(0xfff))); + FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(src) | IMM_I(32))); + FAIL_IF(push_inst(compiler, SLLI | RD(EQUAL_FLAG) | RS1(OTHER_FLAG) | IMM_I(32))); + FAIL_IF(push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1))); + FAIL_IF(push_inst(compiler, OR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(EQUAL_FLAG))); + + FAIL_IF(push_inst(compiler, SRLI | RD(TMP_REG1) | RS1(dst) | IMM_I(16))); + FAIL_IF(push_inst(compiler, AND | RD(dst) | RS1(dst) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, SLLI | RD(EQUAL_FLAG) | RS1(OTHER_FLAG) | IMM_I(8))); + FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(16))); + FAIL_IF(push_inst(compiler, XOR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(EQUAL_FLAG))); + FAIL_IF(push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1))); + + FAIL_IF(push_inst(compiler, SRLI | RD(TMP_REG1) | RS1(dst) | IMM_I(8))); + FAIL_IF(push_inst(compiler, AND | RD(dst) | RS1(dst) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(8))); + return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)); + } +#endif /* SLJIT_CONFIG_RISCV_64 */ + + FAIL_IF(push_inst(compiler, SRLI | WORD_32 | RD(TMP_REG1) | RS1(src) | IMM_I(16))); + FAIL_IF(push_inst(compiler, LUI | RD(OTHER_FLAG) | 0xff0000)); + FAIL_IF(push_inst(compiler, SLLI | WORD_32 | RD(dst) | RS1(src) | IMM_I(16))); + FAIL_IF(push_inst(compiler, ORI | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | IMM_I(0xff))); + FAIL_IF(push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1))); + + FAIL_IF(push_inst(compiler, SRLI | WORD_32 | RD(TMP_REG1) | RS1(dst) | IMM_I(8))); + FAIL_IF(push_inst(compiler, AND | RD(dst) | RS1(dst) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, SLLI | WORD_32 | RD(dst) | RS1(dst) | IMM_I(8))); + return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)); +} + +static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src) +{ +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5; + sljit_ins word_size = (op & SLJIT_32) ? 32 : 64; +#else /* !SLJIT_CONFIG_RISCV_64 */ + sljit_ins word_size = 32; +#endif /* SLJIT_CONFIG_RISCV_64 */ + + FAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(src) | IMM_I(8))); + FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src) | IMM_I(word_size - 8))); + FAIL_IF(push_inst(compiler, ANDI | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_I(0xff))); + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI) | WORD | RD(dst) | RS1(dst) | IMM_I(word_size - 16))); + return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)); +} + #define EMIT_LOGICAL(op_imm, op_reg) \ if (flags & SRC2_IMM) { \ if (op & SLJIT_SET_Z) \ @@ -1105,7 +1190,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl sljit_s32 is_overflow, is_carry, carry_src_r, is_handled; sljit_ins op_imm, op_reg; #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - sljit_ins word = (op & SLJIT_32) >> 5; + sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5; #endif /* SLJIT_CONFIG_RISCV_64 */ SLJIT_ASSERT(WORD == 0 || WORD == 0x8); @@ -1174,10 +1259,33 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); return emit_clz_ctz(compiler, op, dst, src2); + case SLJIT_REV: + case SLJIT_REV_S32: +#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) + case SLJIT_REV_U32: +#endif /* SLJIT_CONFIG_RISCV_32 */ + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + return emit_rev(compiler, op, dst, src2); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + return emit_rev16(compiler, op, dst, src2); + +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + case SLJIT_REV_U32: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && dst != TMP_REG1); + FAIL_IF(emit_rev(compiler, op, dst, src2)); + if (dst == TMP_REG2) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(32))); + return push_inst(compiler, SRLI | RD(dst) | RS1(dst) | IMM_I(32)); +#endif /* SLJIT_CONFIG_RISCV_32 */ + case SLJIT_ADD: /* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */ is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW; - carry_src_r = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + carry_src_r = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_overflow) { @@ -1233,7 +1341,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return push_inst(compiler, XOR | RD(OTHER_FLAG) | RS1(TMP_REG1) | RS2(OTHER_FLAG)); case SLJIT_ADDC: - carry_src_r = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + carry_src_r = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2))); @@ -1280,11 +1388,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl is_handled = 0; if (flags & SRC2_IMM) { - if (GET_FLAG_TYPE(op) == SLJIT_LESS || GET_FLAG_TYPE(op) == SLJIT_GREATER_EQUAL) { + if (GET_FLAG_TYPE(op) == SLJIT_LESS) { FAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2))); is_handled = 1; } - else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS || GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER_EQUAL) { + else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) { FAIL_IF(push_inst(compiler, SLTI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2))); is_handled = 1; } @@ -1301,19 +1409,15 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl switch (GET_FLAG_TYPE(op)) { case SLJIT_LESS: - case SLJIT_GREATER_EQUAL: FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src1) | RS2(src2))); break; case SLJIT_GREATER: - case SLJIT_LESS_EQUAL: FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src2) | RS2(src1))); break; case SLJIT_SIG_LESS: - case SLJIT_SIG_GREATER_EQUAL: FAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RS1(src1) | RS2(src2))); break; case SLJIT_SIG_GREATER: - case SLJIT_SIG_LESS_EQUAL: FAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RS1(src2) | RS2(src1))); break; } @@ -1336,7 +1440,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW; - is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_overflow) { @@ -1385,7 +1489,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl flags &= ~SRC2_IMM; } - is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_carry) @@ -1534,9 +1638,10 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 compiler->cache_argw = 0; } - if (dst == TMP_REG2) { + if (dst == 0) { SLJIT_ASSERT(HAS_FLAGS(op)); flags |= UNUSED_DEST; + dst = TMP_REG2; } else if (FAST_IS_REG(dst)) { dst_r = dst; @@ -1548,11 +1653,11 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 flags |= SLOW_DEST; if (flags & IMM_OP) { - if ((src2 & SLJIT_IMM) && src2w != 0 && src2w <= SIMM_MAX && src2w >= SIMM_MIN) { + if (src2 == SLJIT_IMM && src2w != 0 && src2w <= SIMM_MAX && src2w >= SIMM_MIN) { flags |= SRC2_IMM; src2_r = src2w; } - else if ((flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w != 0 && src1w <= SIMM_MAX && src1w >= SIMM_MIN) { + else if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && src1w <= SIMM_MAX && src1w >= SIMM_MIN) { flags |= SRC2_IMM; src2_r = src1w; @@ -1569,7 +1674,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 src1_r = src1; flags |= REG1_SOURCE; } - else if (src1 & SLJIT_IMM) { + else if (src1 == SLJIT_IMM) { if (src1w) { FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3)); src1_r = TMP_REG1; @@ -1592,7 +1697,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP) dst_r = (sljit_s32)src2_r; } - else if (src2 & SLJIT_IMM) { + else if (src2 == SLJIT_IMM) { if (!(flags & SRC2_IMM)) { if (src2w) { FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w, TMP_REG3)); @@ -1649,7 +1754,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - sljit_ins word = (op & SLJIT_32) >> 5; + sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5; SLJIT_ASSERT(word == 0 || word == 0x8); #endif /* SLJIT_CONFIG_RISCV_64 */ @@ -1718,32 +1823,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) case SLJIT_MOV_U32: - return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u32)srcw : srcw); case SLJIT_MOV_S32: /* Logical operators have no W variant, so sign extended input is necessary for them. */ case SLJIT_MOV32: - return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw); #endif case SLJIT_MOV_U8: - return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); + return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw); case SLJIT_MOV_S8: - return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); + return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw); case SLJIT_MOV_U16: - return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); + return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw); case SLJIT_MOV_S16: - return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); - - case SLJIT_NOT: - return emit_op(compiler, SLJIT_XOR | (op & (SLJIT_32 | SLJIT_SET_Z)), flags, dst, dstw, src, srcw, SLJIT_IMM, -1); + return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_CLZ: case SLJIT_CTZ: + case SLJIT_REV: return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + return emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_REV_U32: + case SLJIT_REV_S32: + return emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); } SLJIT_UNREACHABLE(); @@ -1766,9 +1877,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) if (op & SLJIT_32) { flags |= INT_DATA | SIGNED_DATA; - if (src1 & SLJIT_IMM) + if (src1 == SLJIT_IMM) src1w = (sljit_s32)src1w; - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) src2w = (sljit_s32)src2w; } #endif @@ -1801,7 +1912,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile case SLJIT_MASHR: case SLJIT_ROTL: case SLJIT_ROTR: - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) src2w &= 0x1f; #else /* !SLJIT_CONFIG_RISCV_32 */ @@ -1827,18 +1938,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w)); SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w); + return sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_left; sljit_ins ins1, ins2, ins3; #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - sljit_ins word = (op & SLJIT_32) >> 5; + sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5; sljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA; sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64; #else /* !SLJIT_CONFIG_RISCV_64 */ @@ -1849,50 +1961,44 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * SLJIT_ASSERT(WORD == 0 || WORD == 0x8); CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); - if (src2 & SLJIT_IMM) { - src2w &= bit_length - 1; + if (src3 == SLJIT_IMM) { + src3w &= bit_length - 1; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src2, src2w)); - src2 = TMP_REG2; - } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src1, src1w)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3)); - src1 = TMP_REG1; - } - - if (src2 & SLJIT_IMM) { if (is_left) { - ins1 = SLLI | WORD | IMM_I(src2w); - src2w = bit_length - src2w; - ins2 = SRLI | WORD | IMM_I(src2w); + ins1 = SLLI | WORD | IMM_I(src3w); + src3w = bit_length - src3w; + ins2 = SRLI | WORD | IMM_I(src3w); } else { - ins1 = SRLI | WORD | IMM_I(src2w); - src2w = bit_length - src2w; - ins2 = SLLI | WORD | IMM_I(src2w); + ins1 = SRLI | WORD | IMM_I(src3w); + src3w = bit_length - src3w; + ins2 = SLLI | WORD | IMM_I(src3w); } - FAIL_IF(push_inst(compiler, ins1 | RD(src_dst) | RS1(src_dst))); - FAIL_IF(push_inst(compiler, ins2 | RD(TMP_REG1) | RS1(src1))); - return push_inst(compiler, OR | RD(src_dst) | RS1(src_dst) | RS2(TMP_REG1)); + FAIL_IF(push_inst(compiler, ins1 | RD(dst_reg) | RS1(src1_reg))); + FAIL_IF(push_inst(compiler, ins2 | RD(TMP_REG1) | RS1(src2_reg))); + return push_inst(compiler, OR | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1)); + } + + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src3, src3w)); + src3 = TMP_REG2; + } else if (dst_reg == src3) { + push_inst(compiler, ADDI | WORD | RD(TMP_REG2) | RS1(src3) | IMM_I(0)); + src3 = TMP_REG2; } if (is_left) { @@ -1905,21 +2011,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * ins3 = SLL; } - FAIL_IF(push_inst(compiler, ins1 | WORD | RD(src_dst) | RS1(src_dst) | RS2(src2))); + FAIL_IF(push_inst(compiler, ins1 | WORD | RD(dst_reg) | RS1(src1_reg) | RS2(src3))); if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) { - FAIL_IF(push_inst(compiler, ins2 | WORD | RD(TMP_REG1) | RS1(src1) | IMM_I(1))); - FAIL_IF(push_inst(compiler, XORI | RD(TMP_REG2) | RS1(src2) | IMM_I((sljit_ins)bit_length - 1))); - src1 = TMP_REG1; + FAIL_IF(push_inst(compiler, ins2 | WORD | RD(TMP_REG1) | RS1(src2_reg) | IMM_I(1))); + FAIL_IF(push_inst(compiler, XORI | RD(TMP_REG2) | RS1(src3) | IMM_I((sljit_ins)bit_length - 1))); + src2_reg = TMP_REG1; } else - FAIL_IF(push_inst(compiler, SUB | WORD | RD(TMP_REG2) | RS1(TMP_ZERO) | RS2(src2))); + FAIL_IF(push_inst(compiler, SUB | WORD | RD(TMP_REG2) | RS1(TMP_ZERO) | RS2(src3))); - FAIL_IF(push_inst(compiler, ins3 | WORD | RD(TMP_REG1) | RS1(src1) | RS2(TMP_REG2))); - return push_inst(compiler, OR | RD(src_dst) | RS1(src_dst) | RS2(TMP_REG1)); + FAIL_IF(push_inst(compiler, ins3 | WORD | RD(TMP_REG1) | RS1(src2_reg) | RS2(TMP_REG2))); + return push_inst(compiler, OR | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1)); } -#undef WORD - SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { @@ -1947,21 +2051,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + if (FAST_IS_REG(dst)) + return push_inst(compiler, ADDI | RD(dst) | RS1(RETURN_ADDR_REG) | IMM_I(0)); + + SLJIT_ASSERT(RETURN_ADDR_REG == TMP_REG2); + break; + case SLJIT_GET_RETURN_ADDRESS: + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size - SSIZE_OF(sw))); + break; + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type != SLJIT_FLOAT_REGISTER) + return -1; + return freg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_u32 size) { + SLJIT_UNUSED_ARG(size); + CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -2008,51 +2143,73 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp #endif } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { - sljit_ins inst; -#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)) << 21; -#endif - sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); -#else - FAIL_IF(emit_op_mem2(compiler, (flags ? WORD_DATA : INT_DATA) | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); -#endif +#else /* SLJIT_CONFIG_RISCV_32 */ + FAIL_IF(emit_op_mem2(compiler, ((ins & (1 << 21)) ? WORD_DATA : INT_DATA) | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); +#endif /* !SLJIT_CONFIG_RISCV_32 */ src = TMP_REG1; - } else if (src & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) - srcw = (sljit_s32)srcw; -#endif - + } else if (src == SLJIT_IMM) { FAIL_IF(load_immediate(compiler, TMP_REG1, srcw, TMP_REG3)); src = TMP_REG1; } - inst = FCVT_S_W | FMT(op) | FRD(dst_r) | RS1(src); + FAIL_IF(push_inst(compiler, ins | FRD(dst_r) | RS1(src))); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, DOUBLE_DATA | ((sljit_s32)(~ins >> 24) & 0x2), TMP_FREG1, dst, dstw, 0, 0); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins ins = FCVT_S_W | FMT(op); #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) if (op & SLJIT_32) - inst |= F3(0x7); -#else - inst |= flags; + ins |= F3(0x7); +#else /* !SLJIT_CONFIG_RISCV_32 */ + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) + ins |= (1 << 21); + else if (src == SLJIT_IMM) + srcw = (sljit_s32)srcw; if (op != SLJIT_CONV_F64_FROM_S32) - inst |= F3(0x7); -#endif + ins |= F3(0x7); +#endif /* SLJIT_CONFIG_RISCV_32 */ - FAIL_IF(push_inst(compiler, inst)); + return sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw); +} - if (dst & SLJIT_MEM) - return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); - return SLJIT_SUCCESS; +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins ins = FCVT_S_WU | FMT(op); + +#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) + if (op & SLJIT_32) + ins |= F3(0x7); +#else /* !SLJIT_CONFIG_RISCV_32 */ + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_UW) + ins |= (1 << 21); + else if (src == SLJIT_IMM) + srcw = (sljit_u32)srcw; + + if (op != SLJIT_CONV_F64_FROM_S32) + ins |= F3(0x7); +#endif /* SLJIT_CONFIG_RISCV_32 */ + + return sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw); } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, @@ -2073,40 +2230,36 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile switch (GET_FLAG_TYPE(op)) { case SLJIT_F_EQUAL: - case SLJIT_F_NOT_EQUAL: case SLJIT_ORDERED_EQUAL: - case SLJIT_UNORDERED_OR_NOT_EQUAL: inst = FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2); break; case SLJIT_F_LESS: - case SLJIT_F_GREATER_EQUAL: case SLJIT_ORDERED_LESS: - case SLJIT_UNORDERED_OR_GREATER_EQUAL: inst = FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2); break; case SLJIT_ORDERED_GREATER: - case SLJIT_UNORDERED_OR_LESS_EQUAL: inst = FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src2) | FRS2(src1); break; case SLJIT_F_GREATER: - case SLJIT_F_LESS_EQUAL: case SLJIT_UNORDERED_OR_GREATER: - case SLJIT_ORDERED_LESS_EQUAL: inst = FLE_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2); break; case SLJIT_UNORDERED_OR_LESS: - case SLJIT_ORDERED_GREATER_EQUAL: inst = FLE_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src2) | FRS2(src1); break; - case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */ - case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */ + case SLJIT_UNORDERED_OR_EQUAL: FAIL_IF(push_inst(compiler, FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2))); FAIL_IF(push_inst(compiler, FLT_S | FMT(op) | RD(TMP_REG1) | FRS1(src2) | FRS2(src1))); inst = OR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(TMP_REG1); break; - default: /* SLJIT_UNORDERED, SLJIT_ORDERED */ - FAIL_IF(push_inst(compiler, FADD_S | FMT(op) | FRD(TMP_FREG1) | FRS1(src1) | FRS2(src2))); - inst = FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(TMP_FREG1) | FRS2(TMP_FREG1); + default: /* SLJIT_UNORDERED */ + if (src1 == src2) { + inst = FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src1); + break; + } + FAIL_IF(push_inst(compiler, FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src1))); + FAIL_IF(push_inst(compiler, FEQ_S | FMT(op) | RD(TMP_REG1) | FRS1(src2) | FRS2(src2))); + inst = AND | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(TMP_REG1); break; } @@ -2233,6 +2386,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, FDIV_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2))); break; + + case SLJIT_COPYSIGN_F64: + return push_inst(compiler, FSGNJ_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2)); } if (dst_r == TMP_FREG2) @@ -2241,24 +2397,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return SLJIT_SUCCESS; } -#undef FLOAT_DATA -#undef FMT - -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { + union { + sljit_s32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - if (FAST_IS_REG(dst)) - return push_inst(compiler, ADDI | RD(dst) | RS1(RETURN_ADDR_REG) | IMM_I(0)); + u.value = value; - /* Memory. */ - return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); + if (u.imm == 0) + return push_inst(compiler, FMV_W_X | RS1(TMP_ZERO) | FRD(freg)); + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm, TMP_REG3)); + return push_inst(compiler, FMV_W_X | RS1(TMP_REG1) | FRD(freg)); } /* --------------------------------------------------------------------- */ @@ -2287,6 +2443,54 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #define BRANCH_LENGTH ((sljit_ins)(7 * sizeof(sljit_ins)) << 7) #endif +static sljit_ins get_jump_instruction(sljit_s32 type) +{ + switch (type) { + case SLJIT_EQUAL: + return BNE | RS1(EQUAL_FLAG) | RS2(TMP_ZERO); + case SLJIT_NOT_EQUAL: + return BEQ | RS1(EQUAL_FLAG) | RS2(TMP_ZERO); + case SLJIT_LESS: + case SLJIT_GREATER: + case SLJIT_SIG_LESS: + case SLJIT_SIG_GREATER: + case SLJIT_OVERFLOW: + case SLJIT_CARRY: + case SLJIT_F_EQUAL: + case SLJIT_ORDERED_EQUAL: + case SLJIT_ORDERED_NOT_EQUAL: + case SLJIT_F_LESS: + case SLJIT_ORDERED_LESS: + case SLJIT_ORDERED_GREATER: + case SLJIT_F_LESS_EQUAL: + case SLJIT_ORDERED_LESS_EQUAL: + case SLJIT_ORDERED_GREATER_EQUAL: + case SLJIT_ORDERED: + return BEQ | RS1(OTHER_FLAG) | RS2(TMP_ZERO); + break; + case SLJIT_GREATER_EQUAL: + case SLJIT_LESS_EQUAL: + case SLJIT_SIG_GREATER_EQUAL: + case SLJIT_SIG_LESS_EQUAL: + case SLJIT_NOT_OVERFLOW: + case SLJIT_NOT_CARRY: + case SLJIT_F_NOT_EQUAL: + case SLJIT_UNORDERED_OR_NOT_EQUAL: + case SLJIT_UNORDERED_OR_EQUAL: + case SLJIT_F_GREATER_EQUAL: + case SLJIT_UNORDERED_OR_GREATER_EQUAL: + case SLJIT_UNORDERED_OR_LESS_EQUAL: + case SLJIT_F_GREATER: + case SLJIT_UNORDERED_OR_GREATER: + case SLJIT_UNORDERED_OR_LESS: + case SLJIT_UNORDERED: + return BNE | RS1(OTHER_FLAG) | RS2(TMP_ZERO); + default: + /* Not conditional branch. */ + return 0; + } +} + SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; @@ -2300,57 +2504,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); type &= 0xff; - switch (type) { - case SLJIT_EQUAL: - inst = BNE | RS1(EQUAL_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH; - break; - case SLJIT_NOT_EQUAL: - inst = BEQ | RS1(EQUAL_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH; - break; - case SLJIT_LESS: - case SLJIT_GREATER: - case SLJIT_SIG_LESS: - case SLJIT_SIG_GREATER: - case SLJIT_OVERFLOW: - case SLJIT_CARRY: - case SLJIT_F_EQUAL: - case SLJIT_ORDERED_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */ - case SLJIT_F_LESS: - case SLJIT_ORDERED_LESS: - case SLJIT_ORDERED_GREATER: - case SLJIT_F_LESS_EQUAL: - case SLJIT_ORDERED_LESS_EQUAL: - case SLJIT_ORDERED_GREATER_EQUAL: - case SLJIT_ORDERED: - inst = BEQ | RS1(OTHER_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH; - break; - case SLJIT_GREATER_EQUAL: - case SLJIT_LESS_EQUAL: - case SLJIT_SIG_GREATER_EQUAL: - case SLJIT_SIG_LESS_EQUAL: - case SLJIT_NOT_OVERFLOW: - case SLJIT_NOT_CARRY: - case SLJIT_F_NOT_EQUAL: - case SLJIT_UNORDERED_OR_NOT_EQUAL: - case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */ - case SLJIT_F_GREATER_EQUAL: - case SLJIT_UNORDERED_OR_GREATER_EQUAL: - case SLJIT_UNORDERED_OR_LESS_EQUAL: - case SLJIT_F_GREATER: - case SLJIT_UNORDERED_OR_GREATER: - case SLJIT_UNORDERED_OR_LESS: - case SLJIT_UNORDERED: - inst = BNE | RS1(OTHER_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH; - break; - default: - /* Not conditional branch. */ - inst = 0; - break; - } + inst = get_jump_instruction(type); if (inst != 0) { - PTR_FAIL_IF(push_inst(compiler, inst)); + PTR_FAIL_IF(push_inst(compiler, inst | BRANCH_LENGTH)); jump->flags |= IS_COND; } @@ -2420,7 +2577,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler src2 = TMP_REG2; } - if (src1 & SLJIT_IMM) { + if (src1 == SLJIT_IMM) { if (src1w != 0) { PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3)); src1 = TMP_REG1; @@ -2429,7 +2586,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler src1 = TMP_ZERO; } - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { if (src2w != 0) { PTR_FAIL_IF(load_immediate(compiler, TMP_REG2, src2w, TMP_REG3)); src2 = TMP_REG2; @@ -2499,7 +2656,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { if (src & SLJIT_MEM) { ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw)); @@ -2641,16 +2798,110 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, src_r, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { - CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + sljit_ins *ptr; + sljit_uw size; +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + sljit_ins word = (sljit_ins)(type & SLJIT_32) >> 5; + sljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA; +#else /* !SLJIT_CONFIG_RISCV_64 */ + sljit_s32 inp_flags = WORD_DATA | LOAD_DATA; +#endif /* SLJIT_CONFIG_RISCV_64 */ - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);; + SLJIT_ASSERT(WORD == 0 || WORD == 0x8); + + CHECK_ERROR(); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_reg != src2_reg) { + if (dst_reg == src1) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) { + FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG2) | RS1(dst_reg) | IMM_I(0))); + + if ((src1 & REG_MASK) == dst_reg) + src1 = (src1 & ~REG_MASK) | TMP_REG2; + + if (OFFS_REG(src1) == dst_reg) + src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG2); + } + + FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst_reg) | RS1(src2_reg) | IMM_I(0))); + } + } + + size = compiler->size; + + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + compiler->size++; + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, dst_reg, src1, src1w)); + } else if (src1 == SLJIT_IMM) { +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + if (word) + src1w = (sljit_s32)src1w; +#endif /* SLJIT_CONFIG_RISCV_64 */ + FAIL_IF(load_immediate(compiler, dst_reg, src1w, TMP_REG1)); + } else + FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst_reg) | RS1(src1) | IMM_I(0))); + + *ptr = get_jump_instruction(type & ~SLJIT_32) | (sljit_ins)((compiler->size - size) << 9); + return SLJIT_SUCCESS; } +#undef WORD + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_ins *ptr; + sljit_uw size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, FSGNJ_S | FMT(type) | FRD(dst_freg) | FRS1(src2_freg) | FRS2(src2_freg))); + } + + size = compiler->size; + + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + compiler->size++; + + if (src1 & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, dst_freg, src1, src1w)); + else + FAIL_IF(push_inst(compiler, FSGNJ_S | FMT(type) | FRD(dst_freg) | FRS1(src1) | FRS2(src1))); + + *ptr = get_jump_instruction(type & ~SLJIT_32) | (sljit_ins)((compiler->size - size) << 9); + return SLJIT_SUCCESS; +} + +#undef FLOAT_DATA +#undef FMT + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw) diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeS390X.c b/src/3rdparty/pcre2/src/sljit/sljitNativeS390X.c index 8b51bad9bc3..67516f9b320 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeS390X.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeS390X.c @@ -47,8 +47,8 @@ static const sljit_ins sljit_ins_const = (sljit_ins)1 << 48; #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) -static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = { - 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1 +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { + 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1, 14 }; /* there are also a[2-15] available, but they are slower to access and @@ -83,7 +83,7 @@ static const sljit_gpr r10 = 10; /* reg_map[9] */ static const sljit_gpr r11 = 11; /* reg_map[10] */ static const sljit_gpr r12 = 12; /* reg_map[11]: GOT */ static const sljit_gpr r13 = 13; /* reg_map[12]: Literal Pool pointer */ -static const sljit_gpr r14 = 14; /* reg_map[0]: return address and flag register */ +static const sljit_gpr r14 = 14; /* reg_map[0]: return address */ static const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */ /* WARNING: r12 and r13 shouldn't be used as per ABI recommendation */ @@ -96,20 +96,16 @@ static const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stac #define tmp0 r0 #define tmp1 r1 -/* TODO(carenas): flags should move to a different register so that - * link register doesn't need to change - */ - /* When reg cannot be unused. */ #define IS_GPR_REG(reg) ((reg > 0) && (reg) <= SLJIT_SP) /* Link register. */ static const sljit_gpr link_r = 14; /* r14 */ -#define TMP_FREG1 (0) +#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { - 1, 0, 2, 4, 6, 3, 5, 7, 15, 14, 13, 12, 11, 10, 9, 8, +static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = { + 0, 0, 2, 4, 6, 3, 5, 7, 15, 14, 13, 12, 11, 10, 9, 8, 1 }; #define R0A(r) (r) @@ -126,7 +122,10 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { #define F0(r) ((sljit_ins)freg_map[r]) #define F4(r) (R4A((sljit_ins)freg_map[r])) +#define F12(r) (R12A((sljit_ins)freg_map[r])) #define F20(r) (R20A((sljit_ins)freg_map[r])) +#define F28(r) (R28A((sljit_ins)freg_map[r])) +#define F32(r) (R32A((sljit_ins)freg_map[r])) #define F36(r) (R36A((sljit_ins)freg_map[r])) struct sljit_s390x_const { @@ -141,12 +140,6 @@ static SLJIT_INLINE sljit_gpr gpr(sljit_s32 r) return reg_map[r]; } -static SLJIT_INLINE sljit_gpr fgpr(sljit_s32 r) -{ - SLJIT_ASSERT(r >= 0 && r < (sljit_s32)(sizeof(freg_map) / sizeof(freg_map[0]))); - return freg_map[r]; -} - /* Size of instruction in bytes. Tags must already be cleared. */ static SLJIT_INLINE sljit_uw sizeof_ins(sljit_ins ins) { @@ -217,6 +210,7 @@ static SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 t } /* fallthrough */ + case SLJIT_ATOMIC_STORED: case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: return cc0; @@ -236,6 +230,7 @@ static SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 t return (cc1 | cc2 | cc3); case SLJIT_LESS: + case SLJIT_ATOMIC_NOT_STORED: return cc1; case SLJIT_GREATER_EQUAL: @@ -454,10 +449,12 @@ HAVE_FACILITY(have_misc2, MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY) static SLJIT_INLINE sljit_ins disp_s20(sljit_s32 d) { + sljit_uw dh, dl; + SLJIT_ASSERT(is_s20(d)); - sljit_uw dh = (d >> 12) & 0xff; - sljit_uw dl = (d << 8) & 0xfff00; + dh = (d >> 12) & 0xff; + dl = ((sljit_uw)d << 8) & 0xfff00; return (dh | dl) << 8; } @@ -899,23 +896,17 @@ static sljit_s32 push_load_imm_inst(struct sljit_compiler *compiler, sljit_gpr t if (((sljit_uw)v & ~(sljit_uw)0xffff000000000000) == 0) return push_inst(compiler, llihh(target, (sljit_u16)(v >> 48))); - /* 6 byte instructions (requires extended immediate facility) */ - if (have_eimm()) { - if (is_s32(v)) - return push_inst(compiler, lgfi(target, (sljit_s32)v)); + if (is_s32(v)) + return push_inst(compiler, lgfi(target, (sljit_s32)v)); - if (((sljit_uw)v >> 32) == 0) - return push_inst(compiler, llilf(target, (sljit_u32)v)); + if (((sljit_uw)v >> 32) == 0) + return push_inst(compiler, llilf(target, (sljit_u32)v)); - if (((sljit_uw)v << 32) == 0) - return push_inst(compiler, llihf(target, (sljit_u32)((sljit_uw)v >> 32))); + if (((sljit_uw)v << 32) == 0) + return push_inst(compiler, llihf(target, (sljit_u32)((sljit_uw)v >> 32))); - FAIL_IF(push_inst(compiler, llilf(target, (sljit_u32)v))); - return push_inst(compiler, iihf(target, (sljit_u32)(v >> 32))); - } - - /* TODO(mundaym): instruction sequences that don't use extended immediates */ - abort(); + FAIL_IF(push_inst(compiler, llilf(target, (sljit_u32)v))); + return push_inst(compiler, iihf(target, (sljit_u32)(v >> 32))); } struct addr { @@ -995,24 +986,47 @@ static sljit_s32 make_addr_bx(struct sljit_compiler *compiler, (cond) ? EVAL(i1, r, addr) : EVAL(i2, r, addr) /* May clobber tmp1. */ -static sljit_s32 load_word(struct sljit_compiler *compiler, sljit_gpr dst_r, +static sljit_s32 load_store_op(struct sljit_compiler *compiler, sljit_gpr reg, + sljit_s32 mem, sljit_sw memw, + sljit_s32 is_32bit, const sljit_ins* forms) +{ + struct addr addr; + + SLJIT_ASSERT(mem & SLJIT_MEM); + + if (is_32bit && ((mem & OFFS_REG_MASK) || is_u12(memw) || !is_s20(memw))) { + FAIL_IF(make_addr_bx(compiler, &addr, mem, memw, tmp1)); + return push_inst(compiler, forms[0] | R20A(reg) | R16A(addr.index) | R12A(addr.base) | (sljit_ins)addr.offset); + } + + FAIL_IF(make_addr_bxy(compiler, &addr, mem, memw, tmp1)); + return push_inst(compiler, (is_32bit ? forms[1] : forms[2]) | R36A(reg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset)); +} + +static const sljit_ins load_forms[3] = { + 0x58000000 /* l */, + 0xe30000000058 /* ly */, + 0xe30000000004 /* lg */ +}; + +static const sljit_ins store_forms[3] = { + 0x50000000 /* st */, + 0xe30000000050 /* sty */, + 0xe30000000024 /* stg */ +}; + +static const sljit_ins load_halfword_forms[3] = { + 0x48000000 /* lh */, + 0xe30000000078 /* lhy */, + 0xe30000000015 /* lgh */ +}; + +/* May clobber tmp1. */ +static SLJIT_INLINE sljit_s32 load_word(struct sljit_compiler *compiler, sljit_gpr dst_r, sljit_s32 src, sljit_sw srcw, sljit_s32 is_32bit) { - struct addr addr; - sljit_ins ins; - - SLJIT_ASSERT(src & SLJIT_MEM); - - if (is_32bit && ((src & OFFS_REG_MASK) || is_u12(srcw) || !is_s20(srcw))) { - FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1)); - return push_inst(compiler, 0x58000000 /* l */ | R20A(dst_r) | R16A(addr.index) | R12A(addr.base) | (sljit_ins)addr.offset); - } - - FAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp1)); - - ins = is_32bit ? 0xe30000000058 /* ly */ : 0xe30000000004 /* lg */; - return push_inst(compiler, ins | R36A(dst_r) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset)); + return load_store_op(compiler, dst_r, src, srcw, is_32bit, load_forms); } /* May clobber tmp1. */ @@ -1032,24 +1046,11 @@ static sljit_s32 load_unsigned_word(struct sljit_compiler *compiler, sljit_gpr d } /* May clobber tmp1. */ -static sljit_s32 store_word(struct sljit_compiler *compiler, sljit_gpr src_r, +static SLJIT_INLINE sljit_s32 store_word(struct sljit_compiler *compiler, sljit_gpr src_r, sljit_s32 dst, sljit_sw dstw, sljit_s32 is_32bit) { - struct addr addr; - sljit_ins ins; - - SLJIT_ASSERT(dst & SLJIT_MEM); - - if (is_32bit && ((dst & OFFS_REG_MASK) || is_u12(dstw) || !is_s20(dstw))) { - FAIL_IF(make_addr_bx(compiler, &addr, dst, dstw, tmp1)); - return push_inst(compiler, 0x50000000 /* st */ | R20A(src_r) | R16A(addr.index) | R12A(addr.base) | (sljit_ins)addr.offset); - } - - FAIL_IF(make_addr_bxy(compiler, &addr, dst, dstw, tmp1)); - - ins = is_32bit ? 0xe30000000050 /* sty */ : 0xe30000000024 /* stg */; - return push_inst(compiler, ins | R36A(src_r) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset)); + return load_store_op(compiler, src_r, dst, dstw, is_32bit, store_forms); } #undef WHEN @@ -1058,15 +1059,17 @@ static sljit_s32 emit_move(struct sljit_compiler *compiler, sljit_gpr dst_r, sljit_s32 src, sljit_sw srcw) { + sljit_gpr src_r; + SLJIT_ASSERT(!IS_GPR_REG(src) || dst_r != gpr(src & REG_MASK)); - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) return push_load_imm_inst(compiler, dst_r, srcw); if (src & SLJIT_MEM) return load_word(compiler, dst_r, src, srcw, (compiler->mode & SLJIT_32) != 0); - sljit_gpr src_r = gpr(src & REG_MASK); + src_r = gpr(src & REG_MASK); return push_inst(compiler, (compiler->mode & SLJIT_32) ? lr(dst_r, src_r) : lgr(dst_r, src_r)); } @@ -1259,10 +1262,10 @@ static sljit_s32 emit_siy(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_sw srcw) { - SLJIT_ASSERT(dst & SLJIT_MEM); - sljit_gpr dst_r = tmp1; + SLJIT_ASSERT(dst & SLJIT_MEM); + if (dst & OFFS_REG_MASK) { sljit_gpr index = tmp1; @@ -1567,6 +1570,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (jump && jump->addr == j) { sljit_sw target = (sljit_sw)((jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target); if ((jump->flags & SLJIT_REWRITABLE_JUMP) || (jump->flags & JUMP_ADDR)) { + sljit_ins op, arg; + jump->addr = (sljit_uw)pool_ptr; /* load address into tmp1 */ @@ -1583,8 +1588,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil *(pool_ptr++) = (sljit_uw)target; /* branch to tmp1 */ - sljit_ins op = (ins >> 32) & 0xf; - sljit_ins arg = (ins >> 36) & 0xf; + op = (ins >> 32) & 0xf; + arg = (ins >> 36) & 0xf; switch (op) { case 4: /* brcl -> bcr */ ins = bcr(arg, tmp1); @@ -1638,6 +1643,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; compiler->executable_size = ins_size; + if (pool_size) + compiler->executable_size += (pad_size + pool_size); code = SLJIT_ADD_EXEC_OFFSET(code, executable_offset); code_ptr = SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); SLJIT_CACHE_FLUSH(code, code_ptr); @@ -1650,12 +1657,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) /* TODO(mundaym): implement all */ switch (feature_type) { case SLJIT_HAS_FPU: +#ifdef SLJIT_IS_FPU_AVAILABLE + return (SLJIT_IS_FPU_AVAILABLE) != 0; +#else + return 1; +#endif /* SLJIT_IS_FPU_AVAILABLE */ + case SLJIT_HAS_CLZ: + case SLJIT_HAS_REV: case SLJIT_HAS_ROT: case SLJIT_HAS_PREFETCH: + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: + case SLJIT_HAS_SIMD: + case SLJIT_HAS_ATOMIC: return 1; + case SLJIT_HAS_CTZ: return 2; + case SLJIT_HAS_CMOV: return have_lscond1() ? 1 : 0; } @@ -1664,7 +1684,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - return (type >= SLJIT_UNORDERED && type <= SLJIT_ORDERED_LESS_EQUAL); + SLJIT_UNUSED_ARG(type); + return 0; } /* --------------------------------------------------------------------- */ @@ -1741,7 +1762,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi local_size = (local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE + 0xf) & ~0xf; compiler->local_size = local_size; - FAIL_IF(push_inst(compiler, 0xe30000000071 /* lay */ | R36A(r15) | R28A(r15) | disp_s20(-local_size))); + if (is_s20(-local_size)) + FAIL_IF(push_inst(compiler, 0xe30000000071 /* lay */ | R36A(r15) | R28A(r15) | disp_s20(-local_size))); + else + FAIL_IF(push_inst(compiler, 0xc20400000000 /* slgfi */ | R36A(r15) | (sljit_ins)local_size)); if (options & SLJIT_ENTER_REG_ARG) return SLJIT_SUCCESS; @@ -1786,8 +1810,10 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit if (is_u12(local_size)) FAIL_IF(push_inst(compiler, 0x41000000 /* ly */ | R20A(r15) | R12A(r15) | (sljit_ins)local_size)); - else + else if (is_s20(local_size)) FAIL_IF(push_inst(compiler, 0xe30000000071 /* lay */ | R36A(r15) | R28A(r15) | disp_s20(local_size))); + else + FAIL_IF(push_inst(compiler, 0xc20a00000000 /* algfi */ | R36A(r15) | (sljit_ins)local_size)); offset = 2 * SSIZE_OF(sw); if (saveds + scratches >= SLJIT_NUMBER_OF_REGISTERS) { @@ -2011,12 +2037,85 @@ static sljit_s32 sljit_emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 o return push_inst(compiler, ((op & SLJIT_32) ? 0x1800 /* lr */ : 0xb9040000 /* lgr */) | R4A(dst_r) | R0A(tmp0)); } +static sljit_s32 sljit_emit_rev(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + struct addr addr; + sljit_gpr reg; + sljit_ins ins; + sljit_s32 opcode = GET_OPCODE(op); + sljit_s32 is_16bit = (opcode == SLJIT_REV_U16 || opcode == SLJIT_REV_S16); + + if (dst & SLJIT_MEM) { + if (src & SLJIT_MEM) { + FAIL_IF(load_store_op(compiler, tmp0, src, srcw, op & SLJIT_32, is_16bit ? load_halfword_forms : load_forms)); + reg = tmp0; + } else + reg = gpr(src); + + FAIL_IF(make_addr_bxy(compiler, &addr, dst, dstw, tmp1)); + + if (is_16bit) + ins = 0xe3000000003f /* strvh */; + else + ins = (op & SLJIT_32) ? 0xe3000000003e /* strv */ : 0xe3000000002f /* strvg */; + + return push_inst(compiler, ins | R36A(reg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset)); + } + + reg = gpr(dst); + + if (src & SLJIT_MEM) { + FAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp1)); + + if (is_16bit) + ins = 0xe3000000001f /* lrvh */; + else + ins = (op & SLJIT_32) ? 0xe3000000001e /* lrv */ : 0xe3000000000f /* lrvg */; + + FAIL_IF(push_inst(compiler, ins | R36A(reg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset))); + + if (opcode == SLJIT_REV) + return SLJIT_SUCCESS; + + if (is_16bit) { + if (op & SLJIT_32) + ins = (opcode == SLJIT_REV_U16) ? 0xb9950000 /* llhr */ : 0xb9270000 /* lhr */; + else + ins = (opcode == SLJIT_REV_U16) ? 0xb9850000 /* llghr */ : 0xb9070000 /* lghr */; + } else + ins = (opcode == SLJIT_REV_U32) ? 0xb9160000 /* llgfr */ : 0xb9140000 /* lgfr */; + + return push_inst(compiler, ins | R4A(reg) | R0A(reg)); + } + + ins = (op & SLJIT_32) ? 0xb91f0000 /* lrvr */ : 0xb90f0000 /* lrvgr */; + FAIL_IF(push_inst(compiler, ins | R4A(reg) | R0A(gpr(src)))); + + if (opcode == SLJIT_REV) + return SLJIT_SUCCESS; + + if (!is_16bit) { + ins = (opcode == SLJIT_REV_U32) ? 0xb9160000 /* llgfr */ : 0xb9140000 /* lgfr */; + return push_inst(compiler, ins | R4A(reg) | R0A(reg)); + } + + if (op & SLJIT_32) { + ins = (opcode == SLJIT_REV_U16) ? 0x88000000 /* srl */ : 0x8a000000 /* sra */; + return push_inst(compiler, ins | R20A(reg) | 16); + } + + ins = (opcode == SLJIT_REV_U16) ? 0xeb000000000c /* srlg */ : 0xeb000000000a /* srag */; + return push_inst(compiler, ins | R36A(reg) | R32A(reg) | (48 << 16)); +} + /* LEVAL will be defined later with different parameters as needed */ #define WHEN2(cond, i1, i2) (cond) ? LEVAL(i1) : LEVAL(i2) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src, sljit_sw srcw) + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { sljit_ins ins; struct addr mem; @@ -2087,7 +2186,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile return SLJIT_SUCCESS; } /* LOAD IMMEDIATE */ - if (FAST_IS_REG(dst) && (src & SLJIT_IMM)) { + if (FAST_IS_REG(dst) && src == SLJIT_IMM) { switch (opcode) { case SLJIT_MOV_U8: srcw = (sljit_sw)((sljit_u8)(srcw)); @@ -2166,14 +2265,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile return SLJIT_SUCCESS; } /* STORE and STORE IMMEDIATE */ - if ((dst & SLJIT_MEM) - && (FAST_IS_REG(src) || (src & SLJIT_IMM))) { + if ((dst & SLJIT_MEM) && (FAST_IS_REG(src) || src == SLJIT_IMM)) { + struct addr mem; sljit_gpr reg = FAST_IS_REG(src) ? gpr(src) : tmp0; - if (src & SLJIT_IMM) { + + if (src == SLJIT_IMM) { /* TODO(mundaym): MOVE IMMEDIATE? */ FAIL_IF(push_load_imm_inst(compiler, reg, srcw)); } - struct addr mem; FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1)); switch (opcode) { case SLJIT_MOV_U8: @@ -2240,39 +2339,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile SLJIT_UNREACHABLE(); } - SLJIT_ASSERT((src & SLJIT_IMM) == 0); /* no immediates */ + SLJIT_ASSERT(src != SLJIT_IMM); - dst_r = FAST_IS_REG(dst) ? gpr(REG_MASK & dst) : tmp0; - src_r = FAST_IS_REG(src) ? gpr(REG_MASK & src) : tmp0; + dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0; + src_r = FAST_IS_REG(src) ? gpr(src) : tmp0; compiler->status_flags_state = op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z); /* TODO(mundaym): optimize loads and stores */ switch (opcode) { - case SLJIT_NOT: - if (src & SLJIT_MEM) - FAIL_IF(load_word(compiler, src_r, src, srcw, op & SLJIT_32)); - - /* emulate ~x with x^-1 */ - if (!(op & SLJIT_32)) { - FAIL_IF(push_load_imm_inst(compiler, tmp1, -1)); - if (src_r != dst_r) - FAIL_IF(push_inst(compiler, lgr(dst_r, src_r))); - - FAIL_IF(push_inst(compiler, xgr(dst_r, tmp1))); - break; - } - - if (have_eimm()) - FAIL_IF(push_inst(compiler, xilf(dst_r, 0xffffffff))); - else { - FAIL_IF(push_load_imm_inst(compiler, tmp1, -1)); - if (src_r != dst_r) - FAIL_IF(push_inst(compiler, lr(dst_r, src_r))); - - FAIL_IF(push_inst(compiler, xr(dst_r, tmp1))); - } - break; case SLJIT_CLZ: case SLJIT_CTZ: if (src & SLJIT_MEM) @@ -2280,13 +2355,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile FAIL_IF(sljit_emit_clz_ctz(compiler, op, dst_r, src_r)); break; + case SLJIT_REV_U32: + case SLJIT_REV_S32: + op |= SLJIT_32; + /* fallthrough */ + case SLJIT_REV: + case SLJIT_REV_U16: + case SLJIT_REV_S16: + return sljit_emit_rev(compiler, op, dst, dstw, src, srcw); default: SLJIT_UNREACHABLE(); } - if ((op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_SET_Z | SLJIT_SET_OVERFLOW)) - FAIL_IF(update_zero_overflow(compiler, op, dst_r)); - if (dst & SLJIT_MEM) return store_word(compiler, dst_r, dst, dstw, op & SLJIT_32); @@ -2337,7 +2417,7 @@ static sljit_s32 sljit_emit_add(struct sljit_compiler *compiler, sljit_s32 op, const struct ins_forms *forms; sljit_ins ins; - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { if (!sets_zero_overflow && is_s8(src2w) && (src1 & SLJIT_MEM) && (dst == src1 && dstw == src1w)) { if (sets_overflow) ins = (op & SLJIT_32) ? 0xeb000000006a /* asi */ : 0xeb000000007a /* agsi */; @@ -2422,9 +2502,8 @@ static sljit_s32 sljit_emit_sub(struct sljit_compiler *compiler, sljit_s32 op, compiler->status_flags_state |= SLJIT_CURRENT_FLAGS_COMPARE; - if (src2 & SLJIT_IMM) { - if (compare_signed || ((op & VARIABLE_FLAG_MASK) == 0 && is_s32(src2w))) - { + if (src2 == SLJIT_IMM) { + if (compare_signed || ((op & VARIABLE_FLAG_MASK) == 0 && is_s32(src2w))) { if ((op & SLJIT_32) || is_s32(src2w)) { ins = (op & SLJIT_32) ? 0xc20d00000000 /* cfi */ : 0xc20c00000000 /* cgfi */; return emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A); @@ -2465,7 +2544,7 @@ static sljit_s32 sljit_emit_sub(struct sljit_compiler *compiler, sljit_s32 op, goto done; } - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { sljit_sw neg_src2w = -src2w; if (sets_signed || neg_src2w != 0 || (op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == 0) { @@ -2573,7 +2652,7 @@ static sljit_s32 sljit_emit_multiply(struct sljit_compiler *compiler, sljit_s32 return emit_commutative(compiler, &multiply_overflow_forms, dst, src1, src1w, src2, src2w); } - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { if (is_s16(src2w)) { ins = (op & SLJIT_32) ? 0xa70c0000 /* mhi */ : 0xa70d0000 /* mghi */; return emit_ri(compiler, ins, dst, src1, src1w, src2w, RI_A); @@ -2680,7 +2759,7 @@ static sljit_s32 sljit_emit_bitwise(struct sljit_compiler *compiler, sljit_s32 o sljit_s32 type = GET_OPCODE(op); const struct ins_forms *forms; - if ((src2 & SLJIT_IMM) && (!(op & SLJIT_SET_Z) || (type == SLJIT_AND && dst == (sljit_s32)tmp0))) { + if (src2 == SLJIT_IMM && (!(op & SLJIT_SET_Z) || (type == SLJIT_AND && dst == (sljit_s32)tmp0))) { sljit_s32 count16 = 0; sljit_uw imm = (sljit_uw)src2w; @@ -2705,12 +2784,12 @@ static sljit_s32 sljit_emit_bitwise(struct sljit_compiler *compiler, sljit_s32 o FAIL_IF(emit_move(compiler, tmp0, src1, src1w)); if ((imm & 0x000000000000ffffull) != 0 || imm == 0) - return push_inst(compiler, 0xa7010000 | R20A(src_r) | imm); + return push_inst(compiler, 0xa7010000 /* tmll */ | R20A(src_r) | imm); if ((imm & 0x00000000ffff0000ull) != 0) - return push_inst(compiler, 0xa7000000 | R20A(src_r) | (imm >> 16)); + return push_inst(compiler, 0xa7000000 /* tmlh */ | R20A(src_r) | (imm >> 16)); if ((imm & 0x0000ffff00000000ull) != 0) - return push_inst(compiler, 0xa7030000 | R20A(src_r) | (imm >> 32)); - return push_inst(compiler, 0xa7020000 | R20A(src_r) | (imm >> 48)); + return push_inst(compiler, 0xa7030000 /* tmhl */ | R20A(src_r) | (imm >> 32)); + return push_inst(compiler, 0xa7020000 /* tmhh */ | R20A(src_r) | (imm >> 48)); } if (!(op & SLJIT_SET_Z)) @@ -2744,7 +2823,7 @@ static sljit_s32 sljit_emit_shift(struct sljit_compiler *compiler, sljit_s32 op, else FAIL_IF(emit_move(compiler, tmp0, src1, src1w)); - if (!(src2 & SLJIT_IMM)) { + if (src2 != SLJIT_IMM) { if (FAST_IS_REG(src2)) base_r = gpr(src2); else { @@ -2804,7 +2883,7 @@ static sljit_s32 sljit_emit_rotate(struct sljit_compiler *compiler, sljit_s32 op else FAIL_IF(emit_move(compiler, tmp0, src1, src1w)); - if (!(src2 & SLJIT_IMM)) { + if (src2 != SLJIT_IMM) { if (FAST_IS_REG(src2)) base_r = gpr(src2); else { @@ -2814,7 +2893,7 @@ static sljit_s32 sljit_emit_rotate(struct sljit_compiler *compiler, sljit_s32 op } if (GET_OPCODE(op) == SLJIT_ROTR) { - if (!(src2 & SLJIT_IMM)) { + if (src2 != SLJIT_IMM) { ins = (op & SLJIT_32) ? 0x1300 /* lcr */ : 0xb9030000 /* lcgr */; FAIL_IF(push_inst(compiler, ins | R4A(tmp1) | R0A(base_r))); base_r = tmp1; @@ -2822,7 +2901,7 @@ static sljit_s32 sljit_emit_rotate(struct sljit_compiler *compiler, sljit_s32 op src2w = -src2w; } - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) imm = (sljit_ins)(src2w & ((op & SLJIT_32) ? 0x1f : 0x3f)); ins = (op & SLJIT_32) ? 0xeb000000001d /* rll */ : 0xeb000000001c /* rllg */; @@ -2863,7 +2942,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile compiler->mode = op & SLJIT_32; compiler->status_flags_state = op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z); - if (is_commutative(op) && (src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM)) { + if (is_commutative(op) && src1 == SLJIT_IMM && src2 != SLJIT_IMM) { src1 ^= src2; src2 ^= src1; src1 ^= src2; @@ -2931,122 +3010,125 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_right; sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64; - sljit_gpr src_dst_r = gpr(src_dst); - sljit_gpr src1_r = tmp0; - sljit_gpr src2_r = tmp1; + sljit_gpr dst_r = gpr(dst_reg); + sljit_gpr src1_r = gpr(src1_reg); + sljit_gpr src2_r = gpr(src2_reg); + sljit_gpr src3_r = tmp1; sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); is_right = (GET_OPCODE(op) == SLJIT_LSHR || GET_OPCODE(op) == SLJIT_MLSHR); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); - if (src1 & SLJIT_MEM) - FAIL_IF(load_word(compiler, tmp0, src1, src1w, op & SLJIT_32)); - else if (src1 & SLJIT_IMM) - FAIL_IF(push_load_imm_inst(compiler, tmp0, src1w)); - else - src1_r = gpr(src1); + if (src3 == SLJIT_IMM) { + src3w &= bit_length - 1; - if (src2 & SLJIT_IMM) { - src2w &= bit_length - 1; - - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (!(src2 & SLJIT_MEM)) - src2_r = gpr(src2); - else - FAIL_IF(load_word(compiler, tmp1, src2, src2w, op & SLJIT_32)); - if (src2 & SLJIT_IMM) { if (op & SLJIT_32) { - ins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */; - FAIL_IF(push_inst(compiler, ins | R20A(src_dst_r) | (sljit_ins)src2w)); + if (dst_r == src1_r) { + ins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */; + FAIL_IF(push_inst(compiler, ins | R20A(dst_r) | (sljit_ins)src3w)); + } else { + ins = is_right ? 0xeb00000000de /* srlk */ : 0xeb00000000df /* sllk */; + FAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | ((sljit_ins)src3w << 16))); + } } else { ins = is_right ? 0xeb000000000c /* srlg */ : 0xeb000000000d /* sllg */; - FAIL_IF(push_inst(compiler, ins | R36A(src_dst_r) | R32A(src_dst_r) | ((sljit_ins)src2w << 16))); + FAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | ((sljit_ins)src3w << 16))); } ins = 0xec0000000055 /* risbg */; if (is_right) { - src2w = bit_length - src2w; - ins |= ((sljit_ins)(64 - bit_length) << 24) | ((sljit_ins)(63 - src2w) << 16) | ((sljit_ins)src2w << 8); + src3w = bit_length - src3w; + ins |= ((sljit_ins)(64 - bit_length) << 24) | ((sljit_ins)(63 - src3w) << 16) | ((sljit_ins)src3w << 8); } else - ins |= ((sljit_ins)(64 - src2w) << 24) | ((sljit_ins)63 << 16) | ((sljit_ins)src2w << 8); + ins |= ((sljit_ins)(64 - src3w) << 24) | ((sljit_ins)63 << 16) | ((sljit_ins)(src3w + 64 - bit_length) << 8); - return push_inst(compiler, ins | R36A(src_dst_r) | R32A(src1_r)); + return push_inst(compiler, ins | R36A(dst_r) | R32A(src2_r)); } + if (!(src3 & SLJIT_MEM)) { + src3_r = gpr(src3); + + if (dst_r == src3_r) { + FAIL_IF(push_inst(compiler, 0x1800 /* lr */ | R4A(tmp1) | R0A(src3_r))); + src3_r = tmp1; + } + } else + FAIL_IF(load_word(compiler, tmp1, src3, src3w, op & SLJIT_32)); + if (op & SLJIT_32) { if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR) { - if (src2_r != tmp1) { - FAIL_IF(push_inst(compiler, 0xec0000000055 /* risbg */ | R36A(tmp1) | R32A(src2_r) | (59 << 24) | (1 << 23) | (63 << 16))); - src2_r = tmp1; + if (src3_r != tmp1) { + FAIL_IF(push_inst(compiler, 0xec0000000055 /* risbg */ | R36A(tmp1) | R32A(src3_r) | (59 << 24) | (1 << 23) | (63 << 16))); + src3_r = tmp1; } else FAIL_IF(push_inst(compiler, 0xa5070000 /* nill */ | R20A(tmp1) | 0x1f)); } - ins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */; - FAIL_IF(push_inst(compiler, ins | R20A(src_dst_r) | R12A(src2_r))); + if (dst_r == src1_r) { + ins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */; + FAIL_IF(push_inst(compiler, ins | R20A(dst_r) | R12A(src3_r))); + } else { + ins = is_right ? 0xeb00000000de /* srlk */ : 0xeb00000000df /* sllk */; + FAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | R28A(src3_r))); + } - if (src2_r != tmp1) { + if (src3_r != tmp1) { FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | 0x1f)); - FAIL_IF(push_inst(compiler, 0x1700 /* xr */ | R4A(tmp1) | R0A(src2_r))); + FAIL_IF(push_inst(compiler, 0x1700 /* xr */ | R4A(tmp1) | R0A(src3_r))); } else FAIL_IF(push_inst(compiler, 0xc00700000000 /* xilf */ | R36A(tmp1) | 0x1f)); - if (src1_r == tmp0) { - ins = is_right ? 0x89000000 /* sll */ : 0x88000000 /* srl */; - FAIL_IF(push_inst(compiler, ins | R20A(tmp0) | R12A(tmp1) | 0x1)); - } else { - ins = is_right ? 0xeb00000000df /* sllk */ : 0xeb00000000de /* srlk */; - FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src1_r) | R28A(tmp1) | (0x1 << 16))); - } + ins = is_right ? 0xeb00000000df /* sllk */ : 0xeb00000000de /* srlk */; + FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src2_r) | R28A(tmp1) | (0x1 << 16))); - return push_inst(compiler, 0x1600 /* or */ | R4A(src_dst_r) | R0A(tmp0)); + return push_inst(compiler, 0x1600 /* or */ | R4A(dst_r) | R0A(tmp0)); } ins = is_right ? 0xeb000000000c /* srlg */ : 0xeb000000000d /* sllg */; - FAIL_IF(push_inst(compiler, ins | R36A(src_dst_r) | R32A(src_dst_r) | R28A(src2_r))); + FAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | R28A(src3_r))); ins = is_right ? 0xeb000000000d /* sllg */ : 0xeb000000000c /* srlg */; if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) { - if (src2_r != tmp1) + if (src3_r != tmp1) FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | 0x3f)); - FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src1_r) | (0x1 << 16))); - src1_r = tmp0; + FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src2_r) | (0x1 << 16))); + src2_r = tmp0; - if (src2_r != tmp1) - FAIL_IF(push_inst(compiler, 0xb9820000 /* xgr */ | R4A(tmp1) | R0A(src2_r))); + if (src3_r != tmp1) + FAIL_IF(push_inst(compiler, 0xb9820000 /* xgr */ | R4A(tmp1) | R0A(src3_r))); else FAIL_IF(push_inst(compiler, 0xc00700000000 /* xilf */ | R36A(tmp1) | 0x3f)); } else - FAIL_IF(push_inst(compiler, 0xb9030000 /* lcgr */ | R4A(tmp1) | R0A(src2_r))); + FAIL_IF(push_inst(compiler, 0xb9030000 /* lcgr */ | R4A(tmp1) | R0A(src3_r))); - FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src1_r) | R28A(tmp1))); - return push_inst(compiler, 0xb9810000 /* ogr */ | R4A(src_dst_r) | R0A(tmp0)); + FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src2_r) | R28A(tmp1))); + return push_inst(compiler, 0xb9810000 /* ogr */ | R4A(dst_r) | R0A(tmp0)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src( - struct sljit_compiler *compiler, - sljit_s32 op, sljit_s32 src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw) { sljit_gpr src_r; struct addr addr; @@ -3077,16 +3159,46 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src( return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return (sljit_s32)gpr(reg); + sljit_gpr dst_r = link_r; + sljit_s32 size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + if (FAST_IS_REG(dst)) + return push_inst(compiler, lgr(gpr(dst), link_r)); + break; + case SLJIT_GET_RETURN_ADDRESS: + dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0; + + size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 2); + FAIL_IF(load_word(compiler, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + size, 0)); + break; + } + + if (dst & SLJIT_MEM) + return store_word(compiler, dst_r, dst, dstw, 0); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return (sljit_s32)fgpr(reg); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return (sljit_s32)gpr(reg); + + if (type != SLJIT_FLOAT_REGISTER) + return -1; + + return (sljit_s32)freg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -3177,33 +3289,61 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_ins ins; - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { FAIL_IF(push_load_imm_inst(compiler, tmp0, srcw)); src = (sljit_s32)tmp0; } else if (src & SLJIT_MEM) { - FAIL_IF(load_word(compiler, tmp0, src, srcw, GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_S32)); + FAIL_IF(load_word(compiler, tmp0, src, srcw, ins & 0x100000)); src = (sljit_s32)tmp0; } + FAIL_IF(push_inst(compiler, ins | F4(dst_r) | R0(src))); + + if (dst & SLJIT_MEM) + return float_mem(compiler, FLOAT_STORE | ((ins & 0x10000) ? 0 : SLJIT_32), TMP_FREG1, dst, dstw); + + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins ins; + + if (src == SLJIT_IMM && GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) ins = (op & SLJIT_32) ? 0xb3a40000 /* cegbr */ : 0xb3a50000 /* cdgbr */; else ins = (op & SLJIT_32) ? 0xb3940000 /* cefbr */ : 0xb3950000 /* cdfbr */; - FAIL_IF(push_inst(compiler, ins | F4(dst_r) | R0(src))); + return sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw); +} - if (dst & SLJIT_MEM) - return float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), TMP_FREG1, dst, dstw); +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins ins; - return SLJIT_SUCCESS; + if (src == SLJIT_IMM && GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) + srcw = (sljit_u32)srcw; + + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_UW) + ins = (op & SLJIT_32) ? 0xb3a00000 /* celgbr */ : 0xb3a10000 /* cdlgbr */; + else + ins = (op & SLJIT_32) ? 0xb3900000 /* celfbr */ : 0xb3910000 /* cdlfbr */; + + return sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw); } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, @@ -3355,21 +3495,91 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return SLJIT_SUCCESS; } -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { + sljit_s32 reg; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); - if (FAST_IS_REG(dst)) - return push_inst(compiler, lgr(gpr(dst), link_r)); + if (src2 & SLJIT_MEM) { + FAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), TMP_FREG1, src2, src2w)); + src2 = TMP_FREG1; + } - /* memory */ - return store_word(compiler, link_r, dst, dstw, 0); + if (src1 & SLJIT_MEM) { + reg = (dst_freg == src2) ? TMP_FREG1 : dst_freg; + FAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), reg, src1, src1w)); + src1 = reg; + } + + return push_inst(compiler, 0xb3720000 /* cpsdr */ | F12(src2) | F4(dst_freg) | F0(src1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) +{ + union { + sljit_s32 imm; + sljit_f32 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); + + u.value = value; + + FAIL_IF(push_load_imm_inst(compiler, tmp1, (sljit_sw)(((sljit_uw)u.imm << 32)))); + return push_inst(compiler, 0xb3c10000 /* ldgr */ | F4(freg) | R0A(tmp1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_sw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + FAIL_IF(push_load_imm_inst(compiler, tmp1, (sljit_sw)u.imm)); + return push_inst(compiler, 0xb3c10000 /* ldgr */ | F4(freg) | R0A(tmp1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_gpr gen_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + gen_r = gpr(reg); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) { + if (op & SLJIT_32) { + FAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp0) | R32A(gen_r) | (32 << 16))); + gen_r = tmp0; + } + + return push_inst(compiler, 0xb3c10000 /* ldgr */ | F4(freg) | R0A(gen_r)); + } + + FAIL_IF(push_inst(compiler, 0xb3cd0000 /* lgdr */ | R4A(gen_r) | F0(freg))); + + if (!(op & SLJIT_32)) + return SLJIT_SUCCESS; + + return push_inst(compiler, 0xeb000000000c /* srlg */ | R36A(gen_r) | R32A(gen_r) | (32 << 16)); } /* --------------------------------------------------------------------- */ @@ -3394,14 +3604,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { + struct sljit_jump *jump; sljit_u8 mask = ((type & 0xff) < SLJIT_JUMP) ? get_cc(compiler, type & 0xff) : 0xf; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_jump(compiler, type)); /* record jump */ - struct sljit_jump *jump = (struct sljit_jump *) - ensure_abuf(compiler, sizeof(struct sljit_jump)); + jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump)); PTR_FAIL_IF(!jump); set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); jump->addr = compiler->size; @@ -3439,7 +3649,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { SLJIT_ASSERT(!(srcw & 1)); /* target address must be even */ FAIL_IF(push_load_imm_inst(compiler, src_r, srcw)); } @@ -3459,6 +3669,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi sljit_s32 arg_types, sljit_s32 src, sljit_sw srcw) { + SLJIT_UNUSED_ARG(arg_types); + CHECK_ERROR(); CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw)); @@ -3490,13 +3702,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_s32 dst, sljit_sw dstw, sljit_s32 type) { + sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0; + sljit_gpr loc_r = tmp1; sljit_u8 mask = get_cc(compiler, type); CHECK_ERROR(); CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type)); - sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0; - sljit_gpr loc_r = tmp1; switch (GET_OPCODE(op)) { case SLJIT_AND: case SLJIT_OR: @@ -3556,37 +3768,125 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { - sljit_ins mask = get_cc(compiler, type & ~SLJIT_32); + sljit_ins mask; sljit_gpr src_r; + sljit_gpr dst_r = gpr(dst_reg); sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); - if (type & SLJIT_32) - srcw = (sljit_s32)srcw; + ADJUST_LOCAL_OFFSET(src1, src1w); - if (have_lscond2() && (src & SLJIT_IMM) && is_s16(srcw)) { - ins = (type & SLJIT_32) ? 0xec0000000042 /* lochi */ : 0xec0000000046 /* locghi */; - return push_inst(compiler, ins | R36A(gpr(dst_reg)) | (mask << 32) | (sljit_ins)(srcw & 0xffff) << 16); + if (dst_reg != src2_reg) { + if (src1 == dst_reg) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) { + FAIL_IF(load_word(compiler, dst_r, src1, src1w, type & SLJIT_32)); + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, ((type & SLJIT_32) ? 0x1800 /* lr */ : 0xb9040000 /* lgr */) | R4A(dst_r) | R0A(gpr(src2_reg)))); + } } - if (src & SLJIT_IMM) { - FAIL_IF(push_load_imm_inst(compiler, tmp0, srcw)); + mask = get_cc(compiler, type & ~SLJIT_32); + + if (src1 & SLJIT_MEM) { + if (src1 & OFFS_REG_MASK) { + src_r = gpr(OFFS_REG(src1)); + + if (src1w != 0) { + FAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp1) | R32A(src_r) | ((sljit_ins)(src1w & 0x3) << 16))); + src_r = tmp1; + } + + FAIL_IF(push_inst(compiler, 0xb9e80000 /* agrk */ | R12A(src_r) | R4A(tmp1) | R0A(gpr(src1 & REG_MASK)))); + src_r = tmp1; + src1w = 0; + } else if (!is_s20(src1w)) { + FAIL_IF(push_load_imm_inst(compiler, tmp1, src1w)); + + if (src1 & REG_MASK) + FAIL_IF(push_inst(compiler, 0xb9e80000 /* agrk */ | R12A(tmp1) | R4A(tmp1) | R0A(gpr(src1 & REG_MASK)))); + + src_r = tmp1; + src1w = 0; + } else + src_r = gpr(src1 & REG_MASK); + + ins = (type & SLJIT_32) ? 0xeb00000000f2 /* loc */ : 0xeb00000000e2 /* locg */; + return push_inst(compiler, ins | R36A(dst_r) | (mask << 32) | R28A(src_r) | disp_s20((sljit_s32)src1w)); + } + + if (src1 == SLJIT_IMM) { + if (type & SLJIT_32) + src1w = (sljit_s32)src1w; + + if (have_lscond2() && is_s16(src1w)) { + ins = (type & SLJIT_32) ? 0xec0000000042 /* lochi */ : 0xec0000000046 /* locghi */; + return push_inst(compiler, ins | R36A(dst_r) | (mask << 32) | (sljit_ins)(src1w & 0xffff) << 16); + } + + FAIL_IF(push_load_imm_inst(compiler, tmp0, src1w)); src_r = tmp0; } else - src_r = gpr(src); + src_r = gpr(src1); - if (have_lscond1()) { - ins = (type & SLJIT_32) ? 0xb9f20000 /* locr */ : 0xb9e20000 /* locgr */; - return push_inst(compiler, ins | (mask << 12) | R4A(gpr(dst_reg)) | R0A(src_r)); + ins = (type & SLJIT_32) ? 0xb9f20000 /* locr */ : 0xb9e20000 /* locgr */; + return push_inst(compiler, ins | (mask << 12) | R4A(dst_r) | R0A(src_r)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_ins ins; + struct sljit_label *label; + struct sljit_jump *jump; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else { + ins = (type & SLJIT_32) ? 0x3800 /* ler */ : 0x2800 /* ldr */; + FAIL_IF(push_inst(compiler, ins | F4(dst_freg) | F0(src2_freg))); + } } - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw); + SLJIT_SKIP_CHECKS(compiler); + jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1); + FAIL_IF(!jump); + + if (!(src1 & SLJIT_MEM)) { + ins = (type & SLJIT_32) ? 0x3800 /* ler */ : 0x2800 /* ldr */; + FAIL_IF(push_inst(compiler, ins | F4(dst_freg) | F0(src1))); + } else + FAIL_IF(float_mem(compiler, FLOAT_LOAD | (type & SLJIT_32), dst_freg, src1, src1w)); + + SLJIT_SKIP_CHECKS(compiler); + label = sljit_emit_label(compiler); + FAIL_IF(!label); + + sljit_set_label(jump, label); + return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, @@ -3648,6 +3948,502 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile return push_inst(compiler, ins | R36A(reg2) | disp_s20((sljit_s32)memw + SSIZE_OF(sw))); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); + struct addr addr; + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (!(srcdst & SLJIT_MEM)) { + if (type & SLJIT_SIMD_STORE) + ins = F36(srcdst) | F32(freg); + else + ins = F36(freg) | F32(srcdst); + + return push_inst(compiler, 0xe70000000056 /* vlr */ | ins); + } + + FAIL_IF(make_addr_bx(compiler, &addr, srcdst, srcdstw, tmp1)); + ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + + if (alignment >= 4) + ins |= 4 << 12; + else if (alignment == 3) + ins |= 3 << 12; + + return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? 0xe7000000000e /* vst */ : 0xe70000000006 /* vl */) | ins); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + struct addr addr; + sljit_gpr reg; + sljit_sw sign_ext; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && elem_size < 2) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (src & SLJIT_MEM) { + FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1)); + return push_inst(compiler, 0xe70000000005 /* vlrep */ | F36(freg) + | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset) | ((sljit_ins)elem_size << 12)); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (src == SLJIT_IMM) + return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg)); + + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(src) | ((sljit_ins)elem_size << 12)); + } + + if (src == SLJIT_IMM) { + sign_ext = 0x10000; + + switch (elem_size) { + case 0: + srcw &= 0xff; + sign_ext = (sljit_s8)srcw; + break; + case 1: + srcw &= 0xffff; + sign_ext = (sljit_s16)srcw; + break; + case 2: + if ((sljit_s32)srcw == (sljit_s16)srcw) { + srcw &= 0xffff; + sign_ext = (sljit_s16)srcw; + } else + srcw &= 0xffffffff; + break; + default: + if (srcw == (sljit_s16)srcw) { + srcw &= 0xffff; + sign_ext = (sljit_s16)srcw; + } + break; + } + + if (sign_ext != 0x10000) { + if (sign_ext == 0 || sign_ext == -1) + return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg) + | (sign_ext == 0 ? 0 : ((sljit_ins)0xffff << 16))); + + return push_inst(compiler, 0xe70000000045 /* vrepi */ | F36(freg) + | ((sljit_ins)srcw << 16) | ((sljit_ins)elem_size << 12)); + } + + push_load_imm_inst(compiler, tmp0, srcw); + reg = tmp0; + } else + reg = gpr(src); + + FAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(reg) | ((sljit_ins)elem_size << 12))); + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(freg) | ((sljit_ins)elem_size << 12)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + struct addr addr; + sljit_gpr reg; + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && elem_size < 2) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (srcdst & SLJIT_MEM) { + FAIL_IF(make_addr_bx(compiler, &addr, srcdst, srcdstw, tmp1)); + ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + } + + if (type & SLJIT_SIMD_LANE_ZERO) { + if ((srcdst & SLJIT_MEM) && lane_index == ((1 << (3 - elem_size)) - 1)) + return push_inst(compiler, 0xe70000000004 /* vllez */ | ins | ((sljit_ins)elem_size << 12)); + + if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { + FAIL_IF(push_inst(compiler, 0xe70000000056 /* vlr */ | F36(TMP_FREG1) | F32(freg))); + srcdst = TMP_FREG1; + srcdstw = 0; + } + + FAIL_IF(push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg))); + } + + if (srcdst & SLJIT_MEM) { + switch (elem_size) { + case 0: + ins |= 0xe70000000000 /* vleb */; + break; + case 1: + ins |= 0xe70000000001 /* vleh */; + break; + case 2: + ins |= 0xe70000000003 /* vlef */; + break; + default: + ins |= 0xe70000000002 /* vleg */; + break; + } + + /* Convert to vsteb - vsteg */ + if (type & SLJIT_SIMD_STORE) + ins |= 0x8; + + return push_inst(compiler, ins | ((sljit_ins)lane_index << 12)); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (type & SLJIT_SIMD_STORE) + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(srcdst) | F32(freg) | ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12)); + + if (elem_size == 3) { + if (lane_index == 0) + ins = F32(srcdst) | F28(freg) | (1 << 12); + else + ins = F32(freg) | F28(srcdst); + + return push_inst(compiler, 0xe70000000084 /* vpdi */ | F36(freg) | ins); + } + + FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(tmp0) | F32(srcdst) | ((sljit_ins)2 << 12))); + return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(tmp0) | ((sljit_ins)lane_index << 16) | ((sljit_ins)2 << 12)); + } + + if (srcdst == SLJIT_IMM) { + switch (elem_size) { + case 0: + ins = 0xe70000000040 /* vleib */; + srcdstw &= 0xff; + break; + case 1: + ins = 0xe70000000041 /* vleih */; + srcdstw &= 0xffff; + break; + case 2: + if ((sljit_s32)srcdstw == (sljit_s16)srcdstw) { + srcdstw &= 0xffff; + ins = 0xe70000000043 /* vleif */; + } else + srcdstw &= 0xffffffff; + break; + default: + if (srcdstw == (sljit_s16)srcdstw) { + srcdstw &= 0xffff; + ins = 0xe70000000042 /* vleig */; + } + break; + } + + if (ins != 0) + return push_inst(compiler, ins | F36(freg) | ((sljit_ins)srcdstw << 16) | ((sljit_ins)lane_index << 12)); + + push_load_imm_inst(compiler, tmp0, srcdstw); + reg = tmp0; + } else + reg = gpr(srcdst); + + ins = ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12); + + if (!(type & SLJIT_SIMD_STORE)) + return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(reg) | ins); + + FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(reg) | F32(freg) | ins)); + + if (!(type & SLJIT_SIMD_LANE_SIGNED) || elem_size >= 3) + return SLJIT_SUCCESS; + + switch (elem_size) { + case 0: + ins = 0xb9060000 /* lgbr */; + break; + case 1: + ins = 0xb9070000 /* lghr */; + break; + default: + ins = 0xb9140000 /* lgfr */; + break; + } + + return push_inst(compiler, ins | R4A(reg) | R0A(reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && elem_size < 2) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(src) + | ((sljit_ins)src_lane_index << 16) | ((sljit_ins)elem_size << 12)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); + struct addr addr; + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && elem_size < 2) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (src & SLJIT_MEM) { + FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1)); + ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + + switch (elem2_size - elem_size) { + case 1: + ins |= 0xe70000000002 /* vleg */; + break; + case 2: + ins |= 0xe70000000003 /* vlef */; + break; + default: + ins |= 0xe70000000001 /* vleh */; + break; + } + + FAIL_IF(push_inst(compiler, ins)); + src = freg; + } + + if (type & SLJIT_SIMD_FLOAT) { + FAIL_IF(push_inst(compiler, 0xe700000000d5 /* vuplh */ | F36(freg) | F32(src) | (2 << 12))); + FAIL_IF(push_inst(compiler, 0xe70000000030 /* vesl */ | F36(freg) | F32(freg) | (32 << 16) | (3 << 12))); + return push_inst(compiler, 0xe700000000c4 /* vfll */ | F36(freg) | F32(freg) | (2 << 12)); + } + + ins = ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0xe700000000d7 /* vuph */ : 0xe700000000d5 /* vuplh */) | F36(freg); + + do { + FAIL_IF(push_inst(compiler, ins | F32(src) | ((sljit_ins)elem_size << 12))); + src = freg; + } while (++elem_size < elem2_size); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_gpr dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && elem_size < 2) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + switch (elem_size) { + case 0: + push_load_imm_inst(compiler, tmp0, (sljit_sw)0x4048505860687078); + push_load_imm_inst(compiler, tmp1, (sljit_sw)0x0008101820283038); + FAIL_IF(push_inst(compiler, 0xe70000000062 /* vlvgp */ | F36(TMP_FREG1) | R32A(tmp1) | R28A(tmp0))); + break; + case 1: + push_load_imm_inst(compiler, tmp0, (sljit_sw)0x0010203040506070); + break; + case 2: + push_load_imm_inst(compiler, tmp0, (sljit_sw)0x8080808000204060); + break; + default: + push_load_imm_inst(compiler, tmp0, (sljit_sw)0x8080808080800040); + break; + } + + if (elem_size != 0) + FAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(TMP_FREG1) | R32A(tmp0) | (1 << 16) | (3 << 12))); + + FAIL_IF(push_inst(compiler, 0xe70000000085 /* vbperm */ | F36(TMP_FREG1) | F32(freg) | F28(TMP_FREG1))); + + dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0; + FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(dst_r) | F32(TMP_FREG1) + | (elem_size == 0 ? ((3 << 16) | (1 << 12)) : (7 << 16)))); + + if (dst_r == tmp0) + return store_word(compiler, tmp0, dst, dstw, type & SLJIT_32); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + switch (SLJIT_SIMD_GET_OPCODE(type)) { + case SLJIT_SIMD_OP2_AND: + ins = 0xe70000000068 /* vn */; + break; + case SLJIT_SIMD_OP2_OR: + ins = 0xe7000000006a /* vo */; + break; + case SLJIT_SIMD_OP2_XOR: + ins = 0xe7000000006d /* vx */; + break; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + return push_inst(compiler, ins | F36(dst_freg) | F32(src1_freg) | F28(src2_freg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + SLJIT_SKIP_CHECKS(compiler); + return sljit_emit_op1(compiler, op, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_ins mask; + sljit_gpr tmp_r = gpr(temp_reg); + sljit_gpr mem_r = gpr(mem_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + return push_inst(compiler, 0xba000000 /* cs */ | R20A(tmp_r) | R16A(gpr(src_reg)) | R12A(mem_r)); + case SLJIT_MOV_U8: + mask = 0xff; + break; + case SLJIT_MOV_U16: + mask = 0xffff; + break; + default: + return push_inst(compiler, 0xeb0000000030 /* csg */ | R36A(tmp_r) | R32A(gpr(src_reg)) | R28A(mem_r)); + } + + /* tmp0 = (src_reg ^ tmp_r) & mask */ + FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | mask)); + FAIL_IF(push_inst(compiler, 0xb9e70000 /* xgrk */ | R4A(tmp0) | R0A(gpr(src_reg)) | R12A(tmp_r))); + FAIL_IF(push_inst(compiler, 0xa7090000 /* lghi */ | R20A(tmp_r) | 0xfffc)); + FAIL_IF(push_inst(compiler, 0xb9800000 /* ngr */ | R4A(tmp0) | R0A(tmp1))); + + /* tmp0 = tmp0 << (((mem_r ^ 0x3) & 0x3) << 3) */ + FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | (sljit_ins)((mask == 0xff) ? 0x18 : 0x10))); + FAIL_IF(push_inst(compiler, 0xb9800000 /* ngr */ | R4A(tmp_r) | R0A(mem_r))); + FAIL_IF(push_inst(compiler, 0xec0000000057 /* rxsbg */ | R36A(tmp1) | R32A(mem_r) | (59 << 24) | (60 << 16) | (3 << 8))); + FAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp0) | R32A(tmp0) | R28A(tmp1))); + + /* Already computed: tmp_r = mem_r & ~0x3 */ + + FAIL_IF(push_inst(compiler, 0x58000000 /* l */ | R20A(tmp1) | R12A(tmp_r))); + FAIL_IF(push_inst(compiler, 0x1700 /* x */ | R4A(tmp0) | R0A(tmp1))); + return push_inst(compiler, 0xba000000 /* cs */ | R20A(tmp1) | R16A(tmp0) | R12A(tmp_r)); +} + /* --------------------------------------------------------------------- */ /* Other instructions */ /* --------------------------------------------------------------------- */ diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c index 08da03026d4..ba4a1ebbc20 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c @@ -62,21 +62,19 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw /* Both size flags cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); /* SSE2 and immediate is not possible. */ - SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); - SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) - && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) - && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); + SLJIT_ASSERT(a != SLJIT_IMM || !(flags & EX86_SSE2)); + SLJIT_ASSERT(((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) + & ((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0); + SLJIT_ASSERT((flags & (EX86_VEX_EXT | EX86_REX)) != EX86_VEX_EXT); size &= 0xf; - inst_size = size; + /* The mod r/m byte is always present. */ + inst_size = size + 1; - if (flags & (EX86_PREF_F2 | EX86_PREF_F3)) - inst_size++; - if (flags & EX86_PREF_66) + if (flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) inst_size++; /* Calculate size of b. */ - inst_size += 1; /* mod r/m byte. */ if (b & SLJIT_MEM) { if (!(b & REG_MASK)) inst_size += sizeof(sljit_sw); @@ -87,8 +85,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw inst_size += sizeof(sljit_s8); else inst_size += sizeof(sljit_sw); - } - else if (reg_map[b & REG_MASK] == 5) { + } else if (reg_map[b & REG_MASK] == 5) { /* Swap registers if possible. */ if ((b & OFFS_REG_MASK) && (immb & 0x3) == 0 && reg_map[OFFS_REG(b)] != 5) b = SLJIT_MEM | OFFS_REG(b) | TO_OFFS_REG(b & REG_MASK); @@ -105,15 +102,14 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw } /* Calculate size of a. */ - if (a & SLJIT_IMM) { + if (a == SLJIT_IMM) { if (flags & EX86_BIN_INS) { if (imma <= 127 && imma >= -128) { inst_size += 1; flags |= EX86_BYTE_ARG; } else inst_size += 4; - } - else if (flags & EX86_SHIFT_INS) { + } else if (flags & EX86_SHIFT_INS) { SLJIT_ASSERT(imma <= 0x1f); if (imma != 1) { inst_size++; @@ -125,8 +121,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw inst_size += sizeof(short); else inst_size += sizeof(sljit_sw); - } - else + } else SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size); @@ -136,27 +131,26 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw INC_SIZE(inst_size); if (flags & EX86_PREF_F2) *inst++ = 0xf2; - if (flags & EX86_PREF_F3) + else if (flags & EX86_PREF_F3) *inst++ = 0xf3; - if (flags & EX86_PREF_66) + else if (flags & EX86_PREF_66) *inst++ = 0x66; buf_ptr = inst + size; /* Encode mod/rm byte. */ if (!(flags & EX86_SHIFT_INS)) { - if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) + if ((flags & EX86_BIN_INS) && a == SLJIT_IMM) *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; - if (a & SLJIT_IMM) + if (a == SLJIT_IMM) *buf_ptr = 0; else if (!(flags & EX86_SSE2_OP1)) *buf_ptr = U8(reg_map[a] << 3); else - *buf_ptr = U8(a << 3); - } - else { - if (a & SLJIT_IMM) { + *buf_ptr = U8(freg_map[a] << 3); + } else { + if (a == SLJIT_IMM) { if (imma == 1) *inst = GROUP_SHIFT_1; else @@ -167,7 +161,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw } if (!(b & SLJIT_MEM)) { - *buf_ptr = U8(*buf_ptr | MOD_REG | (!(flags & EX86_SSE2_OP2) ? reg_map[b] : b)); + *buf_ptr = U8(*buf_ptr | MOD_REG | (!(flags & EX86_SSE2_OP2) ? reg_map[b] : freg_map[b])); buf_ptr++; } else if (b & REG_MASK) { reg_map_b = reg_map[b & REG_MASK]; @@ -183,8 +177,9 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw if (!(b & OFFS_REG_MASK)) *buf_ptr++ |= reg_map_b; else { - *buf_ptr++ |= 0x04; - *buf_ptr++ = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3)); + buf_ptr[0] |= 0x04; + buf_ptr[1] = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3)); + buf_ptr += 2; } if (immb != 0 || reg_map_b == 5) { @@ -195,25 +190,24 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw buf_ptr += sizeof(sljit_sw); } } - } - else { + } else { if (reg_map_b == 5) *buf_ptr |= 0x40; - *buf_ptr++ |= 0x04; - *buf_ptr++ = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3) | (immb << 6)); + buf_ptr[0] |= 0x04; + buf_ptr[1] = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3) | (immb << 6)); + buf_ptr += 2; if (reg_map_b == 5) *buf_ptr++ = 0; } - } - else { + } else { *buf_ptr++ |= 0x05; sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */ buf_ptr += sizeof(sljit_sw); } - if (a & SLJIT_IMM) { + if (a == SLJIT_IMM) { if (flags & EX86_BYTE_ARG) *buf_ptr = U8(imma); else if (flags & EX86_HALF_ARG) @@ -222,7 +216,67 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw sljit_unaligned_store_sw(buf_ptr, imma); } - return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); + return inst; +} + +static sljit_s32 emit_vex_instruction(struct sljit_compiler *compiler, sljit_uw op, + /* The first and second register operand. */ + sljit_s32 a, sljit_s32 v, + /* The general operand (not immediate). */ + sljit_s32 b, sljit_sw immb) +{ + sljit_u8 *inst; + sljit_u8 vex = 0; + sljit_u8 vex_m = 0; + sljit_uw size; + + SLJIT_ASSERT(((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) + & ((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0); + + if (op & VEX_OP_0F38) + vex_m = 0x2; + else if (op & VEX_OP_0F3A) + vex_m = 0x3; + + if (op & VEX_W) { + if (vex_m == 0) + vex_m = 0x1; + + vex |= 0x80; + } + + if (op & EX86_PREF_66) + vex |= 0x1; + else if (op & EX86_PREF_F2) + vex |= 0x3; + else if (op & EX86_PREF_F3) + vex |= 0x2; + + op &= ~(EX86_PREF_66 | EX86_PREF_F2 | EX86_PREF_F3); + + if (op & VEX_256) + vex |= 0x4; + + vex = U8(vex | ((((op & VEX_SSE2_OPV) ? freg_map[v] : reg_map[v]) ^ 0xf) << 3)); + + size = op & ~(sljit_uw)0xff; + size |= (vex_m == 0) ? 3 : 4; + + inst = emit_x86_instruction(compiler, size, a, 0, b, immb); + FAIL_IF(!inst); + + if (vex_m == 0) { + inst[0] = 0xc5; + inst[1] = U8(vex | 0x80); + inst[2] = U8(op); + return SLJIT_SUCCESS; + } + + inst[0] = 0xc4; + inst[1] = U8(vex_m | 0xe0); + inst[2] = vex; + inst[3] = U8(op); + return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ @@ -578,8 +632,6 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler) { - sljit_u8 *inst; - CHECK_ERROR(); CHECK(check_sljit_emit_return_void(compiler)); @@ -588,11 +640,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler FAIL_IF(emit_stack_frame_release(compiler, 0)); - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - RET(); - return SLJIT_SUCCESS; + return emit_byte(compiler, RET_near); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler, @@ -782,7 +830,7 @@ static sljit_s32 tail_call_with_args(struct sljit_compiler *compiler, offset = stack_size + compiler->local_size; - if (!(src & SLJIT_IMM) && src != SLJIT_R0) { + if (src != SLJIT_IMM && src != SLJIT_R0) { if (word_arg_count >= 1) { EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R0, 0); r2_offset = sizeof(sljit_sw); @@ -836,7 +884,7 @@ static sljit_s32 tail_call_with_args(struct sljit_compiler *compiler, stack_size = args_size + SSIZE_OF(sw); - if (word_arg_count >= 1 && !(src & SLJIT_IMM) && src != SLJIT_R0) { + if (word_arg_count >= 1 && src != SLJIT_IMM && src != SLJIT_R0) { r2_offset = SSIZE_OF(sw); stack_size += SSIZE_OF(sw); } @@ -865,7 +913,7 @@ static sljit_s32 tail_call_with_args(struct sljit_compiler *compiler, EMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), word_arg4_offset); } - if (!(src & SLJIT_IMM) && src != SLJIT_R0) { + if (src != SLJIT_IMM && src != SLJIT_R0) { if (word_arg_count >= 1) { SLJIT_ASSERT(r2_offset == sizeof(sljit_sw)); EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R0, 0); @@ -952,13 +1000,7 @@ static sljit_s32 emit_tail_call_end(struct sljit_compiler *compiler, sljit_s32 e sljit_u8 *inst; BINARY_IMM32(ADD, extra_space, SLJIT_SP, 0); - - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - RET(); - - return SLJIT_SUCCESS; + return emit_byte(compiler, RET_near); } static sljit_s32 tail_call_reg_arg_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types) @@ -1075,7 +1117,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi stack_size = type; FAIL_IF(tail_call_with_args(compiler, &stack_size, arg_types, src, srcw)); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { src = SLJIT_R0; srcw = 0; } @@ -1142,30 +1184,20 @@ static SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *com return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +static sljit_s32 emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { sljit_u8 *inst; - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - CHECK_EXTRA_REGS(dst, dstw, (void)0); - if (FAST_IS_REG(dst)) { - /* Unused dest is possible here. */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - - INC_SIZE(1); - POP_REG(reg_map[dst]); - return SLJIT_SUCCESS; - } + /* Unused dest is possible here. */ + if (FAST_IS_REG(dst)) + return emit_byte(compiler, U8(POP_r + reg_map[dst])); /* Memory. */ inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!inst); - *inst++ = POP_rm; + *inst = POP_rm; return SLJIT_SUCCESS; } @@ -1185,8 +1217,8 @@ static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src else { inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst |= PUSH_rm; + inst[0] = GROUP_FF; + inst[1] |= PUSH_rm; inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); @@ -1197,6 +1229,22 @@ static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src return SLJIT_SUCCESS; } +static sljit_s32 sljit_emit_get_return_address(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 options = compiler->options; + sljit_s32 saveds = compiler->saveds; + sljit_s32 scratches = compiler->scratches; + + saveds = ((scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3) - SLJIT_KEPT_SAVEDS_COUNT(options)) * SSIZE_OF(sw); + + /* Saving ebp. */ + if (!(options & SLJIT_ENTER_REG_ARG)) + saveds += SSIZE_OF(sw); + + return emit_mov(compiler, dst, dstw, SLJIT_MEM1(SLJIT_SP), compiler->local_size + saveds); +} + /* --------------------------------------------------------------------- */ /* Other operations */ /* --------------------------------------------------------------------- */ @@ -1279,6 +1327,283 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile return SLJIT_SUCCESS; } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; + sljit_u8 *inst, *jump_inst1, *jump_inst2; + sljit_uw size1, size2; + + /* Binary representation of 0x80000000. */ + static const sljit_f64 f64_high_bit = (sljit_f64)0x80000000ul; + + CHECK_EXTRA_REGS(src, srcw, (void)0); + + if (!(op & SLJIT_32)) { + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0); + FAIL_IF(!inst); + inst[1] |= ROL; + + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0); + FAIL_IF(!inst); + inst[1] |= SHR; + + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_PREF_F2 | EX86_SSE2_OP1, dst_r, TMP_REG1, 0)); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = U8(get_jump_code(SLJIT_NOT_CARRY) - 0x10); + + size1 = compiler->size; + FAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_PREF_F2 | EX86_SSE2, dst_r, SLJIT_MEM0(), (sljit_sw)&f64_high_bit)); + + inst[1] = U8(compiler->size - size1); + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, 0, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; + } + + if (!FAST_IS_REG(src)) { + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + src = TMP_REG1; + } + + BINARY_IMM32(CMP, 0, src, 0); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = JL_i8; + jump_inst1 = inst; + + size1 = compiler->size; + + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, src, 0)); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = JMP_i8; + jump_inst2 = inst; + + size2 = compiler->size; + + jump_inst1[1] = U8(size2 - size1); + + if (src != TMP_REG1) + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); + + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0); + FAIL_IF(!inst); + inst[1] |= SHR; + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = JNC_i8; + jump_inst1 = inst; + + size1 = compiler->size; + + BINARY_IMM32(OR, 1, TMP_REG1, 0); + jump_inst1[1] = U8(compiler->size - size1); + + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, TMP_REG1, 0)); + FAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, dst_r, 0)); + + jump_inst2[1] = U8(compiler->size - size2); + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) +{ + sljit_u8 *inst; + union { + sljit_s32 imm; + sljit_f32 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); + + u.value = value; + + if (u.imm != 0) + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + + inst[0] = GROUP_66; + inst[1] = GROUP_0F; + + if (u.imm == 0) { + inst[2] = PXOR_x_xm; + inst[3] = U8(freg | (freg << 3) | MOD_REG); + } else { + inst[2] = MOVD_x_rm; + inst[3] = U8(reg_map[TMP_REG1] | (freg << 3) | MOD_REG); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + sljit_u8 *inst; + sljit_s32 tmp_freg = freg; + union { + sljit_s32 imm[2]; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm[0] == 0) { + if (u.imm[1] == 0) + return emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, freg, freg, 0); + + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm[1]); + } else + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm[0]); + + FAIL_IF(emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, freg, TMP_REG1, 0)); + + if (u.imm[1] == 0) + return SLJIT_SUCCESS; + + if (u.imm[0] == 0) { + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + + inst[0] = GROUP_0F; + inst[1] = SHUFPS_x_xm; + inst[2] = U8(MOD_REG | (freg << 3) | freg); + inst[3] = 0x51; + return SLJIT_SUCCESS; + } + + if (u.imm[0] != u.imm[1]) { + SLJIT_ASSERT(u.imm[1] != 0 && cpu_feature_list != 0); + + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm[1]); + + if (cpu_feature_list & CPU_FEATURE_SSE41) { + FAIL_IF(emit_groupf_ext(compiler, PINSRD_x_rm_i8 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2_OP1, freg, TMP_REG1, 0)); + return emit_byte(compiler, 1); + } + + FAIL_IF(emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, TMP_FREG, TMP_REG1, 0)); + tmp_freg = TMP_FREG; + } + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); + FAIL_IF(!inst); + INC_SIZE(3); + + inst[0] = GROUP_0F; + inst[1] = UNPCKLPS_x_xm; + inst[2] = U8(MOD_REG | (freg << 3) | tmp_freg); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_u8 *inst; + sljit_s32 reg2; + sljit_sw regw, reg2w; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + regw = 0; + reg2 = 0; + reg2w = 0; + + SLJIT_ASSERT(cpu_feature_list != 0); + + if (!(op & SLJIT_32) && (cpu_feature_list & CPU_FEATURE_SSE41)) { + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_FIRST(reg); + reg = REG_PAIR_SECOND(reg); + + CHECK_EXTRA_REGS(reg, regw, (void)0); + + FAIL_IF(emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x) + | EX86_PREF_66 | EX86_SSE2_OP1, freg, reg, regw)); + } else + reg2 = reg; + + CHECK_EXTRA_REGS(reg2, reg2w, (void)0); + + FAIL_IF(emit_groupf_ext(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? PINSRD_x_rm_i8 : PEXTRD_rm_x_i8) + | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2_OP1, freg, reg2, reg2w)); + return emit_byte(compiler, 1); + } + + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + + if (reg == reg2) + reg = 0; + + CHECK_EXTRA_REGS(reg2, reg2w, (void)0); + } + + CHECK_EXTRA_REGS(reg, regw, (void)0); + + if (op & SLJIT_32) + return emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x) + | EX86_PREF_66 | EX86_SSE2_OP1, freg, reg, regw); + + if (op == SLJIT_COPY_FROM_F64) { + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); + + inst[0] = GROUP_66; + inst[1] = GROUP_0F; + inst[2] = PSHUFD_x_xm; + inst[3] = U8(MOD_REG | (TMP_FREG << 3) | freg); + inst[4] = 1; + } else if (reg != 0) + FAIL_IF(emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, TMP_FREG, reg, regw)); + + if (reg2 != 0) + FAIL_IF(emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x) + | EX86_PREF_66 | EX86_SSE2_OP1, freg, reg2, reg2w)); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) { + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); + FAIL_IF(!inst); + INC_SIZE(3); + + inst[0] = GROUP_0F; + inst[1] = UNPCKLPS_x_xm; + inst[2] = U8(MOD_REG | (freg << 3) | (reg == 0 ? freg : TMP_FREG)); + } else + FAIL_IF(emit_groupf(compiler, MOVD_rm_x | EX86_PREF_66 | EX86_SSE2_OP1, TMP_FREG, reg, regw)); + + return SLJIT_SUCCESS; +} + static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler) { sljit_sw size; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c index 4e938ffcf31..f313f3f038f 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c @@ -37,9 +37,9 @@ static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg, inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw)); FAIL_IF(!inst); INC_SIZE(2 + sizeof(sljit_sw)); - *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); - *inst++ = U8(MOV_r_i32 | (reg_map[reg] & 0x7)); - sljit_unaligned_store_sw(inst, imm); + inst[0] = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); + inst[1] = U8(MOV_r_i32 | reg_lmap[reg]); + sljit_unaligned_store_sw(inst + 2, imm); return SLJIT_SUCCESS; } @@ -72,7 +72,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw sljit_uw inst_size; /* The immediate operand must be 32 bit. */ - SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma)); + SLJIT_ASSERT(a != SLJIT_IMM || compiler->mode32 || IS_HALFWORD(imma)); /* Both cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); /* Size flags not allowed for typed instructions. */ @@ -80,26 +80,24 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw /* Both size flags cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); /* SSE2 and immediate is not possible. */ - SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); - SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) - && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) - && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); + SLJIT_ASSERT(a != SLJIT_IMM || !(flags & EX86_SSE2)); + SLJIT_ASSERT(((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) + & ((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0); + SLJIT_ASSERT((flags & (EX86_VEX_EXT | EX86_REX)) != EX86_VEX_EXT); size &= 0xf; - inst_size = size; + /* The mod r/m byte is always present. */ + inst_size = size + 1; if (!compiler->mode32 && !(flags & EX86_NO_REXW)) rex |= REX_W; else if (flags & EX86_REX) rex |= REX; - if (flags & (EX86_PREF_F2 | EX86_PREF_F3)) - inst_size++; - if (flags & EX86_PREF_66) + if (flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) inst_size++; /* Calculate size of b. */ - inst_size += 1; /* mod r/m byte. */ if (b & SLJIT_MEM) { if (!(b & OFFS_REG_MASK) && NOT_HALFWORD(immb)) { PTR_FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immb)); @@ -119,8 +117,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw inst_size += sizeof(sljit_s8); else inst_size += sizeof(sljit_s32); - } - else if (reg_lmap[b & REG_MASK] == 5) { + } else if (reg_lmap[b & REG_MASK] == 5) { /* Swap registers if possible. */ if ((b & OFFS_REG_MASK) && (immb & 0x3) == 0 && reg_lmap[OFFS_REG(b)] != 5) b = SLJIT_MEM | OFFS_REG(b) | TO_OFFS_REG(b & REG_MASK); @@ -140,23 +137,26 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw rex |= REX_X; } } - } - else if (!(flags & EX86_SSE2_OP2)) { + } else if (!(flags & EX86_SSE2_OP2)) { if (reg_map[b] >= 8) rex |= REX_B; - } - else if (freg_map[b] >= 8) + } else if (freg_map[b] >= 8) rex |= REX_B; - if (a & SLJIT_IMM) { + if ((flags & EX86_VEX_EXT) && (rex & 0x3)) { + SLJIT_ASSERT(size == 2); + size++; + inst_size++; + } + + if (a == SLJIT_IMM) { if (flags & EX86_BIN_INS) { if (imma <= 127 && imma >= -128) { inst_size += 1; flags |= EX86_BYTE_ARG; } else inst_size += 4; - } - else if (flags & EX86_SHIFT_INS) { + } else if (flags & EX86_SHIFT_INS) { SLJIT_ASSERT(imma <= (compiler->mode32 ? 0x1f : 0x3f)); if (imma != 1) { inst_size++; @@ -168,8 +168,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw inst_size += sizeof(short); else inst_size += sizeof(sljit_s32); - } - else { + } else { SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */ if (!(flags & EX86_SSE2_OP1)) { @@ -186,32 +185,34 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size); PTR_FAIL_IF(!inst); - /* Encoding the byte. */ + /* Encoding prefixes. */ INC_SIZE(inst_size); if (flags & EX86_PREF_F2) *inst++ = 0xf2; - if (flags & EX86_PREF_F3) + else if (flags & EX86_PREF_F3) *inst++ = 0xf3; - if (flags & EX86_PREF_66) + else if (flags & EX86_PREF_66) *inst++ = 0x66; + + /* Rex is always the last prefix. */ if (rex) *inst++ = rex; + buf_ptr = inst + size; /* Encode mod/rm byte. */ if (!(flags & EX86_SHIFT_INS)) { - if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) + if ((flags & EX86_BIN_INS) && a == SLJIT_IMM) *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; - if (a & SLJIT_IMM) + if (a == SLJIT_IMM) *buf_ptr = 0; else if (!(flags & EX86_SSE2_OP1)) *buf_ptr = U8(reg_lmap[a] << 3); else *buf_ptr = U8(freg_lmap[a] << 3); - } - else { - if (a & SLJIT_IMM) { + } else { + if (a == SLJIT_IMM) { if (imma == 1) *inst = GROUP_SHIFT_1; else @@ -238,8 +239,9 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw if (!(b & OFFS_REG_MASK)) *buf_ptr++ |= reg_lmap_b; else { - *buf_ptr++ |= 0x04; - *buf_ptr++ = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3)); + buf_ptr[0] |= 0x04; + buf_ptr[1] = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3)); + buf_ptr += 2; } if (immb != 0 || reg_lmap_b == 5) { @@ -250,26 +252,26 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw buf_ptr += sizeof(sljit_s32); } } - } - else { + } else { if (reg_lmap_b == 5) *buf_ptr |= 0x40; - *buf_ptr++ |= 0x04; - *buf_ptr++ = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6)); + buf_ptr[0] |= 0x04; + buf_ptr[1] = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6)); + buf_ptr += 2; if (reg_lmap_b == 5) *buf_ptr++ = 0; } - } - else { - *buf_ptr++ |= 0x04; - *buf_ptr++ = 0x25; + } else { + buf_ptr[0] |= 0x04; + buf_ptr[1] = 0x25; + buf_ptr += 2; sljit_unaligned_store_s32(buf_ptr, (sljit_s32)immb); /* 32 bit displacement. */ buf_ptr += sizeof(sljit_s32); } - if (a & SLJIT_IMM) { + if (a == SLJIT_IMM) { if (flags & EX86_BYTE_ARG) *buf_ptr = U8(imma); else if (flags & EX86_HALF_ARG) @@ -278,7 +280,78 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw sljit_unaligned_store_s32(buf_ptr, (sljit_s32)imma); } - return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); + return inst; +} + +static sljit_s32 emit_vex_instruction(struct sljit_compiler *compiler, sljit_uw op, + /* The first and second register operand. */ + sljit_s32 a, sljit_s32 v, + /* The general operand (not immediate). */ + sljit_s32 b, sljit_sw immb) +{ + sljit_u8 *inst; + sljit_u8 vex = 0; + sljit_u8 vex_m = 0; + sljit_uw size; + + SLJIT_ASSERT(((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) + & ((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0); + + op |= EX86_REX; + + if (op & VEX_OP_0F38) + vex_m = 0x2; + else if (op & VEX_OP_0F3A) + vex_m = 0x3; + + if ((op & VEX_W) || ((op & VEX_AUTO_W) && !compiler->mode32)) { + if (vex_m == 0) + vex_m = 0x1; + + vex |= 0x80; + } + + if (op & EX86_PREF_66) + vex |= 0x1; + else if (op & EX86_PREF_F2) + vex |= 0x3; + else if (op & EX86_PREF_F3) + vex |= 0x2; + + op &= ~(EX86_PREF_66 | EX86_PREF_F2 | EX86_PREF_F3); + + if (op & VEX_256) + vex |= 0x4; + + vex = U8(vex | ((((op & VEX_SSE2_OPV) ? freg_map[v] : reg_map[v]) ^ 0xf) << 3)); + + size = op & ~(sljit_uw)0xff; + size |= (vex_m == 0) ? (EX86_VEX_EXT | 2) : 3; + + inst = emit_x86_instruction(compiler, size, a, 0, b, immb); + FAIL_IF(!inst); + + SLJIT_ASSERT((inst[-1] & 0xf0) == REX); + + /* If X or B is present in REX prefix. */ + if (vex_m == 0 && inst[-1] & 0x3) + vex_m = 0x1; + + if (vex_m == 0) { + vex |= U8(((inst[-1] >> 2) ^ 0x1) << 7); + + inst[-1] = 0xc5; + inst[0] = vex; + inst[1] = U8(op); + return SLJIT_SUCCESS; + } + + vex_m |= U8((inst[-1] ^ 0x7) << 5); + inst[-1] = 0xc4; + inst[0] = vex_m; + inst[1] = vex; + inst[2] = U8(op); + return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ @@ -370,6 +443,12 @@ static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, slji return code_ptr; } +#ifdef _WIN64 +typedef struct { + sljit_sw regs[2]; +} sljit_sse2_reg; +#endif /* _WIN64 */ + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) @@ -423,7 +502,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #ifdef _WIN64 local_size += SLJIT_LOCALS_OFFSET; - saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, 16); + saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg); if (saved_float_regs_size > 0) { saved_float_regs_offset = ((local_size + 0xf) & ~0xf); @@ -532,16 +611,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi tmp = SLJIT_FS0 - fsaveds; for (i = SLJIT_FS0; i > tmp; i--) { - inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset); - *inst++ = GROUP_0F; - *inst = MOVAPS_xm_x; + FAIL_IF(emit_groupf(compiler, MOVAPS_xm_x | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset)); saved_float_regs_offset += 16; } for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) { - inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset); - *inst++ = GROUP_0F; - *inst = MOVAPS_xm_x; + FAIL_IF(emit_groupf(compiler, MOVAPS_xm_x | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset)); saved_float_regs_offset += 16; } } @@ -565,7 +640,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp #ifdef _WIN64 local_size += SLJIT_LOCALS_OFFSET; - saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, 16); + saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg); if (saved_float_regs_size > 0) local_size = ((local_size + 0xf) & ~0xf) + saved_float_regs_size; @@ -591,7 +666,7 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit #endif /* _WIN64 */ #ifdef _WIN64 - saved_float_regs_offset = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, 16); + saved_float_regs_offset = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg); if (saved_float_regs_offset > 0) { compiler->mode32 = 1; @@ -599,16 +674,12 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit tmp = SLJIT_FS0 - fsaveds; for (i = SLJIT_FS0; i > tmp; i--) { - inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset); - *inst++ = GROUP_0F; - *inst = MOVAPS_x_xm; + FAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset)); saved_float_regs_offset += 16; } for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) { - inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset); - *inst++ = GROUP_0F; - *inst = MOVAPS_x_xm; + FAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset)); saved_float_regs_offset += 16; } @@ -656,20 +727,13 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler) { - sljit_u8 *inst; - CHECK_ERROR(); CHECK(check_sljit_emit_return_void(compiler)); compiler->mode32 = 0; FAIL_IF(emit_stack_frame_release(compiler, 0)); - - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - RET(); - return SLJIT_SUCCESS; + return emit_byte(compiler, RET_near); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler, @@ -863,22 +927,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi return sljit_emit_ijump(compiler, type, src, srcw); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +static sljit_s32 emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { sljit_u8 *inst; - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - if (FAST_IS_REG(dst)) { - if (reg_map[dst] < 8) { - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - POP_REG(reg_lmap[dst]); - return SLJIT_SUCCESS; - } + if (reg_map[dst] < 8) + return emit_byte(compiler, U8(POP_r + reg_lmap[dst])); inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); @@ -892,7 +947,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * compiler->mode32 = 1; inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!inst); - *inst++ = POP_rm; + *inst = POP_rm; return SLJIT_SUCCESS; } @@ -922,8 +977,8 @@ static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src compiler->mode32 = 1; inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst |= PUSH_rm; + inst[0] = GROUP_FF; + inst[1] |= PUSH_rm; inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); @@ -934,6 +989,16 @@ static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src return SLJIT_SUCCESS; } +static sljit_s32 sljit_emit_get_return_address(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 saved_regs_size; + + compiler->mode32 = 0; + saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 0); + return emit_mov(compiler, dst, dstw, SLJIT_MEM1(SLJIT_SP), compiler->local_size + saved_regs_size); +} + /* --------------------------------------------------------------------- */ /* Other operations */ /* --------------------------------------------------------------------- */ @@ -1027,15 +1092,15 @@ static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign, compiler->mode32 = 0; - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { if (FAST_IS_REG(dst)) { - if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_i32; - return SLJIT_SUCCESS; - } - return emit_load_imm64(compiler, dst, srcw); + if (!sign || ((sljit_u32)srcw <= 0x7fffffff)) + return emit_do_imm32(compiler, reg_map[dst] <= 7 ? 0 : REX_B, U8(MOV_r_i32 | reg_lmap[dst]), srcw); + + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; } compiler->mode32 = 1; inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw); @@ -1053,10 +1118,10 @@ static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign, if (sign) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw); FAIL_IF(!inst); - *inst++ = MOVSXD_r_rm; + *inst = MOVSXD_r_rm; } else { compiler->mode32 = 1; - FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw)); + EMIT_MOV(compiler, dst_r, 0, src, srcw); compiler->mode32 = 0; } } @@ -1072,6 +1137,203 @@ static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign, return SLJIT_SUCCESS; } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; + sljit_u8 *inst, *jump_inst1, *jump_inst2; + sljit_uw size1, size2; + + compiler->mode32 = 0; + + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) { + if (src != SLJIT_IMM) { + compiler->mode32 = 1; + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + compiler->mode32 = 0; + } else + FAIL_IF(emit_do_imm32(compiler, reg_map[TMP_REG1] <= 7 ? 0 : REX_B, U8(MOV_r_i32 | reg_lmap[TMP_REG1]), srcw)); + + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, TMP_REG1, 0)); + + compiler->mode32 = 1; + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; + } + + if (!FAST_IS_REG(src)) { + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + src = TMP_REG1; + } + + BINARY_IMM32(CMP, 0, src, 0); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = JL_i8; + jump_inst1 = inst; + + size1 = compiler->size; + + compiler->mode32 = 0; + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, src, 0)); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = JMP_i8; + jump_inst2 = inst; + + size2 = compiler->size; + + jump_inst1[1] = U8(size2 - size1); + + if (src != TMP_REG1) + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); + + EMIT_MOV(compiler, TMP_REG2, 0, src, 0); + + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0); + FAIL_IF(!inst); + inst[1] |= SHR; + + compiler->mode32 = 1; + BINARY_IMM32(AND, 1, TMP_REG2, 0); + + compiler->mode32 = 0; + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG2, 0); + FAIL_IF(!inst); + inst[0] = OR_r_rm; + + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, TMP_REG1, 0)); + compiler->mode32 = 1; + FAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, dst_r, 0)); + + jump_inst2[1] = U8(compiler->size - size2); + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; +} + +static sljit_s32 sljit_emit_fset(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_u8 rex, sljit_s32 is_zero) +{ + sljit_u8 *inst; + sljit_u32 size; + + if (is_zero) { + rex = freg_map[freg] >= 8 ? (REX_R | REX_B) : 0; + } else { + if (freg_map[freg] >= 8) + rex |= REX_R; + if (reg_map[TMP_REG1] >= 8) + rex |= REX_B; + } + + size = (rex != 0) ? 5 : 4; + + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + + *inst++ = GROUP_66; + if (rex != 0) + *inst++ = rex; + inst[0] = GROUP_0F; + + if (is_zero) { + inst[1] = PXOR_x_xm; + inst[2] = U8(freg_lmap[freg] | (freg_lmap[freg] << 3) | MOD_REG); + } else { + inst[1] = MOVD_x_rm; + inst[2] = U8(reg_lmap[TMP_REG1] | (freg_lmap[freg] << 3) | MOD_REG); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) +{ + union { + sljit_s32 imm; + sljit_f32 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); + + u.value = value; + + if (u.imm != 0) { + compiler->mode32 = 1; + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm); + } + + return sljit_emit_fset(compiler, freg, 0, u.imm == 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_sw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm != 0) { + compiler->mode32 = 0; + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm); + } + + return sljit_emit_fset(compiler, freg, REX_W, u.imm == 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_u8 *inst; + sljit_u32 size; + sljit_u8 rex = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (!(op & SLJIT_32)) + rex = REX_W; + + if (freg_map[freg] >= 8) + rex |= REX_R; + + if (reg_map[reg] >= 8) + rex |= REX_B; + + size = (rex != 0) ? 5 : 4; + + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + + *inst++ = GROUP_66; + if (rex != 0) + *inst++ = rex; + inst[0] = GROUP_0F; + inst[1] = GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x; + inst[2] = U8(reg_lmap[reg] | (freg_lmap[freg] << 3) | MOD_REG); + + return SLJIT_SUCCESS; +} + static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler) { sljit_s32 tmp, size; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c index 651942be80a..c2c0421349b 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c @@ -24,6 +24,12 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#include +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ + SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "x86" SLJIT_CPUINFO; @@ -61,15 +67,18 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) 15 - R15 */ -#define TMP_FREG (0) +#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) +#define TMP_FREG (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -/* Last register + 1. */ -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { - 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 7, 6, 3, 4, 5 + 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 5, 7, 6, 4, 3 +}; + +static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = { + 0, 1, 2, 3, 4, 5, 6, 7, 0 }; #define CHECK_EXTRA_REGS(p, w, do) \ @@ -81,12 +90,10 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { #else /* SLJIT_CONFIG_X86_32 */ -/* Last register + 1. */ -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present - Note: avoid to use r12 and r13 for memory addessing + Note: avoid to use r12 and r13 for memory addressing therefore r12 is better to be a higher saved register. */ #ifndef _WIN64 /* Args: rdi(=7), rsi(=6), rdx(=2), rcx(=1), r8, r9. Scratches: rax(=0), r10, r11 */ @@ -95,7 +102,7 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = { }; /* low-map. reg_map & 0x7. */ static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = { - 0, 0, 6, 7, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 1 + 0, 0, 6, 7, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 1 }; #else /* Args: rcx(=1), rdx(=2), r8, r9. Scratches: rax(=0), r10, r11 */ @@ -109,12 +116,12 @@ static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = { #endif /* Args: xmm0-xmm3 */ -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { - 4, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = { + 0, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4 }; /* low-map. freg_map & 0x7. */ -static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { - 4, 0, 1, 2, 3, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 +static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = { + 0, 0, 1, 2, 3, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 4 }; #define REX_W 0x48 @@ -140,155 +147,237 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { #define U8(v) ((sljit_u8)(v)) - /* Size flags for emit_x86_instruction: */ -#define EX86_BIN_INS 0x0010 -#define EX86_SHIFT_INS 0x0020 -#define EX86_REX 0x0040 -#define EX86_NO_REXW 0x0080 -#define EX86_BYTE_ARG 0x0100 -#define EX86_HALF_ARG 0x0200 -#define EX86_PREF_66 0x0400 -#define EX86_PREF_F2 0x0800 -#define EX86_PREF_F3 0x1000 -#define EX86_SSE2_OP1 0x2000 -#define EX86_SSE2_OP2 0x4000 +#define EX86_BIN_INS ((sljit_uw)0x000010) +#define EX86_SHIFT_INS ((sljit_uw)0x000020) +#define EX86_BYTE_ARG ((sljit_uw)0x000040) +#define EX86_HALF_ARG ((sljit_uw)0x000080) +/* Size flags for both emit_x86_instruction and emit_vex_instruction: */ +#define EX86_REX ((sljit_uw)0x000100) +#define EX86_NO_REXW ((sljit_uw)0x000200) +#define EX86_PREF_66 ((sljit_uw)0x000400) +#define EX86_PREF_F2 ((sljit_uw)0x000800) +#define EX86_PREF_F3 ((sljit_uw)0x001000) +#define EX86_SSE2_OP1 ((sljit_uw)0x002000) +#define EX86_SSE2_OP2 ((sljit_uw)0x004000) #define EX86_SSE2 (EX86_SSE2_OP1 | EX86_SSE2_OP2) +#define EX86_VEX_EXT ((sljit_uw)0x008000) +/* Op flags for emit_vex_instruction: */ +#define VEX_OP_0F38 ((sljit_uw)0x010000) +#define VEX_OP_0F3A ((sljit_uw)0x020000) +#define VEX_SSE2_OPV ((sljit_uw)0x040000) +#define VEX_AUTO_W ((sljit_uw)0x080000) +#define VEX_W ((sljit_uw)0x100000) +#define VEX_256 ((sljit_uw)0x200000) + +#define EX86_SELECT_66(op) (((op) & SLJIT_32) ? 0 : EX86_PREF_66) +#define EX86_SELECT_F2_F3(op) (((op) & SLJIT_32) ? EX86_PREF_F3 : EX86_PREF_F2) /* --------------------------------------------------------------------- */ -/* Instrucion forms */ +/* Instruction forms */ /* --------------------------------------------------------------------- */ -#define ADD (/* BINARY */ 0 << 3) -#define ADD_EAX_i32 0x05 -#define ADD_r_rm 0x03 -#define ADD_rm_r 0x01 -#define ADDSD_x_xm 0x58 -#define ADC (/* BINARY */ 2 << 3) -#define ADC_EAX_i32 0x15 -#define ADC_r_rm 0x13 -#define ADC_rm_r 0x11 -#define AND (/* BINARY */ 4 << 3) -#define AND_EAX_i32 0x25 -#define AND_r_rm 0x23 -#define AND_rm_r 0x21 -#define ANDPD_x_xm 0x54 -#define BSR_r_rm (/* GROUP_0F */ 0xbd) -#define BSF_r_rm (/* GROUP_0F */ 0xbc) -#define CALL_i32 0xe8 -#define CALL_rm (/* GROUP_FF */ 2 << 3) -#define CDQ 0x99 -#define CMOVE_r_rm (/* GROUP_0F */ 0x44) -#define CMP (/* BINARY */ 7 << 3) -#define CMP_EAX_i32 0x3d -#define CMP_r_rm 0x3b -#define CMP_rm_r 0x39 -#define CVTPD2PS_x_xm 0x5a -#define CVTSI2SD_x_rm 0x2a -#define CVTTSD2SI_r_xm 0x2c -#define DIV (/* GROUP_F7 */ 6 << 3) -#define DIVSD_x_xm 0x5e -#define FLDS 0xd9 -#define FLDL 0xdd -#define FSTPS 0xd9 -#define FSTPD 0xdd -#define INT3 0xcc -#define IDIV (/* GROUP_F7 */ 7 << 3) -#define IMUL (/* GROUP_F7 */ 5 << 3) -#define IMUL_r_rm (/* GROUP_0F */ 0xaf) -#define IMUL_r_rm_i8 0x6b -#define IMUL_r_rm_i32 0x69 -#define JE_i8 0x74 -#define JNE_i8 0x75 -#define JMP_i8 0xeb -#define JMP_i32 0xe9 -#define JMP_rm (/* GROUP_FF */ 4 << 3) -#define LEA_r_m 0x8d -#define LOOP_i8 0xe2 -#define LZCNT_r_rm (/* GROUP_F3 */ /* GROUP_0F */ 0xbd) -#define MOV_r_rm 0x8b -#define MOV_r_i32 0xb8 -#define MOV_rm_r 0x89 -#define MOV_rm_i32 0xc7 -#define MOV_rm8_i8 0xc6 -#define MOV_rm8_r8 0x88 -#define MOVAPS_x_xm 0x28 -#define MOVAPS_xm_x 0x29 -#define MOVSD_x_xm 0x10 -#define MOVSD_xm_x 0x11 -#define MOVSXD_r_rm 0x63 -#define MOVSX_r_rm8 (/* GROUP_0F */ 0xbe) -#define MOVSX_r_rm16 (/* GROUP_0F */ 0xbf) -#define MOVZX_r_rm8 (/* GROUP_0F */ 0xb6) -#define MOVZX_r_rm16 (/* GROUP_0F */ 0xb7) -#define MUL (/* GROUP_F7 */ 4 << 3) -#define MULSD_x_xm 0x59 -#define NEG_rm (/* GROUP_F7 */ 3 << 3) -#define NOP 0x90 -#define NOT_rm (/* GROUP_F7 */ 2 << 3) -#define OR (/* BINARY */ 1 << 3) -#define OR_r_rm 0x0b -#define OR_EAX_i32 0x0d -#define OR_rm_r 0x09 -#define OR_rm8_r8 0x08 -#define POP_r 0x58 -#define POP_rm 0x8f -#define POPF 0x9d -#define PREFETCH 0x18 -#define PUSH_i32 0x68 -#define PUSH_r 0x50 -#define PUSH_rm (/* GROUP_FF */ 6 << 3) -#define PUSHF 0x9c -#define ROL (/* SHIFT */ 0 << 3) -#define ROR (/* SHIFT */ 1 << 3) -#define RET_near 0xc3 -#define RET_i16 0xc2 -#define SBB (/* BINARY */ 3 << 3) -#define SBB_EAX_i32 0x1d -#define SBB_r_rm 0x1b -#define SBB_rm_r 0x19 -#define SAR (/* SHIFT */ 7 << 3) -#define SHL (/* SHIFT */ 4 << 3) -#define SHLD (/* GROUP_0F */ 0xa5) -#define SHRD (/* GROUP_0F */ 0xad) -#define SHR (/* SHIFT */ 5 << 3) -#define SUB (/* BINARY */ 5 << 3) -#define SUB_EAX_i32 0x2d -#define SUB_r_rm 0x2b -#define SUB_rm_r 0x29 -#define SUBSD_x_xm 0x5c -#define TEST_EAX_i32 0xa9 -#define TEST_rm_r 0x85 -#define TZCNT_r_rm (/* GROUP_F3 */ /* GROUP_0F */ 0xbc) -#define UCOMISD_x_xm 0x2e -#define UNPCKLPD_x_xm 0x14 -#define XCHG_EAX_r 0x90 -#define XCHG_r_rm 0x87 -#define XOR (/* BINARY */ 6 << 3) -#define XOR_EAX_i32 0x35 -#define XOR_r_rm 0x33 -#define XOR_rm_r 0x31 -#define XORPD_x_xm 0x57 +#define ADD (/* BINARY */ 0 << 3) +#define ADD_EAX_i32 0x05 +#define ADD_r_rm 0x03 +#define ADD_rm_r 0x01 +#define ADDSD_x_xm 0x58 +#define ADC (/* BINARY */ 2 << 3) +#define ADC_EAX_i32 0x15 +#define ADC_r_rm 0x13 +#define ADC_rm_r 0x11 +#define AND (/* BINARY */ 4 << 3) +#define AND_EAX_i32 0x25 +#define AND_r_rm 0x23 +#define AND_rm_r 0x21 +#define ANDPD_x_xm 0x54 +#define BSR_r_rm (/* GROUP_0F */ 0xbd) +#define BSF_r_rm (/* GROUP_0F */ 0xbc) +#define BSWAP_r (/* GROUP_0F */ 0xc8) +#define CALL_i32 0xe8 +#define CALL_rm (/* GROUP_FF */ 2 << 3) +#define CDQ 0x99 +#define CMOVE_r_rm (/* GROUP_0F */ 0x44) +#define CMP (/* BINARY */ 7 << 3) +#define CMP_EAX_i32 0x3d +#define CMP_r_rm 0x3b +#define CMP_rm_r 0x39 +#define CMPS_x_xm 0xc2 +#define CMPXCHG_rm_r 0xb1 +#define CMPXCHG_rm8_r 0xb0 +#define CVTPD2PS_x_xm 0x5a +#define CVTPS2PD_x_xm 0x5a +#define CVTSI2SD_x_rm 0x2a +#define CVTTSD2SI_r_xm 0x2c +#define DIV (/* GROUP_F7 */ 6 << 3) +#define DIVSD_x_xm 0x5e +#define EXTRACTPS_x_xm 0x17 +#define FLDS 0xd9 +#define FLDL 0xdd +#define FSTPS 0xd9 +#define FSTPD 0xdd +#define INSERTPS_x_xm 0x21 +#define INT3 0xcc +#define IDIV (/* GROUP_F7 */ 7 << 3) +#define IMUL (/* GROUP_F7 */ 5 << 3) +#define IMUL_r_rm (/* GROUP_0F */ 0xaf) +#define IMUL_r_rm_i8 0x6b +#define IMUL_r_rm_i32 0x69 +#define JL_i8 0x7c +#define JE_i8 0x74 +#define JNC_i8 0x73 +#define JNE_i8 0x75 +#define JMP_i8 0xeb +#define JMP_i32 0xe9 +#define JMP_rm (/* GROUP_FF */ 4 << 3) +#define LEA_r_m 0x8d +#define LOOP_i8 0xe2 +#define LZCNT_r_rm (/* GROUP_F3 */ /* GROUP_0F */ 0xbd) +#define MOV_r_rm 0x8b +#define MOV_r_i32 0xb8 +#define MOV_rm_r 0x89 +#define MOV_rm_i32 0xc7 +#define MOV_rm8_i8 0xc6 +#define MOV_rm8_r8 0x88 +#define MOVAPS_x_xm 0x28 +#define MOVAPS_xm_x 0x29 +#define MOVD_x_rm 0x6e +#define MOVD_rm_x 0x7e +#define MOVDDUP_x_xm 0x12 +#define MOVDQA_x_xm 0x6f +#define MOVDQA_xm_x 0x7f +#define MOVHLPS_x_x 0x12 +#define MOVHPD_m_x 0x17 +#define MOVHPD_x_m 0x16 +#define MOVLHPS_x_x 0x16 +#define MOVLPD_m_x 0x13 +#define MOVLPD_x_m 0x12 +#define MOVMSKPS_r_x (/* GROUP_0F */ 0x50) +#define MOVQ_x_xm (/* GROUP_0F */ 0x7e) +#define MOVSD_x_xm 0x10 +#define MOVSD_xm_x 0x11 +#define MOVSHDUP_x_xm 0x16 +#define MOVSXD_r_rm 0x63 +#define MOVSX_r_rm8 (/* GROUP_0F */ 0xbe) +#define MOVSX_r_rm16 (/* GROUP_0F */ 0xbf) +#define MOVUPS_x_xm 0x10 +#define MOVZX_r_rm8 (/* GROUP_0F */ 0xb6) +#define MOVZX_r_rm16 (/* GROUP_0F */ 0xb7) +#define MUL (/* GROUP_F7 */ 4 << 3) +#define MULSD_x_xm 0x59 +#define NEG_rm (/* GROUP_F7 */ 3 << 3) +#define NOP 0x90 +#define NOT_rm (/* GROUP_F7 */ 2 << 3) +#define OR (/* BINARY */ 1 << 3) +#define OR_r_rm 0x0b +#define OR_EAX_i32 0x0d +#define OR_rm_r 0x09 +#define OR_rm8_r8 0x08 +#define ORPD_x_xm 0x56 +#define PACKSSWB_x_xm (/* GROUP_0F */ 0x63) +#define PAND_x_xm 0xdb +#define PCMPEQD_x_xm 0x76 +#define PINSRB_x_rm_i8 0x20 +#define PINSRW_x_rm_i8 0xc4 +#define PINSRD_x_rm_i8 0x22 +#define PEXTRB_rm_x_i8 0x14 +#define PEXTRW_rm_x_i8 0x15 +#define PEXTRD_rm_x_i8 0x16 +#define PMOVMSKB_r_x (/* GROUP_0F */ 0xd7) +#define PMOVSXBD_x_xm 0x21 +#define PMOVSXBQ_x_xm 0x22 +#define PMOVSXBW_x_xm 0x20 +#define PMOVSXDQ_x_xm 0x25 +#define PMOVSXWD_x_xm 0x23 +#define PMOVSXWQ_x_xm 0x24 +#define PMOVZXBD_x_xm 0x31 +#define PMOVZXBQ_x_xm 0x32 +#define PMOVZXBW_x_xm 0x30 +#define PMOVZXDQ_x_xm 0x35 +#define PMOVZXWD_x_xm 0x33 +#define PMOVZXWQ_x_xm 0x34 +#define POP_r 0x58 +#define POP_rm 0x8f +#define POPF 0x9d +#define POR_x_xm 0xeb +#define PREFETCH 0x18 +#define PSHUFB_x_xm 0x00 +#define PSHUFD_x_xm 0x70 +#define PSHUFLW_x_xm 0x70 +#define PSRLDQ_x 0x73 +#define PSLLD_x_i8 0x72 +#define PSLLQ_x_i8 0x73 +#define PUSH_i32 0x68 +#define PUSH_r 0x50 +#define PUSH_rm (/* GROUP_FF */ 6 << 3) +#define PUSHF 0x9c +#define PXOR_x_xm 0xef +#define ROL (/* SHIFT */ 0 << 3) +#define ROR (/* SHIFT */ 1 << 3) +#define RET_near 0xc3 +#define RET_i16 0xc2 +#define SBB (/* BINARY */ 3 << 3) +#define SBB_EAX_i32 0x1d +#define SBB_r_rm 0x1b +#define SBB_rm_r 0x19 +#define SAR (/* SHIFT */ 7 << 3) +#define SHL (/* SHIFT */ 4 << 3) +#define SHLD (/* GROUP_0F */ 0xa5) +#define SHRD (/* GROUP_0F */ 0xad) +#define SHR (/* SHIFT */ 5 << 3) +#define SHUFPS_x_xm 0xc6 +#define SUB (/* BINARY */ 5 << 3) +#define SUB_EAX_i32 0x2d +#define SUB_r_rm 0x2b +#define SUB_rm_r 0x29 +#define SUBSD_x_xm 0x5c +#define TEST_EAX_i32 0xa9 +#define TEST_rm_r 0x85 +#define TZCNT_r_rm (/* GROUP_F3 */ /* GROUP_0F */ 0xbc) +#define UCOMISD_x_xm 0x2e +#define UNPCKLPD_x_xm 0x14 +#define UNPCKLPS_x_xm 0x14 +#define VBROADCASTSD_x_xm 0x19 +#define VBROADCASTSS_x_xm 0x18 +#define VEXTRACTF128_x_ym 0x19 +#define VEXTRACTI128_x_ym 0x39 +#define VINSERTF128_y_y_xm 0x18 +#define VINSERTI128_y_y_xm 0x38 +#define VPBROADCASTB_x_xm 0x78 +#define VPBROADCASTD_x_xm 0x58 +#define VPBROADCASTQ_x_xm 0x59 +#define VPBROADCASTW_x_xm 0x79 +#define VPERMPD_y_ym 0x01 +#define VPERMQ_y_ym 0x00 +#define XCHG_EAX_r 0x90 +#define XCHG_r_rm 0x87 +#define XOR (/* BINARY */ 6 << 3) +#define XOR_EAX_i32 0x35 +#define XOR_r_rm 0x33 +#define XOR_rm_r 0x31 +#define XORPD_x_xm 0x57 -#define GROUP_0F 0x0f -#define GROUP_F3 0xf3 -#define GROUP_F7 0xf7 -#define GROUP_FF 0xff -#define GROUP_BINARY_81 0x81 -#define GROUP_BINARY_83 0x83 -#define GROUP_SHIFT_1 0xd1 -#define GROUP_SHIFT_N 0xc1 -#define GROUP_SHIFT_CL 0xd3 +#define GROUP_0F 0x0f +#define GROUP_66 0x66 +#define GROUP_F3 0xf3 +#define GROUP_F7 0xf7 +#define GROUP_FF 0xff +#define GROUP_BINARY_81 0x81 +#define GROUP_BINARY_83 0x83 +#define GROUP_SHIFT_1 0xd1 +#define GROUP_SHIFT_N 0xc1 +#define GROUP_SHIFT_CL 0xd3 +#define GROUP_LOCK 0xf0 -#define MOD_REG 0xc0 -#define MOD_DISP8 0x40 +#define MOD_REG 0xc0 +#define MOD_DISP8 0x40 -#define INC_SIZE(s) (*inst++ = U8(s), compiler->size += (s)) +#define INC_SIZE(s) (*inst++ = U8(s), compiler->size += (s)) -#define PUSH_REG(r) (*inst++ = U8(PUSH_r + (r))) -#define POP_REG(r) (*inst++ = U8(POP_r + (r))) -#define RET() (*inst++ = RET_near) -#define RET_I16(n) (*inst++ = RET_i16, *inst++ = U8(n), *inst++ = 0) +#define PUSH_REG(r) (*inst++ = U8(PUSH_r + (r))) +#define POP_REG(r) (*inst++ = U8(POP_r + (r))) +#define RET() (*inst++ = RET_near) +#define RET_I16(n) (*inst++ = RET_i16, *inst++ = U8(n), *inst++ = 0) /* Multithreading does not affect these static variables, since they store built-in CPU features. Therefore they can be overwritten by different threads @@ -297,9 +386,12 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) #define CPU_FEATURE_SSE2 0x002 #endif -#define CPU_FEATURE_LZCNT 0x004 -#define CPU_FEATURE_TZCNT 0x008 -#define CPU_FEATURE_CMOV 0x010 +#define CPU_FEATURE_SSE41 0x004 +#define CPU_FEATURE_LZCNT 0x008 +#define CPU_FEATURE_TZCNT 0x010 +#define CPU_FEATURE_CMOV 0x020 +#define CPU_FEATURE_AVX 0x040 +#define CPU_FEATURE_AVX2 0x080 static sljit_u32 cpu_feature_list = 0; @@ -332,124 +424,124 @@ static SLJIT_INLINE void sljit_unaligned_store_sw(void *addr, sljit_sw value) /* Utility functions */ /******************************************************/ -static void get_cpu_features(void) +static void execute_cpu_id(sljit_u32 info[4]) { - sljit_u32 feature_list = CPU_FEATURE_DETECTED; - sljit_u32 value; - #if defined(_MSC_VER) && _MSC_VER >= 1400 - int CPUInfo[4]; + __cpuidex((int*)info, (int)info[0], (int)info[2]); - __cpuid(CPUInfo, 0); - if (CPUInfo[0] >= 7) { - __cpuidex(CPUInfo, 7, 0); - if (CPUInfo[1] & 0x8) - feature_list |= CPU_FEATURE_TZCNT; - } - - __cpuid(CPUInfo, (int)0x80000001); - if (CPUInfo[2] & 0x20) - feature_list |= CPU_FEATURE_LZCNT; - - __cpuid(CPUInfo, 1); - value = (sljit_u32)CPUInfo[3]; - -#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) +#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__TINYC__) /* AT&T syntax. */ __asm__ ( - "movl $0x0, %%eax\n" - "lzcnt %%eax, %%eax\n" - "setnz %%al\n" - "movl %%eax, %0\n" - : "=g" (value) - : #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - : "eax" -#else - : "rax" -#endif - ); - - if (value & 0x1) - feature_list |= CPU_FEATURE_LZCNT; - - __asm__ ( - "movl $0x0, %%eax\n" - "tzcnt %%eax, %%eax\n" - "setnz %%al\n" - "movl %%eax, %0\n" - : "=g" (value) - : -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - : "eax" -#else - : "rax" -#endif - ); - - if (value & 0x1) - feature_list |= CPU_FEATURE_TZCNT; - - __asm__ ( - "movl $0x1, %%eax\n" -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - /* On x86-32, there is no red zone, so this - should work (no need for a local variable). */ - "push %%ebx\n" -#endif + "movl %0, %%esi\n" + "movl (%%esi), %%eax\n" + "movl 8(%%esi), %%ecx\n" + "pushl %%ebx\n" "cpuid\n" -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - "pop %%ebx\n" -#endif - "movl %%edx, %0\n" - : "=g" (value) + "movl %%eax, (%%esi)\n" + "movl %%ebx, 4(%%esi)\n" + "popl %%ebx\n" + "movl %%ecx, 8(%%esi)\n" + "movl %%edx, 12(%%esi)\n" +#else /* !SLJIT_CONFIG_X86_32 */ + "movq %0, %%rsi\n" + "movl (%%rsi), %%eax\n" + "movl 8(%%rsi), %%ecx\n" + "cpuid\n" + "movl %%eax, (%%rsi)\n" + "movl %%ebx, 4(%%rsi)\n" + "movl %%ecx, 8(%%rsi)\n" + "movl %%edx, 12(%%rsi)\n" +#endif /* SLJIT_CONFIG_X86_32 */ : + : "r" (info) #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - : "%eax", "%ecx", "%edx" -#else - : "%rax", "%rbx", "%rcx", "%rdx" -#endif + : "memory", "eax", "ecx", "edx", "esi" +#else /* !SLJIT_CONFIG_X86_32 */ + : "memory", "rax", "rbx", "rcx", "rdx", "rsi" +#endif /* SLJIT_CONFIG_X86_32 */ ); -#else /* _MSC_VER && _MSC_VER >= 1400 */ +#else /* _MSC_VER < 1400 */ /* Intel syntax. */ __asm { - mov eax, 0 - lzcnt eax, eax - setnz al - mov value, eax - } - - if (value & 0x1) - feature_list |= CPU_FEATURE_LZCNT; - - __asm { - mov eax, 0 - tzcnt eax, eax - setnz al - mov value, eax - } - - if (value & 0x1) - feature_list |= CPU_FEATURE_TZCNT; - - __asm { - mov eax, 1 +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + mov esi, info + mov eax, [esi] + mov ecx, [esi + 8] cpuid - mov value, edx + mov [esi], eax + mov [esi + 4], ebx + mov [esi + 8], ecx + mov [esi + 12], edx +#else /* !SLJIT_CONFIG_X86_32 */ + mov rsi, info + mov eax, [rsi] + mov ecx, [rsi + 8] + cpuid + mov [rsi], eax + mov [rsi + 4], ebx + mov [rsi + 8], ecx + mov [rsi + 12], edx +#endif /* SLJIT_CONFIG_X86_32 */ } #endif /* _MSC_VER && _MSC_VER >= 1400 */ +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +__msan_unpoison(info, 4 * sizeof(sljit_u32)); +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ + +} + +static void get_cpu_features(void) +{ + sljit_u32 feature_list = CPU_FEATURE_DETECTED; + sljit_u32 info[4]; + sljit_u32 max_id; + + info[0] = 0; + execute_cpu_id(info); + max_id = info[0]; + + if (max_id >= 7) { + info[0] = 7; + info[2] = 0; + execute_cpu_id(info); + + if (info[1] & 0x8) + feature_list |= CPU_FEATURE_TZCNT; + if (info[1] & 0x20) + feature_list |= CPU_FEATURE_AVX2; + } + + if (max_id >= 1) { + info[0] = 1; + execute_cpu_id(info); + + if (info[2] & 0x80000) + feature_list |= CPU_FEATURE_SSE41; + if (info[2] & 0x10000000) + feature_list |= CPU_FEATURE_AVX; #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) - if (value & 0x4000000) - feature_list |= CPU_FEATURE_SSE2; + if (info[3] & 0x4000000) + feature_list |= CPU_FEATURE_SSE2; #endif - if (value & 0x8000) - feature_list |= CPU_FEATURE_CMOV; + if (info[3] & 0x8000) + feature_list |= CPU_FEATURE_CMOV; + } + + info[0] = 0x80000001; + info[2] = 0; /* Silences an incorrect compiler warning. */ + execute_cpu_id(info); + + if (info[2] & 0x20) + feature_list |= CPU_FEATURE_LZCNT; cpu_feature_list = feature_list; } @@ -458,15 +550,15 @@ static sljit_u8 get_jump_code(sljit_uw type) { switch (type) { case SLJIT_EQUAL: + case SLJIT_ATOMIC_STORED: case SLJIT_F_EQUAL: case SLJIT_UNORDERED_OR_EQUAL: - case SLJIT_ORDERED_EQUAL: /* Not supported. */ return 0x84 /* je */; case SLJIT_NOT_EQUAL: + case SLJIT_ATOMIC_NOT_STORED: case SLJIT_F_NOT_EQUAL: case SLJIT_ORDERED_NOT_EQUAL: - case SLJIT_UNORDERED_OR_NOT_EQUAL: /* Not supported. */ return 0x85 /* jne */; case SLJIT_LESS: @@ -514,9 +606,11 @@ static sljit_u8 get_jump_code(sljit_uw type) return 0x81 /* jno */; case SLJIT_UNORDERED: + case SLJIT_ORDERED_EQUAL: /* NaN. */ return 0x8a /* jp */; case SLJIT_ORDERED: + case SLJIT_UNORDERED_OR_NOT_EQUAL: /* Not NaN. */ return 0x8b /* jpo */; } return 0; @@ -541,7 +635,7 @@ static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code label_addr = jump->u.target - (sljit_uw)executable_offset; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN) + if ((sljit_sw)(label_addr - (jump->addr + 2)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 6)) < HALFWORD_MIN) return generate_far_jump_code(jump, code_ptr); #endif @@ -737,7 +831,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) switch (feature_type) { case SLJIT_HAS_FPU: #ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; + return (SLJIT_IS_FPU_AVAILABLE) != 0; #elif (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) if (cpu_feature_list == 0) get_cpu_features(); @@ -768,19 +862,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) get_cpu_features(); return (cpu_feature_list & CPU_FEATURE_CMOV) != 0; + case SLJIT_HAS_REV: case SLJIT_HAS_ROT: case SLJIT_HAS_PREFETCH: + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: + case SLJIT_HAS_ATOMIC: return 1; - case SLJIT_HAS_SSE2: -#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) +#if !(defined SLJIT_IS_FPU_AVAILABLE) || SLJIT_IS_FPU_AVAILABLE + case SLJIT_HAS_AVX: if (cpu_feature_list == 0) get_cpu_features(); - return (cpu_feature_list & CPU_FEATURE_SSE2) != 0; -#else /* !SLJIT_DETECT_SSE2 */ - return 1; -#endif /* SLJIT_DETECT_SSE2 */ - + return (cpu_feature_list & CPU_FEATURE_AVX) != 0; + case SLJIT_HAS_AVX2: + if (cpu_feature_list == 0) + get_cpu_features(); + return (cpu_feature_list & CPU_FEATURE_AVX2) != 0; + case SLJIT_HAS_SIMD: + if (cpu_feature_list == 0) + get_cpu_features(); + return (cpu_feature_list & CPU_FEATURE_SSE41) != 0; +#endif /* SLJIT_IS_FPU_AVAILABLE */ default: return 0; } @@ -788,16 +891,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - if (type < SLJIT_UNORDERED || type > SLJIT_ORDERED_LESS_EQUAL) - return 0; - switch (type) { case SLJIT_ORDERED_EQUAL: case SLJIT_UNORDERED_OR_NOT_EQUAL: - return 0; + return 2; } - return 1; + return 0; } /* --------------------------------------------------------------------- */ @@ -841,6 +941,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) #endif /* SLJIT_CONFIG_X86_64 */ +static sljit_s32 emit_byte(struct sljit_compiler *compiler, sljit_u8 byte) +{ + sljit_u8 *inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = byte; + return SLJIT_SUCCESS; +} + static sljit_s32 emit_mov(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw); @@ -848,6 +957,14 @@ static sljit_s32 emit_mov(struct sljit_compiler *compiler, #define EMIT_MOV(compiler, dst, dstw, src, srcw) \ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); +static sljit_s32 emit_groupf(struct sljit_compiler *compiler, + sljit_uw op, + sljit_s32 dst, sljit_s32 src, sljit_sw srcw); + +static sljit_s32 emit_groupf_ext(struct sljit_compiler *compiler, + sljit_uw op, + sljit_s32 dst, sljit_s32 src, sljit_sw srcw); + static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler, sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src); @@ -858,6 +975,10 @@ static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w); +static sljit_s32 emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_reg, + sljit_s32 src, sljit_sw srcw); + static SLJIT_INLINE sljit_s32 emit_endbranch(struct sljit_compiler *compiler) { #if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) @@ -866,14 +987,14 @@ static SLJIT_INLINE sljit_s32 emit_endbranch(struct sljit_compiler *compiler) inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); - *inst++ = 0xf3; - *inst++ = 0x0f; - *inst++ = 0x1e; + inst[0] = GROUP_F3; + inst[1] = GROUP_0F; + inst[2] = 0x1e; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *inst = 0xfb; -#else - *inst = 0xfa; -#endif + inst[3] = 0xfb; +#else /* !SLJIT_CONFIG_X86_32 */ + inst[3] = 0xfa; +#endif /* SLJIT_CONFIG_X86_32 */ #else /* !SLJIT_CONFIG_X86_CET */ SLJIT_UNUSED_ARG(compiler); #endif /* SLJIT_CONFIG_X86_CET */ @@ -896,13 +1017,17 @@ static SLJIT_INLINE sljit_s32 emit_rdssp(struct sljit_compiler *compiler, sljit_ inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); - *inst++ = 0xf3; + *inst++ = GROUP_F3; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B); #endif - *inst++ = 0x0f; - *inst++ = 0x1e; - *inst = (0x3 << 6) | (0x1 << 3) | (reg_map[reg] & 0x7); + inst[0] = GROUP_0F; + inst[1] = 0x1e; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + inst[2] = U8(MOD_REG | (0x1 << 3) | reg_lmap[reg]); +#else + inst[2] = U8(MOD_REG | (0x1 << 3) | reg_map[reg]); +#endif return SLJIT_SUCCESS; } @@ -920,13 +1045,13 @@ static SLJIT_INLINE sljit_s32 emit_incssp(struct sljit_compiler *compiler, sljit inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); - *inst++ = 0xf3; + *inst++ = GROUP_F3; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B); #endif - *inst++ = 0x0f; - *inst++ = 0xae; - *inst = (0x3 << 6) | (0x5 << 3) | (reg_map[reg] & 0x7); + inst[0] = GROUP_0F; + inst[1] = 0xae; + inst[2] = (0x3 << 6) | (0x5 << 3) | (reg_map[reg] & 0x7); return SLJIT_SUCCESS; } @@ -954,19 +1079,7 @@ static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compile FAIL_IF(emit_rdssp(compiler, TMP_REG1)); /* Load return address on shadow stack into TMP_REG1. */ -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - SLJIT_ASSERT(reg_map[TMP_REG1] == 5); - - /* Hand code unsupported "mov 0x0(%ebp),%ebp". */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); - FAIL_IF(!inst); - INC_SIZE(3); - *inst++ = 0x8b; - *inst++ = 0x6d; - *inst = 0; -#else /* !SLJIT_CONFIG_X86_32 */ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), 0); -#endif /* SLJIT_CONFIG_X86_32 */ /* Compare return address against TMP_REG1. */ FAIL_IF(emit_cmp_binary (compiler, TMP_REG1, 0, src, srcw)); @@ -994,8 +1107,8 @@ static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compile inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); - *inst++ = JMP_i8; - *inst = size_before_rdssp_inst - compiler->size; + inst[0] = JMP_i8; + inst[1] = size_before_rdssp_inst - compiler->size; *jz_after_cmp_inst = compiler->size - size_jz_after_cmp_inst; #else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */ @@ -1024,7 +1137,8 @@ static sljit_s32 emit_mov(struct sljit_compiler *compiler, *inst = MOV_rm_r; return SLJIT_SUCCESS; } - if (src & SLJIT_IMM) { + + if (src == SLJIT_IMM) { if (FAST_IS_REG(dst)) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw); @@ -1071,6 +1185,27 @@ static sljit_s32 emit_mov(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } +static sljit_s32 emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_reg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_u8* inst; + sljit_uw size; + + SLJIT_ASSERT(type >= SLJIT_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = U8(get_jump_code((sljit_uw)type ^ 0x1) - 0x10); + + size = compiler->size; + EMIT_MOV(compiler, dst_reg, 0, src, srcw); + + inst[1] = U8(compiler->size - size); + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { sljit_u8 *inst; @@ -1083,17 +1218,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile switch (GET_OPCODE(op)) { case SLJIT_BREAKPOINT: - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = INT3; - break; + return emit_byte(compiler, INT3); case SLJIT_NOP: - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = NOP; - break; + return emit_byte(compiler, NOP); case SLJIT_LMUL_UW: case SLJIT_LMUL_SW: case SLJIT_DIVMOD_UW: @@ -1134,23 +1261,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = CDQ; + FAIL_IF(emit_byte(compiler, CDQ)); #else - if (compiler->mode32) { - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = CDQ; - } else { + if (!compiler->mode32) { inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); - *inst++ = REX_W; - *inst = CDQ; - } + inst[0] = REX_W; + inst[1] = CDQ; + } else + FAIL_IF(emit_byte(compiler, CDQ)); #endif } @@ -1158,14 +1278,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); - *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); -#else + inst[0] = GROUP_F7; + inst[1] = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); +#else /* !SLJIT_CONFIG_X86_32 */ #ifdef _WIN64 size = (!compiler->mode32 || op >= SLJIT_DIVMOD_UW) ? 3 : 2; -#else +#else /* !_WIN64 */ size = (!compiler->mode32) ? 3 : 2; -#endif +#endif /* _WIN64 */ inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); @@ -1174,29 +1294,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile *inst++ = REX_W | ((op >= SLJIT_DIVMOD_UW) ? REX_B : 0); else if (op >= SLJIT_DIVMOD_UW) *inst++ = REX_B; - *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); -#else + inst[0] = GROUP_F7; + inst[1] = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); +#else /* !_WIN64 */ if (!compiler->mode32) *inst++ = REX_W; - *inst++ = GROUP_F7; - *inst = MOD_REG | reg_map[SLJIT_R1]; -#endif -#endif + inst[0] = GROUP_F7; + inst[1] = MOD_REG | reg_map[SLJIT_R1]; +#endif /* _WIN64 */ +#endif /* SLJIT_CONFIG_X86_32 */ switch (op) { case SLJIT_LMUL_UW: - *inst |= MUL; + inst[1] |= MUL; break; case SLJIT_LMUL_SW: - *inst |= IMUL; + inst[1] |= IMUL; break; case SLJIT_DIVMOD_UW: case SLJIT_DIV_UW: - *inst |= DIV; + inst[1] |= DIV; break; case SLJIT_DIVMOD_SW: case SLJIT_DIV_SW: - *inst |= IDIV; + inst[1] |= IDIV; break; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) @@ -1216,29 +1336,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return SLJIT_SUCCESS; } -#define ENCODE_PREFIX(prefix) \ - do { \ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); \ - FAIL_IF(!inst); \ - INC_SIZE(1); \ - *inst = U8(prefix); \ - } while (0) - static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { sljit_u8* inst; sljit_s32 dst_r; -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_s32 work_r; -#endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; #endif - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { if (FAST_IS_REG(dst)) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw); @@ -1267,100 +1376,33 @@ static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign, #else dst_r = src; #endif - } + } else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - else if (FAST_IS_REG(src) && reg_map[src] >= 4) { - /* src, dst are registers. */ - SLJIT_ASSERT(FAST_IS_REG(dst)); - if (reg_map[dst] < 4) { - if (dst != src) - EMIT_MOV(compiler, dst, 0, src, 0); - inst = emit_x86_instruction(compiler, 2, dst, 0, dst, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; - } - else { - if (dst != src) - EMIT_MOV(compiler, dst, 0, src, 0); - if (sign) { - /* shl reg, 24 */ - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); - FAIL_IF(!inst); - *inst |= SHL; - /* sar reg, 24 */ - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); - FAIL_IF(!inst); - *inst |= SAR; - } - else { + if (FAST_IS_REG(src) && reg_map[src] >= 4) { + /* Both src and dst are registers. */ + SLJIT_ASSERT(FAST_IS_REG(dst)); + + if (src == dst && !sign) { inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0xff, dst, 0); FAIL_IF(!inst); *(inst + 1) |= AND; + return SLJIT_SUCCESS; } + + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); + src = TMP_REG1; + srcw = 0; } - return SLJIT_SUCCESS; - } -#endif - else { +#endif /* !SLJIT_CONFIG_X86_32 */ + /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */ - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; + FAIL_IF(emit_groupf(compiler, sign ? MOVSX_r_rm8 : MOVZX_r_rm8, dst_r, src, srcw)); } if (dst & SLJIT_MEM) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (dst_r == TMP_REG1) { - /* Find a non-used register, whose reg_map[src] < 4. */ - if ((dst & REG_MASK) == SLJIT_R0) { - if ((dst & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_R1)) - work_r = SLJIT_R2; - else - work_r = SLJIT_R1; - } - else { - if ((dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0)) - work_r = SLJIT_R0; - else if ((dst & REG_MASK) == SLJIT_R1) - work_r = SLJIT_R2; - else - work_r = SLJIT_R1; - } - - if (work_r == SLJIT_R0) { - ENCODE_PREFIX(XCHG_EAX_r | reg_map[TMP_REG1]); - } - else { - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); - FAIL_IF(!inst); - *inst = XCHG_r_rm; - } - - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_r8; - - if (work_r == SLJIT_R0) { - ENCODE_PREFIX(XCHG_EAX_r | reg_map[TMP_REG1]); - } - else { - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); - FAIL_IF(!inst); - *inst = XCHG_r_rm; - } - } - else { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_r8; - } -#else inst = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw); FAIL_IF(!inst); *inst = MOV_rm8_r8; -#endif } return SLJIT_SUCCESS; @@ -1377,15 +1419,15 @@ static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, sljit_s32 op, inst = emit_x86_instruction(compiler, 2, 0, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst++ = PREFETCH; + inst[0] = GROUP_0F; + inst[1] = PREFETCH; if (op == SLJIT_PREFETCH_L1) - *inst |= (1 << 3); + inst[2] |= (1 << 3); else if (op == SLJIT_PREFETCH_L2) - *inst |= (2 << 3); + inst[2] |= (2 << 3); else if (op == SLJIT_PREFETCH_L3) - *inst |= (3 << 3); + inst[2] |= (3 << 3); return SLJIT_SUCCESS; } @@ -1401,7 +1443,7 @@ static sljit_s32 emit_mov_half(struct sljit_compiler *compiler, sljit_s32 sign, compiler->mode32 = 0; #endif - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { if (FAST_IS_REG(dst)) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw); @@ -1422,12 +1464,8 @@ static sljit_s32 emit_mov_half(struct sljit_compiler *compiler, sljit_s32 sign, if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) dst_r = src; - else { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm16 : MOVZX_r_rm16; - } + else + FAIL_IF(emit_groupf(compiler, sign ? MOVSX_r_rm16 : MOVZX_r_rm16, dst_r, src, srcw)); if (dst & SLJIT_MEM) { inst = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw); @@ -1448,8 +1486,8 @@ static sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode, /* Same input and output */ inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; + inst[0] = GROUP_F7; + inst[1] |= opcode; return SLJIT_SUCCESS; } @@ -1457,46 +1495,16 @@ static sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode, EMIT_MOV(compiler, dst, 0, src, srcw); inst = emit_x86_instruction(compiler, 1, 0, 0, dst, 0); FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; + inst[0] = GROUP_F7; + inst[1] |= opcode; return SLJIT_SUCCESS; } EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; - EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); - return SLJIT_SUCCESS; -} - -static sljit_s32 emit_not_with_flags(struct sljit_compiler *compiler, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src, sljit_sw srcw) -{ - sljit_u8* inst; - - if (FAST_IS_REG(dst)) { - EMIT_MOV(compiler, dst, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0); - FAIL_IF(!inst); - *inst = OR_r_rm; - return SLJIT_SUCCESS; - } - - EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst = OR_r_rm; + inst[0] = GROUP_F7; + inst[1] |= opcode; EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); return SLJIT_SUCCESS; } @@ -1514,32 +1522,19 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 is_clz, sljit_s32 dst_r; sljit_sw max; - if (cpu_feature_list == 0) - get_cpu_features(); + SLJIT_ASSERT(cpu_feature_list != 0); dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; if (is_clz ? (cpu_feature_list & CPU_FEATURE_LZCNT) : (cpu_feature_list & CPU_FEATURE_TZCNT)) { - /* Group prefix added separately. */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst++ = GROUP_F3; - - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = is_clz ? LZCNT_r_rm : TZCNT_r_rm; + FAIL_IF(emit_groupf(compiler, (is_clz ? LZCNT_r_rm : TZCNT_r_rm) | EX86_PREF_F3, dst_r, src, srcw)); if (dst & SLJIT_MEM) EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); return SLJIT_SUCCESS; } - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = is_clz ? BSR_r_rm : BSF_r_rm; + FAIL_IF(emit_groupf(compiler, is_clz ? BSR_r_rm : BSF_r_rm, dst_r, src, srcw)); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) max = is_clz ? (32 + 31) : 32; @@ -1553,11 +1548,11 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 is_clz, inst = emit_x86_instruction(compiler, 2, dst_r, 0, SLJIT_MEM0(), is_clz ? (sljit_sw)&emit_clz_arg : (sljit_sw)&emit_ctz_arg); FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CMOVE_r_rm; + inst[0] = GROUP_0F; + inst[1] = CMOVE_r_rm; } else - FAIL_IF(sljit_emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max)); + FAIL_IF(emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max)); if (is_clz) { inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0); @@ -1572,14 +1567,9 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 is_clz, if (cpu_feature_list & CPU_FEATURE_CMOV) { EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, max); - - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CMOVE_r_rm; - } - else - FAIL_IF(sljit_emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max)); + FAIL_IF(emit_groupf(compiler, CMOVE_r_rm, dst_r, TMP_REG2, 0)); + } else + FAIL_IF(emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max)); if (is_clz) { inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, max >> 1, dst_r, 0); @@ -1593,14 +1583,109 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 is_clz, return SLJIT_SUCCESS; } +static sljit_s32 emit_bswap(struct sljit_compiler *compiler, + sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_u8 *inst; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + sljit_uw size; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_u8 rex = 0; +#else /* !SLJIT_CONFIG_X86_64 */ + sljit_s32 dst_is_ereg = op & SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (op == SLJIT_REV_U32 || op == SLJIT_REV_S32) + compiler->mode32 = 1; +#else /* !SLJIT_CONFIG_X86_64 */ + op &= ~SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (src != dst_r) { + /* Only the lower 16 bit is read for eregs. */ + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) + FAIL_IF(emit_mov_half(compiler, 0, dst_r, 0, src, srcw)); + else + EMIT_MOV(compiler, dst_r, 0, src, srcw); + } + + size = 2; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (!compiler->mode32) + rex = REX_W; + + if (reg_map[dst_r] >= 8) + rex |= REX_B; + + if (rex != 0) + size++; +#endif /* SLJIT_CONFIG_X86_64 */ + + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (rex != 0) + *inst++ = rex; + + inst[0] = GROUP_0F; + inst[1] = BSWAP_r | reg_lmap[dst_r]; +#else /* !SLJIT_CONFIG_X86_64 */ + inst[0] = GROUP_0F; + inst[1] = BSWAP_r | reg_map[dst_r]; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + size = compiler->mode32 ? 16 : 48; +#else /* !SLJIT_CONFIG_X86_64 */ + size = 16; +#endif /* SLJIT_CONFIG_X86_64 */ + + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, (sljit_sw)size, dst_r, 0); + FAIL_IF(!inst); + if (op == SLJIT_REV_U16) + inst[1] |= SHR; + else + inst[1] |= SAR; + } + + if (dst & SLJIT_MEM) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst_is_ereg) + op = SLJIT_REV; +#endif /* SLJIT_CONFIG_X86_32 */ + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) + return emit_mov_half(compiler, 0, dst, dstw, TMP_REG1, 0); + + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (op == SLJIT_REV_S32) { + compiler->mode32 = 0; + inst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0); + FAIL_IF(!inst); + *inst = MOVSXD_r_rm; + } +#endif /* SLJIT_CONFIG_X86_64 */ + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { - sljit_s32 op_flags = GET_ALL_FLAGS(op); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) sljit_s32 dst_is_ereg = 0; -#endif +#else /* !SLJIT_CONFIG_X86_32 */ + sljit_s32 op_flags = GET_ALL_FLAGS(op); +#endif /* SLJIT_CONFIG_X86_32 */ CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -1611,14 +1696,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile CHECK_EXTRA_REGS(src, srcw, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = op_flags & SLJIT_32; -#endif +#endif /* SLJIT_CONFIG_X86_64 */ op = GET_OPCODE(op); if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; -#endif +#endif /* SLJIT_CONFIG_X86_64 */ if (FAST_IS_REG(src) && src == dst) { if (!TYPE_CAST_NEEDED(op)) @@ -1631,14 +1716,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile if (op == SLJIT_MOV_S32) op = SLJIT_MOV_U32; } - else if (src & SLJIT_IMM) { + else if (src == SLJIT_IMM) { if (op == SLJIT_MOV_U32) op = SLJIT_MOV_S32; } } -#endif +#endif /* SLJIT_CONFIG_X86_64 */ - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { switch (op) { case SLJIT_MOV_U8: srcw = (sljit_u8)srcw; @@ -1659,12 +1744,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile case SLJIT_MOV_S32: srcw = (sljit_s32)srcw; break; -#endif +#endif /* SLJIT_CONFIG_X86_64 */ } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (SLJIT_UNLIKELY(dst_is_ereg)) return emit_mov(compiler, dst, dstw, src, srcw); -#endif +#endif /* SLJIT_CONFIG_X86_32 */ } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -1672,7 +1757,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_SP)); dst = TMP_REG1; } -#endif +#endif /* SLJIT_CONFIG_X86_32 */ switch (op) { case SLJIT_MOV: @@ -1681,7 +1766,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile case SLJIT_MOV_U32: case SLJIT_MOV_S32: case SLJIT_MOV32: -#endif +#endif /* SLJIT_CONFIG_X86_32 */ EMIT_MOV(compiler, dst, dstw, src, srcw); break; case SLJIT_MOV_U8: @@ -1708,25 +1793,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile EMIT_MOV(compiler, dst, dstw, src, srcw); compiler->mode32 = 0; break; -#endif +#endif /* SLJIT_CONFIG_X86_64 */ } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1) return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), dstw, TMP_REG1, 0); -#endif +#endif /* SLJIT_CONFIG_X86_32 */ return SLJIT_SUCCESS; } switch (op) { - case SLJIT_NOT: - if (SLJIT_UNLIKELY(op_flags & SLJIT_SET_Z)) - return emit_not_with_flags(compiler, dst, dstw, src, srcw); - return emit_unary(compiler, NOT_rm, dst, dstw, src, srcw); - case SLJIT_CLZ: case SLJIT_CTZ: return emit_clz_ctz(compiler, (op == SLJIT_CLZ), dst, dstw, src, srcw); + case SLJIT_REV: + case SLJIT_REV_U16: + case SLJIT_REV_S16: + case SLJIT_REV_U32: + case SLJIT_REV_S32: +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst_is_ereg) + op |= SLJIT_32; +#endif /* SLJIT_CONFIG_X86_32 */ + return emit_bswap(compiler, op, dst, dstw, src, srcw); } return SLJIT_SUCCESS; @@ -1745,7 +1835,7 @@ static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, sljit_u8 op_imm = U8(op_types & 0xff); if (dst == src1 && dstw == src1w) { - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else @@ -1779,7 +1869,7 @@ static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, /* Only for cumulative operations. */ if (dst == src2 && dstw == src2w) { - if (src1 & SLJIT_IMM) { + if (src1 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { #else @@ -1813,7 +1903,7 @@ static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, /* General version. */ if (FAST_IS_REG(dst)) { EMIT_MOV(compiler, dst, 0, src1, src1w); - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); } else { @@ -1825,7 +1915,7 @@ static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, else { /* This version requires less memory writing. */ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); } else { @@ -1852,7 +1942,7 @@ static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler, sljit_u8 op_imm = U8(op_types & 0xff); if (dst == src1 && dstw == src1w) { - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else @@ -1886,7 +1976,7 @@ static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler, /* General version. */ if (FAST_IS_REG(dst) && dst != src2) { EMIT_MOV(compiler, dst, 0, src1, src1w); - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); } else { @@ -1898,7 +1988,7 @@ static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler, else { /* This version requires less memory writing. */ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); } else { @@ -1921,20 +2011,12 @@ static sljit_s32 emit_mul(struct sljit_compiler *compiler, sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; /* Register destination. */ - if (dst_r == src1 && !(src2 & SLJIT_IMM)) { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; - } - else if (dst_r == src2 && !(src1 & SLJIT_IMM)) { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; - } - else if (src1 & SLJIT_IMM) { - if (src2 & SLJIT_IMM) { + if (dst_r == src1 && src2 != SLJIT_IMM) { + FAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, src2, src2w)); + } else if (dst_r == src2 && src1 != SLJIT_IMM) { + FAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, src1, src1w)); + } else if (src1 == SLJIT_IMM) { + if (src2 == SLJIT_IMM) { EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w); src2 = dst_r; src2w = 0; @@ -1944,10 +2026,8 @@ static sljit_s32 emit_mul(struct sljit_compiler *compiler, inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); FAIL_IF(!inst); *inst = IMUL_r_rm_i8; - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = U8(src1w); + + FAIL_IF(emit_byte(compiler, U8(src1w))); } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { @@ -1973,30 +2053,26 @@ static sljit_s32 emit_mul(struct sljit_compiler *compiler, if (dst_r != src2) EMIT_MOV(compiler, dst_r, 0, src2, src2w); FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w)); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; + FAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, TMP_REG2, 0)); } #endif } - else if (src2 & SLJIT_IMM) { + else if (src2 == SLJIT_IMM) { /* Note: src1 is NOT immediate. */ if (src2w <= 127 && src2w >= -128) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i8; - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = U8(src2w); + + FAIL_IF(emit_byte(compiler, U8(src2w))); } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); @@ -2007,31 +2083,24 @@ static sljit_s32 emit_mul(struct sljit_compiler *compiler, inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); sljit_unaligned_store_s32(inst, (sljit_s32)src2w); - } - else { + } else { if (dst_r != src1) EMIT_MOV(compiler, dst_r, 0, src1, src1w); FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; + FAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, TMP_REG2, 0)); } #endif - } - else { + } else { /* Neither argument is immediate. */ if (ADDRESSING_DEPENDS_ON(src2, dst_r)) dst_r = TMP_REG1; EMIT_MOV(compiler, dst_r, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; + FAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, src2, src2w)); } if (dst & SLJIT_MEM) @@ -2064,10 +2133,10 @@ static sljit_s32 emit_lea_binary(struct sljit_compiler *compiler, done = 1; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if (src2 == SLJIT_IMM && (compiler->mode32 || IS_HALFWORD(src2w))) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_s32)src2w); #else - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w); #endif FAIL_IF(!inst); @@ -2077,10 +2146,10 @@ static sljit_s32 emit_lea_binary(struct sljit_compiler *compiler, } else if (FAST_IS_REG(src2)) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { + if (src1 == SLJIT_IMM && (compiler->mode32 || IS_HALFWORD(src1w))) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_s32)src1w); #else - if (src1 & SLJIT_IMM) { + if (src1 == SLJIT_IMM) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w); #endif FAIL_IF(!inst); @@ -2104,16 +2173,16 @@ static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler, sljit_u8* inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { + if (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(CMP_EAX_i32, src2w); return SLJIT_SUCCESS; } if (FAST_IS_REG(src1)) { - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { BINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0); } else { @@ -2124,15 +2193,15 @@ static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } - if (FAST_IS_REG(src2) && !(src1 & SLJIT_IMM)) { + if (FAST_IS_REG(src2) && src1 != SLJIT_IMM) { inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); FAIL_IF(!inst); *inst = CMP_rm_r; return SLJIT_SUCCESS; } - if (src2 & SLJIT_IMM) { - if (src1 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { + if (src1 == SLJIT_IMM) { EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); src1 = TMP_REG1; src1w = 0; @@ -2155,25 +2224,25 @@ static sljit_s32 emit_test_binary(struct sljit_compiler *compiler, sljit_u8* inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { + if (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(TEST_EAX_i32, src2w); return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { + if (src2 == SLJIT_R0 && src1 == SLJIT_IMM && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { #else - if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) { + if (src2 == SLJIT_R0 && src1 == SLJIT_IMM && (src1w > 127 || src1w < -128)) { #endif BINARY_EAX_IMM(TEST_EAX_i32, src1w); return SLJIT_SUCCESS; } - if (!(src1 & SLJIT_IMM)) { - if (src2 & SLJIT_IMM) { + if (src1 != SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src2w) || compiler->mode32) { inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w); @@ -2201,8 +2270,8 @@ static sljit_s32 emit_test_binary(struct sljit_compiler *compiler, } } - if (!(src2 & SLJIT_IMM)) { - if (src1 & SLJIT_IMM) { + if (src2 != SLJIT_IMM) { + if (src1 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src1w) || compiler->mode32) { inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, src2w); @@ -2231,7 +2300,7 @@ static sljit_s32 emit_test_binary(struct sljit_compiler *compiler, } EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src2w) || compiler->mode32) { inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0); @@ -2269,18 +2338,18 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler, #endif sljit_u8* inst; - if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) { + if (src2 == SLJIT_IMM || src2 == SLJIT_PREF_SHIFT_REG) { if (dst == src1 && dstw == src1w) { inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; return SLJIT_SUCCESS; } if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) { EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); return SLJIT_SUCCESS; } @@ -2288,14 +2357,14 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler, EMIT_MOV(compiler, dst, 0, src1, src1w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; return SLJIT_SUCCESS; } EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); return SLJIT_SUCCESS; } @@ -2305,7 +2374,7 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler, EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; return emit_mov(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); } @@ -2323,7 +2392,7 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler, EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; #endif @@ -2349,7 +2418,7 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler, EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), 0); @@ -2372,7 +2441,7 @@ static sljit_s32 emit_shift_with_flags(struct sljit_compiler *compiler, sljit_s32 src2, sljit_sw src2w) { /* The CPU does not set flags if the shift count is 0. */ - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) src2w &= compiler->mode32 ? 0x1f : 0x3f; #else /* !SLJIT_CONFIG_X86_64 */ @@ -2437,7 +2506,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return emit_unary(compiler, NEG_rm, dst, dstw, src2, src2w); if (!HAS_FLAGS(op)) { - if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED) + if (src2 == SLJIT_IMM && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED) return compiler->error; if (FAST_IS_REG(dst) && src2 == dst) { FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), dst, 0, dst, 0, src1, src1w)); @@ -2459,6 +2528,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return emit_cum_binary(compiler, BINARY_OPCODE(OR), dst, dstw, src1, src1w, src2, src2w); case SLJIT_XOR: + if (!HAS_FLAGS(op)) { + if (src2 == SLJIT_IMM && src2w == -1) + return emit_unary(compiler, NOT_rm, dst, dstw, src1, src1w); + if (src1 == SLJIT_IMM && src1w == -1) + return emit_unary(compiler, NOT_rm, dst, dstw, src2, src2w); + } + return emit_cum_binary(compiler, BINARY_OPCODE(XOR), dst, dstw, src1, src1w, src2, src2w); case SLJIT_SHL: @@ -2514,117 +2590,192 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { - sljit_s32 restore_ecx = 0; - sljit_s32 is_rotate, is_left; + sljit_s32 is_rotate, is_left, move_src1; sljit_u8* inst; + sljit_sw src1w = 0; sljit_sw dstw = 0; + /* The whole register must be saved even for 32 bit operations. */ + sljit_u8 restore_ecx = 0; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_s32 tmp2 = SLJIT_MEM1(SLJIT_SP); -#else /* !SLJIT_CONFIG_X86_32 */ - sljit_s32 tmp2 = TMP_REG2; + sljit_sw src2w = 0; + sljit_s32 restore_sp4 = 0; #endif /* SLJIT_CONFIG_X86_32 */ CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); + ADJUST_LOCAL_OFFSET(src3, src3w); - CHECK_EXTRA_REGS(src1, src1w, (void)0); - CHECK_EXTRA_REGS(src2, src2w, (void)0); + CHECK_EXTRA_REGS(dst_reg, dstw, (void)0); + CHECK_EXTRA_REGS(src3, src3w, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = op & SLJIT_32; -#endif +#endif /* SLJIT_CONFIG_X86_64 */ - if (src2 & SLJIT_IMM) { + if (src3 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - src2w &= 0x1f; + src3w &= 0x1f; #else /* !SLJIT_CONFIG_X86_32 */ - src2w &= (op & SLJIT_32) ? 0x1f : 0x3f; + src3w &= (op & SLJIT_32) ? 0x1f : 0x3f; #endif /* SLJIT_CONFIG_X86_32 */ - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; } is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL); - is_rotate = (src_dst == src1); - CHECK_EXTRA_REGS(src_dst, dstw, (void)0); + is_rotate = (src1_reg == src2_reg); + CHECK_EXTRA_REGS(src1_reg, src1w, (void)0); + CHECK_EXTRA_REGS(src2_reg, src2w, (void)0); if (is_rotate) - return emit_shift(compiler, is_left ? ROL : ROR, src_dst, dstw, src1, src1w, src2, src2w); + return emit_shift(compiler, is_left ? ROL : ROR, dst_reg, dstw, src1_reg, src1w, src3, src3w); - if ((src2 & SLJIT_IMM) || src2 == SLJIT_PREF_SHIFT_REG) { - if (!FAST_IS_REG(src1)) { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - src1 = TMP_REG1; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (src2_reg & SLJIT_MEM) { + EMIT_MOV(compiler, TMP_REG1, 0, src2_reg, src2w); + src2_reg = TMP_REG1; + } +#endif /* SLJIT_CONFIG_X86_32 */ + + if (dst_reg == SLJIT_PREF_SHIFT_REG && src3 != SLJIT_IMM && (src3 != SLJIT_PREF_SHIFT_REG || src1_reg != SLJIT_PREF_SHIFT_REG)) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + EMIT_MOV(compiler, TMP_REG1, 0, src1_reg, src1w); + src1_reg = TMP_REG1; + src1w = 0; +#else /* !SLJIT_CONFIG_X86_64 */ + if (src2_reg != TMP_REG1) { + EMIT_MOV(compiler, TMP_REG1, 0, src1_reg, src1w); + src1_reg = TMP_REG1; + src1w = 0; + } else if ((src1_reg & SLJIT_MEM) || src1_reg == SLJIT_PREF_SHIFT_REG) { + restore_sp4 = (src3 == SLJIT_R0) ? SLJIT_R1 : SLJIT_R0; + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), restore_sp4, 0); + EMIT_MOV(compiler, restore_sp4, 0, src1_reg, src1w); + src1_reg = restore_sp4; + src1w = 0; + } else { + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), src1_reg, 0); + restore_sp4 = src1_reg; } - } else if (FAST_IS_REG(src1)) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 0; -#endif - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0); -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = op & SLJIT_32; -#endif - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); +#endif /* SLJIT_CONFIG_X86_64 */ - if (src1 == SLJIT_PREF_SHIFT_REG) - src1 = TMP_REG1; - - if (src_dst == SLJIT_PREF_SHIFT_REG) - src_dst = TMP_REG1; - - restore_ecx = 1; + if (src3 != SLJIT_PREF_SHIFT_REG) + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src3, src3w); } else { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + if (src2_reg == SLJIT_PREF_SHIFT_REG && src3 != SLJIT_IMM && src3 != SLJIT_PREF_SHIFT_REG) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 0; -#endif - EMIT_MOV(compiler, tmp2, 0, SLJIT_PREF_SHIFT_REG, 0); + compiler->mode32 = 0; +#endif /* SLJIT_CONFIG_X86_64 */ + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = op & SLJIT_32; -#endif - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); - - src1 = TMP_REG1; - - if (src_dst == SLJIT_PREF_SHIFT_REG) { - src_dst = tmp2; - SLJIT_ASSERT(dstw == 0); + compiler->mode32 = op & SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ + src2_reg = TMP_REG1; + restore_ecx = 1; } - restore_ecx = 2; + move_src1 = 0; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (dst_reg != src1_reg) { + if (dst_reg != src3) { + EMIT_MOV(compiler, dst_reg, 0, src1_reg, src1w); + src1_reg = dst_reg; + src1w = 0; + } else + move_src1 = 1; + } +#else /* !SLJIT_CONFIG_X86_64 */ + if (dst_reg & SLJIT_MEM) { + if (src2_reg != TMP_REG1) { + EMIT_MOV(compiler, TMP_REG1, 0, src1_reg, src1w); + src1_reg = TMP_REG1; + src1w = 0; + } else if ((src1_reg & SLJIT_MEM) || src1_reg == SLJIT_PREF_SHIFT_REG) { + restore_sp4 = (src3 == SLJIT_R0) ? SLJIT_R1 : SLJIT_R0; + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), restore_sp4, 0); + EMIT_MOV(compiler, restore_sp4, 0, src1_reg, src1w); + src1_reg = restore_sp4; + src1w = 0; + } else { + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), src1_reg, 0); + restore_sp4 = src1_reg; + } + } else if (dst_reg != src1_reg) { + if (dst_reg != src3) { + EMIT_MOV(compiler, dst_reg, 0, src1_reg, src1w); + src1_reg = dst_reg; + src1w = 0; + } else + move_src1 = 1; + } +#endif /* SLJIT_CONFIG_X86_64 */ + + if (src3 != SLJIT_IMM && src3 != SLJIT_PREF_SHIFT_REG) { + if (!restore_ecx) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0); + compiler->mode32 = op & SLJIT_32; + restore_ecx = 1; +#else /* !SLJIT_CONFIG_X86_64 */ + if (src1_reg != TMP_REG1 && src2_reg != TMP_REG1) { + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0); + restore_ecx = 1; + } else { + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_PREF_SHIFT_REG, 0); + restore_ecx = 2; + } +#endif /* SLJIT_CONFIG_X86_64 */ + } + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src3, src3w); + } + + if (move_src1) { + EMIT_MOV(compiler, dst_reg, 0, src1_reg, src1w); + src1_reg = dst_reg; + src1w = 0; + } } - inst = emit_x86_instruction(compiler, 2, src1, 0, src_dst, dstw); + inst = emit_x86_instruction(compiler, 2, src2_reg, 0, src1_reg, src1w); FAIL_IF(!inst); inst[0] = GROUP_0F; - if (src2 & SLJIT_IMM) { + if (src3 == SLJIT_IMM) { inst[1] = U8((is_left ? SHLD : SHRD) - 1); - /* Immedate argument is added separately. */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = U8(src2w); + /* Immediate argument is added separately. */ + FAIL_IF(emit_byte(compiler, U8(src3w))); } else inst[1] = U8(is_left ? SHLD : SHRD); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 0; -#endif + if (restore_ecx) { + compiler->mode32 = 0; + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); + } - if (restore_ecx == 1) - return emit_mov(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); - if (restore_ecx == 2) - return emit_mov(compiler, SLJIT_PREF_SHIFT_REG, 0, tmp2, 0); + if (src1_reg != dst_reg) { + compiler->mode32 = op & SLJIT_32; + return emit_mov(compiler, dst_reg, dstw, src1_reg, 0); + } +#else /* !SLJIT_CONFIG_X86_64 */ + if (restore_ecx) + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, restore_ecx == 1 ? TMP_REG1 : SLJIT_MEM1(SLJIT_SP), 0); + + if (src1_reg != dst_reg) + EMIT_MOV(compiler, dst_reg, dstw, src1_reg, 0); + + if (restore_sp4) + return emit_mov(compiler, restore_sp4, 0, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32)); +#endif /* SLJIT_CONFIG_X86_32 */ return SLJIT_SUCCESS; } @@ -2656,24 +2807,41 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (reg >= SLJIT_R3 && reg <= SLJIT_R8) - return -1; -#endif - return reg_map[reg]; + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + + switch (op) { + case SLJIT_FAST_ENTER: + return emit_fast_enter(compiler, dst, dstw); + case SLJIT_GET_RETURN_ADDRESS: + return sljit_emit_get_return_address(compiler, dst, dstw); + } + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - return reg; -#else + if (reg >= SLJIT_R3 && reg <= SLJIT_R8) + return -1; +#endif /* SLJIT_CONFIG_X86_32 */ + return reg_map[reg]; + } + + if (type != SLJIT_FLOAT_REGISTER && type != SLJIT_SIMD_REG_128 && type != SLJIT_SIMD_REG_256 && type != SLJIT_SIMD_REG_512) + return -1; + return freg_map[reg]; -#endif } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -2701,6 +2869,8 @@ static sljit_u32 *sse2_buffer; static void init_compiler(void) { + get_cpu_features(); + /* Align to 16 bytes. */ sse2_buffer = (sljit_u32*)(((sljit_uw)sse2_data + 15) & ~(sljit_uw)0xf); @@ -2714,58 +2884,60 @@ static void init_compiler(void) sse2_buffer[13] = 0x7fffffff; } -static sljit_s32 emit_sse2(struct sljit_compiler *compiler, sljit_u8 opcode, - sljit_s32 single, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w) +static sljit_s32 emit_groupf(struct sljit_compiler *compiler, + sljit_uw op, + sljit_s32 dst, sljit_s32 src, sljit_sw srcw) { - sljit_u8 *inst; - - inst = emit_x86_instruction(compiler, 2 | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + sljit_u8 *inst = emit_x86_instruction(compiler, 2 | (op & ~(sljit_uw)0xff), dst, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = opcode; + inst[0] = GROUP_0F; + inst[1] = op & 0xff; return SLJIT_SUCCESS; } -static sljit_s32 emit_sse2_logic(struct sljit_compiler *compiler, sljit_u8 opcode, - sljit_s32 pref66, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w) +static sljit_s32 emit_groupf_ext(struct sljit_compiler *compiler, + sljit_uw op, + sljit_s32 dst, sljit_s32 src, sljit_sw srcw) { sljit_u8 *inst; - inst = emit_x86_instruction(compiler, 2 | (pref66 ? EX86_PREF_66 : 0) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + SLJIT_ASSERT((op & EX86_SSE2) && ((op & VEX_OP_0F38) || (op & VEX_OP_0F3A))); + + inst = emit_x86_instruction(compiler, 3 | (op & ~((sljit_uw)0xff | VEX_OP_0F38 | VEX_OP_0F3A)), dst, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = opcode; + inst[0] = GROUP_0F; + inst[1] = U8((op & VEX_OP_0F38) ? 0x38 : 0x3A); + inst[2] = op & 0xff; return SLJIT_SUCCESS; } static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler, sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw) { - return emit_sse2(compiler, MOVSD_x_xm, single, dst, src, srcw); + return emit_groupf(compiler, MOVSD_x_xm | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, dst, src, srcw); } static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler, sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src) { - return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw); + return emit_groupf(compiler, MOVSD_xm_x | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, src, dst, dstw); } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { - sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - sljit_u8 *inst; + sljit_s32 dst_r; + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64) compiler->mode32 = 0; #endif - inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_32) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CVTTSD2SI_r_xm; + FAIL_IF(emit_groupf(compiler, CVTTSD2SI_r_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP2, dst_r, src, srcw)); if (dst & SLJIT_MEM) return emit_mov(compiler, dst, dstw, TMP_REG1, 0); @@ -2777,14 +2949,15 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; - sljit_u8 *inst; + + CHECK_EXTRA_REGS(src, srcw, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) compiler->mode32 = 0; #endif - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) srcw = (sljit_s32)srcw; @@ -2794,10 +2967,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp srcw = 0; } - inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_32) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CVTSI2SD_x_rm; + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, src, srcw)); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; @@ -2812,16 +2982,28 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile sljit_s32 src2, sljit_sw src2w) { switch (GET_FLAG_TYPE(op)) { + case SLJIT_ORDERED_EQUAL: + /* Also: SLJIT_UNORDERED_OR_NOT_EQUAL */ + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w)); + FAIL_IF(emit_groupf(compiler, CMPS_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, TMP_FREG, src2, src2w)); + + /* EQ */ + FAIL_IF(emit_byte(compiler, 0)); + + src1 = TMP_FREG; + src2 = TMP_FREG; + src2w = 0; + break; + case SLJIT_ORDERED_LESS: - case SLJIT_UNORDERED_OR_GREATER_EQUAL: case SLJIT_UNORDERED_OR_GREATER: - case SLJIT_ORDERED_LESS_EQUAL: + /* Also: SLJIT_UNORDERED_OR_GREATER_EQUAL, SLJIT_ORDERED_LESS_EQUAL */ if (!FAST_IS_REG(src2)) { FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src2, src2w)); src2 = TMP_FREG; } - return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_32), src2, src1, src1w); + return emit_groupf(compiler, UCOMISD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, src2, src1, src1w); } if (!FAST_IS_REG(src1)) { @@ -2829,7 +3011,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile src1 = TMP_FREG; } - return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_32), src1, src2, src2w); + return emit_groupf(compiler, UCOMISD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, src1, src2, src2w); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, @@ -2837,6 +3019,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; @@ -2860,42 +3043,57 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil /* We overwrite the high bits of source. From SLJIT point of view, this is not an issue. Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */ - FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_32, src, src, 0)); - } - else { + FAIL_IF(emit_groupf(compiler, UNPCKLPD_x_xm | ((op & SLJIT_32) ? EX86_PREF_66 : 0) | EX86_SSE2, src, src, 0)); + } else { FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_32), TMP_FREG, src, srcw)); src = TMP_FREG; } - FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_32, dst_r, src, 0)); + FAIL_IF(emit_groupf(compiler, CVTPD2PS_x_xm | ((op & SLJIT_32) ? EX86_PREF_66 : 0) | EX86_SSE2, dst_r, src, 0)); if (dst_r == TMP_FREG) return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } if (FAST_IS_REG(dst)) { - dst_r = dst; - if (dst != src) - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src, srcw)); - } - else { - dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src, srcw)); + dst_r = (dst == src) ? TMP_FREG : dst; + + if (src & SLJIT_MEM) + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src, srcw)); + + FAIL_IF(emit_groupf(compiler, PCMPEQD_x_xm | EX86_PREF_66 | EX86_SSE2, dst_r, dst_r, 0)); + + inst = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2_OP2, 0, 0, dst_r, 0); + inst[0] = GROUP_0F; + /* Same as PSRLD_x / PSRLQ_x */ + inst[1] = (op & SLJIT_32) ? PSLLD_x_i8 : PSLLQ_x_i8; + + if (GET_OPCODE(op) == SLJIT_ABS_F64) { + inst[2] |= 2 << 3; + FAIL_IF(emit_byte(compiler, 1)); + } else { + inst[2] |= 6 << 3; + FAIL_IF(emit_byte(compiler, ((op & SLJIT_32) ? 31 : 63))); + } + + if (dst_r != TMP_FREG) + dst_r = (src & SLJIT_MEM) ? TMP_FREG : src; + return emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_NEG_F64 ? XORPD_x_xm : ANDPD_x_xm) | EX86_SSE2, dst, dst_r, 0); } + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src, srcw)); + switch (GET_OPCODE(op)) { case SLJIT_NEG_F64: - FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_32 ? sse2_buffer : sse2_buffer + 8))); + FAIL_IF(emit_groupf(compiler, XORPD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, TMP_FREG, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer : sse2_buffer + 8))); break; case SLJIT_ABS_F64: - FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_32 ? sse2_buffer + 4 : sse2_buffer + 12))); + FAIL_IF(emit_groupf(compiler, ANDPD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, TMP_FREG, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer + 4 : sse2_buffer + 12))); break; } - if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); - return SLJIT_SUCCESS; + return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, @@ -2938,19 +3136,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil switch (GET_OPCODE(op)) { case SLJIT_ADD_F64: - FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_32, dst_r, src2, src2w)); + FAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w)); break; case SLJIT_SUB_F64: - FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_32, dst_r, src2, src2w)); + FAIL_IF(emit_groupf(compiler, SUBSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w)); break; case SLJIT_MUL_F64: - FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_32, dst_r, src2, src2w)); + FAIL_IF(emit_groupf(compiler, MULSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w)); break; case SLJIT_DIV_F64: - FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_32, dst_r, src2, src2w)); + FAIL_IF(emit_groupf(compiler, DIVSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w)); break; } @@ -2959,6 +3157,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return SLJIT_SUCCESS; } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) +{ + sljit_uw pref; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif + + if (dst_freg == src1) { + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src2, src2w)); + pref = EX86_SELECT_66(op) | EX86_SSE2; + FAIL_IF(emit_groupf(compiler, XORPD_x_xm | pref, TMP_FREG, src1, src1w)); + FAIL_IF(emit_groupf(compiler, ANDPD_x_xm | pref, TMP_FREG, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer : sse2_buffer + 8))); + return emit_groupf(compiler, XORPD_x_xm | pref, dst_freg, TMP_FREG, 0); + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w)); + src1 = TMP_FREG; + src1w = 0; + } + + if (dst_freg != src2) + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_freg, src2, src2w)); + + pref = EX86_SELECT_66(op) | EX86_SSE2; + FAIL_IF(emit_groupf(compiler, XORPD_x_xm | pref, dst_freg, src1, src1w)); + FAIL_IF(emit_groupf(compiler, ANDPD_x_xm | pref, dst_freg, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer : sse2_buffer + 8))); + return emit_groupf(compiler, XORPD_x_xm | pref, dst_freg, src1, src1w); +} + /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ @@ -2980,9 +3217,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF(!inst); - - *inst++ = 0; - *inst++ = 0; + inst[0] = 0; + inst[1] = 0; return label; } @@ -3010,8 +3246,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF_NULL(inst); - *inst++ = 0; - *inst++ = 1; + inst[0] = 0; + inst[1] = 1; return jump; } @@ -3042,8 +3278,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi inst = (sljit_u8*)ensure_buf(compiler, 2); FAIL_IF_NULL(inst); - *inst++ = 0; - *inst++ = 1; + inst[0] = 0; + inst[1] = 1; } else { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -3052,8 +3288,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi #endif inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst = U8(*inst | ((type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm)); + inst[0] = GROUP_FF; + inst[1] = U8(inst[1] | ((type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm)); } return SLJIT_SUCCESS; } @@ -3063,10 +3299,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_s32 type) { sljit_u8 *inst; - sljit_u8 cond_set = 0; + sljit_u8 cond_set; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) sljit_s32 reg; -#endif +#endif /* !SLJIT_CONFIG_X86_64 */ /* ADJUST_LOCAL_OFFSET and CHECK_EXTRA_REGS might overwrite these values. */ sljit_s32 dst_save = dst; sljit_sw dstw_save = dstw; @@ -3086,13 +3322,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co FAIL_IF(!inst); INC_SIZE(4 + 3); /* Set low register to conditional flag. */ - *inst++ = (reg_map[TMP_REG1] <= 7) ? REX : REX_B; - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | reg_lmap[TMP_REG1]; - *inst++ = U8(REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B)); - *inst++ = OR_rm8_r8; - *inst++ = U8(MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]); + inst[0] = (reg_map[TMP_REG1] <= 7) ? REX : REX_B; + inst[1] = GROUP_0F; + inst[2] = cond_set; + inst[3] = MOD_REG | reg_lmap[TMP_REG1]; + inst[4] = U8(REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B)); + inst[5] = OR_rm8_r8; + inst[6] = U8(MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]); return SLJIT_SUCCESS; } @@ -3102,15 +3338,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co FAIL_IF(!inst); INC_SIZE(4 + 4); /* Set low register to conditional flag. */ - *inst++ = (reg_map[reg] <= 7) ? REX : REX_B; - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | reg_lmap[reg]; - *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); + inst[0] = (reg_map[reg] <= 7) ? REX : REX_B; + inst[1] = GROUP_0F; + inst[2] = cond_set; + inst[3] = MOD_REG | reg_lmap[reg]; + inst[4] = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); /* The movzx instruction does not affect flags. */ - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst = U8(MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]); + inst[5] = GROUP_0F; + inst[6] = MOVZX_r_rm8; + inst[7] = U8(MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]); if (reg != TMP_REG1) return SLJIT_SUCCESS; @@ -3123,110 +3359,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co SLJIT_SKIP_CHECKS(compiler); return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0); -#else +#else /* !SLJIT_CONFIG_X86_64 */ + SLJIT_ASSERT(reg_map[TMP_REG1] < 4); + /* The SLJIT_CONFIG_X86_32 code path starts here. */ - if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) { - if (reg_map[dst] <= 4) { - /* Low byte is accessible. */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3); - FAIL_IF(!inst); - INC_SIZE(3 + 3); - /* Set low byte to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = U8(MOD_REG | reg_map[dst]); - - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst = U8(MOD_REG | (reg_map[dst] << 3) | reg_map[dst]); - return SLJIT_SUCCESS; - } - - /* Low byte is not accessible. */ - if (cpu_feature_list == 0) - get_cpu_features(); - - if (cpu_feature_list & CPU_FEATURE_CMOV) { - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1); - /* a xor reg, reg operation would overwrite the flags. */ - EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0); - - inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); - FAIL_IF(!inst); - INC_SIZE(3); - - *inst++ = GROUP_0F; - /* cmovcc = setcc - 0x50. */ - *inst++ = U8(cond_set - 0x50); - *inst++ = U8(MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REG1]); - return SLJIT_SUCCESS; - } - - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst) && reg_map[dst] <= 4) { + /* Low byte is accessible. */ + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3); FAIL_IF(!inst); - INC_SIZE(1 + 3 + 3 + 1); - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); - /* Set al to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 0 /* eax */; + INC_SIZE(3 + 3); + /* Set low byte to conditional flag. */ + inst[0] = GROUP_0F; + inst[1] = cond_set; + inst[2] = U8(MOD_REG | reg_map[dst]); - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst++ = U8(MOD_REG | (reg_map[dst] << 3) | 0 /* eax */); - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); + inst[3] = GROUP_0F; + inst[4] = MOVZX_r_rm8; + inst[5] = U8(MOD_REG | (reg_map[dst] << 3) | reg_map[dst]); return SLJIT_SUCCESS; } if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && reg_map[dst] <= 4) { - SLJIT_ASSERT(reg_map[SLJIT_R0] == 0); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 2); + FAIL_IF(!inst); + INC_SIZE(3 + 2); - if (dst != SLJIT_R0) { - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1); - FAIL_IF(!inst); - INC_SIZE(1 + 3 + 2 + 1); - /* Set low register to conditional flag. */ - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 0 /* eax */; - *inst++ = OR_rm8_r8; - *inst++ = MOD_REG | (0 /* eax */ << 3) | reg_map[dst]; - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); - } - else { - inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2); - FAIL_IF(!inst); - INC_SIZE(2 + 3 + 2 + 2); - /* Set low register to conditional flag. */ - *inst++ = XCHG_r_rm; - *inst++ = U8(MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]); - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 1 /* ecx */; - *inst++ = OR_rm8_r8; - *inst++ = MOD_REG | (1 /* ecx */ << 3) | 0 /* eax */; - *inst++ = XCHG_r_rm; - *inst++ = U8(MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]); - } + /* Set low byte to conditional flag. */ + inst[0] = GROUP_0F; + inst[1] = cond_set; + inst[2] = U8(MOD_REG | reg_map[TMP_REG1]); + + inst[3] = OR_rm8_r8; + inst[4] = U8(MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[dst]); return SLJIT_SUCCESS; } - /* Set TMP_REG1 to the bit. */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3); FAIL_IF(!inst); - INC_SIZE(1 + 3 + 3 + 1); - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); - /* Set al to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 0 /* eax */; + INC_SIZE(3 + 3); + /* Set low byte to conditional flag. */ + inst[0] = GROUP_0F; + inst[1] = cond_set; + inst[2] = U8(MOD_REG | reg_map[TMP_REG1]); - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst++ = MOD_REG | (0 << 3) /* eax */ | 0 /* eax */; - - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); + inst[3] = GROUP_0F; + inst[4] = MOVZX_r_rm8; + inst[5] = U8(MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[TMP_REG1]); if (GET_OPCODE(op) < SLJIT_ADD) return emit_mov(compiler, dst, dstw, TMP_REG1, 0); @@ -3236,43 +3414,1256 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co #endif /* SLJIT_CONFIG_X86_64 */ } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { - sljit_u8* inst; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_s32 dst = dst_reg; + sljit_sw dstw = 0; +#endif /* SLJIT_CONFIG_X86_32 */ + sljit_sw src2w = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - type &= ~SLJIT_32; + ADJUST_LOCAL_OFFSET(src1, src1w); - if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV) || (dst_reg >= SLJIT_R3 && dst_reg <= SLJIT_S3)) - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw); -#else - if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV)) - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw); -#endif - - /* ADJUST_LOCAL_OFFSET is not needed. */ - CHECK_EXTRA_REGS(src, srcw, (void)0); + CHECK_EXTRA_REGS(dst, dstw, (void)0); + CHECK_EXTRA_REGS(src1, src1w, (void)0); + CHECK_EXTRA_REGS(src2_reg, src2w, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = type & SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ type &= ~SLJIT_32; -#endif - if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst & SLJIT_MEM) { + if (src1 == SLJIT_IMM || (!(src1 & SLJIT_MEM) && (src2_reg & SLJIT_MEM))) { + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + src1 = src2_reg; + src1w = src2w; + type ^= 0x1; + } else + EMIT_MOV(compiler, TMP_REG1, 0, src2_reg, src2w); + + dst_reg = TMP_REG1; + } else { +#endif /* SLJIT_CONFIG_X86_32 */ + if (dst_reg != src2_reg) { + if (dst_reg == src1) { + src1 = src2_reg; + src1w = src2w; + type ^= 0x1; + } else { + if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) { + EMIT_MOV(compiler, dst_reg, 0, src1, src1w); + src1 = src2_reg; + src1w = src2w; + type ^= 0x1; + } else + EMIT_MOV(compiler, dst_reg, 0, src2_reg, src2w); + } + } + + if (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) { + SLJIT_ASSERT(dst_reg != TMP_REG1); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + src1 = TMP_REG1; + src1w = 0; + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + } +#endif /* SLJIT_CONFIG_X86_32 */ + + if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) + FAIL_IF(emit_groupf(compiler, U8(get_jump_code((sljit_uw)type) - 0x40), dst_reg, src1, src1w)); + else + FAIL_IF(emit_cmov_generic(compiler, type, dst_reg, src1, src1w)); + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst_reg == TMP_REG1) + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); +#endif /* SLJIT_CONFIG_X86_32 */ + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_u8* inst; + sljit_uw size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(emit_sse2_load(compiler, type & SLJIT_32, dst_freg, src2_freg, 0)); + } + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = U8(get_jump_code((sljit_uw)(type & ~SLJIT_32) ^ 0x1) - 0x10); + + size = compiler->size; + FAIL_IF(emit_sse2_load(compiler, type & SLJIT_32, dst_freg, src1, src1w)); + + inst[1] = U8(compiler->size - size); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_uw op; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + + switch (reg_size) { + case 4: + op = EX86_SSE2; + break; + case 5: + if (!(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + op = EX86_SSE2 | VEX_256; + break; + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (!(srcdst & SLJIT_MEM)) + alignment = reg_size; + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 2 || elem_size == 3) { + op |= alignment >= reg_size ? MOVAPS_x_xm : MOVUPS_x_xm; + + if (elem_size == 3) + op |= EX86_PREF_66; + + if (type & SLJIT_SIMD_STORE) + op += 1; + } else + return SLJIT_ERR_UNSUPPORTED; + } else { + op |= ((type & SLJIT_SIMD_STORE) ? MOVDQA_xm_x : MOVDQA_x_xm) + | (alignment >= reg_size ? EX86_PREF_66 : EX86_PREF_F3); + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (op & VEX_256) + return emit_vex_instruction(compiler, op, freg, 0, srcdst, srcdstw); + + return emit_groupf(compiler, op, freg, srcdst, srcdstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_u8 *inst; + sljit_u8 opcode = 0; + sljit_uw size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (!(type & SLJIT_SIMD_FLOAT)) { + CHECK_EXTRA_REGS(src, srcw, (void)0); + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2)) + return SLJIT_ERR_UNSUPPORTED; +#else /* !SLJIT_CONFIG_X86_32 */ + compiler->mode32 = 1; + + if (elem_size > 3 || ((type & SLJIT_SIMD_FLOAT) && elem_size < 2)) + return SLJIT_ERR_UNSUPPORTED; +#endif /* SLJIT_CONFIG_X86_32 */ + + if (cpu_feature_list & CPU_FEATURE_AVX2) { + if (reg_size < 4 || reg_size > 5) + return SLJIT_ERR_UNSUPPORTED; + + if (src != SLJIT_IMM && (reg_size == 5 || elem_size < 3 || !(type & SLJIT_SIMD_FLOAT))) { + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (!(src & SLJIT_MEM) && !(type & SLJIT_SIMD_FLOAT)) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (elem_size >= 3) + compiler->mode32 = 0; +#endif /* SLJIT_CONFIG_X86_64 */ + FAIL_IF(emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, freg, src, srcw)); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + src = freg; + srcw = 0; + } + + switch (elem_size) { + case 0: + size = VPBROADCASTB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + case 1: + size = VPBROADCASTW_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + case 2: + size = ((type & SLJIT_SIMD_FLOAT) ? VBROADCASTSS_x_xm : VPBROADCASTD_x_xm) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + default: +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + size = VBROADCASTSD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; +#else /* !SLJIT_CONFIG_X86_32 */ + size = ((type & SLJIT_SIMD_FLOAT) ? VBROADCASTSD_x_xm : VPBROADCASTQ_x_xm) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; +#endif /* SLJIT_CONFIG_X86_32 */ + break; + } + + if (reg_size == 5) + size |= VEX_256; + + return emit_vex_instruction(compiler, size, freg, 0, src, srcw); + } + } else if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (type & SLJIT_SIMD_FLOAT) { + if (src == SLJIT_IMM) { + if (reg_size == 5) + return emit_vex_instruction(compiler, XORPD_x_xm | VEX_256 | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0); + + return emit_groupf(compiler, XORPD_x_xm | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2, freg, freg, 0); + } + + if (elem_size == 2 && freg != src) { + FAIL_IF(emit_sse2_load(compiler, 1, freg, src, srcw)); + src = freg; + srcw = 0; + } + + FAIL_IF(emit_groupf(compiler, (elem_size == 2 ? SHUFPS_x_xm : MOVDDUP_x_xm) | (elem_size == 2 ? 0 : EX86_PREF_F2) | EX86_SSE2, freg, src, srcw)); + + if (elem_size == 2) + return emit_byte(compiler, 0); + return SLJIT_SUCCESS; + } + + if (src == SLJIT_IMM) { + if (elem_size == 0) { + srcw = (sljit_u8)srcw; + srcw |= srcw << 8; + srcw |= srcw << 16; + elem_size = 2; + } else if (elem_size == 1) { + srcw = (sljit_u16)srcw; + srcw |= srcw << 16; + elem_size = 2; + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (elem_size == 2 && (sljit_s32)srcw == -1) + srcw = -1; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (srcw == 0 || srcw == -1) { + if (reg_size == 5) + return emit_vex_instruction(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | VEX_256 | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0); + + return emit_groupf(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | EX86_PREF_66 | EX86_SSE2, freg, freg, 0); + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (elem_size == 3) + FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw)); + else +#endif /* SLJIT_CONFIG_X86_64 */ + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); + src = TMP_REG1; srcw = 0; } - inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw); + size = 2; + opcode = MOVD_x_rm; + + switch (elem_size) { + case 0: + if (!FAST_IS_REG(src)) { + opcode = 0x3a /* Prefix of PINSRB_x_rm_i8. */; + size = 3; + } + break; + case 1: + if (!FAST_IS_REG(src)) + opcode = PINSRW_x_rm_i8; + break; + case 2: + break; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + case 3: + /* MOVQ */ + compiler->mode32 = 0; + break; +#endif /* SLJIT_CONFIG_X86_64 */ + } + + inst = emit_x86_instruction(compiler, size | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = U8(get_jump_code((sljit_uw)type) - 0x40); + inst[0] = GROUP_0F; + inst[1] = opcode; + + if (reg_size == 5) { + SLJIT_ASSERT(opcode == MOVD_x_rm); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + size = VPBROADCASTD_x_xm; +#else /* !SLJIT_CONFIG_X86_32 */ + size = (elem_size == 3) ? VPBROADCASTQ_x_xm : VPBROADCASTD_x_xm; +#endif /* SLJIT_CONFIG_X86_32 */ + return emit_vex_instruction(compiler, size | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); + } + + if (size == 3) { + SLJIT_ASSERT(opcode == 0x3a); + inst[2] = PINSRB_x_rm_i8; + } + + if (opcode != MOVD_x_rm) + FAIL_IF(emit_byte(compiler, 0)); + + switch (elem_size) { + case 0: + FAIL_IF(emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, TMP_FREG, 0)); + return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, TMP_FREG, 0); + case 1: + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, freg, 0)); + FAIL_IF(emit_byte(compiler, 0)); + /* fallthrough */ + default: + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, freg, 0)); + return emit_byte(compiler, 0); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + case 3: + compiler->mode32 = 1; + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, freg, 0)); + return emit_byte(compiler, 0x44); +#endif /* SLJIT_CONFIG_X86_64 */ + } +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_u8 *inst; + sljit_u8 opcode = 0; + sljit_uw size; + sljit_s32 freg_orig = freg; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_s32 srcdst_is_ereg = 0; + sljit_s32 srcdst_orig = 0; + sljit_sw srcdstw_orig = 0; +#endif /* SLJIT_CONFIG_X86_32 */ + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size == 5) { + if (!(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + } else if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2) + return SLJIT_ERR_UNSUPPORTED; +#else /* SLJIT_CONFIG_X86_32 */ + if (elem_size > 3 || ((type & SLJIT_SIMD_FLOAT) && elem_size < 2)) + return SLJIT_ERR_UNSUPPORTED; +#endif /* SLJIT_CONFIG_X86_32 */ + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#else /* !SLJIT_CONFIG_X86_64 */ + if (!(type & SLJIT_SIMD_FLOAT)) { + CHECK_EXTRA_REGS(srcdst, srcdstw, srcdst_is_ereg = 1); + + if ((type & SLJIT_SIMD_STORE) && ((srcdst_is_ereg && elem_size < 2) || (elem_size == 0 && (type & SLJIT_SIMD_LANE_SIGNED) && FAST_IS_REG(srcdst) && reg_map[srcdst] >= 4))) { + srcdst_orig = srcdst; + srcdstw_orig = srcdstw; + srcdst = TMP_REG1; + srcdstw = 0; + } + } +#endif /* SLJIT_CONFIG_X86_64 */ + + if (type & SLJIT_SIMD_LANE_ZERO) { + if (lane_index == 0) { + if (!(type & SLJIT_SIMD_FLOAT)) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (elem_size == 3) { + compiler->mode32 = 0; + elem_size = 2; + } +#endif /* SLJIT_CONFIG_X86_64 */ + if (srcdst == SLJIT_IMM) { + if (elem_size == 0) + srcdstw = (sljit_u8)srcdstw; + else if (elem_size == 1) + srcdstw = (sljit_u16)srcdstw; + + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcdstw); + srcdst = TMP_REG1; + srcdstw = 0; + elem_size = 2; + } + + if (elem_size == 2) { + if (reg_size == 4) + return emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, freg, srcdst, srcdstw); + return emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, srcdst, srcdstw); + } + } else if (srcdst & SLJIT_MEM) { + SLJIT_ASSERT(elem_size == 2 || elem_size == 3); + + if (reg_size == 4) + return emit_groupf(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, freg, srcdst, srcdstw); + return emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, freg, 0, srcdst, srcdstw); + } else if (elem_size == 3) { + if (reg_size == 4) + return emit_groupf(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, freg, srcdst, 0); + return emit_vex_instruction(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, freg, 0, srcdst, 0); + } + } + + if (reg_size == 5 && lane_index >= (1 << (4 - elem_size))) { + freg = TMP_FREG; + lane_index -= (1 << (4 - elem_size)); + } else if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { + FAIL_IF(emit_sse2_load(compiler, elem_size == 2, TMP_FREG, srcdst, srcdstw)); + srcdst = TMP_FREG; + srcdstw = 0; + } + + size = ((!(type & SLJIT_SIMD_FLOAT) || elem_size != 2) ? EX86_PREF_66 : 0) + | ((type & SLJIT_SIMD_FLOAT) ? XORPD_x_xm : PXOR_x_xm) | EX86_SSE2; + + if (reg_size == 5) + FAIL_IF(emit_vex_instruction(compiler, size | VEX_256 | VEX_SSE2_OPV, freg, freg, freg, 0)); + else + FAIL_IF(emit_groupf(compiler, size, freg, freg, 0)); + } else if (reg_size == 5 && lane_index >= (1 << (4 - elem_size))) { + FAIL_IF(emit_vex_instruction(compiler, ((type & SLJIT_SIMD_FLOAT) ? VEXTRACTF128_x_ym : VEXTRACTI128_x_ym) | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, 0, TMP_FREG, 0)); + FAIL_IF(emit_byte(compiler, 1)); + + freg = TMP_FREG; + lane_index -= (1 << (4 - elem_size)); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 3) { + if (srcdst & SLJIT_MEM) { + if (type & SLJIT_SIMD_STORE) + size = lane_index == 0 ? MOVLPD_m_x : MOVHPD_m_x; + else + size = lane_index == 0 ? MOVLPD_x_m : MOVHPD_x_m; + + FAIL_IF(emit_groupf(compiler, size | EX86_PREF_66 | EX86_SSE2, freg, srcdst, srcdstw)); + + /* In case of store, freg is not TMP_FREG. */ + } else if (type & SLJIT_SIMD_STORE) { + if (lane_index == 1) + return emit_groupf(compiler, MOVHLPS_x_x | EX86_SSE2, srcdst, freg, 0); + return emit_sse2_load(compiler, 0, srcdst, freg, 0); + } else { + if (lane_index == 1) + FAIL_IF(emit_groupf(compiler, MOVLHPS_x_x | EX86_SSE2, freg, srcdst, 0)); + else + FAIL_IF(emit_sse2_store(compiler, 0, freg, 0, srcdst)); + } + } else if (type & SLJIT_SIMD_STORE) { + if (lane_index == 0) + return emit_sse2_store(compiler, 1, srcdst, srcdstw, freg); + + if (srcdst & SLJIT_MEM) { + FAIL_IF(emit_groupf_ext(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, srcdst, srcdstw)); + return emit_byte(compiler, U8(lane_index)); + } + + if (srcdst == freg) + size = SHUFPS_x_xm | EX86_SSE2; + else { + if (cpu_feature_list & CPU_FEATURE_AVX) { + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, srcdst, freg, freg, 0)); + return emit_byte(compiler, U8(lane_index)); + } + + switch (lane_index) { + case 1: + size = MOVSHDUP_x_xm | EX86_PREF_F3 | EX86_SSE2; + break; + case 2: + size = MOVHLPS_x_x | EX86_SSE2; + break; + default: + SLJIT_ASSERT(lane_index == 3); + size = PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2; + break; + } + } + + FAIL_IF(emit_groupf(compiler, size, srcdst, freg, 0)); + + size &= 0xff; + if (size == SHUFPS_x_xm || size == PSHUFD_x_xm) + return emit_byte(compiler, U8(lane_index)); + + return SLJIT_SUCCESS; + } else { + if (lane_index != 0 || (srcdst & SLJIT_MEM)) { + FAIL_IF(emit_groupf_ext(compiler, INSERTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, srcdst, srcdstw)); + FAIL_IF(emit_byte(compiler, U8(lane_index << 4))); + } else + FAIL_IF(emit_sse2_store(compiler, 1, freg, 0, srcdst)); + } + + if (freg != TMP_FREG || (type & SLJIT_SIMD_STORE)) + return SLJIT_SUCCESS; + + SLJIT_ASSERT(reg_size == 5); + + if (type & SLJIT_SIMD_LANE_ZERO) { + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg_orig, 0, TMP_FREG, 0)); + return emit_byte(compiler, 0x4e); + } + + FAIL_IF(emit_vex_instruction(compiler, VINSERTF128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, freg_orig, freg_orig, TMP_FREG, 0)); + return emit_byte(compiler, 1); + } + + if (srcdst == SLJIT_IMM) { + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcdstw); + srcdst = TMP_REG1; + srcdstw = 0; + } + + size = 3; + + switch (elem_size) { + case 0: + opcode = (type & SLJIT_SIMD_STORE) ? PEXTRB_rm_x_i8 : PINSRB_x_rm_i8; + break; + case 1: + if (!(type & SLJIT_SIMD_STORE)) { + size = 2; + opcode = PINSRW_x_rm_i8; + } else + opcode = PEXTRW_rm_x_i8; + break; + case 2: + opcode = (type & SLJIT_SIMD_STORE) ? PEXTRD_rm_x_i8 : PINSRD_x_rm_i8; + break; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + case 3: + /* PINSRQ / PEXTRQ */ + opcode = (type & SLJIT_SIMD_STORE) ? PEXTRD_rm_x_i8 : PINSRD_x_rm_i8; + compiler->mode32 = 0; + break; +#endif /* SLJIT_CONFIG_X86_64 */ + } + + inst = emit_x86_instruction(compiler, size | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, srcdst, srcdstw); + FAIL_IF(!inst); + inst[0] = GROUP_0F; + + if (size == 3) { + inst[1] = 0x3a; + inst[2] = opcode; + } else + inst[1] = opcode; + + FAIL_IF(emit_byte(compiler, U8(lane_index))); + + if (!(type & SLJIT_SIMD_LANE_SIGNED) || (srcdst & SLJIT_MEM)) { + if (freg == TMP_FREG && !(type & SLJIT_SIMD_STORE)) { + SLJIT_ASSERT(reg_size == 5); + + if (type & SLJIT_SIMD_LANE_ZERO) { + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg_orig, 0, TMP_FREG, 0)); + return emit_byte(compiler, 0x4e); + } + + FAIL_IF(emit_vex_instruction(compiler, VINSERTI128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, freg_orig, freg_orig, TMP_FREG, 0)); + return emit_byte(compiler, 1); + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (srcdst_orig & SLJIT_MEM) + return emit_mov(compiler, srcdst_orig, srcdstw_orig, TMP_REG1, 0); +#endif /* SLJIT_CONFIG_X86_32 */ + return SLJIT_SUCCESS; + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (elem_size >= 3) + return SLJIT_SUCCESS; + + compiler->mode32 = (type & SLJIT_32); + + size = 2; + + if (elem_size == 0) + size |= EX86_REX; + + if (elem_size == 2) { + if (type & SLJIT_32) + return SLJIT_SUCCESS; + + SLJIT_ASSERT(!(compiler->mode32)); + size = 1; + } + + inst = emit_x86_instruction(compiler, size, srcdst, 0, srcdst, 0); + FAIL_IF(!inst); + + if (size != 1) { + inst[0] = GROUP_0F; + inst[1] = U8((elem_size == 0) ? MOVSX_r_rm8 : MOVSX_r_rm16); + } else + inst[0] = MOVSXD_r_rm; +#else /* !SLJIT_CONFIG_X86_64 */ + if (elem_size >= 2) + return SLJIT_SUCCESS; + + FAIL_IF(emit_groupf(compiler, (elem_size == 0) ? MOVSX_r_rm8 : MOVSX_r_rm16, + (srcdst_orig != 0 && FAST_IS_REG(srcdst_orig)) ? srcdst_orig : srcdst, srcdst, 0)); + + if (srcdst_orig & SLJIT_MEM) + return emit_mov(compiler, srcdst_orig, srcdstw_orig, TMP_REG1, 0); +#endif /* SLJIT_CONFIG_X86_64 */ + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_uw pref; + sljit_u8 byte; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_s32 opcode3 = TMP_REG1; +#else /* !SLJIT_CONFIG_X86_32 */ + sljit_s32 opcode3 = SLJIT_S0; +#endif /* SLJIT_CONFIG_X86_32 */ + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + SLJIT_ASSERT(reg_map[opcode3] == 3); + + if (reg_size == 5) { + if (!(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + } else if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_FLOAT) { + pref = 0; + byte = U8(src_lane_index); + + if (elem_size == 3) { + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 5) { + if (src_lane_index == 0) + return emit_vex_instruction(compiler, VBROADCASTSD_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); + + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + + byte = U8(byte | (byte << 2)); + return emit_byte(compiler, U8(byte | (byte << 4))); + } + + if (src_lane_index == 0) + return emit_groupf(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, src, 0); + + /* Changes it to SHUFPD_x_xm. */ + pref = EX86_PREF_66; + } else if (elem_size != 2) + return SLJIT_ERR_UNSUPPORTED; + else if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 5) { + SLJIT_ASSERT(elem_size == 2); + + if (src_lane_index == 0) + return emit_vex_instruction(compiler, VBROADCASTSS_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); + + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + + byte = 0x44; + if (src_lane_index >= 4) { + byte = 0xee; + src_lane_index -= 4; + } + + FAIL_IF(emit_byte(compiler, byte)); + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | VEX_256 | pref | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0)); + byte = U8(src_lane_index); + } else if (freg != src && (cpu_feature_list & CPU_FEATURE_AVX)) { + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | pref | EX86_SSE2 | VEX_SSE2_OPV, freg, src, src, 0)); + } else { + if (freg != src) + FAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | pref | EX86_SSE2, freg, src, 0)); + + FAIL_IF(emit_groupf(compiler, SHUFPS_x_xm | pref | EX86_SSE2, freg, freg, 0)); + } + + if (elem_size == 2) { + byte = U8(byte | (byte << 2)); + byte = U8(byte | (byte << 4)); + } else + byte = U8(byte | (byte << 1)); + + return emit_byte(compiler, U8(byte)); + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (elem_size == 0) { + if (reg_size == 5 && src_lane_index >= 16) { + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + FAIL_IF(emit_byte(compiler, src_lane_index >= 24 ? 0xff : 0xaa)); + src_lane_index &= 0x7; + src = freg; + } + + if ((freg != src && !(cpu_feature_list & CPU_FEATURE_AVX2)) || src_lane_index != 0) { + pref = 0; + + if ((src_lane_index & 0x3) == 0) { + pref = EX86_PREF_66; + byte = U8(src_lane_index >> 2); + } else if (src_lane_index < 8 && (src_lane_index & 0x1) == 0) { + pref = EX86_PREF_F2; + byte = U8(src_lane_index >> 1); + } else { + if (freg == src || !(cpu_feature_list & CPU_FEATURE_AVX2)) { + if (freg != src) + FAIL_IF(emit_groupf(compiler, MOVDQA_x_xm | EX86_PREF_66 | EX86_SSE2, freg, src, 0)); + + FAIL_IF(emit_groupf(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2, opcode3, freg, 0)); + } else + FAIL_IF(emit_vex_instruction(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2 | VEX_SSE2_OPV, opcode3, freg, src, 0)); + + FAIL_IF(emit_byte(compiler, U8(src_lane_index))); + } + + if (pref != 0) { + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, src, 0)); + FAIL_IF(emit_byte(compiler, byte)); + } + + src = freg; + } + + if (cpu_feature_list & CPU_FEATURE_AVX2) + return emit_vex_instruction(compiler, VPBROADCASTB_x_xm | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); + + SLJIT_ASSERT(reg_size == 4); + FAIL_IF(emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, TMP_FREG, 0)); + return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, TMP_FREG, 0); + } + + if ((cpu_feature_list & CPU_FEATURE_AVX2) && src_lane_index == 0 && elem_size <= 3) { + switch (elem_size) { + case 1: + pref = VPBROADCASTW_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + case 2: + pref = VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + default: + pref = VPBROADCASTQ_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + } + + if (reg_size == 5) + pref |= VEX_256; + + return emit_vex_instruction(compiler, pref, freg, 0, src, 0); + } + + if (reg_size == 5) { + switch (elem_size) { + case 1: + byte = U8(src_lane_index & 0x3); + src_lane_index >>= 2; + pref = PSHUFLW_x_xm | VEX_256 | ((src_lane_index & 1) == 0 ? EX86_PREF_F2 : EX86_PREF_F3) | EX86_SSE2; + break; + case 2: + byte = U8(src_lane_index & 0x3); + src_lane_index >>= 1; + pref = PSHUFD_x_xm | VEX_256 | EX86_PREF_66 | EX86_SSE2; + break; + case 3: + pref = 0; + break; + default: + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + return emit_byte(compiler, U8(src_lane_index == 0 ? 0x44 : 0xee)); + } + + if (pref != 0) { + FAIL_IF(emit_vex_instruction(compiler, pref, freg, 0, src, 0)); + byte = U8(byte | (byte << 2)); + FAIL_IF(emit_byte(compiler, U8(byte | (byte << 4)))); + + if (src_lane_index == 0) + return emit_vex_instruction(compiler, VPBROADCASTQ_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); + + src = freg; + } + + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + byte = U8(src_lane_index); + byte = U8(byte | (byte << 2)); + return emit_byte(compiler, U8(byte | (byte << 4))); + } + + switch (elem_size) { + case 1: + byte = U8(src_lane_index & 0x3); + src_lane_index >>= 1; + pref = (src_lane_index & 2) == 0 ? EX86_PREF_F2 : EX86_PREF_F3; + + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, src, 0)); + byte = U8(byte | (byte << 2)); + FAIL_IF(emit_byte(compiler, U8(byte | (byte << 4)))); + + if ((cpu_feature_list & CPU_FEATURE_AVX2) && pref == EX86_PREF_F2) + return emit_vex_instruction(compiler, VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); + + src = freg; + /* fallthrough */ + case 2: + byte = U8(src_lane_index); + byte = U8(byte | (byte << 2)); + break; + default: + byte = U8(src_lane_index << 1); + byte = U8(byte | (byte << 2) | 0x4); + break; + } + + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, src, 0)); + return emit_byte(compiler, U8(byte | (byte << 4))); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_u8 opcode; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (reg_size == 5) { + if (!(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + } else if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size != 2 || elem2_size != 3) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + return emit_groupf(compiler, CVTPS2PD_x_xm | EX86_SSE2, freg, src, srcw); + return emit_vex_instruction(compiler, CVTPS2PD_x_xm | VEX_256 | EX86_SSE2, freg, 0, src, srcw); + } + + switch (elem_size) { + case 0: + if (elem2_size == 1) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXBW_x_xm : PMOVZXBW_x_xm; + else if (elem2_size == 2) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXBD_x_xm : PMOVZXBD_x_xm; + else if (elem2_size == 3) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXBQ_x_xm : PMOVZXBQ_x_xm; + else + return SLJIT_ERR_UNSUPPORTED; + break; + case 1: + if (elem2_size == 2) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXWD_x_xm : PMOVZXWD_x_xm; + else if (elem2_size == 3) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXWQ_x_xm : PMOVZXWQ_x_xm; + else + return SLJIT_ERR_UNSUPPORTED; + break; + case 2: + if (elem2_size == 3) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXDQ_x_xm : PMOVZXDQ_x_xm; + else + return SLJIT_ERR_UNSUPPORTED; + break; + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + return emit_groupf_ext(compiler, opcode | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, src, srcw); + return emit_vex_instruction(compiler, opcode | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, srcw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 dst_r; + sljit_uw pref; + sljit_u8 *inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (elem_size > 3 || ((type & SLJIT_SIMD_FLOAT) && elem_size < 2)) + return SLJIT_ERR_UNSUPPORTED; + + if (reg_size == 4) { + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + pref = EX86_PREF_66 | EX86_SSE2_OP2; + + switch (elem_size) { + case 1: + FAIL_IF(emit_groupf(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, freg, 0)); + freg = TMP_FREG; + break; + case 2: + pref = EX86_SSE2_OP2; + break; + } + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + FAIL_IF(emit_groupf(compiler, (elem_size < 2 ? PMOVMSKB_r_x : MOVMSKPS_r_x) | pref, dst_r, freg, 0)); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = type & SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (elem_size == 1) { + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 8, dst_r, 0); + FAIL_IF(!inst); + inst[1] |= SHR; + } + + if (dst_r == TMP_REG1) + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); + + return SLJIT_SUCCESS; + } + + if (reg_size != 5 || !(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + + if (elem_size == 1) { + FAIL_IF(emit_vex_instruction(compiler, VEXTRACTI128_x_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, 0, TMP_FREG, 0)); + FAIL_IF(emit_byte(compiler, 1)); + FAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | VEX_256 | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, freg, TMP_FREG, 0)); + FAIL_IF(emit_groupf(compiler, PMOVMSKB_r_x | EX86_PREF_66 | EX86_SSE2_OP2, dst_r, TMP_FREG, 0)); + } else { + pref = MOVMSKPS_r_x | VEX_256 | EX86_SSE2_OP2; + + if (elem_size == 0) + pref = PMOVMSKB_r_x | VEX_256 | EX86_PREF_66 | EX86_SSE2_OP2; + else if (elem_size == 3) + pref |= EX86_PREF_66; + + FAIL_IF(emit_vex_instruction(compiler, pref, dst_r, 0, freg, 0)); + } + + if (dst_r == TMP_REG1) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = type & SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); + } + + return SLJIT_SUCCESS; +} + +static sljit_s32 emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src_freg) +{ + sljit_uw op = ((type & SLJIT_SIMD_FLOAT) ? MOVAPS_x_xm : MOVDQA_x_xm) | EX86_SSE2; + + SLJIT_ASSERT(SLJIT_SIMD_GET_REG_SIZE(type) == 4); + + if (!(type & SLJIT_SIMD_FLOAT) || SLJIT_SIMD_GET_ELEM_SIZE(type) == 3) + op |= EX86_PREF_66; + + return emit_groupf(compiler, op, dst_freg, src_freg, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 needs_move = 0; + sljit_uw op = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (reg_size == 5) { + if (!(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + } else if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + switch (SLJIT_SIMD_GET_OPCODE(type)) { + case SLJIT_SIMD_OP2_AND: + op = (type & SLJIT_SIMD_FLOAT) ? ANDPD_x_xm : PAND_x_xm; + + if (!(type & SLJIT_SIMD_FLOAT) || elem_size == 3) + op |= EX86_PREF_66; + break; + case SLJIT_SIMD_OP2_OR: + op = (type & SLJIT_SIMD_FLOAT) ? ORPD_x_xm : POR_x_xm; + + if (!(type & SLJIT_SIMD_FLOAT) || elem_size == 3) + op |= EX86_PREF_66; + break; + case SLJIT_SIMD_OP2_XOR: + op = (type & SLJIT_SIMD_FLOAT) ? XORPD_x_xm : PXOR_x_xm; + + if (!(type & SLJIT_SIMD_FLOAT) || elem_size == 3) + op |= EX86_PREF_66; + break; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + needs_move = dst_freg != src1_freg && dst_freg != src2_freg; + + if (reg_size == 5 || (needs_move && (cpu_feature_list & CPU_FEATURE_AVX2))) { + if (reg_size == 5) + op |= VEX_256; + + return emit_vex_instruction(compiler, op | EX86_SSE2 | VEX_SSE2_OPV, dst_freg, src1_freg, src2_freg, 0); + } + + if (needs_move) { + FAIL_IF(emit_simd_mov(compiler, type, dst_freg, src1_freg)); + } else if (dst_freg != src1_freg) { + SLJIT_ASSERT(dst_freg == src2_freg); + src2_freg = src1_freg; + } + + FAIL_IF(emit_groupf(compiler, op | EX86_SSE2, dst_freg, src2_freg, 0)); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + SLJIT_SKIP_CHECKS(compiler); + return sljit_emit_op1(compiler, op, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_uw pref; + sljit_s32 free_reg = TMP_REG1; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_sw srcw = 0; + sljit_sw tempw = 0; +#endif /* SLJIT_CONFIG_X86_32 */ + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + CHECK_EXTRA_REGS(src_reg, srcw, (void)0); + CHECK_EXTRA_REGS(temp_reg, tempw, (void)0); + + SLJIT_ASSERT(FAST_IS_REG(src_reg) || src_reg == SLJIT_MEM1(SLJIT_SP)); + SLJIT_ASSERT(FAST_IS_REG(temp_reg) || temp_reg == SLJIT_MEM1(SLJIT_SP)); + + op = GET_OPCODE(op); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if ((src_reg & SLJIT_MEM) || (op == SLJIT_MOV_U8 && reg_map[src_reg] >= 4)) { + /* Src is virtual register or its low byte is not accessible. */ + SLJIT_ASSERT(src_reg != SLJIT_R1); + free_reg = src_reg; + + EMIT_MOV(compiler, TMP_REG1, 0, src_reg, srcw); + src_reg = TMP_REG1; + + if (mem_reg == src_reg) + mem_reg = TMP_REG1; + } +#endif /* SLJIT_CONFIG_X86_32 */ + + if (temp_reg != SLJIT_R0) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; + + EMIT_MOV(compiler, free_reg, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, 0); + + if (src_reg == SLJIT_R0) + src_reg = free_reg; + if (mem_reg == SLJIT_R0) + mem_reg = free_reg; +#else /* !SLJIT_CONFIG_X86_64 */ + if (src_reg == TMP_REG1 && mem_reg == SLJIT_R0 && (free_reg & SLJIT_MEM)) { + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R1, 0); + EMIT_MOV(compiler, SLJIT_R1, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); + + mem_reg = SLJIT_R1; + free_reg = SLJIT_R1; + } else { + EMIT_MOV(compiler, free_reg, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); + + if (src_reg == SLJIT_R0) + src_reg = free_reg; + if (mem_reg == SLJIT_R0) + mem_reg = free_reg; + } +#endif /* SLJIT_CONFIG_X86_64 */ + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = op != SLJIT_MOV && op != SLJIT_MOV_P; +#endif /* SLJIT_CONFIG_X86_64 */ + + /* Lock prefix. */ + FAIL_IF(emit_byte(compiler, GROUP_LOCK)); + + pref = 0; + if (op == SLJIT_MOV_U16) + pref = EX86_HALF_ARG | EX86_PREF_66; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (op == SLJIT_MOV_U8) + pref = EX86_REX; +#endif /* SLJIT_CONFIG_X86_64 */ + + FAIL_IF(emit_groupf(compiler, (op == SLJIT_MOV_U8 ? CMPXCHG_rm8_r : CMPXCHG_rm_r) | pref, src_reg, SLJIT_MEM1(mem_reg), 0)); + + if (temp_reg != SLJIT_R0) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; + return emit_mov(compiler, SLJIT_R0, 0, TMP_REG1, 0); +#else /* !SLJIT_CONFIG_X86_64 */ + EMIT_MOV(compiler, SLJIT_R0, 0, free_reg, 0); + if (free_reg != TMP_REG1) + return emit_mov(compiler, free_reg, 0, (free_reg == SLJIT_R1) ? SLJIT_MEM1(SLJIT_SP) : TMP_REG1, 0); +#endif /* SLJIT_CONFIG_X86_64 */ + } return SLJIT_SUCCESS; } @@ -3339,8 +4730,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF(!inst); - *inst++ = 0; - *inst++ = 2; + inst[0] = 0; + inst[1] = 2; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (dst & SLJIT_MEM) @@ -3393,8 +4784,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF(!inst); - *inst++ = 0; - *inst++ = 3; + inst[0] = 0; + inst[1] = 3; return put_label; } diff --git a/src/corelib/text/qregularexpression.cpp b/src/corelib/text/qregularexpression.cpp index c2c2dacb767..91809df5959 100644 --- a/src/corelib/text/qregularexpression.cpp +++ b/src/corelib/text/qregularexpression.cpp @@ -3127,7 +3127,8 @@ static const char *pcreCompileErrorCodes[] = QT_TRANSLATE_NOOP("QRegularExpression", "heap limit exceeded"), QT_TRANSLATE_NOOP("QRegularExpression", "invalid syntax"), QT_TRANSLATE_NOOP("QRegularExpression", "internal error - duplicate substitution match"), - QT_TRANSLATE_NOOP("QRegularExpression", "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching") + QT_TRANSLATE_NOOP("QRegularExpression", "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching"), + QT_TRANSLATE_NOOP("QRegularExpression", "INTERNAL ERROR: invalid substring offset") }; #endif // #if 0 From 86552dafc4df546903526f74374ce8974b5865f7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 20 Mar 2024 17:14:41 +0100 Subject: [PATCH 51/58] QMetaMethod: document that fromSignal(nullptr) is ok MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... and add a test. Change-Id: I907899d7c54349d2fc23ea5ab58a1e67826b622b Reviewed-by: Thiago Macieira Reviewed-by: Mårten Nordheim (cherry picked from commit 78db468f4895911e50849223899abf2c5fb1c72e) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 9f14d0a288ef5355ca92e64fe464735f119b8ec5) (cherry picked from commit fcd465512aa78039123343da86610a36f509878e) (cherry picked from commit f9e79171b6228de4a223c19c82b76ed1d5b4524b) (cherry picked from commit 7fc97b66603fca73ddafa849d3b165d2b8624acb) --- src/corelib/kernel/qmetaobject.cpp | 2 +- tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index e4c34800950..2894aacec6a 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2112,7 +2112,7 @@ QMetaMethod::MethodType QMetaMethod::methodType() const \since 5.0 Returns the meta-method that corresponds to the given \a signal, or an - invalid QMetaMethod if \a signal is not a signal of the class. + invalid QMetaMethod if \a signal is \c{nullptr} or not a signal of the class. Example: diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index 4584b6ce318..8f545ca47ba 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -46,6 +46,7 @@ private slots: void comparisonOperators(); void fromSignal(); + void fromSignalOfNullSignalIsInvalid(); void gadget(); }; @@ -725,6 +726,12 @@ void tst_QMetaMethod::fromSignal() #undef FROMSIGNAL_HELPER } +void tst_QMetaMethod::fromSignalOfNullSignalIsInvalid() +{ + constexpr decltype(&QObject::destroyed) ptr = nullptr; + QVERIFY(!QMetaMethod::fromSignal(ptr).isValid()); +} + class MyGadget { Q_GADGET public: From a5cc2d979049ea8113352b079c321bb90b8a5200 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Tue, 19 Mar 2024 12:26:00 +0100 Subject: [PATCH 52/58] xcb: Avoid recreating xcb window in QXcbWindow::requestActivateWindow() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 12203e94f5a34b59b6a7389402c854e823135a35 exposes the issue in xcb qpa plugin. We should not recreate xcb window via the call of focusWindow->winId(). Fixes: QTBUG-123032 Change-Id: I6da4f3e64a9d7a92a2aab714591986c5d128fbd4 Reviewed-by: Tor Arne Vestbø (cherry picked from commit 23a906335e0d8a03388bbd73db43682c724d04a7) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 167287e11a1b608f298d3aed5c593ac41897d8a9) (cherry picked from commit 3999eab0a0e2a350860a6ac4397de9bb24c7846f) (cherry picked from commit 72ce299bad2d7a71294160e1766a4620a0e1eb98) (cherry picked from commit 643c97c975981f43ed032d9b8b7f90a741a66b5a) --- src/plugins/platforms/xcb/qxcbwindow.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 51d1b73e0b1..ac9ab39c6fe 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1482,6 +1482,11 @@ void QXcbWindow::requestActivateWindow() updateNetWmUserTime(connection()->time()); QWindow *focusWindow = QGuiApplication::focusWindow(); + xcb_window_t current = XCB_NONE; + if (focusWindow) { + if (QPlatformWindow *pw = focusWindow->handle()) + current = pw->winId(); + } if (window()->isTopLevel() && !(window()->flags() & Qt::X11BypassWindowManagerHint) @@ -1496,7 +1501,7 @@ void QXcbWindow::requestActivateWindow() event.type = atom(QXcbAtom::_NET_ACTIVE_WINDOW); event.data.data32[0] = 1; event.data.data32[1] = connection()->time(); - event.data.data32[2] = focusWindow ? focusWindow->winId() : XCB_NONE; + event.data.data32[2] = current; event.data.data32[3] = 0; event.data.data32[4] = 0; From 9c38eead3f789fa8265d4cab2841a22ecff983b2 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Thu, 21 Mar 2024 14:18:54 +0100 Subject: [PATCH 53/58] gui: fix build against gcc-14 (-Werror=calloc-transposed-args) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit src/gui/painting/qpaintengine_raster.cpp:3811:42: error: ‘void* calloc(size_t, size_t)’ sizes specified with ‘sizeof’ in the earlier argument and not in the later argument [-Werror=calloc-transposed-args] 3811 | m_clipLines = (ClipLine *)calloc(sizeof(ClipLine), clipSpanHeight); | ^~~~~~~~~~~~~~~~ src/gui/painting/qpaintengine_raster.cpp:3811:42: note: earlier argument should specify number of elements, later size of each element Change-Id: I41ec3dd5c439e5cd51dd917741125ce50659500e Reviewed-by: Thiago Macieira Reviewed-by: Ahmad Samir Reviewed-by: Giuseppe D'Angelo (cherry picked from commit 12a432c80feba60ced4c67b496ac0762bacb8777) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit d96653f559175f42da36ad5f590a113121368e65) (cherry picked from commit 4082598bb987c6ea7173d84b63561563966ca8f2) (cherry picked from commit 34e267702e54ef468cf087aa0df93589bb92af3a) (cherry picked from commit 1470b18726ec308d53f358febea9699b203b471b) --- src/gui/painting/qpaintengine_raster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 56957c2e534..b29f6df7c76 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3862,7 +3862,7 @@ void QClipData::initialize() return; if (!m_clipLines) - m_clipLines = (ClipLine *)calloc(sizeof(ClipLine), clipSpanHeight); + m_clipLines = (ClipLine *)calloc(clipSpanHeight, sizeof(ClipLine)); Q_CHECK_PTR(m_clipLines); QT_TRY { From 54a5feb8e0195496d4e631de861a5dd18c6a62c4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 11 Mar 2024 11:24:00 -0400 Subject: [PATCH 54/58] QFutureInterface: fix build with GCC14/C++20: template-id not allowed When declaring a constructor, you must use the injected name, not a template. qfutureinterface.h:472:37: error: template-id not allowed for constructor in C++20 [-Werror=template-id-cdtor] Change-Id: I6818d78a57394e37857bfffd17bbbf2313001cbf Reviewed-by: Ahmad Samir (cherry picked from commit 111c08d0eaa134652f1f1e602ead1a539614258f) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit af41847af512f2fb2329cc6b258f6de79ab1355b) (cherry picked from commit d75965ee24d9f3e9097688f184fc389f5d5d1528) Reviewed-by: Liang Qi (cherry picked from commit 9884be691c331152da97846d2ffb6391a8c1f84b) (cherry picked from commit 73d266ebcd9b235dfe737ee7b4d26764cd1f8514) --- src/corelib/thread/qfutureinterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h index 043032d1c56..de88d9681d5 100644 --- a/src/corelib/thread/qfutureinterface.h +++ b/src/corelib/thread/qfutureinterface.h @@ -281,7 +281,7 @@ template <> class QFutureInterface : public QFutureInterfaceBase { public: - explicit QFutureInterface(State initialState = NoState) + explicit QFutureInterface(State initialState = NoState) : QFutureInterfaceBase(initialState) { } From 4055c760f20881273e3b5434406435046ca228c6 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 23 Jan 2024 23:53:48 -0700 Subject: [PATCH 55/58] Update md4c to 0.5.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The update from 0.4.8 was redone for 5.15 as one squashed patch, whereas 16bcdba8e7adae79729c6347e711bd0a976dbbe7 was a smaller incremental change. [ChangeLog][Third-Party Code] md4c was updated to 0.5.2. Task-number: QTBUG-121442 Change-Id: I097d9aa5f54c59c301a91fb824adf949daae3af2 Reviewed-by: Kai Köhne (cherry picked from commit 16bcdba8e7adae79729c6347e711bd0a976dbbe7) Reviewed-by: Tarja Sundqvist --- src/3rdparty/md4c/md4c.c | 1647 ++++++++++++++----------- src/3rdparty/md4c/md4c.h | 14 +- src/3rdparty/md4c/qt_attribution.json | 6 +- 3 files changed, 913 insertions(+), 754 deletions(-) diff --git a/src/3rdparty/md4c/md4c.c b/src/3rdparty/md4c/md4c.c index e4ab47c2f67..812bde53585 100644 --- a/src/3rdparty/md4c/md4c.c +++ b/src/3rdparty/md4c/md4c.c @@ -2,7 +2,7 @@ * MD4C: Markdown parser for C * (http://github.com/mity/md4c) * - * Copyright (c) 2016-2020 Martin Mitas + * Copyright (c) 2016-2024 Martin Mitáš * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -67,11 +67,72 @@ #define STRINGIZE_(x) #x #define STRINGIZE(x) STRINGIZE_(x) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif +#define MD_LOG(msg) \ + do { \ + if(ctx->parser.debug_log != NULL) \ + ctx->parser.debug_log((msg), ctx->userdata); \ + } while(0) + +#ifdef DEBUG + #define MD_ASSERT(cond) \ + do { \ + if(!(cond)) { \ + MD_LOG(__FILE__ ":" STRINGIZE(__LINE__) ": " \ + "Assertion '" STRINGIZE(cond) "' failed."); \ + exit(1); \ + } \ + } while(0) + + #define MD_UNREACHABLE() MD_ASSERT(1 == 0) +#else + #ifdef __GNUC__ + #define MD_ASSERT(cond) do { if(!(cond)) __builtin_unreachable(); } while(0) + #define MD_UNREACHABLE() do { __builtin_unreachable(); } while(0) + #elif defined _MSC_VER && _MSC_VER > 120 + #define MD_ASSERT(cond) do { __assume(cond); } while(0) + #define MD_UNREACHABLE() do { __assume(0); } while(0) + #else + #define MD_ASSERT(cond) do {} while(0) + #define MD_UNREACHABLE() do {} while(0) + #endif +#endif + +/* For falling through case labels in switch statements. */ +#if defined __clang__ && __clang_major__ >= 12 + #define MD_FALLTHROUGH() __attribute__((fallthrough)) +#elif defined __GNUC__ && __GNUC__ >= 7 + #define MD_FALLTHROUGH() __attribute__((fallthrough)) +#else + #define MD_FALLTHROUGH() ((void)0) +#endif + +/* Suppress "unused parameter" warnings. */ +#define MD_UNUSED(x) ((void)x) + + +/****************************** + *** Some internal limits *** + ******************************/ + +/* We limit code span marks to lower than 32 backticks. This solves the + * pathologic case of too many openers, each of different length: Their + * resolving would be then O(n^2). */ +#define CODESPAN_MARK_MAXLEN 32 + +/* We limit column count of tables to prevent quadratic explosion of output + * from pathological input of a table thousands of columns and thousands + * of rows where rows are requested with as little as single character + * per-line, relying on us to "helpfully" fill all the missing "". */ +#define TABLE_MAXCOLCOUNT 128 + /************************ *** Internal Types *** @@ -88,14 +149,13 @@ typedef struct MD_CONTAINER_tag MD_CONTAINER; typedef struct MD_REF_DEF_tag MD_REF_DEF; -/* During analyzes of inline marks, we need to manage some "mark chains", - * of (yet unresolved) openers. This structure holds start/end of the chain. - * The chain internals are then realized through MD_MARK::prev and ::next. +/* During analyzes of inline marks, we need to manage stacks of unresolved + * openers of the given type. + * The stack connects the marks via MD_MARK::next; */ -typedef struct MD_MARKCHAIN_tag MD_MARKCHAIN; -struct MD_MARKCHAIN_tag { - int head; /* Index of first mark in the chain, or -1 if empty. */ - int tail; /* Index of last mark in the chain, or -1 if empty. */ +typedef struct MD_MARKSTACK_tag MD_MARKSTACK; +struct MD_MARKSTACK_tag { + int top; /* -1 if empty. */ }; /* Context propagated through all the parsing. */ @@ -136,24 +196,33 @@ struct MD_CTX_tag { #endif /* For resolving of inline spans. */ - MD_MARKCHAIN mark_chains[13]; -#define PTR_CHAIN (ctx->mark_chains[0]) -#define TABLECELLBOUNDARIES (ctx->mark_chains[1]) -#define ASTERISK_OPENERS_extraword_mod3_0 (ctx->mark_chains[2]) -#define ASTERISK_OPENERS_extraword_mod3_1 (ctx->mark_chains[3]) -#define ASTERISK_OPENERS_extraword_mod3_2 (ctx->mark_chains[4]) -#define ASTERISK_OPENERS_intraword_mod3_0 (ctx->mark_chains[5]) -#define ASTERISK_OPENERS_intraword_mod3_1 (ctx->mark_chains[6]) -#define ASTERISK_OPENERS_intraword_mod3_2 (ctx->mark_chains[7]) -#define UNDERSCORE_OPENERS (ctx->mark_chains[8]) -#define TILDE_OPENERS_1 (ctx->mark_chains[9]) -#define TILDE_OPENERS_2 (ctx->mark_chains[10]) -#define BRACKET_OPENERS (ctx->mark_chains[11]) -#define DOLLAR_OPENERS (ctx->mark_chains[12]) -#define OPENERS_CHAIN_FIRST 2 -#define OPENERS_CHAIN_LAST 12 + MD_MARKSTACK opener_stacks[16]; +#define ASTERISK_OPENERS_oo_mod3_0 (ctx->opener_stacks[0]) /* Opener-only */ +#define ASTERISK_OPENERS_oo_mod3_1 (ctx->opener_stacks[1]) +#define ASTERISK_OPENERS_oo_mod3_2 (ctx->opener_stacks[2]) +#define ASTERISK_OPENERS_oc_mod3_0 (ctx->opener_stacks[3]) /* Both opener and closer candidate */ +#define ASTERISK_OPENERS_oc_mod3_1 (ctx->opener_stacks[4]) +#define ASTERISK_OPENERS_oc_mod3_2 (ctx->opener_stacks[5]) +#define UNDERSCORE_OPENERS_oo_mod3_0 (ctx->opener_stacks[6]) /* Opener-only */ +#define UNDERSCORE_OPENERS_oo_mod3_1 (ctx->opener_stacks[7]) +#define UNDERSCORE_OPENERS_oo_mod3_2 (ctx->opener_stacks[8]) +#define UNDERSCORE_OPENERS_oc_mod3_0 (ctx->opener_stacks[9]) /* Both opener and closer candidate */ +#define UNDERSCORE_OPENERS_oc_mod3_1 (ctx->opener_stacks[10]) +#define UNDERSCORE_OPENERS_oc_mod3_2 (ctx->opener_stacks[11]) +#define TILDE_OPENERS_1 (ctx->opener_stacks[12]) +#define TILDE_OPENERS_2 (ctx->opener_stacks[13]) +#define BRACKET_OPENERS (ctx->opener_stacks[14]) +#define DOLLAR_OPENERS (ctx->opener_stacks[15]) + /* Stack of dummies which need to call free() for pointers stored in them. + * These are constructed during inline parsing and freed after all the block + * is processed (i.e. all callbacks referring those strings are called). */ + MD_MARKSTACK ptr_stack; + + /* For resolving table rows. */ int n_table_cell_boundaries; + int table_cell_boundaries_head; + int table_cell_boundaries_tail; /* For resolving links. */ int unresolved_link_head; @@ -209,8 +278,9 @@ typedef enum MD_LINETYPE_tag MD_LINETYPE; typedef struct MD_LINE_ANALYSIS_tag MD_LINE_ANALYSIS; struct MD_LINE_ANALYSIS_tag { - MD_LINETYPE type : 16; - unsigned data : 16; + MD_LINETYPE type; + unsigned data; + int enforce_new_block; OFF beg; OFF end; unsigned indent; /* Indentation level. */ @@ -230,41 +300,6 @@ struct MD_VERBATIMLINE_tag { }; -/******************* - *** Debugging *** - *******************/ - -#define MD_LOG(msg) \ - do { \ - if(ctx->parser.debug_log != NULL) \ - ctx->parser.debug_log((msg), ctx->userdata); \ - } while(0) - -#ifdef DEBUG - #define MD_ASSERT(cond) \ - do { \ - if(!(cond)) { \ - MD_LOG(__FILE__ ":" STRINGIZE(__LINE__) ": " \ - "Assertion '" STRINGIZE(cond) "' failed."); \ - exit(1); \ - } \ - } while(0) - - #define MD_UNREACHABLE() MD_ASSERT(1 == 0) -#else - #ifdef __GNUC__ - #define MD_ASSERT(cond) do { if(!(cond)) __builtin_unreachable(); } while(0) - #define MD_UNREACHABLE() do { __builtin_unreachable(); } while(0) - #elif defined _MSC_VER && _MSC_VER > 120 - #define MD_ASSERT(cond) do { __assume(cond); } while(0) - #define MD_UNREACHABLE() do { __assume(0); } while(0) - #else - #define MD_ASSERT(cond) do {} while(0) - #define MD_UNREACHABLE() do {} while(0) - #endif -#endif - - /***************** *** Helpers *** *****************/ @@ -458,6 +493,40 @@ md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ } while(0) +/* If the offset falls into a gap between line, we return the following + * line. */ +static const MD_LINE* +md_lookup_line(OFF off, const MD_LINE* lines, MD_SIZE n_lines, MD_SIZE* p_line_index) +{ + MD_SIZE lo, hi; + MD_SIZE pivot; + const MD_LINE* line; + + lo = 0; + hi = n_lines - 1; + while(lo <= hi) { + pivot = (lo + hi) / 2; + line = &lines[pivot]; + + if(off < line->beg) { + if(hi == 0 || lines[hi-1].end < off) { + if(p_line_index != NULL) + *p_line_index = pivot; + return line; + } + hi = pivot - 1; + } else if(off > line->end) { + lo = pivot + 1; + } else { + if(p_line_index != NULL) + *p_line_index = pivot; + return line; + } + } + + return NULL; +} + /************************* *** Unicode Support *** @@ -466,7 +535,7 @@ md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ typedef struct MD_UNICODE_FOLD_INFO_tag MD_UNICODE_FOLD_INFO; struct MD_UNICODE_FOLD_INFO_tag { unsigned codepoints[3]; - int n_codepoints; + unsigned n_codepoints; }; @@ -530,39 +599,67 @@ struct MD_UNICODE_FOLD_INFO_tag { { #define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000) #define S(cp) (cp) - /* Unicode "Pc", "Pd", "Pe", "Pf", "Pi", "Po", "Ps" categories. + /* Unicode general "P" and "S" categories. * (generated by scripts/build_punct_map.py) */ static const unsigned PUNCT_MAP[] = { - R(0x0021,0x0023), R(0x0025,0x002a), R(0x002c,0x002f), R(0x003a,0x003b), R(0x003f,0x0040), - R(0x005b,0x005d), S(0x005f), S(0x007b), S(0x007d), S(0x00a1), S(0x00a7), S(0x00ab), R(0x00b6,0x00b7), - S(0x00bb), S(0x00bf), S(0x037e), S(0x0387), R(0x055a,0x055f), R(0x0589,0x058a), S(0x05be), S(0x05c0), - S(0x05c3), S(0x05c6), R(0x05f3,0x05f4), R(0x0609,0x060a), R(0x060c,0x060d), S(0x061b), R(0x061e,0x061f), - R(0x066a,0x066d), S(0x06d4), R(0x0700,0x070d), R(0x07f7,0x07f9), R(0x0830,0x083e), S(0x085e), - R(0x0964,0x0965), S(0x0970), S(0x09fd), S(0x0a76), S(0x0af0), S(0x0c77), S(0x0c84), S(0x0df4), S(0x0e4f), - R(0x0e5a,0x0e5b), R(0x0f04,0x0f12), S(0x0f14), R(0x0f3a,0x0f3d), S(0x0f85), R(0x0fd0,0x0fd4), - R(0x0fd9,0x0fda), R(0x104a,0x104f), S(0x10fb), R(0x1360,0x1368), S(0x1400), S(0x166e), R(0x169b,0x169c), - R(0x16eb,0x16ed), R(0x1735,0x1736), R(0x17d4,0x17d6), R(0x17d8,0x17da), R(0x1800,0x180a), - R(0x1944,0x1945), R(0x1a1e,0x1a1f), R(0x1aa0,0x1aa6), R(0x1aa8,0x1aad), R(0x1b5a,0x1b60), - R(0x1bfc,0x1bff), R(0x1c3b,0x1c3f), R(0x1c7e,0x1c7f), R(0x1cc0,0x1cc7), S(0x1cd3), R(0x2010,0x2027), - R(0x2030,0x2043), R(0x2045,0x2051), R(0x2053,0x205e), R(0x207d,0x207e), R(0x208d,0x208e), - R(0x2308,0x230b), R(0x2329,0x232a), R(0x2768,0x2775), R(0x27c5,0x27c6), R(0x27e6,0x27ef), - R(0x2983,0x2998), R(0x29d8,0x29db), R(0x29fc,0x29fd), R(0x2cf9,0x2cfc), R(0x2cfe,0x2cff), S(0x2d70), - R(0x2e00,0x2e2e), R(0x2e30,0x2e4f), S(0x2e52), R(0x3001,0x3003), R(0x3008,0x3011), R(0x3014,0x301f), - S(0x3030), S(0x303d), S(0x30a0), S(0x30fb), R(0xa4fe,0xa4ff), R(0xa60d,0xa60f), S(0xa673), S(0xa67e), - R(0xa6f2,0xa6f7), R(0xa874,0xa877), R(0xa8ce,0xa8cf), R(0xa8f8,0xa8fa), S(0xa8fc), R(0xa92e,0xa92f), - S(0xa95f), R(0xa9c1,0xa9cd), R(0xa9de,0xa9df), R(0xaa5c,0xaa5f), R(0xaade,0xaadf), R(0xaaf0,0xaaf1), - S(0xabeb), R(0xfd3e,0xfd3f), R(0xfe10,0xfe19), R(0xfe30,0xfe52), R(0xfe54,0xfe61), S(0xfe63), S(0xfe68), - R(0xfe6a,0xfe6b), R(0xff01,0xff03), R(0xff05,0xff0a), R(0xff0c,0xff0f), R(0xff1a,0xff1b), - R(0xff1f,0xff20), R(0xff3b,0xff3d), S(0xff3f), S(0xff5b), S(0xff5d), R(0xff5f,0xff65), R(0x10100,0x10102), - S(0x1039f), S(0x103d0), S(0x1056f), S(0x10857), S(0x1091f), S(0x1093f), R(0x10a50,0x10a58), S(0x10a7f), - R(0x10af0,0x10af6), R(0x10b39,0x10b3f), R(0x10b99,0x10b9c), S(0x10ead), R(0x10f55,0x10f59), - R(0x11047,0x1104d), R(0x110bb,0x110bc), R(0x110be,0x110c1), R(0x11140,0x11143), R(0x11174,0x11175), - R(0x111c5,0x111c8), S(0x111cd), S(0x111db), R(0x111dd,0x111df), R(0x11238,0x1123d), S(0x112a9), - R(0x1144b,0x1144f), R(0x1145a,0x1145b), S(0x1145d), S(0x114c6), R(0x115c1,0x115d7), R(0x11641,0x11643), - R(0x11660,0x1166c), R(0x1173c,0x1173e), S(0x1183b), R(0x11944,0x11946), S(0x119e2), R(0x11a3f,0x11a46), - R(0x11a9a,0x11a9c), R(0x11a9e,0x11aa2), R(0x11c41,0x11c45), R(0x11c70,0x11c71), R(0x11ef7,0x11ef8), - S(0x11fff), R(0x12470,0x12474), R(0x16a6e,0x16a6f), S(0x16af5), R(0x16b37,0x16b3b), S(0x16b44), - R(0x16e97,0x16e9a), S(0x16fe2), S(0x1bc9f), R(0x1da87,0x1da8b), R(0x1e95e,0x1e95f) + R(0x0021,0x002f), R(0x003a,0x0040), R(0x005b,0x0060), R(0x007b,0x007e), R(0x00a1,0x00a9), + R(0x00ab,0x00ac), R(0x00ae,0x00b1), S(0x00b4), R(0x00b6,0x00b8), S(0x00bb), S(0x00bf), S(0x00d7), + S(0x00f7), R(0x02c2,0x02c5), R(0x02d2,0x02df), R(0x02e5,0x02eb), S(0x02ed), R(0x02ef,0x02ff), S(0x0375), + S(0x037e), R(0x0384,0x0385), S(0x0387), S(0x03f6), S(0x0482), R(0x055a,0x055f), R(0x0589,0x058a), + R(0x058d,0x058f), S(0x05be), S(0x05c0), S(0x05c3), S(0x05c6), R(0x05f3,0x05f4), R(0x0606,0x060f), + S(0x061b), R(0x061d,0x061f), R(0x066a,0x066d), S(0x06d4), S(0x06de), S(0x06e9), R(0x06fd,0x06fe), + R(0x0700,0x070d), R(0x07f6,0x07f9), R(0x07fe,0x07ff), R(0x0830,0x083e), S(0x085e), S(0x0888), + R(0x0964,0x0965), S(0x0970), R(0x09f2,0x09f3), R(0x09fa,0x09fb), S(0x09fd), S(0x0a76), R(0x0af0,0x0af1), + S(0x0b70), R(0x0bf3,0x0bfa), S(0x0c77), S(0x0c7f), S(0x0c84), S(0x0d4f), S(0x0d79), S(0x0df4), S(0x0e3f), + S(0x0e4f), R(0x0e5a,0x0e5b), R(0x0f01,0x0f17), R(0x0f1a,0x0f1f), S(0x0f34), S(0x0f36), S(0x0f38), + R(0x0f3a,0x0f3d), S(0x0f85), R(0x0fbe,0x0fc5), R(0x0fc7,0x0fcc), R(0x0fce,0x0fda), R(0x104a,0x104f), + R(0x109e,0x109f), S(0x10fb), R(0x1360,0x1368), R(0x1390,0x1399), S(0x1400), R(0x166d,0x166e), + R(0x169b,0x169c), R(0x16eb,0x16ed), R(0x1735,0x1736), R(0x17d4,0x17d6), R(0x17d8,0x17db), + R(0x1800,0x180a), S(0x1940), R(0x1944,0x1945), R(0x19de,0x19ff), R(0x1a1e,0x1a1f), R(0x1aa0,0x1aa6), + R(0x1aa8,0x1aad), R(0x1b5a,0x1b6a), R(0x1b74,0x1b7e), R(0x1bfc,0x1bff), R(0x1c3b,0x1c3f), + R(0x1c7e,0x1c7f), R(0x1cc0,0x1cc7), S(0x1cd3), S(0x1fbd), R(0x1fbf,0x1fc1), R(0x1fcd,0x1fcf), + R(0x1fdd,0x1fdf), R(0x1fed,0x1fef), R(0x1ffd,0x1ffe), R(0x2010,0x2027), R(0x2030,0x205e), + R(0x207a,0x207e), R(0x208a,0x208e), R(0x20a0,0x20c0), R(0x2100,0x2101), R(0x2103,0x2106), + R(0x2108,0x2109), S(0x2114), R(0x2116,0x2118), R(0x211e,0x2123), S(0x2125), S(0x2127), S(0x2129), + S(0x212e), R(0x213a,0x213b), R(0x2140,0x2144), R(0x214a,0x214d), S(0x214f), R(0x218a,0x218b), + R(0x2190,0x2426), R(0x2440,0x244a), R(0x249c,0x24e9), R(0x2500,0x2775), R(0x2794,0x2b73), + R(0x2b76,0x2b95), R(0x2b97,0x2bff), R(0x2ce5,0x2cea), R(0x2cf9,0x2cfc), R(0x2cfe,0x2cff), S(0x2d70), + R(0x2e00,0x2e2e), R(0x2e30,0x2e5d), R(0x2e80,0x2e99), R(0x2e9b,0x2ef3), R(0x2f00,0x2fd5), + R(0x2ff0,0x2fff), R(0x3001,0x3004), R(0x3008,0x3020), S(0x3030), R(0x3036,0x3037), R(0x303d,0x303f), + R(0x309b,0x309c), S(0x30a0), S(0x30fb), R(0x3190,0x3191), R(0x3196,0x319f), R(0x31c0,0x31e3), S(0x31ef), + R(0x3200,0x321e), R(0x322a,0x3247), S(0x3250), R(0x3260,0x327f), R(0x328a,0x32b0), R(0x32c0,0x33ff), + R(0x4dc0,0x4dff), R(0xa490,0xa4c6), R(0xa4fe,0xa4ff), R(0xa60d,0xa60f), S(0xa673), S(0xa67e), + R(0xa6f2,0xa6f7), R(0xa700,0xa716), R(0xa720,0xa721), R(0xa789,0xa78a), R(0xa828,0xa82b), + R(0xa836,0xa839), R(0xa874,0xa877), R(0xa8ce,0xa8cf), R(0xa8f8,0xa8fa), S(0xa8fc), R(0xa92e,0xa92f), + S(0xa95f), R(0xa9c1,0xa9cd), R(0xa9de,0xa9df), R(0xaa5c,0xaa5f), R(0xaa77,0xaa79), R(0xaade,0xaadf), + R(0xaaf0,0xaaf1), S(0xab5b), R(0xab6a,0xab6b), S(0xabeb), S(0xfb29), R(0xfbb2,0xfbc2), R(0xfd3e,0xfd4f), + S(0xfdcf), R(0xfdfc,0xfdff), R(0xfe10,0xfe19), R(0xfe30,0xfe52), R(0xfe54,0xfe66), R(0xfe68,0xfe6b), + R(0xff01,0xff0f), R(0xff1a,0xff20), R(0xff3b,0xff40), R(0xff5b,0xff65), R(0xffe0,0xffe6), + R(0xffe8,0xffee), R(0xfffc,0xfffd), R(0x10100,0x10102), R(0x10137,0x1013f), R(0x10179,0x10189), + R(0x1018c,0x1018e), R(0x10190,0x1019c), S(0x101a0), R(0x101d0,0x101fc), S(0x1039f), S(0x103d0), + S(0x1056f), S(0x10857), R(0x10877,0x10878), S(0x1091f), S(0x1093f), R(0x10a50,0x10a58), S(0x10a7f), + S(0x10ac8), R(0x10af0,0x10af6), R(0x10b39,0x10b3f), R(0x10b99,0x10b9c), S(0x10ead), R(0x10f55,0x10f59), + R(0x10f86,0x10f89), R(0x11047,0x1104d), R(0x110bb,0x110bc), R(0x110be,0x110c1), R(0x11140,0x11143), + R(0x11174,0x11175), R(0x111c5,0x111c8), S(0x111cd), S(0x111db), R(0x111dd,0x111df), R(0x11238,0x1123d), + S(0x112a9), R(0x1144b,0x1144f), R(0x1145a,0x1145b), S(0x1145d), S(0x114c6), R(0x115c1,0x115d7), + R(0x11641,0x11643), R(0x11660,0x1166c), S(0x116b9), R(0x1173c,0x1173f), S(0x1183b), R(0x11944,0x11946), + S(0x119e2), R(0x11a3f,0x11a46), R(0x11a9a,0x11a9c), R(0x11a9e,0x11aa2), R(0x11b00,0x11b09), + R(0x11c41,0x11c45), R(0x11c70,0x11c71), R(0x11ef7,0x11ef8), R(0x11f43,0x11f4f), R(0x11fd5,0x11ff1), + S(0x11fff), R(0x12470,0x12474), R(0x12ff1,0x12ff2), R(0x16a6e,0x16a6f), S(0x16af5), R(0x16b37,0x16b3f), + R(0x16b44,0x16b45), R(0x16e97,0x16e9a), S(0x16fe2), S(0x1bc9c), S(0x1bc9f), R(0x1cf50,0x1cfc3), + R(0x1d000,0x1d0f5), R(0x1d100,0x1d126), R(0x1d129,0x1d164), R(0x1d16a,0x1d16c), R(0x1d183,0x1d184), + R(0x1d18c,0x1d1a9), R(0x1d1ae,0x1d1ea), R(0x1d200,0x1d241), S(0x1d245), R(0x1d300,0x1d356), S(0x1d6c1), + S(0x1d6db), S(0x1d6fb), S(0x1d715), S(0x1d735), S(0x1d74f), S(0x1d76f), S(0x1d789), S(0x1d7a9), + S(0x1d7c3), R(0x1d800,0x1d9ff), R(0x1da37,0x1da3a), R(0x1da6d,0x1da74), R(0x1da76,0x1da83), + R(0x1da85,0x1da8b), S(0x1e14f), S(0x1e2ff), R(0x1e95e,0x1e95f), S(0x1ecac), S(0x1ecb0), S(0x1ed2e), + R(0x1eef0,0x1eef1), R(0x1f000,0x1f02b), R(0x1f030,0x1f093), R(0x1f0a0,0x1f0ae), R(0x1f0b1,0x1f0bf), + R(0x1f0c1,0x1f0cf), R(0x1f0d1,0x1f0f5), R(0x1f10d,0x1f1ad), R(0x1f1e6,0x1f202), R(0x1f210,0x1f23b), + R(0x1f240,0x1f248), R(0x1f250,0x1f251), R(0x1f260,0x1f265), R(0x1f300,0x1f6d7), R(0x1f6dc,0x1f6ec), + R(0x1f6f0,0x1f6fc), R(0x1f700,0x1f776), R(0x1f77b,0x1f7d9), R(0x1f7e0,0x1f7eb), S(0x1f7f0), + R(0x1f800,0x1f80b), R(0x1f810,0x1f847), R(0x1f850,0x1f859), R(0x1f860,0x1f887), R(0x1f890,0x1f8ad), + R(0x1f8b0,0x1f8b1), R(0x1f900,0x1fa53), R(0x1fa60,0x1fa6d), R(0x1fa70,0x1fa7c), R(0x1fa80,0x1fa88), + R(0x1fa90,0x1fabd), R(0x1fabf,0x1fac5), R(0x1face,0x1fadb), R(0x1fae0,0x1fae8), R(0x1faf0,0x1faf8), + R(0x1fb00,0x1fb92), R(0x1fb94,0x1fbca) }; #undef R #undef S @@ -603,13 +700,14 @@ struct MD_UNICODE_FOLD_INFO_tag { R(0x1f68,0x1f6f), S(0x1fb8), S(0x1fb9), S(0x1fba), S(0x1fbb), S(0x1fbe), R(0x1fc8,0x1fcb), S(0x1fd8), S(0x1fd9), S(0x1fda), S(0x1fdb), S(0x1fe8), S(0x1fe9), S(0x1fea), S(0x1feb), S(0x1fec), S(0x1ff8), S(0x1ff9), S(0x1ffa), S(0x1ffb), S(0x2126), S(0x212a), S(0x212b), S(0x2132), R(0x2160,0x216f), S(0x2183), - R(0x24b6,0x24cf), R(0x2c00,0x2c2e), S(0x2c60), S(0x2c62), S(0x2c63), S(0x2c64), R(0x2c67,0x2c6b), + R(0x24b6,0x24cf), R(0x2c00,0x2c2f), S(0x2c60), S(0x2c62), S(0x2c63), S(0x2c64), R(0x2c67,0x2c6b), S(0x2c6d), S(0x2c6e), S(0x2c6f), S(0x2c70), S(0x2c72), S(0x2c75), S(0x2c7e), S(0x2c7f), R(0x2c80,0x2ce2), S(0x2ceb), S(0x2ced), S(0x2cf2), R(0xa640,0xa66c), R(0xa680,0xa69a), R(0xa722,0xa72e), R(0xa732,0xa76e), S(0xa779), S(0xa77b), S(0xa77d), R(0xa77e,0xa786), S(0xa78b), S(0xa78d), S(0xa790), S(0xa792), R(0xa796,0xa7a8), S(0xa7aa), S(0xa7ab), S(0xa7ac), S(0xa7ad), S(0xa7ae), S(0xa7b0), S(0xa7b1), S(0xa7b2), - S(0xa7b3), R(0xa7b4,0xa7be), S(0xa7c2), S(0xa7c4), S(0xa7c5), S(0xa7c6), S(0xa7c7), S(0xa7c9), S(0xa7f5), - R(0xab70,0xabbf), R(0xff21,0xff3a), R(0x10400,0x10427), R(0x104b0,0x104d3), R(0x10c80,0x10cb2), + S(0xa7b3), R(0xa7b4,0xa7c2), S(0xa7c4), S(0xa7c5), S(0xa7c6), S(0xa7c7), S(0xa7c9), S(0xa7d0), S(0xa7d6), + S(0xa7d8), S(0xa7f5), R(0xab70,0xabbf), R(0xff21,0xff3a), R(0x10400,0x10427), R(0x104b0,0x104d3), + R(0x10570,0x1057a), R(0x1057c,0x1058a), R(0x1058c,0x10592), S(0x10594), S(0x10595), R(0x10c80,0x10cb2), R(0x118a0,0x118bf), R(0x16e40,0x16e5f), R(0x1e900,0x1e921) }; static const unsigned FOLD_MAP_1_DATA[] = { @@ -628,13 +726,13 @@ struct MD_UNICODE_FOLD_INFO_tag { 0x1f10, 0x1f15, 0x1f20, 0x1f27, 0x1f30, 0x1f37, 0x1f40, 0x1f45, 0x1f51, 0x1f53, 0x1f55, 0x1f57, 0x1f60, 0x1f67, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x03b9, 0x1f72, 0x1f75, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x03c9, 0x006b, 0x00e5, 0x214e, 0x2170, - 0x217f, 0x2184, 0x24d0, 0x24e9, 0x2c30, 0x2c5e, 0x2c61, 0x026b, 0x1d7d, 0x027d, 0x2c68, 0x2c6c, 0x0251, + 0x217f, 0x2184, 0x24d0, 0x24e9, 0x2c30, 0x2c5f, 0x2c61, 0x026b, 0x1d7d, 0x027d, 0x2c68, 0x2c6c, 0x0251, 0x0271, 0x0250, 0x0252, 0x2c73, 0x2c76, 0x023f, 0x0240, 0x2c81, 0x2ce3, 0x2cec, 0x2cee, 0x2cf3, 0xa641, 0xa66d, 0xa681, 0xa69b, 0xa723, 0xa72f, 0xa733, 0xa76f, 0xa77a, 0xa77c, 0x1d79, 0xa77f, 0xa787, 0xa78c, 0x0265, 0xa791, 0xa793, 0xa797, 0xa7a9, 0x0266, 0x025c, 0x0261, 0x026c, 0x026a, 0x029e, 0x0287, 0x029d, - 0xab53, 0xa7b5, 0xa7bf, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8, 0xa7ca, 0xa7f6, 0x13a0, 0x13ef, 0xff41, - 0xff5a, 0x10428, 0x1044f, 0x104d8, 0x104fb, 0x10cc0, 0x10cf2, 0x118c0, 0x118df, 0x16e60, 0x16e7f, 0x1e922, - 0x1e943 + 0xab53, 0xa7b5, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8, 0xa7ca, 0xa7d1, 0xa7d7, 0xa7d9, 0xa7f6, 0x13a0, + 0x13ef, 0xff41, 0xff5a, 0x10428, 0x1044f, 0x104d8, 0x104fb, 0x10597, 0x105a1, 0x105a3, 0x105b1, 0x105b3, + 0x105b9, 0x105bb, 0x105bc, 0x10cc0, 0x10cf2, 0x118c0, 0x118df, 0x16e60, 0x16e7f, 0x1e922, 0x1e943 }; static const unsigned FOLD_MAP_2[] = { S(0x00df), S(0x0130), S(0x0149), S(0x01f0), S(0x0587), S(0x1e96), S(0x1e97), S(0x1e98), S(0x1e99), @@ -670,7 +768,7 @@ struct MD_UNICODE_FOLD_INFO_tag { const unsigned* map; const unsigned* data; size_t map_size; - int n_codepoints; + unsigned n_codepoints; } FOLD_MAP_LIST[] = { { FOLD_MAP_1, FOLD_MAP_1_DATA, SIZEOF_ARRAY(FOLD_MAP_1), 1 }, { FOLD_MAP_2, FOLD_MAP_2_DATA, SIZEOF_ARRAY(FOLD_MAP_2), 2 }, @@ -695,7 +793,7 @@ struct MD_UNICODE_FOLD_INFO_tag { index = md_unicode_bsearch__(codepoint, FOLD_MAP_LIST[i].map, FOLD_MAP_LIST[i].map_size); if(index >= 0) { /* Found the mapping. */ - int n_codepoints = FOLD_MAP_LIST[i].n_codepoints; + unsigned n_codepoints = FOLD_MAP_LIST[i].n_codepoints; const unsigned* map = FOLD_MAP_LIST[i].map; const unsigned* codepoints = FOLD_MAP_LIST[i].data + (index * n_codepoints); @@ -887,13 +985,15 @@ struct MD_UNICODE_FOLD_INFO_tag { * what the caller should allocate.) */ static void -md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines, +md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines, CHAR line_break_replacement_char, CHAR* buffer, SZ* p_size) { CHAR* ptr = buffer; int line_index = 0; OFF off = beg; + MD_UNUSED(n_lines); + while(1) { const MD_LINE* line = &lines[line_index]; OFF line_end = line->end; @@ -907,7 +1007,7 @@ md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines, } if(off >= end) { - *p_size = ptr - buffer; + *p_size = (MD_SIZE)(ptr - buffer); return; } @@ -922,7 +1022,7 @@ md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines, /* Wrapper of md_merge_lines() which allocates new buffer for the output string. */ static int -md_merge_lines_alloc(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines, +md_merge_lines_alloc(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines, CHAR line_break_replacement_char, CHAR** p_str, SZ* p_size) { CHAR* buffer; @@ -969,12 +1069,12 @@ md_skip_unicode_whitespace(const CHAR* label, OFF off, SZ size) * by n_lines == 0. */ static int -md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { int attr_state; OFF off = beg; OFF line_end = (n_lines > 0) ? lines[0].end : ctx->size; - int i = 0; + MD_SIZE line_index = 0; MD_ASSERT(CH(beg) == _T('<')); @@ -1064,12 +1164,12 @@ md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_ if(n_lines == 0) return FALSE; - i++; - if(i >= n_lines) + line_index++; + if(line_index >= n_lines) return FALSE; - off = lines[i].beg; - line_end = lines[i].end; + off = lines[line_index].beg; + line_end = lines[line_index].end; if(attr_state == 0 || attr_state == 41) attr_state = 1; @@ -1088,12 +1188,12 @@ done: static int md_scan_for_html_closer(MD_CTX* ctx, const MD_CHAR* str, MD_SIZE len, - const MD_LINE* lines, int n_lines, + const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end, OFF* p_scan_horizon) { OFF off = beg; - int i = 0; + MD_SIZE line_index = 0; if(off < *p_scan_horizon && *p_scan_horizon >= max_end - len) { /* We have already scanned the range up to the max_end so we know @@ -1102,7 +1202,7 @@ md_scan_for_html_closer(MD_CTX* ctx, const MD_CHAR* str, MD_SIZE len, } while(TRUE) { - while(off + len <= lines[i].end && off + len <= max_end) { + while(off + len <= lines[line_index].end && off + len <= max_end) { if(md_ascii_eq(STR(off), str, len)) { /* Success. */ *p_end = off + len; @@ -1111,19 +1211,19 @@ md_scan_for_html_closer(MD_CTX* ctx, const MD_CHAR* str, MD_SIZE len, off++; } - i++; - if(off >= max_end || i >= n_lines) { + line_index++; + if(off >= max_end || line_index >= n_lines) { /* Failure. */ *p_scan_horizon = off; return FALSE; } - off = lines[i].beg; + off = lines[line_index].beg; } } static int -md_is_html_comment(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_comment(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { OFF off = beg; @@ -1133,30 +1233,17 @@ md_is_html_comment(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF return FALSE; if(CH(off+1) != _T('!') || CH(off+2) != _T('-') || CH(off+3) != _T('-')) return FALSE; - off += 4; - /* ">" and "->" must not follow the opening. */ - if(off < lines[0].end && CH(off) == _T('>')) - return FALSE; - if(off+1 < lines[0].end && CH(off) == _T('-') && CH(off+1) == _T('>')) - return FALSE; + /* Skip only "" or "" */ + off += 2; - /* HTML comment must not contain "--", so we scan just for "--" instead - * of "-->" and verify manually that '>' follows. */ - if(md_scan_for_html_closer(ctx, _T("--"), 2, - lines, n_lines, off, max_end, p_end, &ctx->html_comment_horizon)) - { - if(*p_end < max_end && CH(*p_end) == _T('>')) { - *p_end = *p_end + 1; - return TRUE; - } - } - - return FALSE; + /* Scan for ordinary comment closer "-->". */ + return md_scan_for_html_closer(ctx, _T("-->"), 3, + lines, n_lines, off, max_end, p_end, &ctx->html_comment_horizon); } static int -md_is_html_processing_instruction(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_processing_instruction(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { OFF off = beg; @@ -1171,7 +1258,7 @@ md_is_html_processing_instruction(MD_CTX* ctx, const MD_LINE* lines, int n_lines } static int -md_is_html_declaration(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_declaration(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { OFF off = beg; @@ -1187,15 +1274,13 @@ md_is_html_declaration(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, off++; while(off < lines[0].end && ISALPHA(off)) off++; - if(off < lines[0].end && !ISWHITESPACE(off)) - return FALSE; return md_scan_for_html_closer(ctx, _T(">"), 1, lines, n_lines, off, max_end, p_end, &ctx->html_decl_horizon); } static int -md_is_html_cdata(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_cdata(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { static const CHAR open_str[] = _T(""), 3, lines, n_lines, off, max_end, p_end, &ctx->html_cdata_horizon); } static int -md_is_html_any(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_any(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { MD_ASSERT(CH(beg) == _T('<')); return (md_is_html_tag(ctx, lines, n_lines, beg, max_end, p_end) || @@ -1235,6 +1317,7 @@ static int md_is_hex_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) { OFF off = beg; + MD_UNUSED(ctx); while(off < max_end && ISXDIGIT_(text[off]) && off - beg <= 8) off++; @@ -1251,6 +1334,7 @@ static int md_is_dec_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) { OFF off = beg; + MD_UNUSED(ctx); while(off < max_end && ISDIGIT_(text[off]) && off - beg <= 8) off++; @@ -1267,6 +1351,7 @@ static int md_is_named_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) { OFF off = beg; + MD_UNUSED(ctx); if(off < max_end && ISALPHA_(text[off])) off++; @@ -1372,6 +1457,8 @@ md_build_attr_append_substr(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build, static void md_free_attribute(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build) { + MD_UNUSED(ctx); + if(build->substr_alloc > 0) { free(build->text); free(build->substr_types); @@ -1547,12 +1634,6 @@ md_link_label_cmp_load_fold_info(const CHAR* label, OFF off, SZ size, goto whitespace; } - if(ISNEWLINE_(label[off])) { - /* Treat new lines as a whitespace. */ - off++; - goto whitespace; - } - codepoint = md_decode_unicode(label, off, size, &char_size); off += char_size; if(ISUNICODEWHITESPACE_(codepoint)) { @@ -1575,8 +1656,6 @@ md_link_label_cmp(const CHAR* a_label, SZ a_size, const CHAR* b_label, SZ b_size { OFF a_off; OFF b_off; - int a_reached_end = FALSE; - int b_reached_end = FALSE; MD_UNICODE_FOLD_INFO a_fi = { { 0 }, 0 }; MD_UNICODE_FOLD_INFO b_fi = { { 0 }, 0 }; OFF a_fi_off = 0; @@ -1585,17 +1664,17 @@ md_link_label_cmp(const CHAR* a_label, SZ a_size, const CHAR* b_label, SZ b_size a_off = md_skip_unicode_whitespace(a_label, 0, a_size); b_off = md_skip_unicode_whitespace(b_label, 0, b_size); - while(!a_reached_end || !b_reached_end) { + while(a_off < a_size || a_fi_off < a_fi.n_codepoints || + b_off < b_size || b_fi_off < b_fi.n_codepoints) + { /* If needed, load fold info for next char. */ if(a_fi_off >= a_fi.n_codepoints) { a_fi_off = 0; a_off = md_link_label_cmp_load_fold_info(a_label, a_off, a_size, &a_fi); - a_reached_end = (a_off >= a_size); } if(b_fi_off >= b_fi.n_codepoints) { b_fi_off = 0; b_off = md_link_label_cmp_load_fold_info(b_label, b_off, b_size, &b_fi); - b_reached_end = (b_off >= b_size); } cmp = b_fi.codepoints[b_fi_off] - a_fi.codepoints[a_fi_off]; @@ -1847,14 +1926,14 @@ struct MD_LINK_ATTR_tag { static int -md_is_link_label(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, - OFF* p_end, int* p_beg_line_index, int* p_end_line_index, +md_is_link_label(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, + OFF* p_end, MD_SIZE* p_beg_line_index, MD_SIZE* p_end_line_index, OFF* p_contents_beg, OFF* p_contents_end) { OFF off = beg; OFF contents_beg = 0; OFF contents_end = 0; - int line_index = 0; + MD_SIZE line_index = 0; int len = 0; if(CH(off) != _T('[')) @@ -2004,13 +2083,13 @@ md_is_link_destination(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, } static int -md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, - OFF* p_end, int* p_beg_line_index, int* p_end_line_index, +md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, + OFF* p_end, MD_SIZE* p_beg_line_index, MD_SIZE* p_end_line_index, OFF* p_contents_beg, OFF* p_contents_end) { OFF off = beg; CHAR closer_char; - int line_index = 0; + MD_SIZE line_index = 0; /* White space with up to one line break. */ while(off < lines[line_index].end && ISWHITESPACE(off)) @@ -2072,21 +2151,21 @@ md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, * Returns -1 in case of an error (out of memory). */ static int -md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines) +md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) { OFF label_contents_beg; OFF label_contents_end; - int label_contents_line_index = -1; + MD_SIZE label_contents_line_index; int label_is_multiline = FALSE; OFF dest_contents_beg; OFF dest_contents_end; OFF title_contents_beg; OFF title_contents_end; - int title_contents_line_index; + MD_SIZE title_contents_line_index; int title_is_multiline = FALSE; OFF off; - int line_index = 0; - int tmp_line_index; + MD_SIZE line_index = 0; + MD_SIZE tmp_line_index; MD_REF_DEF* def = NULL; int ret = 0; @@ -2194,12 +2273,12 @@ abort: } static int -md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, int n_lines, +md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF end, MD_LINK_ATTR* attr) { const MD_REF_DEF* def; const MD_LINE* beg_line; - const MD_LINE* end_line; + int is_multiline; CHAR* label; SZ label_size; int ret; @@ -2211,19 +2290,12 @@ md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, int n_lines, end--; /* Find lines corresponding to the beg and end positions. */ - MD_ASSERT(lines[0].beg <= beg); - beg_line = lines; - while(beg >= beg_line->end) - beg_line++; + beg_line = md_lookup_line(beg, lines, n_lines, NULL); + is_multiline = (end > beg_line->end); - MD_ASSERT(end <= lines[n_lines-1].end); - end_line = beg_line; - while(end >= end_line->end) - end_line++; - - if(beg_line != end_line) { + if(is_multiline) { MD_CHECK(md_merge_lines_alloc(ctx, beg, end, beg_line, - n_lines - (beg_line - lines), _T(' '), &label, &label_size)); + (int)(n_lines - (beg_line - lines)), _T(' '), &label, &label_size)); } else { label = (CHAR*) STR(beg); label_size = end - beg; @@ -2238,7 +2310,7 @@ md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, int n_lines, attr->title_needs_free = FALSE; } - if(beg_line != end_line) + if(is_multiline) free(label); ret = (def != NULL); @@ -2248,14 +2320,14 @@ abort: } static int -md_is_inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, int n_lines, +md_is_inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF* p_end, MD_LINK_ATTR* attr) { - int line_index = 0; - int tmp_line_index; + MD_SIZE line_index = 0; + MD_SIZE tmp_line_index; OFF title_contents_beg; OFF title_contents_end; - int title_contents_line_index; + MD_SIZE title_contents_line_index; int title_is_multiline; OFF off = beg; int ret = FALSE; @@ -2269,7 +2341,7 @@ md_is_inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, int n_lines, /* Optional white space with up to one line break. */ while(off < lines[line_index].end && ISWHITESPACE(off)) off++; - if(off >= lines[line_index].end && ISNEWLINE(off)) { + if(off >= lines[line_index].end && (off >= ctx->size || ISNEWLINE(off))) { line_index++; if(line_index >= n_lines) return FALSE; @@ -2312,7 +2384,7 @@ md_is_inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, int n_lines, /* Optional whitespace followed with final ')'. */ while(off < lines[line_index].end && ISWHITESPACE(off)) off++; - if(off >= lines[line_index].end && ISNEWLINE(off)) { + if(off >= lines[line_index].end) { line_index++; if(line_index >= n_lines) return FALSE; @@ -2432,11 +2504,11 @@ struct MD_MARK_tag { OFF beg; OFF end; - /* For unresolved openers, 'prev' and 'next' form the chain of open openers - * of given type 'ch'. + /* For unresolved openers, 'next' may be used to form a stack of + * unresolved open openers. * - * During resolving, we disconnect from the chain and point to the - * corresponding counterpart so opener points to its closer and vice versa. + * When resolved with MD_MARK_OPENER/CLOSER flag, next/prev is index of the + * respective closer/opener. */ int prev; int next; @@ -2452,46 +2524,60 @@ struct MD_MARK_tag { #define MD_MARK_RESOLVED 0x10 /* Resolved in any definite way. */ /* Mark flags specific for various mark types (so they can share bits). */ -#define MD_MARK_EMPH_INTRAWORD 0x20 /* Helper for the "rule of 3". */ +#define MD_MARK_EMPH_OC 0x20 /* Opener/closer mixed candidate. Helper for the "rule of 3". */ #define MD_MARK_EMPH_MOD3_0 0x40 #define MD_MARK_EMPH_MOD3_1 0x80 #define MD_MARK_EMPH_MOD3_2 (0x40 | 0x80) #define MD_MARK_EMPH_MOD3_MASK (0x40 | 0x80) #define MD_MARK_AUTOLINK 0x20 /* Distinguisher for '<', '>'. */ +#define MD_MARK_AUTOLINK_MISSING_MAILTO 0x40 #define MD_MARK_VALIDPERMISSIVEAUTOLINK 0x20 /* For permissive autolinks. */ +#define MD_MARK_HASNESTEDBRACKETS 0x20 /* For '[' to rule out invalid link labels early */ -static MD_MARKCHAIN* -md_asterisk_chain(MD_CTX* ctx, unsigned flags) +static MD_MARKSTACK* +md_emph_stack(MD_CTX* ctx, MD_CHAR ch, unsigned flags) { - switch(flags & (MD_MARK_EMPH_INTRAWORD | MD_MARK_EMPH_MOD3_MASK)) { - case MD_MARK_EMPH_INTRAWORD | MD_MARK_EMPH_MOD3_0: return &ASTERISK_OPENERS_intraword_mod3_0; - case MD_MARK_EMPH_INTRAWORD | MD_MARK_EMPH_MOD3_1: return &ASTERISK_OPENERS_intraword_mod3_1; - case MD_MARK_EMPH_INTRAWORD | MD_MARK_EMPH_MOD3_2: return &ASTERISK_OPENERS_intraword_mod3_2; - case MD_MARK_EMPH_MOD3_0: return &ASTERISK_OPENERS_extraword_mod3_0; - case MD_MARK_EMPH_MOD3_1: return &ASTERISK_OPENERS_extraword_mod3_1; - case MD_MARK_EMPH_MOD3_2: return &ASTERISK_OPENERS_extraword_mod3_2; - default: MD_UNREACHABLE(); + MD_MARKSTACK* stack; + + switch(ch) { + case '*': stack = &ASTERISK_OPENERS_oo_mod3_0; break; + case '_': stack = &UNDERSCORE_OPENERS_oo_mod3_0; break; + default: MD_UNREACHABLE(); } - return NULL; + + if(flags & MD_MARK_EMPH_OC) + stack += 3; + + switch(flags & MD_MARK_EMPH_MOD3_MASK) { + case MD_MARK_EMPH_MOD3_0: stack += 0; break; + case MD_MARK_EMPH_MOD3_1: stack += 1; break; + case MD_MARK_EMPH_MOD3_2: stack += 2; break; + default: MD_UNREACHABLE(); + } + + return stack; } -static MD_MARKCHAIN* -md_mark_chain(MD_CTX* ctx, int mark_index) +static MD_MARKSTACK* +md_opener_stack(MD_CTX* ctx, int mark_index) { MD_MARK* mark = &ctx->marks[mark_index]; switch(mark->ch) { - case _T('*'): return md_asterisk_chain(ctx, mark->flags); - case _T('_'): return &UNDERSCORE_OPENERS; + case _T('*'): + case _T('_'): return md_emph_stack(ctx, mark->ch, mark->flags); + case _T('~'): return (mark->end - mark->beg == 1) ? &TILDE_OPENERS_1 : &TILDE_OPENERS_2; + + case _T('!'): case _T('['): return &BRACKET_OPENERS; - case _T('|'): return &TABLECELLBOUNDARIES; - default: return NULL; + + default: MD_UNREACHABLE(); } } static MD_MARK* -md_push_mark(MD_CTX* ctx) +md_add_mark(MD_CTX* ctx) { if(ctx->n_marks >= ctx->alloc_marks) { MD_MARK* new_marks; @@ -2511,18 +2597,18 @@ md_push_mark(MD_CTX* ctx) return &ctx->marks[ctx->n_marks++]; } -#define PUSH_MARK_() \ +#define ADD_MARK_() \ do { \ - mark = md_push_mark(ctx); \ + mark = md_add_mark(ctx); \ if(mark == NULL) { \ ret = -1; \ goto abort; \ } \ } while(0) -#define PUSH_MARK(ch_, beg_, end_, flags_) \ +#define ADD_MARK(ch_, beg_, end_, flags_) \ do { \ - PUSH_MARK_(); \ + ADD_MARK_(); \ mark->beg = (beg_); \ mark->end = (end_); \ mark->prev = -1; \ @@ -2532,17 +2618,20 @@ md_push_mark(MD_CTX* ctx) } while(0) -static void -md_mark_chain_append(MD_CTX* ctx, MD_MARKCHAIN* chain, int mark_index) +static inline void +md_mark_stack_push(MD_CTX* ctx, MD_MARKSTACK* stack, int mark_index) { - if(chain->tail >= 0) - ctx->marks[chain->tail].next = mark_index; - else - chain->head = mark_index; + ctx->marks[mark_index].next = stack->top; + stack->top = mark_index; +} - ctx->marks[mark_index].prev = chain->tail; - ctx->marks[mark_index].next = -1; - chain->tail = mark_index; +static inline int +md_mark_stack_pop(MD_CTX* ctx, MD_MARKSTACK* stack) +{ + int top = stack->top; + if(top >= 0) + stack->top = ctx->marks[top].next; + return top; } /* Sometimes, we need to store a pointer into the mark. It is quite rare @@ -2569,112 +2658,52 @@ md_mark_get_ptr(MD_CTX* ctx, int mark_index) return ptr; } -static void -md_resolve_range(MD_CTX* ctx, MD_MARKCHAIN* chain, int opener_index, int closer_index) +static inline void +md_resolve_range(MD_CTX* ctx, int opener_index, int closer_index) { MD_MARK* opener = &ctx->marks[opener_index]; MD_MARK* closer = &ctx->marks[closer_index]; - /* Remove opener from the list of openers. */ - if(chain != NULL) { - if(opener->prev >= 0) - ctx->marks[opener->prev].next = opener->next; - else - chain->head = opener->next; - - if(opener->next >= 0) - ctx->marks[opener->next].prev = opener->prev; - else - chain->tail = opener->prev; - } - /* Interconnect opener and closer and mark both as resolved. */ opener->next = closer_index; - opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; closer->prev = opener_index; + + opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED; } -#define MD_ROLLBACK_ALL 0 -#define MD_ROLLBACK_CROSSING 1 +#define MD_ROLLBACK_CROSSING 0 +#define MD_ROLLBACK_ALL 1 /* In the range ctx->marks[opener_index] ... [closer_index], undo some or all * resolvings accordingly to these rules: * - * (1) All openers BEFORE the range corresponding to any closer inside the - * range are un-resolved and they are re-added to their respective chains - * of unresolved openers. This ensures we can reuse the opener for closers - * AFTER the range. + * (1) All stacks of openers are cut so that any pending potential openers + * are discarded from future consideration. * * (2) If 'how' is MD_ROLLBACK_ALL, then ALL resolved marks inside the range - * are discarded. + * are thrown away and turned into dummy marks ('D'). * - * (3) If 'how' is MD_ROLLBACK_CROSSING, only closers with openers handled - * in (1) are discarded. I.e. pairs of openers and closers which are both - * inside the range are retained as well as any unpaired marks. + * WARNING: Do not call for arbitrary range of opener and closer. + * This must form (potentially) valid range not crossing nesting boundaries + * of already resolved ranges. */ static void md_rollback(MD_CTX* ctx, int opener_index, int closer_index, int how) { int i; - int mark_index; - /* Cut all unresolved openers at the mark index. */ - for(i = OPENERS_CHAIN_FIRST; i < OPENERS_CHAIN_LAST+1; i++) { - MD_MARKCHAIN* chain = &ctx->mark_chains[i]; - - while(chain->tail >= opener_index) - chain->tail = ctx->marks[chain->tail].prev; - - if(chain->tail >= 0) - ctx->marks[chain->tail].next = -1; - else - chain->head = -1; + for(i = 0; i < (int) SIZEOF_ARRAY(ctx->opener_stacks); i++) { + MD_MARKSTACK* stack = &ctx->opener_stacks[i]; + while(stack->top >= opener_index) + md_mark_stack_pop(ctx, stack); } - /* Go backwards so that unresolved openers are re-added into their - * respective chains, in the right order. */ - mark_index = closer_index - 1; - while(mark_index > opener_index) { - MD_MARK* mark = &ctx->marks[mark_index]; - int mark_flags = mark->flags; - int discard_flag = (how == MD_ROLLBACK_ALL); - - if(mark->flags & MD_MARK_CLOSER) { - int mark_opener_index = mark->prev; - - /* Undo opener BEFORE the range. */ - if(mark_opener_index < opener_index) { - MD_MARK* mark_opener = &ctx->marks[mark_opener_index]; - MD_MARKCHAIN* chain; - - mark_opener->flags &= ~(MD_MARK_OPENER | MD_MARK_CLOSER | MD_MARK_RESOLVED); - chain = md_mark_chain(ctx, opener_index); - if(chain != NULL) { - md_mark_chain_append(ctx, chain, mark_opener_index); - discard_flag = 1; - } - } - } - - /* And reset our flags. */ - if(discard_flag) - mark->flags &= ~(MD_MARK_OPENER | MD_MARK_CLOSER | MD_MARK_RESOLVED); - - /* Jump as far as we can over unresolved or non-interesting marks. */ - switch(how) { - case MD_ROLLBACK_CROSSING: - if((mark_flags & MD_MARK_CLOSER) && mark->prev > opener_index) { - /* If we are closer with opener INSIDE the range, there may - * not be any other crosser inside the subrange. */ - mark_index = mark->prev; - break; - } - /* Pass through. */ - default: - mark_index--; - break; + if(how == MD_ROLLBACK_ALL) { + for(i = opener_index + 1; i < closer_index; i++) { + ctx->marks[i].ch = 'D'; + ctx->marks[i].flags = 0; } } } @@ -2725,15 +2754,9 @@ md_build_mark_char_map(MD_CTX* ctx) } } -/* We limit code span marks to lower than 32 backticks. This solves the - * pathologic case of too many openers, each of different length: Their - * resolving would be then O(n^2). */ -#define CODESPAN_MARK_MAXLEN 32 - static int -md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, - OFF* p_opener_beg, OFF* p_opener_end, - OFF* p_closer_beg, OFF* p_closer_end, +md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, + MD_MARK* opener, MD_MARK* closer, OFF last_potential_closers[CODESPAN_MARK_MAXLEN], int* p_reached_paragraph_end) { @@ -2748,7 +2771,7 @@ md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, int has_space_before_closer = FALSE; int has_eol_before_closer = FALSE; int has_only_space = TRUE; - int line_index = 0; + MD_SIZE line_index = 0; line_end = lines[0].end; opener_end = opener_beg; @@ -2758,7 +2781,7 @@ md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, has_eol_after_opener = (opener_end == line_end); /* The caller needs to know end of the opening mark even if we fail. */ - *p_opener_end = opener_end; + opener->end = opener_end; mark_len = opener_end - opener_beg; if(mark_len > CODESPAN_MARK_MAXLEN) @@ -2834,18 +2857,22 @@ md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, if(has_space_before_closer) closer_beg--; else { + /* Go back to the end of prev line */ closer_beg = lines[line_index-1].end; - /* We need to eat the preceding "\r\n" but not any line trailing - * spaces. */ + /* But restore any trailing whitespace */ while(closer_beg < ctx->size && ISBLANK(closer_beg)) closer_beg++; } } - *p_opener_beg = opener_beg; - *p_opener_end = opener_end; - *p_closer_beg = closer_beg; - *p_closer_end = closer_end; + opener->ch = _T('`'); + opener->beg = opener_beg; + opener->end = opener_end; + opener->flags = MD_MARK_POTENTIAL_OPENER; + closer->ch = _T('`'); + closer->beg = closer_beg; + closer->end = closer_end; + closer->flags = MD_MARK_POTENTIAL_CLOSER; return TRUE; } @@ -2955,18 +2982,17 @@ md_is_autolink(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, int* p_missing_mai } static int -md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) +md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int table_mode) { - int i; + MD_SIZE line_index; int ret = 0; MD_MARK* mark; OFF codespan_last_potential_closers[CODESPAN_MARK_MAXLEN] = { 0 }; int codespan_scanned_till_paragraph_end = FALSE; - for(i = 0; i < n_lines; i++) { - const MD_LINE* line = &lines[i]; + for(line_index = 0; line_index < n_lines; line_index++) { + const MD_LINE* line = &lines[line_index]; OFF off = line->beg; - OFF line_end = line->end; while(TRUE) { CHAR ch; @@ -2981,13 +3007,13 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) #endif /* Optimization: Use some loop unrolling. */ - while(off + 3 < line_end && !IS_MARK_CHAR(off+0) && !IS_MARK_CHAR(off+1) - && !IS_MARK_CHAR(off+2) && !IS_MARK_CHAR(off+3)) + while(off + 3 < line->end && !IS_MARK_CHAR(off+0) && !IS_MARK_CHAR(off+1) + && !IS_MARK_CHAR(off+2) && !IS_MARK_CHAR(off+3)) off += 4; - while(off < line_end && !IS_MARK_CHAR(off+0)) + while(off < line->end && !IS_MARK_CHAR(off+0)) off++; - if(off >= line_end) + if(off >= line->end) break; ch = CH(off); @@ -2997,8 +3023,8 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) * line to form a hard break. */ if(ch == _T('\\') && off+1 < ctx->size && (ISPUNCT(off+1) || ISNEWLINE(off+1))) { /* Hard-break cannot be on the last line of the block. */ - if(!ISNEWLINE(off+1) || i+1 < n_lines) - PUSH_MARK(ch, off, off+2, MD_MARK_RESOLVED); + if(!ISNEWLINE(off+1) || line_index+1 < n_lines) + ADD_MARK(ch, off, off+2, MD_MARK_RESOLVED); off += 2; continue; } @@ -3009,7 +3035,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) int left_level; /* What precedes: 0 = whitespace; 1 = punctuation; 2 = other char. */ int right_level; /* What follows: 0 = whitespace; 1 = punctuation; 2 = other char. */ - while(tmp < line_end && CH(tmp) == ch) + while(tmp < line->end && CH(tmp) == ch) tmp++; if(off == line->beg || ISUNICODEWHITESPACEBEFORE(off)) @@ -3019,7 +3045,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) else left_level = 2; - if(tmp == line_end || ISUNICODEWHITESPACE(tmp)) + if(tmp == line->end || ISUNICODEWHITESPACE(tmp)) right_level = 0; else if(ISUNICODEPUNCT(tmp)) right_level = 1; @@ -3039,8 +3065,8 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) flags |= MD_MARK_POTENTIAL_CLOSER; if(right_level > 0 && right_level >= left_level) flags |= MD_MARK_POTENTIAL_OPENER; - if(left_level == 2 && right_level == 2) - flags |= MD_MARK_EMPH_INTRAWORD; + if(flags == (MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER)) + flags |= MD_MARK_EMPH_OC; /* For "the rule of three" we need to remember the original * size of the mark (modulo three), before we potentially @@ -3052,7 +3078,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) case 2: flags |= MD_MARK_EMPH_MOD3_2; break; } - PUSH_MARK(ch, off, tmp, flags); + ADD_MARK(ch, off, tmp, flags); /* During resolving, multiple asterisks may have to be * split into independent span start/ends. Consider e.g. @@ -3060,7 +3086,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) * marks to have enough space for that. */ off++; while(off < tmp) { - PUSH_MARK('D', off, off, 0); + ADD_MARK('D', off, off, 0); off++; } continue; @@ -3072,38 +3098,32 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* A potential code span start/end. */ if(ch == _T('`')) { - OFF opener_beg, opener_end; - OFF closer_beg, closer_end; + MD_MARK opener; + MD_MARK closer; int is_code_span; - is_code_span = md_is_code_span(ctx, lines + i, n_lines - i, off, - &opener_beg, &opener_end, &closer_beg, &closer_end, - codespan_last_potential_closers, - &codespan_scanned_till_paragraph_end); + is_code_span = md_is_code_span(ctx, line, n_lines - line_index, off, + &opener, &closer, codespan_last_potential_closers, + &codespan_scanned_till_paragraph_end); if(is_code_span) { - PUSH_MARK(_T('`'), opener_beg, opener_end, MD_MARK_OPENER | MD_MARK_RESOLVED); - PUSH_MARK(_T('`'), closer_beg, closer_end, MD_MARK_CLOSER | MD_MARK_RESOLVED); - ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; - ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; - - off = closer_end; + ADD_MARK(opener.ch, opener.beg, opener.end, opener.flags); + ADD_MARK(closer.ch, closer.beg, closer.end, closer.flags); + md_resolve_range(ctx, ctx->n_marks-2, ctx->n_marks-1); + off = closer.end; /* Advance the current line accordingly. */ - while(off > line_end) { - i++; - line++; - line_end = line->end; - } + if(off > line->end) + line = md_lookup_line(off, lines, n_lines, &line_index); continue; } - off = opener_end; + off = opener.end; continue; } /* A potential entity start. */ if(ch == _T('&')) { - PUSH_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); off++; continue; } @@ -3112,7 +3132,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) if(ch == _T(';')) { /* We surely cannot be entity unless the previous mark is '&'. */ if(ctx->n_marks > 0 && ctx->marks[ctx->n_marks-1].ch == _T('&')) - PUSH_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); off++; continue; @@ -3131,21 +3151,18 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* Given the nature of the raw HTML, we have to recognize * it here. Doing so later in md_analyze_lt_gt() could * open can of worms of quadratic complexity. */ - is_html = md_is_html_any(ctx, lines + i, n_lines - i, off, + is_html = md_is_html_any(ctx, line, n_lines - line_index, off, lines[n_lines-1].end, &html_end); if(is_html) { - PUSH_MARK(_T('<'), off, off, MD_MARK_OPENER | MD_MARK_RESOLVED); - PUSH_MARK(_T('>'), html_end, html_end, MD_MARK_CLOSER | MD_MARK_RESOLVED); + ADD_MARK(_T('<'), off, off, MD_MARK_OPENER | MD_MARK_RESOLVED); + ADD_MARK(_T('>'), html_end, html_end, MD_MARK_CLOSER | MD_MARK_RESOLVED); ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; off = html_end; /* Advance the current line accordingly. */ - while(off > line_end) { - i++; - line++; - line_end = line->end; - } + if(off > line->end) + line = md_lookup_line(off, lines, n_lines, &line_index); continue; } } @@ -3153,10 +3170,12 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) is_autolink = md_is_autolink(ctx, off, lines[n_lines-1].end, &autolink_end, &missing_mailto); if(is_autolink) { - PUSH_MARK((missing_mailto ? _T('@') : _T('<')), off, off+1, - MD_MARK_OPENER | MD_MARK_RESOLVED | MD_MARK_AUTOLINK); - PUSH_MARK(_T('>'), autolink_end-1, autolink_end, - MD_MARK_CLOSER | MD_MARK_RESOLVED | MD_MARK_AUTOLINK); + unsigned flags = MD_MARK_RESOLVED | MD_MARK_AUTOLINK; + if(missing_mailto) + flags |= MD_MARK_AUTOLINK_MISSING_MAILTO; + + ADD_MARK(_T('<'), off, off+1, MD_MARK_OPENER | flags); + ADD_MARK(_T('>'), autolink_end-1, autolink_end, MD_MARK_CLOSER | flags); ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; off = autolink_end; @@ -3168,18 +3187,18 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) } /* A potential link or its part. */ - if(ch == _T('[') || (ch == _T('!') && off+1 < line_end && CH(off+1) == _T('['))) { + if(ch == _T('[') || (ch == _T('!') && off+1 < line->end && CH(off+1) == _T('['))) { OFF tmp = (ch == _T('[') ? off+1 : off+2); - PUSH_MARK(ch, off, tmp, MD_MARK_POTENTIAL_OPENER); + ADD_MARK(ch, off, tmp, MD_MARK_POTENTIAL_OPENER); off = tmp; /* Two dummies to make enough place for data we need if it is * a link. */ - PUSH_MARK('D', off, off, 0); - PUSH_MARK('D', off, off, 0); + ADD_MARK('D', off, off, 0); + ADD_MARK('D', off, off, 0); continue; } if(ch == _T(']')) { - PUSH_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); off++; continue; } @@ -3189,9 +3208,9 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) if(line->beg + 1 <= off && ISALNUM(off-1) && off + 3 < line->end && ISALNUM(off+1)) { - PUSH_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); /* Push a dummy as a reserve for a closer. */ - PUSH_MARK('D', off, off, 0); + ADD_MARK('D', line->beg, line->end, 0); } off++; @@ -3220,14 +3239,13 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) const SZ suffix_size = scheme_map[scheme_index].suffix_size; if(line->beg + scheme_size <= off && md_ascii_eq(STR(off-scheme_size), scheme, scheme_size) && - (line->beg + scheme_size == off || ISWHITESPACE(off-scheme_size-1) || ISANYOF(off-scheme_size-1, _T("*_~(["))) && off + 1 + suffix_size < line->end && md_ascii_eq(STR(off+1), suffix, suffix_size)) { - PUSH_MARK(ch, off-scheme_size, off+1+suffix_size, MD_MARK_POTENTIAL_OPENER); + ADD_MARK(ch, off-scheme_size, off+1+suffix_size, MD_MARK_POTENTIAL_OPENER); /* Push a dummy as a reserve for a closer. */ - PUSH_MARK('D', off, off, 0); + ADD_MARK('D', line->beg, line->end, 0); off += 1 + suffix_size; - continue; + break; } } @@ -3238,12 +3256,11 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* A potential permissive WWW autolink. */ if(ch == _T('.')) { if(line->beg + 3 <= off && md_ascii_eq(STR(off-3), _T("www"), 3) && - (line->beg + 3 == off || ISWHITESPACE(off-4) || ISANYOF(off-4, _T("*_~(["))) && - off + 1 < line_end) + (off-3 == line->beg || ISUNICODEWHITESPACEBEFORE(off-3) || ISUNICODEPUNCTBEFORE(off-3))) { - PUSH_MARK(ch, off-3, off+1, MD_MARK_POTENTIAL_OPENER); + ADD_MARK(ch, off-3, off+1, MD_MARK_POTENTIAL_OPENER); /* Push a dummy as a reserve for a closer. */ - PUSH_MARK('D', off, off, 0); + ADD_MARK('D', line->beg, line->end, 0); off++; continue; } @@ -3254,7 +3271,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* A potential table cell boundary or wiki link label delimiter. */ if((table_mode || ctx->parser.flags & MD_FLAG_WIKILINKS) && ch == _T('|')) { - PUSH_MARK(ch, off, off+1, 0); + ADD_MARK(ch, off, off+1, 0); off++; continue; } @@ -3263,18 +3280,18 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) if(ch == _T('~')) { OFF tmp = off+1; - while(tmp < line_end && CH(tmp) == _T('~')) + while(tmp < line->end && CH(tmp) == _T('~')) tmp++; if(tmp - off < 3) { unsigned flags = 0; - if(tmp < line_end && !ISUNICODEWHITESPACE(tmp)) + if(tmp < line->end && !ISUNICODEWHITESPACE(tmp)) flags |= MD_MARK_POTENTIAL_OPENER; if(off > line->beg && !ISUNICODEWHITESPACEBEFORE(off)) flags |= MD_MARK_POTENTIAL_CLOSER; if(flags != 0) - PUSH_MARK(ch, off, tmp, flags); + ADD_MARK(ch, off, tmp, flags); } off = tmp; @@ -3287,11 +3304,20 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) * where two dollar signs signify a display equation. */ OFF tmp = off+1; - while(tmp < line_end && CH(tmp) == _T('$')) + while(tmp < line->end && CH(tmp) == _T('$')) tmp++; - if (tmp - off <= 2) - PUSH_MARK(ch, off, tmp, MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER); + if(tmp - off <= 2) { + unsigned flags = MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER; + + if(off > line->beg && !ISUNICODEWHITESPACEBEFORE(off) && !ISUNICODEPUNCTBEFORE(off)) + flags &= ~MD_MARK_POTENTIAL_OPENER; + if(tmp < line->end && !ISUNICODEWHITESPACE(tmp) && !ISUNICODEPUNCT(tmp)) + flags &= ~MD_MARK_POTENTIAL_CLOSER; + if(flags != 0) + ADD_MARK(ch, off, tmp, flags); + } + off = tmp; continue; } @@ -3300,11 +3326,11 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) if(ISWHITESPACE_(ch)) { OFF tmp = off+1; - while(tmp < line_end && ISWHITESPACE(tmp)) + while(tmp < line->end && ISWHITESPACE(tmp)) tmp++; if(tmp - off > 1 || ch != _T(' ')) - PUSH_MARK(ch, off, tmp, MD_MARK_RESOLVED); + ADD_MARK(ch, off, tmp, MD_MARK_RESOLVED); off = tmp; continue; @@ -3312,7 +3338,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* NULL character. */ if(ch == _T('\0')) { - PUSH_MARK(ch, off, off+1, MD_MARK_RESOLVED); + ADD_MARK(ch, off, off+1, MD_MARK_RESOLVED); off++; continue; } @@ -3323,7 +3349,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* Add a dummy mark at the end of the mark vector to simplify * process_inlines(). */ - PUSH_MARK(127, ctx->size, ctx->size, MD_MARK_RESOLVED); + ADD_MARK(127, ctx->size, ctx->size, MD_MARK_RESOLVED); abort: return ret; @@ -3337,36 +3363,33 @@ md_analyze_bracket(MD_CTX* ctx, int mark_index) * or enclosing pair of brackets (if the inner is the link, the outer * one cannot be.) * - * Therefore we here only construct a list of resolved '[' ']' pairs - * ordered by position of the closer. This allows ur to analyze what is - * or is not link in the right order, from inside to outside in case - * of nested brackets. + * Therefore we here only construct a list of '[' ']' pairs ordered by + * position of the closer. This allows us to analyze what is or is not + * link in the right order, from inside to outside in case of nested + * brackets. * - * The resolving itself is deferred into md_resolve_links(). + * The resolving itself is deferred to md_resolve_links(). */ MD_MARK* mark = &ctx->marks[mark_index]; if(mark->flags & MD_MARK_POTENTIAL_OPENER) { - md_mark_chain_append(ctx, &BRACKET_OPENERS, mark_index); + if(BRACKET_OPENERS.top >= 0) + ctx->marks[BRACKET_OPENERS.top].flags |= MD_MARK_HASNESTEDBRACKETS; + + md_mark_stack_push(ctx, &BRACKET_OPENERS, mark_index); return; } - if(BRACKET_OPENERS.tail >= 0) { - /* Pop the opener from the chain. */ - int opener_index = BRACKET_OPENERS.tail; + if(BRACKET_OPENERS.top >= 0) { + int opener_index = md_mark_stack_pop(ctx, &BRACKET_OPENERS); MD_MARK* opener = &ctx->marks[opener_index]; - if(opener->prev >= 0) - ctx->marks[opener->prev].next = -1; - else - BRACKET_OPENERS.head = -1; - BRACKET_OPENERS.tail = opener->prev; /* Interconnect the opener and closer. */ opener->next = mark_index; mark->prev = opener_index; - /* Add the pair into chain of potential links for md_resolve_links(). + /* Add the pair into a list of potential links for md_resolve_links(). * Note we misuse opener->prev for this as opener->next points to its * closer. */ if(ctx->unresolved_link_tail >= 0) @@ -3379,11 +3402,11 @@ md_analyze_bracket(MD_CTX* ctx, int mark_index) } /* Forward declaration. */ -static void md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines, +static void md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int mark_beg, int mark_end); static int -md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) +md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) { int opener_index = ctx->unresolved_link_head; OFF last_link_beg = 0; @@ -3454,10 +3477,15 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) delim = m; break; } - if(m->ch != 'D' && m->beg - opener->end > 100) - break; + if(m->ch != 'D') { + if(m->beg - opener->end > 100) + break; + if(m->ch != 'D' && (m->flags & MD_MARK_OPENER)) + delim_index = m->next; + } delim_index++; } + dest_beg = opener->end; dest_end = (delim != NULL) ? delim->beg : closer->beg; if(dest_end - dest_beg == 0 || dest_end - dest_beg > 100) @@ -3477,9 +3505,13 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) if(is_link) { if(delim != NULL) { if(delim->end < closer->beg) { + md_rollback(ctx, opener_index, delim_index, MD_ROLLBACK_ALL); + md_rollback(ctx, delim_index, closer_index, MD_ROLLBACK_CROSSING); + delim->flags |= MD_MARK_RESOLVED; opener->end = delim->beg; } else { /* The pipe is just before the closer: [[foo|]] */ + md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL); closer->beg = delim->beg; delim = NULL; } @@ -3496,13 +3528,8 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) last_link_beg = opener->beg; last_link_end = closer->end; - if(delim != NULL) { - delim->flags |= MD_MARK_RESOLVED; - md_rollback(ctx, opener_index, delim_index, MD_ROLLBACK_ALL); - md_analyze_link_contents(ctx, lines, n_lines, opener_index+1, closer_index); - } else { - md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL); - } + if(delim != NULL) + md_analyze_link_contents(ctx, lines, n_lines, delim_index+1, closer_index); opener_index = next_opener->prev; continue; @@ -3512,10 +3539,12 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) if(next_opener != NULL && next_opener->beg == closer->end) { if(next_closer->beg > closer->end + 1) { /* Might be full reference link. */ - is_link = md_is_link_reference(ctx, lines, n_lines, next_opener->beg, next_closer->end, &attr); + if(!(next_opener->flags & MD_MARK_HASNESTEDBRACKETS)) + is_link = md_is_link_reference(ctx, lines, n_lines, next_opener->beg, next_closer->end, &attr); } else { /* Might be shortcut reference link. */ - is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); + if(!(opener->flags & MD_MARK_HASNESTEDBRACKETS)) + is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); } if(is_link < 0) @@ -3524,6 +3553,10 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) if(is_link) { /* Eat the 2nd "[...]". */ closer->end = next_closer->end; + + /* Do not analyze the label as a standalone link in the next + * iteration. */ + next_index = ctx->marks[next_index].prev; } } else { if(closer->end < ctx->size && CH(closer->end) == _T('(')) { @@ -3568,7 +3601,8 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) if(!is_link) { /* Might be collapsed reference link. */ - is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); + if(!(opener->flags & MD_MARK_HASNESTEDBRACKETS)) + is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); if(is_link < 0) return -1; } @@ -3589,7 +3623,7 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) md_mark_store_ptr(ctx, opener_index+2, attr.title); /* The title might or might not have been allocated for us. */ if(attr.title_needs_free) - md_mark_chain_append(ctx, &PTR_CHAIN, opener_index+2); + md_mark_stack_push(ctx, &ctx->ptr_stack, opener_index+2); ctx->marks[opener_index+2].prev = attr.title_size; if(opener->ch == '[') { @@ -3662,7 +3696,7 @@ md_analyze_entity(MD_CTX* ctx, int mark_index) if(md_is_entity(ctx, opener->beg, closer->end, &off)) { MD_ASSERT(off == closer->end); - md_resolve_range(ctx, NULL, mark_index, mark_index+1); + md_resolve_range(ctx, mark_index, mark_index+1); opener->end = closer->end; } } @@ -3672,8 +3706,13 @@ md_analyze_table_cell_boundary(MD_CTX* ctx, int mark_index) { MD_MARK* mark = &ctx->marks[mark_index]; mark->flags |= MD_MARK_RESOLVED; + mark->next = -1; - md_mark_chain_append(ctx, &TABLECELLBOUNDARIES, mark_index); + if(ctx->table_cell_boundaries_head < 0) + ctx->table_cell_boundaries_head = mark_index; + else + ctx->marks[ctx->table_cell_boundaries_tail].next = mark_index; + ctx->table_cell_boundaries_tail = mark_index; ctx->n_table_cell_boundaries++; } @@ -3702,257 +3741,323 @@ static void md_analyze_emph(MD_CTX* ctx, int mark_index) { MD_MARK* mark = &ctx->marks[mark_index]; - MD_MARKCHAIN* chain = md_mark_chain(ctx, mark_index); /* If we can be a closer, try to resolve with the preceding opener. */ if(mark->flags & MD_MARK_POTENTIAL_CLOSER) { MD_MARK* opener = NULL; - int opener_index; + int opener_index = 0; + MD_MARKSTACK* opener_stacks[6]; + int i, n_opener_stacks; + unsigned flags = mark->flags; - if(mark->ch == _T('*')) { - MD_MARKCHAIN* opener_chains[6]; - int i, n_opener_chains; - unsigned flags = mark->flags; + n_opener_stacks = 0; - /* Apply the "rule of three". */ - n_opener_chains = 0; - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_intraword_mod3_0; - if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_intraword_mod3_1; - if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_intraword_mod3_2; - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_extraword_mod3_0; - if(!(flags & MD_MARK_EMPH_INTRAWORD) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_extraword_mod3_1; - if(!(flags & MD_MARK_EMPH_INTRAWORD) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_extraword_mod3_2; + /* Apply the rule of 3 */ + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_0 | MD_MARK_EMPH_OC); + if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_1 | MD_MARK_EMPH_OC); + if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_2 | MD_MARK_EMPH_OC); + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_0); + if(!(flags & MD_MARK_EMPH_OC) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_1); + if(!(flags & MD_MARK_EMPH_OC) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_2); - /* Opener is the most recent mark from the allowed chains. */ - for(i = 0; i < n_opener_chains; i++) { - if(opener_chains[i]->tail >= 0) { - int tmp_index = opener_chains[i]->tail; - MD_MARK* tmp_mark = &ctx->marks[tmp_index]; - if(opener == NULL || tmp_mark->end > opener->end) { - opener_index = tmp_index; - opener = tmp_mark; - } + /* Opener is the most recent mark from the allowed stacks. */ + for(i = 0; i < n_opener_stacks; i++) { + if(opener_stacks[i]->top >= 0) { + int m_index = opener_stacks[i]->top; + MD_MARK* m = &ctx->marks[m_index]; + + if(opener == NULL || m->end > opener->end) { + opener_index = m_index; + opener = m; } } - } else { - /* Simple emph. mark */ - if(chain->tail >= 0) { - opener_index = chain->tail; - opener = &ctx->marks[opener_index]; - } } /* Resolve, if we have found matching opener. */ if(opener != NULL) { SZ opener_size = opener->end - opener->beg; SZ closer_size = mark->end - mark->beg; - MD_MARKCHAIN* opener_chain = md_mark_chain(ctx, opener_index); + MD_MARKSTACK* stack = md_opener_stack(ctx, opener_index); if(opener_size > closer_size) { opener_index = md_split_emph_mark(ctx, opener_index, closer_size); - md_mark_chain_append(ctx, opener_chain, opener_index); + md_mark_stack_push(ctx, stack, opener_index); } else if(opener_size < closer_size) { md_split_emph_mark(ctx, mark_index, closer_size - opener_size); } + /* Above we were only peeking. */ + md_mark_stack_pop(ctx, stack); + md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING); - md_resolve_range(ctx, opener_chain, opener_index, mark_index); + md_resolve_range(ctx, opener_index, mark_index); return; } } /* If we could not resolve as closer, we may be yet be an opener. */ if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_chain_append(ctx, chain, mark_index); + md_mark_stack_push(ctx, md_emph_stack(ctx, mark->ch, mark->flags), mark_index); } static void md_analyze_tilde(MD_CTX* ctx, int mark_index) { MD_MARK* mark = &ctx->marks[mark_index]; - MD_MARKCHAIN* chain = md_mark_chain(ctx, mark_index); + MD_MARKSTACK* stack = md_opener_stack(ctx, mark_index); /* We attempt to be Github Flavored Markdown compatible here. GFM accepts * only tildes sequences of length 1 and 2, and the length of the opener * and closer has to match. */ - if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && chain->head >= 0) { - int opener_index = chain->head; + if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && stack->top >= 0) { + int opener_index = stack->top; + md_mark_stack_pop(ctx, stack); md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING); - md_resolve_range(ctx, chain, opener_index, mark_index); + md_resolve_range(ctx, opener_index, mark_index); return; } if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_chain_append(ctx, chain, mark_index); + md_mark_stack_push(ctx, stack, mark_index); } static void md_analyze_dollar(MD_CTX* ctx, int mark_index) { - /* This should mimic the way inline equations work in LaTeX, so there - * can only ever be one item in the chain (i.e. the dollars can't be - * nested). This is basically the same as the md_analyze_tilde function, - * except that we require matching openers and closers to be of the same - * length. - * - * E.g.: $abc$$def$$ => abc (display equation) def (end equation) */ - if(DOLLAR_OPENERS.head >= 0) { - /* If the potential closer has a non-matching number of $, discard */ - MD_MARK* open = &ctx->marks[DOLLAR_OPENERS.head]; - MD_MARK* close = &ctx->marks[mark_index]; + MD_MARK* mark = &ctx->marks[mark_index]; - int opener_index = DOLLAR_OPENERS.head; - md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_ALL); - if (open->end - open->beg == close->end - close->beg) { + if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && DOLLAR_OPENERS.top >= 0) { + /* If the potential closer has a non-matching number of $, discard */ + MD_MARK* opener = &ctx->marks[DOLLAR_OPENERS.top]; + int opener_index = DOLLAR_OPENERS.top; + MD_MARK* closer = mark; + int closer_index = mark_index; + + if(opener->end - opener->beg == closer->end - closer->beg) { /* We are the matching closer */ - md_resolve_range(ctx, &DOLLAR_OPENERS, opener_index, mark_index); - } else { - /* We don't match the opener, so discard old opener and insert as opener */ - md_mark_chain_append(ctx, &DOLLAR_OPENERS, mark_index); + md_mark_stack_pop(ctx, &DOLLAR_OPENERS); + md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL); + md_resolve_range(ctx, opener_index, closer_index); + + /* Discard all pending openers: Latex math span do not allow + * nesting. */ + DOLLAR_OPENERS.top = -1; + return; } - } else { - /* No unmatched openers, so we are opener */ - md_mark_chain_append(ctx, &DOLLAR_OPENERS, mark_index); } + + if(mark->flags & MD_MARK_POTENTIAL_OPENER) + md_mark_stack_push(ctx, &DOLLAR_OPENERS, mark_index); +} + +static MD_MARK* +md_scan_left_for_resolved_mark(MD_CTX* ctx, MD_MARK* mark_from, OFF off, MD_MARK** p_cursor) +{ + MD_MARK* mark; + + for(mark = mark_from; mark >= ctx->marks; mark--) { + if(mark->ch == 'D' || mark->beg > off) + continue; + if(mark->beg <= off && off < mark->end && (mark->flags & MD_MARK_RESOLVED)) { + if(p_cursor != NULL) + *p_cursor = mark; + return mark; + } + if(mark->end <= off) + break; + } + + if(p_cursor != NULL) + *p_cursor = mark; + return NULL; +} + +static MD_MARK* +md_scan_right_for_resolved_mark(MD_CTX* ctx, MD_MARK* mark_from, OFF off, MD_MARK** p_cursor) +{ + MD_MARK* mark; + + for(mark = mark_from; mark < ctx->marks + ctx->n_marks; mark++) { + if(mark->ch == 'D' || mark->end <= off) + continue; + if(mark->beg <= off && off < mark->end && (mark->flags & MD_MARK_RESOLVED)) { + if(p_cursor != NULL) + *p_cursor = mark; + return mark; + } + if(mark->beg > off) + break; + } + + if(p_cursor != NULL) + *p_cursor = mark; + return NULL; } static void -md_analyze_permissive_url_autolink(MD_CTX* ctx, int mark_index) +md_analyze_permissive_autolink(MD_CTX* ctx, int mark_index) { + static const struct { + const MD_CHAR start_char; + const MD_CHAR delim_char; + const MD_CHAR* allowed_nonalnum_chars; + int min_components; + const MD_CHAR optional_end_char; + } URL_MAP[] = { + { _T('\0'), _T('.'), _T(".-_"), 2, _T('\0') }, /* host, mandatory */ + { _T('/'), _T('/'), _T("/.-_"), 0, _T('/') }, /* path */ + { _T('?'), _T('&'), _T("&.-+_=()"), 1, _T('\0') }, /* query */ + { _T('#'), _T('\0'), _T(".-+_") , 1, _T('\0') } /* fragment */ + }; + MD_MARK* opener = &ctx->marks[mark_index]; - int closer_index = mark_index + 1; - MD_MARK* closer = &ctx->marks[closer_index]; - MD_MARK* next_resolved_mark; - OFF off = opener->end; - int n_dots = FALSE; - int has_underscore_in_last_seg = FALSE; - int has_underscore_in_next_to_last_seg = FALSE; - int n_opened_parenthesis = 0; + MD_MARK* closer = &ctx->marks[mark_index + 1]; /* The dummy. */ + OFF line_beg = closer->beg; /* md_collect_mark() set this for us */ + OFF line_end = closer->end; /* ditto */ + OFF beg = opener->beg; + OFF end = opener->end; + MD_MARK* left_cursor = opener; + int left_boundary_ok = FALSE; + MD_MARK* right_cursor = opener; + int right_boundary_ok = FALSE; + unsigned i; - /* Check for domain. */ - while(off < ctx->size) { - if(ISALNUM(off) || CH(off) == _T('-')) { - off++; - } else if(CH(off) == _T('.')) { - /* We must see at least one period. */ - n_dots++; - has_underscore_in_next_to_last_seg = has_underscore_in_last_seg; - has_underscore_in_last_seg = FALSE; - off++; - } else if(CH(off) == _T('_')) { - /* No underscore may be present in the last two domain segments. */ - has_underscore_in_last_seg = TRUE; - off++; - } else { - break; - } - } - if(off > opener->end && CH(off-1) == _T('.')) { - off--; - n_dots--; - } - if(off <= opener->end || n_dots == 0 || has_underscore_in_next_to_last_seg || has_underscore_in_last_seg) - return; + MD_ASSERT(closer->ch == 'D'); - /* Check for path. */ - next_resolved_mark = closer + 1; - while(next_resolved_mark->ch == 'D' || !(next_resolved_mark->flags & MD_MARK_RESOLVED)) - next_resolved_mark++; - while(off < next_resolved_mark->beg && CH(off) != _T('<') && !ISWHITESPACE(off) && !ISNEWLINE(off)) { - /* Parenthesis must be balanced. */ - if(CH(off) == _T('(')) { - n_opened_parenthesis++; - } else if(CH(off) == _T(')')) { - if(n_opened_parenthesis > 0) - n_opened_parenthesis--; + if(opener->ch == '@') { + MD_ASSERT(CH(opener->beg) == _T('@')); + + /* Scan backwards for the user name (before '@'). */ + while(beg > line_beg) { + if(ISALNUM(beg-1)) + beg--; + else if(beg >= line_beg+2 && ISALNUM(beg-2) && + ISANYOF(beg-1, _T(".-_+")) && + md_scan_left_for_resolved_mark(ctx, left_cursor, beg-1, &left_cursor) == NULL && + ISALNUM(beg)) + beg--; else break; } - - off++; + if(beg == opener->beg) /* empty user name */ + return; } - /* These cannot be last char In such case they are more likely normal - * punctuation. */ - if(ISANYOF(off-1, _T("?!.,:*_~"))) - off--; - /* Ok. Lets call it auto-link. Adapt opener and create closer to zero - * length so all the contents becomes the link text. */ - MD_ASSERT(closer->ch == 'D'); - opener->end = opener->beg; - closer->ch = opener->ch; - closer->beg = off; - closer->end = off; - md_resolve_range(ctx, NULL, mark_index, closer_index); -} + /* Verify there's line boundary, whitespace, allowed punctuation or + * resolved emphasis mark just before the suspected autolink. */ + if(beg == line_beg || ISUNICODEWHITESPACEBEFORE(beg) || ISANYOF(beg-1, _T("({["))) { + left_boundary_ok = TRUE; + } else if(ISANYOF(beg-1, _T("*_~"))) { + MD_MARK* left_mark; -/* The permissive autolinks do not have to be enclosed in '<' '>' but we - * instead impose stricter rules what is understood as an e-mail address - * here. Actually any non-alphanumeric characters with exception of '.' - * are prohibited both in username and after '@'. */ -static void -md_analyze_permissive_email_autolink(MD_CTX* ctx, int mark_index) -{ - MD_MARK* opener = &ctx->marks[mark_index]; - int closer_index; - MD_MARK* closer; - OFF beg = opener->beg; - OFF end = opener->end; - int dot_count = 0; - - MD_ASSERT(CH(beg) == _T('@')); - - /* Scan for name before '@'. */ - while(beg > 0 && (ISALNUM(beg-1) || ISANYOF(beg-1, _T(".-_+")))) - beg--; - - /* Scan for domain after '@'. */ - while(end < ctx->size && (ISALNUM(end) || ISANYOF(end, _T(".-_")))) { - if(CH(end) == _T('.')) - dot_count++; - end++; + left_mark = md_scan_left_for_resolved_mark(ctx, left_cursor, beg-1, &left_cursor); + if(left_mark != NULL && (left_mark->flags & MD_MARK_OPENER)) + left_boundary_ok = TRUE; } - if(CH(end-1) == _T('.')) { /* Final '.' not part of it. */ - dot_count--; - end--; - } - else if(ISANYOF2(end-1, _T('-'), _T('_'))) /* These are forbidden at the end. */ - return; - if(CH(end-1) == _T('@') || dot_count == 0) + if(!left_boundary_ok) return; - /* Ok. Lets call it auto-link. Adapt opener and create closer to zero - * length so all the contents becomes the link text. */ - closer_index = mark_index + 1; - closer = &ctx->marks[closer_index]; - MD_ASSERT(closer->ch == 'D'); + for(i = 0; i < SIZEOF_ARRAY(URL_MAP); i++) { + int n_components = 0; + int n_open_brackets = 0; + if(URL_MAP[i].start_char != _T('\0')) { + if(end >= line_end || CH(end) != URL_MAP[i].start_char) + continue; + if(URL_MAP[i].min_components > 0 && (end+1 >= line_end || !ISALNUM(end+1))) + continue; + end++; + } + + while(end < line_end) { + if(ISALNUM(end)) { + if(n_components == 0) + n_components++; + end++; + } else if(end < line_end && + ISANYOF(end, URL_MAP[i].allowed_nonalnum_chars) && + md_scan_right_for_resolved_mark(ctx, right_cursor, end, &right_cursor) == NULL && + ((end > line_beg && (ISALNUM(end-1) || CH(end-1) == _T(')'))) || CH(end) == _T('(')) && + ((end+1 < line_end && (ISALNUM(end+1) || CH(end+1) == _T('('))) || CH(end) == _T(')'))) + { + if(CH(end) == URL_MAP[i].delim_char) + n_components++; + + /* brackets have to be balanced. */ + if(CH(end) == _T('(')) { + n_open_brackets++; + } else if(CH(end) == _T(')')) { + if(n_open_brackets <= 0) + break; + n_open_brackets--; + } + + end++; + } else { + break; + } + } + + if(end < line_end && URL_MAP[i].optional_end_char != _T('\0') && + CH(end) == URL_MAP[i].optional_end_char) + end++; + + if(n_components < URL_MAP[i].min_components || n_open_brackets != 0) + return; + + if(opener->ch == '@') /* E-mail autolinks wants only the host. */ + break; + } + + /* Verify there's line boundary, whitespace, allowed punctuation or + * resolved emphasis mark just after the suspected autolink. */ + if(end == line_end || ISUNICODEWHITESPACE(end) || ISANYOF(end, _T(")}].!?,;"))) { + right_boundary_ok = TRUE; + } else { + MD_MARK* right_mark; + + right_mark = md_scan_right_for_resolved_mark(ctx, right_cursor, end, &right_cursor); + if(right_mark != NULL && (right_mark->flags & MD_MARK_CLOSER)) + right_boundary_ok = TRUE; + } + if(!right_boundary_ok) + return; + + /* Success, we are an autolink. */ opener->beg = beg; opener->end = beg; - closer->ch = opener->ch; closer->beg = end; closer->end = end; - md_resolve_range(ctx, NULL, mark_index, closer_index); + closer->ch = opener->ch; + md_resolve_range(ctx, mark_index, mark_index + 1); } +#define MD_ANALYZE_NOSKIP_EMPH 0x01 + static inline void -md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, - int mark_beg, int mark_end, const CHAR* mark_chars) +md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, + int mark_beg, int mark_end, const CHAR* mark_chars, unsigned flags) { int i = mark_beg; + OFF last_end = lines[0].beg; + + MD_UNUSED(lines); + MD_UNUSED(n_lines); while(i < mark_end) { MD_MARK* mark = &ctx->marks[i]; /* Skip resolved spans. */ if(mark->flags & MD_MARK_RESOLVED) { - if(mark->flags & MD_MARK_OPENER) { + if((mark->flags & MD_MARK_OPENER) && + !((flags & MD_ANALYZE_NOSKIP_EMPH) && ISANYOF_(mark->ch, "*_~"))) + { MD_ASSERT(i < mark->next); i = mark->next + 1; } else { @@ -3967,6 +4072,12 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, continue; } + /* The resolving in previous step could have expanded a mark. */ + if(mark->beg < last_end) { + i++; + continue; + } + /* Analyze the mark. */ switch(mark->ch) { case '[': /* Pass through. */ @@ -3979,8 +4090,15 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, case '~': md_analyze_tilde(ctx, i); break; case '$': md_analyze_dollar(ctx, i); break; case '.': /* Pass through. */ - case ':': md_analyze_permissive_url_autolink(ctx, i); break; - case '@': md_analyze_permissive_email_autolink(ctx, i); break; + case ':': /* Pass through. */ + case '@': md_analyze_permissive_autolink(ctx, i); break; + } + + if(mark->flags & MD_MARK_RESOLVED) { + if(mark->flags & MD_MARK_OPENER) + last_end = ctx->marks[mark->next].end; + else + last_end = mark->end; } i++; @@ -3989,7 +4107,7 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, /* Analyze marks (build ctx->marks). */ static int -md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) +md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int table_mode) { int ret; @@ -3999,31 +4117,22 @@ md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mod /* Collect all marks. */ MD_CHECK(md_collect_marks(ctx, lines, n_lines, table_mode)); - /* We analyze marks in few groups to handle their precedence. */ - /* (1) Entities; code spans; autolinks; raw HTML. */ - md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("&")); - - /* (2) Links. */ - md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("[]!")); + /* (1) Links. */ + md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("[]!"), 0); MD_CHECK(md_resolve_links(ctx, lines, n_lines)); - BRACKET_OPENERS.head = -1; - BRACKET_OPENERS.tail = -1; + BRACKET_OPENERS.top = -1; ctx->unresolved_link_head = -1; ctx->unresolved_link_tail = -1; if(table_mode) { - /* (3) Analyze table cell boundaries. - * Note we reset TABLECELLBOUNDARIES chain prior to the call md_analyze_marks(), - * not after, because caller may need it. */ + /* (2) Analyze table cell boundaries. */ MD_ASSERT(n_lines == 1); - TABLECELLBOUNDARIES.head = -1; - TABLECELLBOUNDARIES.tail = -1; ctx->n_table_cell_boundaries = 0; - md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("|")); + md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("|"), 0); return ret; } - /* (4) Emphasis and strong emphasis; permissive autolinks. */ + /* (3) Emphasis and strong emphasis; permissive autolinks. */ md_analyze_link_contents(ctx, lines, n_lines, 0, ctx->n_marks); abort: @@ -4031,22 +4140,28 @@ abort: } static void -md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines, +md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int mark_beg, int mark_end) { int i; - md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("*_~$@:.")); + md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("&"), 0); + md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("*_~$"), 0); - for(i = OPENERS_CHAIN_FIRST; i <= OPENERS_CHAIN_LAST; i++) { - ctx->mark_chains[i].head = -1; - ctx->mark_chains[i].tail = -1; + if((ctx->parser.flags & MD_FLAG_PERMISSIVEAUTOLINKS) != 0) { + /* These have to be processed last, as they may be greedy and expand + * from their original mark. Also their implementation must be careful + * not to cross any (previously) resolved marks when doing so. */ + md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("@:."), MD_ANALYZE_NOSKIP_EMPH); } + + for(i = 0; i < (int) SIZEOF_ARRAY(ctx->opener_stacks); i++) + ctx->opener_stacks[i].top = -1; } static int md_enter_leave_span_a(MD_CTX* ctx, int enter, MD_SPANTYPE type, - const CHAR* dest, SZ dest_size, int prohibit_escapes_in_dest, + const CHAR* dest, SZ dest_size, int is_autolink, const CHAR* title, SZ title_size) { MD_ATTRIBUTE_BUILD href_build = { 0 }; @@ -4058,10 +4173,10 @@ md_enter_leave_span_a(MD_CTX* ctx, int enter, MD_SPANTYPE type, * MD_SPAN_IMG_DETAIL are binary-compatible. */ memset(&det, 0, sizeof(MD_SPAN_A_DETAIL)); MD_CHECK(md_build_attribute(ctx, dest, dest_size, - (prohibit_escapes_in_dest ? MD_BUILD_ATTR_NO_ESCAPES : 0), + (is_autolink ? MD_BUILD_ATTR_NO_ESCAPES : 0), &det.href, &href_build)); MD_CHECK(md_build_attribute(ctx, title, title_size, 0, &det.title, &title_build)); - + det.is_autolink = is_autolink; if(enter) MD_ENTER_SPAN(type, &det); else @@ -4096,7 +4211,7 @@ abort: /* Render the output, accordingly to the analyzed ctx->marks. */ static int -md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) +md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) { MD_TEXTTYPE text_type; const MD_LINE* line = lines; @@ -4104,6 +4219,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) MD_MARK* mark; OFF off = lines[0].beg; OFF end = lines[n_lines-1].end; + OFF tmp; int enforce_hardbreak = 0; int ret = 0; @@ -4119,7 +4235,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) while(1) { /* Process the text up to the next mark or end-of-line. */ - OFF tmp = (line->end < mark->beg ? line->end : mark->beg); + tmp = (line->end < mark->beg ? line->end : mark->beg); if(tmp > off) { MD_TEXT(text_type, STR(off), tmp - off); off = tmp; @@ -4164,7 +4280,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) } break; } - /* Fall though. */ + MD_FALLTHROUGH(); case '*': /* Emphasis, strong emphasis. */ if(mark->flags & MD_MARK_OPENER) { @@ -4241,7 +4357,8 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) MD_CHECK(md_enter_leave_span_a(ctx, (mark->ch != ']'), (opener->ch == '!' ? MD_SPAN_IMG : MD_SPAN_A), STR(dest_mark->beg), dest_mark->end - dest_mark->beg, FALSE, - md_mark_get_ptr(ctx, title_mark - ctx->marks), title_mark->prev)); + md_mark_get_ptr(ctx, (int)(title_mark - ctx->marks)), + title_mark->prev)); /* link/image closer may span multiple lines. */ if(mark->ch == ']') { @@ -4263,6 +4380,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) break; } /* Pass through, if auto-link. */ + MD_FALLTHROUGH(); case '@': /* Permissive e-mail autolink. */ case ':': /* Permissive URL autolink. */ @@ -4282,11 +4400,13 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) if(mark->flags & MD_MARK_OPENER) closer->flags |= MD_MARK_VALIDPERMISSIVEAUTOLINK; - if(opener->ch == '@' || opener->ch == '.') { + if(opener->ch == '@' || opener->ch == '.' || + (opener->ch == '<' && (opener->flags & MD_MARK_AUTOLINK_MISSING_MAILTO))) + { dest_size += 7; MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); memcpy(ctx->buffer, - (opener->ch == '@' ? _T("mailto:") : _T("http://")), + (opener->ch == '.' ? _T("http://") : _T("mailto:")), 7 * sizeof(CHAR)); memcpy(ctx->buffer + 7, dest, (dest_size-7) * sizeof(CHAR)); dest = ctx->buffer; @@ -4326,8 +4446,6 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) break; if(text_type == MD_TEXT_CODE || text_type == MD_TEXT_LATEXMATH) { - OFF tmp; - MD_ASSERT(prev_mark != NULL); MD_ASSERT(ISANYOF2_(prev_mark->ch, '`', '$') && (prev_mark->flags & MD_MARK_OPENER)); MD_ASSERT(ISANYOF2_(mark->ch, '`', '$') && (mark->flags & MD_MARK_CLOSER)); @@ -4341,13 +4459,12 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) MD_TEXT(text_type, STR(tmp), off-tmp); /* and new lines are transformed into single spaces. */ - if(prev_mark->end < off && off < mark->beg) + if(off == line->end) MD_TEXT(text_type, _T(" "), 1); } else if(text_type == MD_TEXT_HTML) { /* Inside raw HTML, we output the new line verbatim, including * any trailing spaces. */ - OFF tmp = off; - + tmp = off; while(tmp < end && ISBLANK(tmp)) tmp++; if(tmp > off) @@ -4358,7 +4475,9 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) MD_TEXTTYPE break_type = MD_TEXT_SOFTBR; if(text_type == MD_TEXT_NORMAL) { - if(enforce_hardbreak) + if(ctx->parser.flags & MD_FLAG_HARD_SOFT_BREAKS) + break_type = MD_TEXT_BR; + else if(enforce_hardbreak) break_type = MD_TEXT_BR; else if((CH(line->end) == _T(' ') && CH(line->end+1) == _T(' '))) break_type = MD_TEXT_BR; @@ -4410,7 +4529,7 @@ md_analyze_table_alignment(MD_CTX* ctx, OFF beg, OFF end, MD_ALIGN* align, int n } /* Forward declaration. */ -static int md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines); +static int md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines); static int md_process_table_cell(MD_CTX* ctx, MD_BLOCKTYPE cell_type, MD_ALIGN align, OFF beg, OFF end) @@ -4463,7 +4582,7 @@ md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end, } j = 0; pipe_offs[j++] = beg; - for(i = TABLECELLBOUNDARIES.head; i >= 0; i = ctx->marks[i].next) { + for(i = ctx->table_cell_boundaries_head; i >= 0; i = ctx->marks[i].next) { MD_MARK* mark = &ctx->marks[i]; pipe_offs[j++] = mark->end; } @@ -4485,20 +4604,17 @@ md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end, abort: free(pipe_offs); - /* Free any temporary memory blocks stored within some dummy marks. */ - for(i = PTR_CHAIN.head; i >= 0; i = ctx->marks[i].next) - free(md_mark_get_ptr(ctx, i)); - PTR_CHAIN.head = -1; - PTR_CHAIN.tail = -1; + ctx->table_cell_boundaries_head = -1; + ctx->table_cell_boundaries_tail = -1; return ret; } static int -md_process_table_block_contents(MD_CTX* ctx, int col_count, const MD_LINE* lines, int n_lines) +md_process_table_block_contents(MD_CTX* ctx, int col_count, const MD_LINE* lines, MD_SIZE n_lines) { MD_ALIGN* align; - int i; + MD_SIZE line_index; int ret = 0; /* At least two lines have to be present: The column headers and the line @@ -4519,12 +4635,14 @@ md_process_table_block_contents(MD_CTX* ctx, int col_count, const MD_LINE* lines lines[0].beg, lines[0].end, align, col_count)); MD_LEAVE_BLOCK(MD_BLOCK_THEAD, NULL); - MD_ENTER_BLOCK(MD_BLOCK_TBODY, NULL); - for(i = 2; i < n_lines; i++) { - MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TD, - lines[i].beg, lines[i].end, align, col_count)); + if(n_lines > 2) { + MD_ENTER_BLOCK(MD_BLOCK_TBODY, NULL); + for(line_index = 2; line_index < n_lines; line_index++) { + MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TD, + lines[line_index].beg, lines[line_index].end, align, col_count)); + } + MD_LEAVE_BLOCK(MD_BLOCK_TBODY, NULL); } - MD_LEAVE_BLOCK(MD_BLOCK_TBODY, NULL); abort: free(align); @@ -4557,7 +4675,7 @@ struct MD_BLOCK_tag { * MD_BLOCK_LI: Task mark offset in the input doc. * MD_BLOCK_OL: Start item number. */ - unsigned n_lines; + MD_SIZE n_lines; }; struct MD_CONTAINER_tag { @@ -4573,7 +4691,7 @@ struct MD_CONTAINER_tag { static int -md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines) +md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) { int i; int ret; @@ -4583,25 +4701,24 @@ md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines) abort: /* Free any temporary memory blocks stored within some dummy marks. */ - for(i = PTR_CHAIN.head; i >= 0; i = ctx->marks[i].next) + for(i = ctx->ptr_stack.top; i >= 0; i = ctx->marks[i].next) free(md_mark_get_ptr(ctx, i)); - PTR_CHAIN.head = -1; - PTR_CHAIN.tail = -1; + ctx->ptr_stack.top = -1; return ret; } static int -md_process_verbatim_block_contents(MD_CTX* ctx, MD_TEXTTYPE text_type, const MD_VERBATIMLINE* lines, int n_lines) +md_process_verbatim_block_contents(MD_CTX* ctx, MD_TEXTTYPE text_type, const MD_VERBATIMLINE* lines, MD_SIZE n_lines) { static const CHAR indent_chunk_str[] = _T(" "); static const SZ indent_chunk_size = SIZEOF_ARRAY(indent_chunk_str) - 1; - int i; + MD_SIZE line_index; int ret = 0; - for(i = 0; i < n_lines; i++) { - const MD_VERBATIMLINE* line = &lines[i]; + for(line_index = 0; line_index < n_lines; line_index++) { + const MD_VERBATIMLINE* line = &lines[line_index]; int indent = line->indent; MD_ASSERT(indent >= 0); @@ -4626,7 +4743,7 @@ abort: } static int -md_process_code_block_contents(MD_CTX* ctx, int is_fenced, const MD_VERBATIMLINE* lines, int n_lines) +md_process_code_block_contents(MD_CTX* ctx, int is_fenced, const MD_VERBATIMLINE* lines, MD_SIZE n_lines) { if(is_fenced) { /* Skip the first line in case of fenced code: It is the fence. @@ -4693,6 +4810,7 @@ md_process_leaf_block(MD_CTX* ctx, const MD_BLOCK* block) union { MD_BLOCK_H_DETAIL header; MD_BLOCK_CODE_DETAIL code; + MD_BLOCK_TABLE_DETAIL table; } det; MD_ATTRIBUTE_BUILD info_build; MD_ATTRIBUTE_BUILD lang_build; @@ -4721,6 +4839,12 @@ md_process_leaf_block(MD_CTX* ctx, const MD_BLOCK* block) } break; + case MD_BLOCK_TABLE: + det.table.col_count = block->data; + det.table.head_row_count = 1; + det.table.body_row_count = block->n_lines - 2; + break; + default: /* Noop. */ break; @@ -4874,7 +4998,7 @@ md_push_block_bytes(MD_CTX* ctx, int n_bytes) /* Fix the ->current_block after the reallocation. */ if(ctx->current_block != NULL) { - OFF off_current_block = (char*) ctx->current_block - (char*) ctx->block_bytes; + OFF off_current_block = (OFF) ((char*) ctx->current_block - (char*) ctx->block_bytes); ctx->current_block = (MD_BLOCK*) ((char*) new_block_bytes + off_current_block); } @@ -4946,8 +5070,8 @@ static int md_consume_link_reference_definitions(MD_CTX* ctx) { MD_LINE* lines = (MD_LINE*) (ctx->current_block + 1); - int n_lines = ctx->current_block->n_lines; - int n = 0; + MD_SIZE n_lines = ctx->current_block->n_lines; + MD_SIZE n = 0; /* Compute how many lines at the start of the block form one or more * reference definitions. */ @@ -5002,7 +5126,7 @@ md_end_current_block(MD_CTX* ctx) (ctx->current_block->type == MD_BLOCK_H && (ctx->current_block->flags & MD_BLOCK_SETEXT_HEADER))) { MD_LINE* lines = (MD_LINE*) (ctx->current_block + 1); - if(CH(lines[0].beg) == _T('[')) { + if(lines[0].beg < ctx->size && CH(lines[0].beg) == _T('[')) { MD_CHECK(md_consume_link_reference_definitions(ctx)); if(ctx->current_block == NULL) return ret; @@ -5010,7 +5134,7 @@ md_end_current_block(MD_CTX* ctx) } if(ctx->current_block->type == MD_BLOCK_H && (ctx->current_block->flags & MD_BLOCK_SETEXT_HEADER)) { - int n_lines = ctx->current_block->n_lines; + MD_SIZE n_lines = ctx->current_block->n_lines; if(n_lines > 1) { /* Get rid of the underline. */ @@ -5149,8 +5273,8 @@ md_is_setext_underline(MD_CTX* ctx, OFF beg, OFF* p_end, unsigned* p_level) while(off < ctx->size && CH(off) == CH(beg)) off++; - /* Optionally, space(s) can follow. */ - while(off < ctx->size && CH(off) == _T(' ')) + /* Optionally, space(s) or tabs can follow. */ + while(off < ctx->size && ISBLANK(off)) off++; /* But nothing more is allowed on the line. */ @@ -5177,21 +5301,23 @@ md_is_table_underline(MD_CTX* ctx, OFF beg, OFF* p_end, unsigned* p_col_count) } while(1) { - OFF cell_beg; int delimited = FALSE; /* Cell underline ("-----", ":----", "----:" or ":----:") */ - cell_beg = off; if(off < ctx->size && CH(off) == _T(':')) off++; + if(off >= ctx->size || CH(off) != _T('-')) + return FALSE; while(off < ctx->size && CH(off) == _T('-')) off++; if(off < ctx->size && CH(off) == _T(':')) off++; - if(off - cell_beg < 3) - return FALSE; col_count++; + if(col_count > TABLE_MAXCOLCOUNT) { + MD_LOG("Suppressing table (column_count >" STRINGIZE(TABLE_MAXCOLCOUNT) ")"); + return FALSE; + } /* Pipe delimiter (optional at the end of line). */ while(off < ctx->size && ISWHITESPACE(off)) @@ -5280,48 +5406,55 @@ out: return ret; } + +/* Helper data for md_is_html_block_start_condition() and + * md_is_html_block_end_condition() */ +typedef struct TAG_tag TAG; +struct TAG_tag { + const CHAR* name; + unsigned len : 8; +}; + +#ifdef X + #undef X +#endif +#define X(name) { _T(name), (sizeof(name)-1) / sizeof(CHAR) } +#define Xend { NULL, 0 } + +static const TAG t1[] = { X("pre"), X("script"), X("style"), X("textarea"), Xend }; + +static const TAG a6[] = { X("address"), X("article"), X("aside"), Xend }; +static const TAG b6[] = { X("base"), X("basefont"), X("blockquote"), X("body"), Xend }; +static const TAG c6[] = { X("caption"), X("center"), X("col"), X("colgroup"), Xend }; +static const TAG d6[] = { X("dd"), X("details"), X("dialog"), X("dir"), + X("div"), X("dl"), X("dt"), Xend }; +static const TAG f6[] = { X("fieldset"), X("figcaption"), X("figure"), X("footer"), + X("form"), X("frame"), X("frameset"), Xend }; +static const TAG h6[] = { X("h1"), X("h2"), X("h3"), X("h4"), X("h5"), X("h6"), + X("head"), X("header"), X("hr"), X("html"), Xend }; +static const TAG i6[] = { X("iframe"), Xend }; +static const TAG l6[] = { X("legend"), X("li"), X("link"), Xend }; +static const TAG m6[] = { X("main"), X("menu"), X("menuitem"), Xend }; +static const TAG n6[] = { X("nav"), X("noframes"), Xend }; +static const TAG o6[] = { X("ol"), X("optgroup"), X("option"), Xend }; +static const TAG p6[] = { X("p"), X("param"), Xend }; +static const TAG s6[] = { X("search"), X("section"), X("summary"), Xend }; +static const TAG t6[] = { X("table"), X("tbody"), X("td"), X("tfoot"), X("th"), + X("thead"), X("title"), X("tr"), X("track"), Xend }; +static const TAG u6[] = { X("ul"), Xend }; +static const TAG xx[] = { Xend }; + +#undef X +#undef Xend + /* Returns type of the raw HTML block, or FALSE if it is not HTML block. * (Refer to CommonMark specification for details about the types.) */ static int md_is_html_block_start_condition(MD_CTX* ctx, OFF beg) { - typedef struct TAG_tag TAG; - struct TAG_tag { - const CHAR* name; - unsigned len : 8; - }; - /* Type 6 is started by a long list of allowed tags. We use two-level * tree to speed-up the search. */ -#ifdef X - #undef X -#endif -#define X(name) { _T(name), (sizeof(name)-1) / sizeof(CHAR) } -#define Xend { NULL, 0 } - static const TAG t1[] = { X("script"), X("pre"), X("style"), Xend }; - - static const TAG a6[] = { X("address"), X("article"), X("aside"), Xend }; - static const TAG b6[] = { X("base"), X("basefont"), X("blockquote"), X("body"), Xend }; - static const TAG c6[] = { X("caption"), X("center"), X("col"), X("colgroup"), Xend }; - static const TAG d6[] = { X("dd"), X("details"), X("dialog"), X("dir"), - X("div"), X("dl"), X("dt"), Xend }; - static const TAG f6[] = { X("fieldset"), X("figcaption"), X("figure"), X("footer"), - X("form"), X("frame"), X("frameset"), Xend }; - static const TAG h6[] = { X("h1"), X("head"), X("header"), X("hr"), X("html"), Xend }; - static const TAG i6[] = { X("iframe"), Xend }; - static const TAG l6[] = { X("legend"), X("li"), X("link"), Xend }; - static const TAG m6[] = { X("main"), X("menu"), X("menuitem"), Xend }; - static const TAG n6[] = { X("nav"), X("noframes"), Xend }; - static const TAG o6[] = { X("ol"), X("optgroup"), X("option"), Xend }; - static const TAG p6[] = { X("p"), X("param"), Xend }; - static const TAG s6[] = { X("section"), X("source"), X("summary"), Xend }; - static const TAG t6[] = { X("table"), X("tbody"), X("td"), X("tfoot"), X("th"), - X("thead"), X("title"), X("tr"), X("track"), Xend }; - static const TAG u6[] = { X("ul"), Xend }; - static const TAG xx[] = { Xend }; -#undef X - static const TAG* map6[26] = { a6, b6, c6, d6, xx, f6, xx, h6, i6, xx, xx, l6, m6, n6, o6, p6, xx, xx, s6, t6, u6, xx, xx, xx, xx, xx @@ -5348,7 +5481,7 @@ md_is_html_block_start_condition(MD_CTX* ctx, OFF beg) /* Check for type 4 or 5: size && CH(off) == _T('!')) { /* Check for type 4: size && ISUPPER(off+1)) + if(off + 1 < ctx->size && ISASCII(off+1)) return 4; /* Check for type 5: size && !ISNEWLINE(off)) { - if(CH(off) == _T('<')) { - if(md_ascii_case_eq(STR(off), _T(""), 9)) { - *p_end = off + 9; - return TRUE; - } - - if(md_ascii_case_eq(STR(off), _T(""), 8)) { - *p_end = off + 8; - return TRUE; - } - - if(md_ascii_case_eq(STR(off), _T(""), 6)) { - *p_end = off + 6; - return TRUE; + while(off+1 < ctx->size && !ISNEWLINE(off)) { + if(CH(off) == _T('<') && CH(off+1) == _T('/')) { + for(i = 0; t1[i].name != NULL; i++) { + if(off + 2 + t1[i].len < ctx->size) { + if(md_ascii_case_eq(STR(off+2), t1[i].name, t1[i].len) && + CH(off+2+t1[i].len) == _T('>')) + { + *p_end = off+2+t1[i].len+1; + return TRUE; + } + } } } - off++; } *p_end = off; @@ -5471,8 +5600,12 @@ md_is_html_block_end_condition(MD_CTX* ctx, OFF beg, OFF* p_end) case 6: /* Pass through */ case 7: - *p_end = beg; - return (ISNEWLINE(beg) ? ctx->html_block_type : FALSE); + if(beg >= ctx->size || ISNEWLINE(beg)) { + /* Blank line ends types 6 and 7. */ + *p_end = beg; + return ctx->html_block_type; + } + return FALSE; default: MD_UNREACHABLE(); @@ -5532,7 +5665,7 @@ md_enter_child_containers(MD_CTX* ctx, int n_children) case _T(')'): case _T('.'): is_ordered_list = TRUE; - /* Pass through */ + MD_FALLTHROUGH(); case _T('-'): case _T('+'): @@ -5578,7 +5711,7 @@ md_leave_child_containers(MD_CTX* ctx, int n_keep) case _T(')'): case _T('.'): is_ordered_list = TRUE; - /* Pass through */ + MD_FALLTHROUGH(); case _T('-'): case _T('+'): @@ -5614,11 +5747,11 @@ md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTA OFF off = beg; OFF max_end; - if(indent >= ctx->code_indent_offset) + if(off >= ctx->size || indent >= ctx->code_indent_offset) return FALSE; /* Check for block quote mark. */ - if(off < ctx->size && CH(off) == _T('>')) { + if(CH(off) == _T('>')) { off++; p_container->ch = _T('>'); p_container->is_loose = FALSE; @@ -5630,13 +5763,13 @@ md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTA } /* Check for list item bullet mark. */ - if(off+1 < ctx->size && ISANYOF(off, _T("-+*")) && (ISBLANK(off+1) || ISNEWLINE(off+1))) { + if(ISANYOF(off, _T("-+*")) && (off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1))) { p_container->ch = CH(off); p_container->is_loose = FALSE; p_container->is_task = FALSE; p_container->mark_indent = indent; p_container->contents_indent = indent + 1; - *p_end = off + 1; + *p_end = off+1; return TRUE; } @@ -5649,16 +5782,17 @@ md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTA p_container->start = p_container->start * 10 + CH(off) - _T('0'); off++; } - if(off > beg && off+1 < ctx->size && + if(off > beg && + off < ctx->size && (CH(off) == _T('.') || CH(off) == _T(')')) && - (ISBLANK(off+1) || ISNEWLINE(off+1))) + (off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1))) { p_container->ch = CH(off); p_container->is_loose = FALSE; p_container->is_task = FALSE; p_container->mark_indent = indent; p_container->contents_indent = indent + off - beg + 1; - *p_end = off + 1; + *p_end = off+1; return TRUE; } @@ -5683,7 +5817,7 @@ md_line_indentation(MD_CTX* ctx, unsigned total_indent, OFF beg, OFF* p_end) return indent - total_indent; } -static const MD_LINE_ANALYSIS md_dummy_blank_line = { MD_LINE_BLANK, 0 }; +static const MD_LINE_ANALYSIS md_dummy_blank_line = { MD_LINE_BLANK, 0, 0, 0, 0, 0 }; /* Analyze type of the line and find some its properties. This serves as a * main input for determining type and boundaries of a block. */ @@ -5704,6 +5838,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, line->indent = md_line_indentation(ctx, total_indent, off, &off); total_indent += line->indent; line->beg = off; + line->enforce_new_block = FALSE; /* Given the indentation and block quote marks '>', determine how many of * the current containers are our parents. */ @@ -5819,12 +5954,14 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, #if 1 /* See https://github.com/mity/md4c/issues/6 * - * This ugly checking tests we are in (yet empty) list item but not - * its very first line (with the list item mark). + * This ugly checking tests we are in (yet empty) list item but + * not its very first line (i.e. not the line with the list + * item mark). * - * If we are such blank line, then any following non-blank line - * which would be part of this list item actually ends the list - * because "a list item can begin with at most one blank line." + * If we are such a blank line, then any following non-blank + * line which would be part of the list item actually has to + * end the list because according to the specification, "a list + * item can begin with at most one blank line." */ if(n_parents > 0 && ctx->containers[n_parents-1].ch != _T('>') && n_brothers + n_children == 0 && ctx->current_block == NULL && @@ -5839,23 +5976,30 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, break; } else { #if 1 - /* This is 2nd half of the hack. If the flag is set (that is there - * were 2nd blank line at the start of the list item) and we would also - * belonging to such list item, than interrupt the list. */ - ctx->last_line_has_list_loosening_effect = FALSE; + /* This is the 2nd half of the hack. If the flag is set (i.e. there + * was a 2nd blank line at the beginning of the list item) and if + * we would otherwise still belong to the list item, we enforce + * the end of the list. */ if(ctx->last_list_item_starts_with_two_blank_lines) { - if(n_parents > 0 && ctx->containers[n_parents-1].ch != _T('>') && + if(n_parents > 0 && n_parents == ctx->n_containers && + ctx->containers[n_parents-1].ch != _T('>') && n_brothers + n_children == 0 && ctx->current_block == NULL && ctx->n_block_bytes > (int) sizeof(MD_BLOCK)) { MD_BLOCK* top_block = (MD_BLOCK*) ((char*)ctx->block_bytes + ctx->n_block_bytes - sizeof(MD_BLOCK)); - if(top_block->type == MD_BLOCK_LI) + if(top_block->type == MD_BLOCK_LI) { n_parents--; + + line->indent = total_indent; + if(n_parents > 0) + line->indent -= MIN(line->indent, ctx->containers[n_parents-1].contents_indent); + } } ctx->last_list_item_starts_with_two_blank_lines = FALSE; } #endif + ctx->last_line_has_list_loosening_effect = FALSE; } /* Check whether we are Setext underline. */ @@ -5921,11 +6065,8 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, /* Check for indented code. * Note indented code block cannot interrupt a paragraph. */ - if(line->indent >= ctx->code_indent_offset && - (pivot_line->type == MD_LINE_BLANK || pivot_line->type == MD_LINE_INDENTEDCODE)) - { + if(line->indent >= ctx->code_indent_offset && (pivot_line->type != MD_LINE_TEXT)) { line->type = MD_LINE_INDENTEDCODE; - MD_ASSERT(line->indent >= ctx->code_indent_offset); line->indent -= ctx->code_indent_offset; line->data = 0; break; @@ -5994,10 +6135,13 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, } /* Check whether we are starting code fence. */ - if(off < ctx->size && ISANYOF2(off, _T('`'), _T('~'))) { + if(line->indent < ctx->code_indent_offset && + off < ctx->size && ISANYOF2(off, _T('`'), _T('~'))) + { if(md_is_opening_code_fence(ctx, off, &off)) { line->type = MD_LINE_FENCEDCODE; line->data = 1; + line->enforce_new_block = TRUE; break; } } @@ -6019,6 +6163,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, ctx->html_block_type = 0; } + line->enforce_new_block = TRUE; line->type = MD_LINE_HTML; break; } @@ -6063,7 +6208,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, task_container->is_task = TRUE; task_container->task_mark_off = tmp + 1; off = tmp + 3; - while(ISWHITESPACE(off)) + while(off < ctx->size && ISWHITESPACE(off)) off++; line->beg = off; } @@ -6117,7 +6262,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, } /* Trim trailing spaces. */ - if(line->type != MD_LINE_INDENTEDCODE && line->type != MD_LINE_FENCEDCODE) { + if(line->type != MD_LINE_INDENTEDCODE && line->type != MD_LINE_FENCEDCODE && line->type != MD_LINE_HTML) { while(line->end > line->beg && CH(line->end-1) == _T(' ')) line->end--; } @@ -6178,6 +6323,9 @@ md_process_line(MD_CTX* ctx, const MD_LINE_ANALYSIS** p_pivot_line, MD_LINE_ANAL return 0; } + if(line->enforce_new_block) + MD_CHECK(md_end_current_block(ctx)); + /* Some line types form block on their own. */ if(line->type == MD_LINE_HR || line->type == MD_LINE_ATXHEADER) { MD_CHECK(md_end_current_block(ctx)); @@ -6322,13 +6470,14 @@ md_parse(const MD_CHAR* text, MD_SIZE size, const MD_PARSER* parser, void* userd md_build_mark_char_map(&ctx); ctx.doc_ends_with_newline = (size > 0 && ISNEWLINE_(text[size-1])); - /* Reset all unresolved opener mark chains. */ - for(i = 0; i < (int) SIZEOF_ARRAY(ctx.mark_chains); i++) { - ctx.mark_chains[i].head = -1; - ctx.mark_chains[i].tail = -1; - } + /* Reset all mark stacks and lists. */ + for(i = 0; i < (int) SIZEOF_ARRAY(ctx.opener_stacks); i++) + ctx.opener_stacks[i].top = -1; + ctx.ptr_stack.top = -1; ctx.unresolved_link_head = -1; ctx.unresolved_link_tail = -1; + ctx.table_cell_boundaries_head = -1; + ctx.table_cell_boundaries_tail = -1; /* All the work. */ ret = md_process_doc(&ctx); diff --git a/src/3rdparty/md4c/md4c.h b/src/3rdparty/md4c/md4c.h index 8bba71242de..8d6be1cb463 100644 --- a/src/3rdparty/md4c/md4c.h +++ b/src/3rdparty/md4c/md4c.h @@ -2,7 +2,7 @@ * MD4C: Markdown parser for C * (http://github.com/mity/md4c) * - * Copyright (c) 2016-2020 Martin Mitas + * Copyright (c) 2016-2024 Martin Mitáš * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -91,7 +91,8 @@ typedef enum MD_BLOCKTYPE { MD_BLOCK_P, /* ...
    and its contents. - * Detail: Structure MD_BLOCK_TD_DETAIL (used with MD_BLOCK_TH and MD_BLOCK_TD) + * Detail: Structure MD_BLOCK_TABLE_DETAIL (for MD_BLOCK_TABLE), + * structure MD_BLOCK_TD_DETAIL (for MD_BLOCK_TH and MD_BLOCK_TD) * Note all of these are used only if extension MD_FLAG_TABLES is enabled. */ MD_BLOCK_TABLE, MD_BLOCK_THEAD, @@ -267,6 +268,13 @@ typedef struct MD_BLOCK_CODE_DETAIL { MD_CHAR fence_char; /* The character used for fenced code block; or zero for indented code block. */ } MD_BLOCK_CODE_DETAIL; +/* Detailed info for MD_BLOCK_TABLE. */ +typedef struct MD_BLOCK_TABLE_DETAIL { + unsigned col_count; /* Count of columns in the table. */ + unsigned head_row_count; /* Count of rows in the table header (currently always 1) */ + unsigned body_row_count; /* Count of rows in the table body */ +} MD_BLOCK_TABLE_DETAIL; + /* Detailed info for MD_BLOCK_TH and MD_BLOCK_TD. */ typedef struct MD_BLOCK_TD_DETAIL { MD_ALIGN align; @@ -276,6 +284,7 @@ typedef struct MD_BLOCK_TD_DETAIL { typedef struct MD_SPAN_A_DETAIL { MD_ATTRIBUTE href; MD_ATTRIBUTE title; + int is_autolink; /* nonzero if this is an autolink */ } MD_SPAN_A_DETAIL; /* Detailed info for MD_SPAN_IMG. */ @@ -308,6 +317,7 @@ typedef struct MD_SPAN_WIKILINK { #define MD_FLAG_LATEXMATHSPANS 0x1000 /* Enable $ and $$ containing LaTeX equations. */ #define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */ #define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */ +#define MD_FLAG_HARD_SOFT_BREAKS 0x8000 /* Force all soft breaks to act as hard breaks. */ #define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS) #define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS) diff --git a/src/3rdparty/md4c/qt_attribution.json b/src/3rdparty/md4c/qt_attribution.json index 29c0666f2d8..3a855eae8c4 100644 --- a/src/3rdparty/md4c/qt_attribution.json +++ b/src/3rdparty/md4c/qt_attribution.json @@ -9,7 +9,7 @@ "License": "MIT License", "LicenseId": "MIT", "LicenseFile": "LICENSE.md", - "Version": "0.4.8", - "DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.4.8", - "Copyright": "Copyright © 2016-2020 Martin Mitáš" + "Version": "0.5.2", + "DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.5.2", + "Copyright": "Copyright © 2016-2024 Martin Mitáš" } From abc097a32e13fe8b0a5b2f08430cc580a24f3b06 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 23 Jan 2024 23:55:46 -0700 Subject: [PATCH 56/58] Avoid detection of heading in tst_QTextMarkdownImporter::thematicBreaks In md4c 0.4.8, three or more hyphens immediately after text were seen as a thematic break: some text --- But in 0.5.1 it makes the text into an H2 heading (even though this style of heading would normally have the text fully "underlined" with hyphens). The CommonMark spec 0.30 says If a line of dashes that meets the above conditions for being a thematic break could also be interpreted as the underline of a setext heading, the interpretation as a setext heading takes precedence. Thus, for example, this is a setext heading, not a paragraph followed by a thematic break: https://spec.commonmark.org/0.30/#example-59 So the new behavior seems more correct. But rather than testing so deeply, just disambiguate by adding a newline, since Qt may be expected to work with various versions of md4c, and such minor behavior differences are not expected to come up often in practice. QTextMarkdownWriter already adds a newline when writing such markdown. Pick-to: 6.2 6.5 6.6 6.6.2 6.7 Change-Id: I5a4bf8720d994616274eb8534b4d7085399130fc Reviewed-by: Axel Spoerl (cherry picked from commit 3bd4c1b670b8b973e8a782bcaec7078027f6ea36) --- tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md b/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md index 7a0d5388adf..e784879326f 100644 --- a/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md +++ b/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md @@ -11,6 +11,7 @@ stars stars with tabs between *** stars with whitespace after + --- hyphens with whitespace after _____ From 6b36951d45b60fea26cfd7e54d1f8ac149d5236a Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Mon, 15 Apr 2024 18:55:19 +0200 Subject: [PATCH 57/58] SQLite: Update SQLite to v3.45.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ChangeLog][Third-Party Code] Updated SQLite to v3.45.3 Change-Id: I8a58699f10cada8b33d47c3032861fa6ef1b6cc9 Reviewed-by: Kai Köhne (cherry picked from commit b6624877c61e8eef45956d62ee9229dc52ffa89a) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 74563f95ae4377bce9563b1c4ddb3c7b38c69f9a) (cherry picked from commit 7c6e3c297d7f2a062d380cc2902973b1675bdb99) (cherry picked from commit e5b126aff0fb53c1c8f247f372752c7c8cf1c971) --- src/3rdparty/sqlite/qt_attribution.json | 4 +- src/3rdparty/sqlite/sqlite3.c | 205 +++++++++++++++++++----- src/3rdparty/sqlite/sqlite3.h | 23 ++- 3 files changed, 185 insertions(+), 47 deletions(-) diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json index 8ba77342047..9a4907d2cbb 100644 --- a/src/3rdparty/sqlite/qt_attribution.json +++ b/src/3rdparty/sqlite/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Homepage": "https://www.sqlite.org/", - "Version": "3.45.2", - "DownloadLocation": "https://www.sqlite.org/2024/sqlite-amalgamation-3450200.zip", + "Version": "3.45.3", + "DownloadLocation": "https://www.sqlite.org/2024/sqlite-amalgamation-3450300.zip", "License": "Public Domain", "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." } diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 55ca309401b..08c593e55c7 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.45.2. By combining all the individual C code files into this +** version 3.45.3. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** d8cd6d49b46a395b13955387d05e9e1a2a47. +** 8653b758870e6ef0c98d46b3ace27849054a. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -459,9 +459,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.45.2" -#define SQLITE_VERSION_NUMBER 3045002 -#define SQLITE_SOURCE_ID "2024-03-12 11:06:23 d8cd6d49b46a395b13955387d05e9e1a2a47e54fb99f3c9b59835bbefad6af77" +#define SQLITE_VERSION "3.45.3" +#define SQLITE_VERSION_NUMBER 3045003 +#define SQLITE_SOURCE_ID "2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -2456,6 +2456,22 @@ struct sqlite3_mem_methods { ** configuration setting is never used, then the default maximum is determined ** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that ** compile-time option is not set, then the default maximum is 1073741824. +** +** [[SQLITE_CONFIG_ROWID_IN_VIEW]] +**
    SQLITE_CONFIG_ROWID_IN_VIEW +**
    The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability +** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is +** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability +** defaults to on. This configuration option queries the current setting or +** changes the setting to off or on. The argument is a pointer to an integer. +** If that integer initially holds a value of 1, then the ability for VIEWs to +** have ROWIDs is activated. If the integer initially holds zero, then the +** ability is deactivated. Any other initial value for the integer leaves the +** setting unchanged. After changes, if any, the integer is written with +** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite +** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and +** recommended case) then the integer is always filled with zero, regardless +** if its initial value. ** */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -2487,6 +2503,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ #define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ #define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ +#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */ /* ** CAPI3REF: Database Connection Configuration Options @@ -18430,6 +18447,15 @@ struct Table { #define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0) #define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0) +/* Macro is true if the SQLITE_ALLOW_ROWID_IN_VIEW (mis-)feature is +** available. By default, this macro is false +*/ +#ifndef SQLITE_ALLOW_ROWID_IN_VIEW +# define ViewCanHaveRowid 0 +#else +# define ViewCanHaveRowid (sqlite3Config.mNoVisibleRowid==0) +#endif + /* ** Each foreign key constraint is an instance of the following structure. ** @@ -20144,6 +20170,11 @@ struct Sqlite3Config { #endif #ifndef SQLITE_UNTESTABLE int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ +#endif +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + u32 mNoVisibleRowid; /* TF_NoVisibleRowid if the ROWID_IN_VIEW + ** feature is disabled. 0 if rowids can + ** occur in views. */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */ @@ -20600,10 +20631,13 @@ SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*); # define EXP754 (((u64)0x7ff)<<52) # define MAN754 ((((u64)1)<<52)-1) # define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0) +# define IsOvfl(X) (((X)&EXP754)==EXP754) SQLITE_PRIVATE int sqlite3IsNaN(double); +SQLITE_PRIVATE int sqlite3IsOverflow(double); #else -# define IsNaN(X) 0 -# define sqlite3IsNaN(X) 0 +# define IsNaN(X) 0 +# define sqlite3IsNaN(X) 0 +# define sqlite3IsOVerflow(X) 0 #endif /* @@ -21839,6 +21873,9 @@ static const char * const sqlite3azCompileOpt[] = { "ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN), # endif #endif +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + "ALLOW_ROWID_IN_VIEW", +#endif #ifdef SQLITE_ALLOW_URI_AUTHORITY "ALLOW_URI_AUTHORITY", #endif @@ -22858,6 +22895,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { #endif #ifndef SQLITE_UNTESTABLE 0, /* xTestCallback */ +#endif +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + 0, /* mNoVisibleRowid. 0 == allow rowid-in-view */ #endif 0, /* bLocaltimeFault */ 0, /* xAltLocaltime */ @@ -34646,6 +34686,19 @@ SQLITE_PRIVATE int sqlite3IsNaN(double x){ } #endif /* SQLITE_OMIT_FLOATING_POINT */ +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Return true if the floating point value is NaN or +Inf or -Inf. +*/ +SQLITE_PRIVATE int sqlite3IsOverflow(double x){ + int rc; /* The value return */ + u64 y; + memcpy(&y,&x,sizeof(y)); + rc = IsOvfl(y); + return rc; +} +#endif /* SQLITE_OMIT_FLOATING_POINT */ + /* ** Compute a string length that is limited to what can be stored in ** lower 30 bits of a 32-bit signed integer. @@ -63802,7 +63855,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){ ** This will be either the rollback journal or the WAL file. */ SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){ -#if SQLITE_OMIT_WAL +#ifdef SQLITE_OMIT_WAL return pPager->jfd; #else return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd; @@ -79619,7 +79672,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( }else if( loc<0 && pPage->nCell>0 ){ assert( pPage->leaf ); idx = ++pCur->ix; - pCur->curFlags &= ~BTCF_ValidNKey; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); }else{ assert( pPage->leaf ); } @@ -79649,7 +79702,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( */ if( pPage->nOverflow ){ assert( rc==SQLITE_OK ); - pCur->curFlags &= ~(BTCF_ValidNKey); + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); rc = balance(pCur); /* Must make sure nOverflow is reset to zero even if the balance() @@ -106656,8 +106709,37 @@ static int lookupName( } } if( 0==cnt && VisibleRowid(pTab) ){ + /* pTab is a potential ROWID match. Keep track of it and match + ** the ROWID later if that seems appropriate. (Search for "cntTab" + ** to find related code.) Only allow a ROWID match if there is + ** a single ROWID match candidate. + */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + /* In SQLITE_ALLOW_ROWID_IN_VIEW mode, allow a ROWID match + ** if there is a single VIEW candidate or if there is a single + ** non-VIEW candidate plus multiple VIEW candidates. In other + ** words non-VIEW candidate terms take precedence over VIEWs. + */ + if( cntTab==0 + || (cntTab==1 + && ALWAYS(pMatch!=0) + && ALWAYS(pMatch->pTab!=0) + && (pMatch->pTab->tabFlags & TF_Ephemeral)!=0 + && (pTab->tabFlags & TF_Ephemeral)==0) + ){ + cntTab = 1; + pMatch = pItem; + }else{ + cntTab++; + } +#else + /* The (much more common) non-SQLITE_ALLOW_ROWID_IN_VIEW case is + ** simpler since we require exactly one candidate, which will + ** always be a non-VIEW + */ cntTab++; pMatch = pItem; +#endif } } if( pMatch ){ @@ -106783,13 +106865,13 @@ static int lookupName( ** Perhaps the name is a reference to the ROWID */ if( cnt==0 - && cntTab==1 + && cntTab>=1 && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) ){ - cnt = 1; + cnt = cntTab; if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; pExpr->affExpr = SQLITE_AFF_INTEGER; } @@ -108647,9 +108729,10 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){ assert( pExpr->x.pList->nExpr>0 ); assert( pExpr->op==TK_FUNCTION ); pExpr = pExpr->x.pList->a[0].pExpr; - }else{ - assert( pExpr->op==TK_COLLATE ); + }else if( pExpr->op==TK_COLLATE ){ pExpr = pExpr->pLeft; + }else{ + break; } } return pExpr; @@ -111168,9 +111251,12 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ return 0; case TK_COLUMN: assert( ExprUseYTab(p) ); - return ExprHasProperty(p, EP_CanBeNull) || - NEVER(p->y.pTab==0) || /* Reference to column of index on expr */ - (p->iColumn>=0 + return ExprHasProperty(p, EP_CanBeNull) + || NEVER(p->y.pTab==0) /* Reference to column of index on expr */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + || (p->iColumn==XN_ROWID && IsView(p->y.pTab)) +#endif + || (p->iColumn>=0 && p->y.pTab->aCol!=0 /* Possible due to prior error */ && ALWAYS(p->iColumny.pTab->nCol) && p->y.pTab->aCol[p->iColumn].notNull==0); @@ -123661,9 +123747,12 @@ SQLITE_PRIVATE void sqlite3CreateView( ** on a view, even though views do not have rowids. The following flag ** setting fixes this problem. But the fix can be disabled by compiling ** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that - ** depend upon the old buggy behavior. */ -#ifndef SQLITE_ALLOW_ROWID_IN_VIEW - p->tabFlags |= TF_NoVisibleRowid; + ** depend upon the old buggy behavior. The ability can also be toggled + ** using sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW,...) */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + p->tabFlags |= sqlite3Config.mNoVisibleRowid; /* Optional. Allow by default */ +#else + p->tabFlags |= TF_NoVisibleRowid; /* Never allow rowid in view */ #endif sqlite3TwoPartName(pParse, pName1, pName2, &pName); @@ -129827,7 +129916,7 @@ static void sumFinalize(sqlite3_context *context){ if( p->approx ){ if( p->ovrfl ){ sqlite3_result_error(context,"integer overflow",-1); - }else if( !sqlite3IsNaN(p->rErr) ){ + }else if( !sqlite3IsOverflow(p->rErr) ){ sqlite3_result_double(context, p->rSum+p->rErr); }else{ sqlite3_result_double(context, p->rSum); @@ -129844,7 +129933,7 @@ static void avgFinalize(sqlite3_context *context){ double r; if( p->approx ){ r = p->rSum; - if( !sqlite3IsNaN(p->rErr) ) r += p->rErr; + if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr; }else{ r = (double)(p->iSum); } @@ -129858,7 +129947,7 @@ static void totalFinalize(sqlite3_context *context){ if( p ){ if( p->approx ){ r = p->rSum; - if( !sqlite3IsNaN(p->rErr) ) r += p->rErr; + if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr; }else{ r = (double)(p->iSum); } @@ -135156,7 +135245,10 @@ static int xferOptimization( } } #ifndef SQLITE_OMIT_CHECK - if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ + if( pDest->pCheck + && (db->mDbFlags & DBFLAG_Vacuum)==0 + && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) + ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } #endif @@ -140557,7 +140649,11 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ j = seen[0]-1; pIdxInfo->aConstraintUsage[j].argvIndex = 1; pIdxInfo->aConstraintUsage[j].omit = 1; - if( seen[1]==0 ) return SQLITE_OK; + if( seen[1]==0 ){ + pIdxInfo->estimatedCost = (double)1000; + pIdxInfo->estimatedRows = 1000; + return SQLITE_OK; + } pIdxInfo->estimatedCost = (double)20; pIdxInfo->estimatedRows = 20; j = seen[1]-1; @@ -143784,11 +143880,7 @@ static const char *columnTypeImpl( ** data for the result-set column of the sub-select. */ if( iColpEList->nExpr -#ifdef SQLITE_ALLOW_ROWID_IN_VIEW - && iCol>=0 -#else - && ALWAYS(iCol>=0) -#endif + && (!ViewCanHaveRowid || iCol>=0) ){ /* If iCol is less than zero, then the expression requests the ** rowid of the sub-select or view. This expression is legal (see @@ -146963,6 +147055,10 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ ** ** (11) The subquery is not a VALUES clause ** +** (12) The WHERE clause is not "rowid ISNULL" or the equivalent. This +** case only comes up if SQLite is compiled using +** SQLITE_ALLOW_ROWID_IN_VIEW. +** ** Return 0 if no changes are made and non-zero if one or more WHERE clause ** terms are duplicated into the subquery. */ @@ -147073,6 +147169,18 @@ static int pushDownWhereTerms( } #endif +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( ViewCanHaveRowid && (pWhere->op==TK_ISNULL || pWhere->op==TK_NOTNULL) ){ + Expr *pLeft = pWhere->pLeft; + if( ALWAYS(pLeft) + && pLeft->op==TK_COLUMN + && pLeft->iColumn < 0 + ){ + return 0; /* Restriction (12) */ + } + } +#endif + if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){ nChng++; pSubq->selFlags |= SF_PushDown; @@ -147700,12 +147808,14 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ while( pSel->pPrior ){ pSel = pSel->pPrior; } sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); pTab->iPKey = -1; + pTab->eTabType = TABTYP_VIEW; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); #ifndef SQLITE_ALLOW_ROWID_IN_VIEW /* The usual case - do not allow ROWID on a subquery */ pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; #else - pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */ + /* Legacy compatibility mode */ + pTab->tabFlags |= TF_Ephemeral | sqlite3Config.mNoVisibleRowid; #endif return pParse->nErr ? SQLITE_ERROR : SQLITE_OK; } @@ -147973,7 +148083,7 @@ static int selectExpander(Walker *pWalker, Select *p){ pNestedFrom = pFrom->pSelect->pEList; assert( pNestedFrom!=0 ); assert( pNestedFrom->nExpr==pTab->nCol ); - assert( VisibleRowid(pTab)==0 ); + assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid ); }else{ if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ continue; @@ -148005,7 +148115,8 @@ static int selectExpander(Walker *pWalker, Select *p){ pUsing = 0; } - nAdd = pTab->nCol + (VisibleRowid(pTab) && (selFlags&SF_NestedFrom)); + nAdd = pTab->nCol; + if( VisibleRowid(pTab) && (selFlags & SF_NestedFrom)!=0 ) nAdd++; for(j=0; ja[pNew->nExpr-1]; assert( pX->zEName==0 ); if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ - if( pNestedFrom ){ + if( pNestedFrom && (!ViewCanHaveRowid || jnExpr) ){ + assert( jnExpr ); pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName); testcase( pX->zEName==0 ); }else{ @@ -153021,6 +153133,9 @@ SQLITE_PRIVATE void sqlite3Update( } } if( chngRowid==0 && pPk==0 ){ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( isView ) sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid); +#endif sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid); } } @@ -166730,16 +166845,10 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( for(i=0; inColumn; i++){ Expr *pExpr; int j = pIdx->aiColumn[i]; - int bMaybeNullRow; if( j==XN_EXPR ){ pExpr = pIdx->aColExpr->a[i].pExpr; - testcase( pTabItem->fg.jointype & JT_LEFT ); - testcase( pTabItem->fg.jointype & JT_RIGHT ); - testcase( pTabItem->fg.jointype & JT_LTORJ ); - bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0; }else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){ pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]); - bMaybeNullRow = 0; }else{ continue; } @@ -166771,7 +166880,7 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( p->iDataCur = pTabItem->iCursor; p->iIdxCur = iIdxCur; p->iIdxCol = i; - p->bMaybeNullRow = bMaybeNullRow; + p->bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0; if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){ p->aff = pIdx->zColAff[i]; } @@ -178976,6 +179085,18 @@ SQLITE_API int sqlite3_config(int op, ...){ } #endif /* SQLITE_OMIT_DESERIALIZE */ + case SQLITE_CONFIG_ROWID_IN_VIEW: { + int *pVal = va_arg(ap,int*); +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( 0==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = TF_NoVisibleRowid; + if( 1==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = 0; + *pVal = (sqlite3GlobalConfig.mNoVisibleRowid==0); +#else + *pVal = 0; +#endif + break; + } + default: { rc = SQLITE_ERROR; break; @@ -250678,7 +250799,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2024-03-12 11:06:23 d8cd6d49b46a395b13955387d05e9e1a2a47e54fb99f3c9b59835bbefad6af77", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355", -1, SQLITE_TRANSIENT); } /* diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index c9fc77fb860..2618b37a7b8 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.45.2" -#define SQLITE_VERSION_NUMBER 3045002 -#define SQLITE_SOURCE_ID "2024-03-12 11:06:23 d8cd6d49b46a395b13955387d05e9e1a2a47e54fb99f3c9b59835bbefad6af77" +#define SQLITE_VERSION "3.45.3" +#define SQLITE_VERSION_NUMBER 3045003 +#define SQLITE_SOURCE_ID "2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -2143,6 +2143,22 @@ struct sqlite3_mem_methods { ** configuration setting is never used, then the default maximum is determined ** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that ** compile-time option is not set, then the default maximum is 1073741824. +** +** [[SQLITE_CONFIG_ROWID_IN_VIEW]] +**
    SQLITE_CONFIG_ROWID_IN_VIEW +**
    The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability +** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is +** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability +** defaults to on. This configuration option queries the current setting or +** changes the setting to off or on. The argument is a pointer to an integer. +** If that integer initially holds a value of 1, then the ability for VIEWs to +** have ROWIDs is activated. If the integer initially holds zero, then the +** ability is deactivated. Any other initial value for the integer leaves the +** setting unchanged. After changes, if any, the integer is written with +** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite +** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and +** recommended case) then the integer is always filled with zero, regardless +** if its initial value. ** */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -2174,6 +2190,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ #define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ #define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ +#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */ /* ** CAPI3REF: Database Connection Configuration Options From 8a25db3204f39a228d14148d9cdf414393d239a5 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 25 Apr 2024 11:17:54 +0200 Subject: [PATCH 58/58] Update Harfbuzz to 8.4.0 Fixes: QTBUG-124757 Change-Id: I1fa9259c2f7cb45b4dcec8956c2186735c89fb95 Reviewed-by: Volker Hilsheimer (cherry picked from commit 9ecb468aec3ec0d649587007786475d9a9974a30) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 843b9921f3c0cbc37a770d32f3a9c651396d1237) (cherry picked from commit d3a3ec9d481b49839adce9b9fc68b2ff0af273ea) Reviewed-by: Eskil Abrahamsen Blomfeldt (cherry picked from commit f4f89727f54c90e9d8e37c3aaa2f193681c30855) (cherry picked from commit 54a91adeab7411e5b7e32c040acbe0cda58c98de) --- src/3rdparty/harfbuzz-ng/README.md | 8 +- src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro | 2 + src/3rdparty/harfbuzz-ng/qt_attribution.json | 2 +- .../harfbuzz-ng/src/OT/Color/COLR/COLR.hh | 96 ++-- .../harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh | 68 ++- .../src/OT/Layout/GPOS/PairPosFormat2.hh | 13 +- .../src/OT/Layout/GPOS/ValueFormat.hh | 2 +- .../harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh | 3 +- src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh | 3 + .../harfbuzz-ng/src/OT/glyf/glyf-helpers.hh | 2 +- .../harfbuzz-ng/src/graph/classdef-graph.hh | 80 ++- src/3rdparty/harfbuzz-ng/src/graph/graph.hh | 96 +++- .../harfbuzz-ng/src/graph/pairpos-graph.hh | 10 +- .../src/graph/test-classdef-graph.cc | 227 +++++++- .../harfbuzz-ng/src/harfbuzz-subset.cc | 1 + .../src/hb-aat-layout-morx-table.hh | 1 + src/3rdparty/harfbuzz-ng/src/hb-algs.hh | 14 +- .../harfbuzz-ng/src/hb-bit-set-invertible.hh | 6 +- src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh | 6 +- src/3rdparty/harfbuzz-ng/src/hb-blob.cc | 21 +- .../harfbuzz-ng/src/hb-buffer-verify.cc | 4 +- src/3rdparty/harfbuzz-ng/src/hb-buffer.cc | 44 ++ src/3rdparty/harfbuzz-ng/src/hb-buffer.h | 6 + src/3rdparty/harfbuzz-ng/src/hb-buffer.hh | 1 + .../src/hb-cff-interp-dict-common.hh | 8 +- .../harfbuzz-ng/src/hb-cff2-interp-cs.hh | 2 +- src/3rdparty/harfbuzz-ng/src/hb-common.cc | 2 +- src/3rdparty/harfbuzz-ng/src/hb-common.h | 15 +- src/3rdparty/harfbuzz-ng/src/hb-cplusplus.hh | 16 +- .../harfbuzz-ng/src/hb-directwrite.cc | 4 +- src/3rdparty/harfbuzz-ng/src/hb-features.h | 119 ++++ src/3rdparty/harfbuzz-ng/src/hb-font.hh | 2 +- src/3rdparty/harfbuzz-ng/src/hb-ft.cc | 16 +- src/3rdparty/harfbuzz-ng/src/hb-icu.cc | 13 +- src/3rdparty/harfbuzz-ng/src/hb-limits.hh | 2 +- src/3rdparty/harfbuzz-ng/src/hb-map.hh | 23 +- src/3rdparty/harfbuzz-ng/src/hb-object.hh | 2 +- src/3rdparty/harfbuzz-ng/src/hb-open-type.hh | 7 + .../harfbuzz-ng/src/hb-ot-cff-common.hh | 19 +- .../harfbuzz-ng/src/hb-ot-cff1-table.hh | 81 +-- .../harfbuzz-ng/src/hb-ot-cff2-table.hh | 55 +- .../harfbuzz-ng/src/hb-ot-cmap-table.hh | 111 +++- src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc | 16 +- .../harfbuzz-ng/src/hb-ot-hmtx-table.hh | 25 +- .../src/hb-ot-layout-base-table.hh | 284 +++++++++- .../harfbuzz-ng/src/hb-ot-layout-common.hh | 32 +- .../harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh | 11 +- src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc | 2 +- .../harfbuzz-ng/src/hb-ot-math-table.hh | 33 +- .../harfbuzz-ng/src/hb-ot-os2-table.hh | 8 +- src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc | 9 +- .../harfbuzz-ng/src/hb-ot-shaper-arabic.cc | 8 +- .../harfbuzz-ng/src/hb-ot-stat-table.hh | 6 +- .../harfbuzz-ng/src/hb-ot-tag-table.hh | 28 +- src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc | 2 +- .../harfbuzz-ng/src/hb-ot-var-avar-table.hh | 6 +- .../harfbuzz-ng/src/hb-ot-var-common.hh | 450 +++++++++------ .../harfbuzz-ng/src/hb-ot-var-gvar-table.hh | 27 +- .../harfbuzz-ng/src/hb-ot-var-hvar-table.hh | 10 +- .../harfbuzz-ng/src/hb-ot-var-mvar-table.hh | 6 +- .../harfbuzz-ng/src/hb-priority-queue.hh | 2 +- src/3rdparty/harfbuzz-ng/src/hb-repacker.hh | 52 +- src/3rdparty/harfbuzz-ng/src/hb-serialize.hh | 66 ++- src/3rdparty/harfbuzz-ng/src/hb-set.hh | 8 +- .../harfbuzz-ng/src/hb-subset-cff2.cc | 12 +- .../harfbuzz-ng/src/hb-subset-input.cc | 105 +++- .../src/hb-subset-instancer-iup.cc | 532 ++++++++++++++++++ .../src/hb-subset-instancer-iup.hh | 37 ++ .../src/hb-subset-instancer-solver.cc | 5 +- .../src/hb-subset-plan-member-list.hh | 9 + .../harfbuzz-ng/src/hb-subset-plan.cc | 71 ++- .../harfbuzz-ng/src/hb-subset-plan.hh | 25 +- src/3rdparty/harfbuzz-ng/src/hb-subset.cc | 3 + src/3rdparty/harfbuzz-ng/src/hb-subset.h | 16 +- src/3rdparty/harfbuzz-ng/src/hb-vector.hh | 6 +- src/3rdparty/harfbuzz-ng/src/hb-version.h | 4 +- src/3rdparty/harfbuzz-ng/src/hb-wasm-shape.cc | 6 +- src/3rdparty/harfbuzz-ng/src/hb.hh | 12 + 78 files changed, 2499 insertions(+), 648 deletions(-) create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-features.h create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-iup.cc create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-iup.hh diff --git a/src/3rdparty/harfbuzz-ng/README.md b/src/3rdparty/harfbuzz-ng/README.md index 33165091a8b..da4de65cf09 100644 --- a/src/3rdparty/harfbuzz-ng/README.md +++ b/src/3rdparty/harfbuzz-ng/README.md @@ -2,7 +2,7 @@ [![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main) [![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/harfbuzz.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html) [![Coverity Scan Build Status](https://scan.coverity.com/projects/15166/badge.svg)](https://scan.coverity.com/projects/harfbuzz) -[![Codacy Badge](https://app.codacy.com/project/badge/Grade/89c872f5ce1c42af802602bfcd15d90a)](https://www.codacy.com/gh/harfbuzz/harfbuzz/dashboard?utm_source=github.com&utm_medium=referral&utm_content=harfbuzz/harfbuzz&utm_campaign=Badge_Grade) +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/89c872f5ce1c42af802602bfcd15d90a)](https://app.codacy.com/gh/harfbuzz/harfbuzz/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) [![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/main/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz) [![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/harfbuzz/harfbuzz/badge)](https://securityscorecards.dev/viewer/?uri=github.com/harfbuzz/harfbuzz) @@ -72,9 +72,9 @@ For a comparison of old vs new HarfBuzz memory consumption see [this][10]. ## Name -HarfBuzz (حرف‌باز) is my Persian translation of “[OpenType][1]”, -transliterated using the Latin script. It sports a second meaning, but that -ain’t translatable. +HarfBuzz (حرف‌باز) is the literal Persian translation of “[OpenType][1]”, +transliterated using the Latin script. It also means "talkative" or +"glib" (also a nod to the GNOME project where HarfBuzz originates from). > Background: Originally there was this font format called TrueType. People and > companies started calling their type engines all things ending in Type: diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index d9f843ccdba..58daaf2cd0a 100644 --- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro +++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro @@ -63,6 +63,7 @@ SOURCES += \ $$PWD/src/hb-subset-cff1.cc \ $$PWD/src/hb-subset-cff2.cc \ $$PWD/src/hb-subset-input.cc \ + $$PWD/src/hb-subset-instancer-iup.cc \ $$PWD/src/hb-subset-instancer-solver.cc \ $$PWD/src/hb-subset-plan.cc \ $$PWD/src/hb-subset-repacker.cc \ @@ -92,6 +93,7 @@ HEADERS += \ $$PWD/src/hb-shaper-impl.hh \ $$PWD/src/hb-shaper-list.hh \ $$PWD/src/hb-string-array.hh \ + $$PWD/src/hb-subset-instancer-iup.hh \ $$PWD/src/hb-subset-plan-member-list.hh \ $$PWD/src/hb-subset-repacker.h \ $$PWD/src/hb-unicode.hh diff --git a/src/3rdparty/harfbuzz-ng/qt_attribution.json b/src/3rdparty/harfbuzz-ng/qt_attribution.json index 26ef2e30e6a..c14b8ab5df3 100644 --- a/src/3rdparty/harfbuzz-ng/qt_attribution.json +++ b/src/3rdparty/harfbuzz-ng/qt_attribution.json @@ -7,7 +7,7 @@ "Description": "HarfBuzz is an OpenType text shaping engine.", "Homepage": "http://harfbuzz.org", - "Version": "8.3.0", + "Version": "8.4.0", "License": "MIT License", "LicenseId": "MIT", "LicenseFile": "COPYING", diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh index b632a1d9eba..623775a771d 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh @@ -68,7 +68,7 @@ public: hb_font_t *font; unsigned int palette_index; hb_color_t foreground; - VarStoreInstancer &instancer; + ItemVarStoreInstancer &instancer; hb_map_t current_glyphs; hb_map_t current_layers; int depth_left = HB_MAX_NESTING_LEVEL; @@ -80,7 +80,7 @@ public: hb_font_t *font_, unsigned int palette_, hb_color_t foreground_, - VarStoreInstancer &instancer_) : + ItemVarStoreInstancer &instancer_) : base (base_), funcs (funcs_), data (data_), @@ -245,7 +245,7 @@ struct Variable { value.closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); if (!value.subset (c, instancer, varIdxBase)) return_trace (false); @@ -270,7 +270,7 @@ struct Variable void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *stop, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { value.get_color_stop (c, stop, varIdxBase, instancer); } @@ -305,7 +305,7 @@ struct NoVariable { value.closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); return_trace (value.subset (c, instancer, varIdxBase)); @@ -325,7 +325,7 @@ struct NoVariable void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *stop, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { value.get_color_stop (c, stop, VarIdx::NO_VARIATION, instancer); } @@ -348,7 +348,7 @@ struct ColorStop { c->add_palette_index (paletteIndex); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -374,7 +374,7 @@ struct ColorStop void get_color_stop (hb_paint_context_t *c, hb_color_stop_t *out, uint32_t varIdx, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { out->offset = stopOffset.to_float(instancer (varIdx, 0)); out->color = c->get_color (paletteIndex, @@ -410,7 +410,7 @@ struct ColorLine } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -439,7 +439,7 @@ struct ColorLine unsigned int start, unsigned int *count, hb_color_stop_t *color_stops, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { unsigned int len = stops.len; @@ -543,7 +543,7 @@ struct Affine2x3 } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -588,7 +588,7 @@ struct PaintColrLayers void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer HB_UNUSED) const + const ItemVarStoreInstancer &instancer HB_UNUSED) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -620,7 +620,7 @@ struct PaintSolid { c->add_palette_index (paletteIndex); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -669,7 +669,7 @@ struct PaintLinearGradient { (this+colorLine).closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -736,7 +736,7 @@ struct PaintRadialGradient { (this+colorLine).closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -803,7 +803,7 @@ struct PaintSweepGradient { (this+colorLine).closurev1 (c); } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -863,7 +863,7 @@ struct PaintGlyph void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -906,7 +906,7 @@ struct PaintColrGlyph void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer HB_UNUSED) const + const ItemVarStoreInstancer &instancer HB_UNUSED) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -936,7 +936,7 @@ struct PaintTransform HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -975,7 +975,7 @@ struct PaintTranslate HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1024,7 +1024,7 @@ struct PaintScale HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1073,7 +1073,7 @@ struct PaintScaleAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1132,7 +1132,7 @@ struct PaintScaleUniform HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1176,7 +1176,7 @@ struct PaintScaleUniformAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1232,7 +1232,7 @@ struct PaintRotate HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1276,7 +1276,7 @@ struct PaintRotateAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1332,7 +1332,7 @@ struct PaintSkew HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1381,7 +1381,7 @@ struct PaintSkewAroundCenter HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1440,7 +1440,7 @@ struct PaintComposite void closurev1 (hb_colrv1_closure_context_t* c) const; bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); @@ -1491,7 +1491,7 @@ struct ClipBoxFormat1 return_trace (c->check_struct (this)); } - void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer HB_UNUSED) const + void get_clip_box (ClipBoxData &clip_box, const ItemVarStoreInstancer &instancer HB_UNUSED) const { clip_box.xMin = xMin; clip_box.yMin = yMin; @@ -1500,7 +1500,7 @@ struct ClipBoxFormat1 } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, uint32_t varIdxBase) const { TRACE_SUBSET (this); @@ -1533,7 +1533,7 @@ struct ClipBoxFormat1 struct ClipBoxFormat2 : Variable { - void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer) const + void get_clip_box (ClipBoxData &clip_box, const ItemVarStoreInstancer &instancer) const { value.get_clip_box(clip_box, instancer); if (instancer) @@ -1549,7 +1549,7 @@ struct ClipBoxFormat2 : Variable struct ClipBox { bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); switch (u.format) { @@ -1572,7 +1572,7 @@ struct ClipBox } bool get_extents (hb_glyph_extents_t *extents, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { ClipBoxData clip_box; switch (u.format) { @@ -1608,7 +1608,7 @@ struct ClipRecord bool subset (hb_subset_context_t *c, const void *base, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (*this); @@ -1625,7 +1625,7 @@ struct ClipRecord bool get_extents (hb_glyph_extents_t *extents, const void *base, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { return (base+clipBox).get_extents (extents, instancer); } @@ -1642,7 +1642,7 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord); struct ClipList { unsigned serialize_clip_records (hb_subset_context_t *c, - const VarStoreInstancer &instancer, + const ItemVarStoreInstancer &instancer, const hb_set_t& gids, const hb_map_t& gid_offset_map) const { @@ -1695,7 +1695,7 @@ struct ClipList } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); @@ -1735,7 +1735,7 @@ struct ClipList bool get_extents (hb_codepoint_t gid, hb_glyph_extents_t *extents, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { auto *rec = clips.as_array ().bsearch (gid); if (rec) @@ -1855,7 +1855,7 @@ struct BaseGlyphPaintRecord bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map, const void* src_base, hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SERIALIZE (this); auto *out = s->embed (this); @@ -1884,7 +1884,7 @@ struct BaseGlyphPaintRecord struct BaseGlyphList : SortedArray32Of { bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -1916,7 +1916,7 @@ struct LayerList : Array32OfOffset32To { return this+(*this)[i]; } bool subset (hb_subset_context_t *c, - const VarStoreInstancer &instancer) const + const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); @@ -2206,7 +2206,7 @@ struct COLR auto snap = c->serializer->snapshot (); if (!c->serializer->allocate_size (5 * HBUINT32::static_size)) return_trace (false); - VarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr, + ItemVarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr, varIdxMap ? &(this+varIdxMap) : nullptr, c->plan->normalized_coords.as_array ()); @@ -2250,7 +2250,7 @@ struct COLR if (version != 1) return false; - VarStoreInstancer instancer (&(this+varStore), + ItemVarStoreInstancer instancer (&(this+varStore), &(this+varIdxMap), hb_array (font->coords, font->num_coords)); @@ -2301,7 +2301,7 @@ struct COLR bool get_clip (hb_codepoint_t glyph, hb_glyph_extents_t *extents, - const VarStoreInstancer instancer) const + const ItemVarStoreInstancer instancer) const { return (this+clipList).get_extents (glyph, extents, @@ -2312,7 +2312,7 @@ struct COLR bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const { - VarStoreInstancer instancer (&(this+varStore), + ItemVarStoreInstancer instancer (&(this+varStore), &(this+varIdxMap), hb_array (font->coords, font->num_coords)); hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); @@ -2327,7 +2327,7 @@ struct COLR { // COLRv1 glyph - VarStoreInstancer instancer (&(this+varStore), + ItemVarStoreInstancer instancer (&(this+varStore), &(this+varIdxMap), hb_array (font->coords, font->num_coords)); @@ -2413,7 +2413,7 @@ struct COLR Offset32To layerList; Offset32To clipList; // Offset to ClipList table (may be NULL) Offset32To varIdxMap; // Offset to DeltaSetIndexMap table (may be NULL) - Offset32To varStore; + Offset32To varStore; public: DEFINE_SIZE_MIN (14); }; diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh index 14a9b5e5cd8..317b96c714b 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh @@ -189,7 +189,7 @@ struct CaretValueFormat3 friend struct CaretValue; hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, - const VariationStore &var_store) const + const ItemVariationStore &var_store) const { return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) : @@ -251,7 +251,7 @@ struct CaretValue hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store) const + const ItemVariationStore &var_store) const { switch (u.format) { case 1: return u.format1.get_caret_value (font, direction); @@ -316,7 +316,7 @@ struct LigGlyph unsigned get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store, + const ItemVariationStore &var_store, unsigned start_offset, unsigned *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const @@ -372,7 +372,7 @@ struct LigCaretList unsigned int get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, - const VariationStore &var_store, + const ItemVariationStore &var_store, unsigned int start_offset, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const @@ -609,7 +609,7 @@ struct GDEFVersion1_2 * definitions--from beginning of GDEF * header (may be NULL). Introduced * in version 0x00010002. */ - Offset32To + Offset32To varStore; /* Offset to the table of Item Variation * Store--from beginning of GDEF * header (may be NULL). Introduced @@ -663,21 +663,16 @@ struct GDEFVersion1_2 auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - out->version.major = version.major; - out->version.minor = version.minor; - bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); - bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); - bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); - - bool subset_markglyphsetsdef = false; + // Push var store first (if it's needed) so that it's last in the + // serialization order. Some font consumers assume that varstore runs to + // the end of the GDEF table. + // See: https://github.com/harfbuzz/harfbuzz/issues/4636 auto snapshot_version0 = c->serializer->snapshot (); - if (version.to_int () >= 0x00010002u) - { - if (unlikely (!c->serializer->embed (markGlyphSetsDef))) return_trace (false); - subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); - } + if (unlikely (version.to_int () >= 0x00010002u && !c->serializer->embed (markGlyphSetsDef))) + return_trace (false); bool subset_varstore = false; + unsigned varstore_index = (unsigned) -1; auto snapshot_version2 = c->serializer->snapshot (); if (version.to_int () >= 0x00010003u) { @@ -690,35 +685,58 @@ struct GDEFVersion1_2 { item_variations_t item_vars; if (item_vars.instantiate (this+varStore, c->plan, true, true, - c->plan->gdef_varstore_inner_maps.as_array ())) + c->plan->gdef_varstore_inner_maps.as_array ())) { subset_varstore = out->varStore.serialize_serialize (c->serializer, item_vars.has_long_word (), c->plan->axis_tags, item_vars.get_region_list (), item_vars.get_vardata_encodings ()); + varstore_index = c->serializer->last_added_child_index(); + } remap_varidx_after_instantiation (item_vars.get_varidx_map (), c->plan->layout_variation_idx_delta_map); } } else + { subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ()); + varstore_index = c->serializer->last_added_child_index(); + } } + out->version.major = version.major; + out->version.minor = version.minor; + + if (!subset_varstore && version.to_int () >= 0x00010002u) { + c->serializer->revert (snapshot_version2); + } + + bool subset_markglyphsetsdef = false; + if (version.to_int () >= 0x00010002u) + { + subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); + } if (subset_varstore) { out->version.minor = 3; c->plan->has_gdef_varstore = true; } else if (subset_markglyphsetsdef) { - out->version.minor = 2; - c->serializer->revert (snapshot_version2); + out->version.minor = 2; } else { out->version.minor = 0; c->serializer->revert (snapshot_version0); } + bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); + bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); + bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); + if (subset_varstore && varstore_index != (unsigned) -1) { + c->serializer->repack_last(varstore_index); + } + return_trace (subset_glyphclassdef || subset_attachlist || subset_ligcaretlist || subset_markattachclassdef || (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) || @@ -884,14 +902,14 @@ struct GDEF default: return false; } } - const VariationStore &get_var_store () const + const ItemVariationStore &get_var_store () const { switch (u.version.major) { - case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore); + case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(ItemVariationStore); #ifndef HB_NO_BEYOND_64K case 2: return this+u.version2.varStore; #endif - default: return Null(VariationStore); + default: return Null(ItemVariationStore); } } @@ -1011,9 +1029,9 @@ struct GDEF hb_hashmap_t> *layout_variation_idx_delta_map /* OUT */) const { if (!has_var_store ()) return; - const VariationStore &var_store = get_var_store (); + const ItemVariationStore &var_store = get_var_store (); float *store_cache = var_store.create_cache (); - + unsigned new_major = 0, new_minor = 0; unsigned last_major = (layout_variation_indices->get_min ()) >> 16; for (unsigned idx : layout_variation_indices->iter ()) diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh index dd02da887d4..9c805b39a18 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -324,17 +324,8 @@ struct PairPosFormat2_4 : ValueBase } } - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - const hb_map_t &glyph_map = *c->plan->glyph_map; - - auto it = - + hb_iter (this+coverage) - | hb_filter (glyphset) - | hb_map_retains_sorting (glyph_map) - ; - - out->coverage.serialize_serialize (c->serializer, it); - return_trace (out->class1Count && out->class2Count && bool (it)); + bool ret = out->coverage.serialize_subset(c, coverage, this); + return_trace (out->class1Count && out->class2Count && ret); } diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh index 17f57db1f5f..9442cc1cc53 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh @@ -116,7 +116,7 @@ struct ValueFormat : HBUINT16 if (!use_x_device && !use_y_device) return ret; - const VariationStore &store = c->var_store; + const ItemVariationStore &store = c->var_store; auto *cache = c->var_store_cache; /* pixel -> fractional pixel */ diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh index 60858a5a581..5c0ecd5133d 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh @@ -240,7 +240,8 @@ struct CompositeGlyphRecord } if (is_anchored ()) tx = ty = 0; - trans.init ((float) tx, (float) ty); + /* set is_end_point flag to true, used by IUP delta optimization */ + trans.init ((float) tx, (float) ty, true); { const F2DOT14 *points = (const F2DOT14 *) p; diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh index 5ea611948f8..69a0b625c73 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh @@ -103,6 +103,9 @@ struct Glyph } } + bool is_composite () const + { return type == COMPOSITE; } + bool get_all_points_without_var (const hb_face_t *face, contour_point_vector_t &points /* OUT */) const { diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf-helpers.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf-helpers.hh index d0a5a132f05..f157bf00200 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf-helpers.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf-helpers.hh @@ -38,7 +38,7 @@ _write_loca (IteratorIn&& it, unsigned padded_size = *it++; offset += padded_size; - DEBUG_MSG (SUBSET, nullptr, "loca entry gid %u offset %u padded-size %u", gid, offset, padded_size); + DEBUG_MSG (SUBSET, nullptr, "loca entry gid %" PRIu32 " offset %u padded-size %u", gid, offset, padded_size); value = offset >> right_shift; *dest++ = value; diff --git a/src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh index 9cf845a82d2..da6378820bb 100644 --- a/src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh +++ b/src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh @@ -134,20 +134,23 @@ struct ClassDef : public OT::ClassDef struct class_def_size_estimator_t { + // TODO(garretrieger): update to support beyond64k coverage/classdef tables. + constexpr static unsigned class_def_format1_base_size = 6; + constexpr static unsigned class_def_format2_base_size = 4; + constexpr static unsigned coverage_base_size = 4; + constexpr static unsigned bytes_per_range = 6; + constexpr static unsigned bytes_per_glyph = 2; + template class_def_size_estimator_t (It glyph_and_class) - : gids_consecutive (true), num_ranges_per_class (), glyphs_per_class () + : num_ranges_per_class (), glyphs_per_class () { - unsigned last_gid = (unsigned) -1; + reset(); for (auto p : + glyph_and_class) { unsigned gid = p.first; unsigned klass = p.second; - if (last_gid != (unsigned) -1 && gid != last_gid + 1) - gids_consecutive = false; - last_gid = gid; - hb_set_t* glyphs; if (glyphs_per_class.has (klass, &glyphs) && glyphs) { glyphs->add (gid); @@ -177,28 +180,54 @@ struct class_def_size_estimator_t } } - // Incremental increase in the Coverage and ClassDef table size - // (worst case) if all glyphs associated with 'klass' were added. - unsigned incremental_coverage_size (unsigned klass) const - { - // Coverage takes 2 bytes per glyph worst case, - return 2 * glyphs_per_class.get (klass).get_population (); + void reset() { + class_def_1_size = class_def_format1_base_size; + class_def_2_size = class_def_format2_base_size; + included_glyphs.clear(); + included_classes.clear(); } - // Incremental increase in the Coverage and ClassDef table size - // (worst case) if all glyphs associated with 'klass' were added. - unsigned incremental_class_def_size (unsigned klass) const + // Compute the size of coverage for all glyphs added via 'add_class_def_size'. + unsigned coverage_size () const { - // ClassDef takes 6 bytes per range - unsigned class_def_2_size = 6 * num_ranges_per_class.get (klass); - if (gids_consecutive) - { - // ClassDef1 takes 2 bytes per glyph, but only can be used - // when gids are consecutive. - return hb_min (2 * glyphs_per_class.get (klass).get_population (), class_def_2_size); + unsigned format1_size = coverage_base_size + bytes_per_glyph * included_glyphs.get_population(); + unsigned format2_size = coverage_base_size + bytes_per_range * num_glyph_ranges(); + return hb_min(format1_size, format2_size); + } + + // Compute the new size of the ClassDef table if all glyphs associated with 'klass' were added. + unsigned add_class_def_size (unsigned klass) + { + if (!included_classes.has(klass)) { + hb_set_t* glyphs = nullptr; + if (glyphs_per_class.has(klass, &glyphs)) { + included_glyphs.union_(*glyphs); + } + + class_def_1_size = class_def_format1_base_size; + if (!included_glyphs.is_empty()) { + unsigned min_glyph = included_glyphs.get_min(); + unsigned max_glyph = included_glyphs.get_max(); + class_def_1_size += bytes_per_glyph * (max_glyph - min_glyph + 1); + } + + class_def_2_size += bytes_per_range * num_ranges_per_class.get (klass); + + included_classes.add(klass); } - return class_def_2_size; + return hb_min (class_def_1_size, class_def_2_size); + } + + unsigned num_glyph_ranges() const { + hb_codepoint_t start = HB_SET_VALUE_INVALID; + hb_codepoint_t end = HB_SET_VALUE_INVALID; + + unsigned count = 0; + while (included_glyphs.next_range (&start, &end)) { + count++; + } + return count; } bool in_error () @@ -214,9 +243,12 @@ struct class_def_size_estimator_t } private: - bool gids_consecutive; hb_hashmap_t num_ranges_per_class; hb_hashmap_t glyphs_per_class; + hb_set_t included_classes; + hb_set_t included_glyphs; + unsigned class_def_1_size; + unsigned class_def_2_size; }; diff --git a/src/3rdparty/harfbuzz-ng/src/graph/graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/graph.hh index 26ad00bdd98..2a9d8346c0b 100644 --- a/src/3rdparty/harfbuzz-ng/src/graph/graph.hh +++ b/src/3rdparty/harfbuzz-ng/src/graph/graph.hh @@ -195,6 +195,15 @@ struct graph_t return incoming_edges_; } + unsigned incoming_edges_from_parent (unsigned parent_index) const { + if (single_parent != (unsigned) -1) { + return single_parent == parent_index ? 1 : 0; + } + + unsigned* count; + return parents.has(parent_index, &count) ? *count : 0; + } + void reset_parents () { incoming_edges_ = 0; @@ -334,6 +343,16 @@ struct graph_t return true; } + bool give_max_priority () + { + bool result = false; + while (!has_max_priority()) { + result = true; + priority++; + } + return result; + } + bool has_max_priority () const { return priority >= 3; } @@ -1023,6 +1042,11 @@ struct graph_t * Creates a copy of child and re-assigns the link from * parent to the clone. The copy is a shallow copy, objects * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parent_idx, this + * will do nothing and return the original child_idx. */ unsigned duplicate_if_shared (unsigned parent_idx, unsigned child_idx) { @@ -1036,18 +1060,20 @@ struct graph_t * Creates a copy of child and re-assigns the link from * parent to the clone. The copy is a shallow copy, objects * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parent_idx, + * duplication isn't possible and this will return -1. */ unsigned duplicate (unsigned parent_idx, unsigned child_idx) { update_parents (); - unsigned links_to_child = 0; - for (const auto& l : vertices_[parent_idx].obj.all_links ()) - { - if (l.objidx == child_idx) links_to_child++; - } + const auto& child = vertices_[child_idx]; + unsigned links_to_child = child.incoming_edges_from_parent(parent_idx); - if (vertices_[child_idx].incoming_edges () <= links_to_child) + if (child.incoming_edges () <= links_to_child) { // Can't duplicate this node, doing so would orphan the original one as all remaining links // to child are from parent. @@ -1060,7 +1086,7 @@ struct graph_t parent_idx, child_idx); unsigned clone_idx = duplicate (child_idx); - if (clone_idx == (unsigned) -1) return false; + if (clone_idx == (unsigned) -1) return -1; // duplicate shifts the root node idx, so if parent_idx was root update it. if (parent_idx == clone_idx) parent_idx++; @@ -1076,6 +1102,62 @@ struct graph_t return clone_idx; } + /* + * Creates a copy of child and re-assigns the links from + * parents to the clone. The copy is a shallow copy, objects + * linked from child are not duplicated. + * + * Returns the index of the newly created duplicate. + * + * If the child_idx only has incoming edges from parents, + * duplication isn't possible or duplication fails and this will + * return -1. + */ + unsigned duplicate (const hb_set_t* parents, unsigned child_idx) + { + if (parents->is_empty()) { + return -1; + } + + update_parents (); + + const auto& child = vertices_[child_idx]; + unsigned links_to_child = 0; + unsigned last_parent = parents->get_max(); + unsigned first_parent = parents->get_min(); + for (unsigned parent_idx : *parents) { + links_to_child += child.incoming_edges_from_parent(parent_idx); + } + + if (child.incoming_edges () <= links_to_child) + { + // Can't duplicate this node, doing so would orphan the original one as all remaining links + // to child are from parent. + DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); + return -1; + } + + DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); + + unsigned clone_idx = duplicate (child_idx); + if (clone_idx == (unsigned) -1) return false; + + for (unsigned parent_idx : *parents) { + // duplicate shifts the root node idx, so if parent_idx was root update it. + if (parent_idx == clone_idx) parent_idx++; + auto& parent = vertices_[parent_idx]; + for (auto& l : parent.obj.all_links_writer ()) + { + if (l.objidx != child_idx) + continue; + + reassign_link (l, parent_idx, clone_idx); + } + } + + return clone_idx; + } + /* * Adds a new node to the graph, not connected to anything. diff --git a/src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh index f7f74b18c9c..fd46861de46 100644 --- a/src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh +++ b/src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh @@ -247,8 +247,8 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4 gid_and_class_list_t; +template +static unsigned actual_class_def_size(It glyph_and_class) { + char buffer[100]; + hb_serialize_context_t serializer(buffer, 100); + OT::ClassDef_serialize (&serializer, glyph_and_class); + serializer.end_serialize (); + assert(!serializer.in_error()); -static bool incremental_size_is (const gid_and_class_list_t& list, unsigned klass, - unsigned cov_expected, unsigned class_def_expected) + hb_blob_t* blob = serializer.copy_blob(); + unsigned size = hb_blob_get_length(blob); + hb_blob_destroy(blob); + return size; +} + +static unsigned actual_class_def_size(gid_and_class_list_t consecutive_map, hb_vector_t classes) { + auto filtered_it = + + consecutive_map.as_sorted_array().iter() + | hb_filter([&] (unsigned c) { + for (unsigned klass : classes) { + if (c == klass) { + return true; + } + } + return false; + }, hb_second); + return actual_class_def_size(+ filtered_it); +} + +template +static unsigned actual_coverage_size(It glyphs) { + char buffer[100]; + hb_serialize_context_t serializer(buffer, 100); + OT::Layout::Common::Coverage_serialize (&serializer, glyphs); + serializer.end_serialize (); + assert(!serializer.in_error()); + + hb_blob_t* blob = serializer.copy_blob(); + unsigned size = hb_blob_get_length(blob); + hb_blob_destroy(blob); + return size; +} + +static unsigned actual_coverage_size(gid_and_class_list_t consecutive_map, hb_vector_t classes) { + auto filtered_it = + + consecutive_map.as_sorted_array().iter() + | hb_filter([&] (unsigned c) { + for (unsigned klass : classes) { + if (c == klass) { + return true; + } + } + return false; + }, hb_second); + return actual_coverage_size(+ filtered_it | hb_map_retains_sorting(hb_first)); +} + +static bool check_coverage_size(graph::class_def_size_estimator_t& estimator, + const gid_and_class_list_t& map, + hb_vector_t klasses) { - graph::class_def_size_estimator_t estimator (list.iter ()); + unsigned result = estimator.coverage_size(); + unsigned expected = actual_coverage_size(map, klasses); + if (result != expected) { + printf ("FAIL: estimated coverage expected size %u but was %u\n", expected, result); + return false; + } + return true; +} - unsigned result = estimator.incremental_coverage_size (klass); - if (result != cov_expected) - { - printf ("FAIL: coverage expected size %u but was %u\n", cov_expected, result); +static bool check_add_class_def_size(graph::class_def_size_estimator_t& estimator, + const gid_and_class_list_t& map, + unsigned klass, hb_vector_t klasses) +{ + unsigned result = estimator.add_class_def_size(klass); + unsigned expected = actual_class_def_size(map, klasses); + if (result != expected) { + printf ("FAIL: estimated class def expected size %u but was %u\n", expected, result); return false; } - result = estimator.incremental_class_def_size (klass); - if (result != class_def_expected) + return check_coverage_size(estimator, map, klasses); +} + +static bool check_add_class_def_size (const gid_and_class_list_t& list, unsigned klass) +{ + graph::class_def_size_estimator_t estimator (list.iter ()); + + unsigned result = estimator.add_class_def_size (klass); + auto filtered_it = + + list.as_sorted_array().iter() + | hb_filter([&] (unsigned c) { + return c == klass; + }, hb_second); + + unsigned expected = actual_class_def_size(filtered_it); + if (result != expected) { - printf ("FAIL: class def expected size %u but was %u\n", class_def_expected, result); + printf ("FAIL: class def expected size %u but was %u\n", expected, result); + return false; + } + + auto cov_it = + filtered_it | hb_map_retains_sorting(hb_first); + result = estimator.coverage_size (); + expected = actual_coverage_size(cov_it); + if (result != expected) + { + printf ("FAIL: coverage expected size %u but was %u\n", expected, result); return false; } @@ -57,43 +149,45 @@ static void test_class_and_coverage_size_estimates () { gid_and_class_list_t empty = { }; - assert (incremental_size_is (empty, 0, 0, 0)); - assert (incremental_size_is (empty, 1, 0, 0)); + assert (check_add_class_def_size (empty, 0)); + assert (check_add_class_def_size (empty, 1)); gid_and_class_list_t class_zero = { {5, 0}, }; - assert (incremental_size_is (class_zero, 0, 2, 0)); + assert (check_add_class_def_size (class_zero, 0)); gid_and_class_list_t consecutive = { {4, 0}, {5, 0}, + {6, 1}, {7, 1}, + {8, 2}, {9, 2}, {10, 2}, {11, 2}, }; - assert (incremental_size_is (consecutive, 0, 4, 0)); - assert (incremental_size_is (consecutive, 1, 4, 4)); - assert (incremental_size_is (consecutive, 2, 8, 6)); + assert (check_add_class_def_size (consecutive, 0)); + assert (check_add_class_def_size (consecutive, 1)); + assert (check_add_class_def_size (consecutive, 2)); gid_and_class_list_t non_consecutive = { {4, 0}, - {5, 0}, + {6, 0}, - {6, 1}, - {7, 1}, + {8, 1}, + {10, 1}, {9, 2}, {10, 2}, {11, 2}, - {12, 2}, + {13, 2}, }; - assert (incremental_size_is (non_consecutive, 0, 4, 0)); - assert (incremental_size_is (non_consecutive, 1, 4, 6)); - assert (incremental_size_is (non_consecutive, 2, 8, 6)); + assert (check_add_class_def_size (non_consecutive, 0)); + assert (check_add_class_def_size (non_consecutive, 1)); + assert (check_add_class_def_size (non_consecutive, 2)); gid_and_class_list_t multiple_ranges = { {4, 0}, @@ -108,12 +202,95 @@ static void test_class_and_coverage_size_estimates () {12, 1}, {13, 1}, }; - assert (incremental_size_is (multiple_ranges, 0, 4, 0)); - assert (incremental_size_is (multiple_ranges, 1, 2 * 6, 3 * 6)); + assert (check_add_class_def_size (multiple_ranges, 0)); + assert (check_add_class_def_size (multiple_ranges, 1)); +} + +static void test_running_class_and_coverage_size_estimates () { + // #### With consecutive gids: switches formats ### + gid_and_class_list_t consecutive_map = { + // range 1-4 (f1: 8 bytes), (f2: 6 bytes) + {1, 1}, + {2, 1}, + {3, 1}, + {4, 1}, + + // (f1: 2 bytes), (f2: 6 bytes) + {5, 2}, + + // (f1: 14 bytes), (f2: 6 bytes) + {6, 3}, + {7, 3}, + {8, 3}, + {9, 3}, + {10, 3}, + {11, 3}, + {12, 3}, + }; + + graph::class_def_size_estimator_t estimator1(consecutive_map.iter()); + assert(check_add_class_def_size(estimator1, consecutive_map, 1, {1})); + assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2})); + assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2})); // check that adding the same class again works + assert(check_add_class_def_size(estimator1, consecutive_map, 3, {1, 2, 3})); + + estimator1.reset(); + assert(check_add_class_def_size(estimator1, consecutive_map, 2, {2})); + assert(check_add_class_def_size(estimator1, consecutive_map, 3, {2, 3})); + + // #### With non-consecutive gids: always uses format 2 ### + gid_and_class_list_t non_consecutive_map = { + // range 1-4 (f1: 8 bytes), (f2: 6 bytes) + {1, 1}, + {2, 1}, + {3, 1}, + {4, 1}, + + // (f1: 2 bytes), (f2: 12 bytes) + {6, 2}, + {8, 2}, + + // (f1: 14 bytes), (f2: 6 bytes) + {9, 3}, + {10, 3}, + {11, 3}, + {12, 3}, + {13, 3}, + {14, 3}, + {15, 3}, + }; + + graph::class_def_size_estimator_t estimator2(non_consecutive_map.iter()); + assert(check_add_class_def_size(estimator2, non_consecutive_map, 1, {1})); + assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {1, 2})); + assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {1, 2, 3})); + + estimator2.reset(); + assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {2})); + assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {2, 3})); +} + +static void test_running_class_size_estimates_with_locally_consecutive_glyphs () { + gid_and_class_list_t map = { + {1, 1}, + {6, 2}, + {7, 3}, + }; + + graph::class_def_size_estimator_t estimator(map.iter()); + assert(check_add_class_def_size(estimator, map, 1, {1})); + assert(check_add_class_def_size(estimator, map, 2, {1, 2})); + assert(check_add_class_def_size(estimator, map, 3, {1, 2, 3})); + + estimator.reset(); + assert(check_add_class_def_size(estimator, map, 2, {2})); + assert(check_add_class_def_size(estimator, map, 3, {2, 3})); } int main (int argc, char **argv) { test_class_and_coverage_size_estimates (); + test_running_class_and_coverage_size_estimates (); + test_running_class_size_estimates_with_locally_consecutive_glyphs (); } diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc b/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc index c0e23b3eb82..f80c004cbb4 100644 --- a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc +++ b/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc @@ -54,6 +54,7 @@ #include "hb-subset-cff1.cc" #include "hb-subset-cff2.cc" #include "hb-subset-input.cc" +#include "hb-subset-instancer-iup.cc" #include "hb-subset-instancer-solver.cc" #include "hb-subset-plan.cc" #include "hb-subset-repacker.cc" diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh index 06c9334b370..84365513240 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh @@ -552,6 +552,7 @@ struct LigatureSubtable { DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return; + buffer->cur().unicode_props() |= UPROPS_MASK_IGNORABLE; if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-algs.hh b/src/3rdparty/harfbuzz-ng/src/hb-algs.hh index ea970571654..efa6074a422 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-algs.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-algs.hh @@ -671,7 +671,7 @@ struct hb_pair_t return 0; } - friend void swap (hb_pair_t& a, hb_pair_t& b) + friend void swap (hb_pair_t& a, hb_pair_t& b) noexcept { hb_swap (a.first, b.first); hb_swap (a.second, b.second); @@ -1053,6 +1053,18 @@ _hb_cmp_method (const void *pkey, const void *pval, Ts... ds) return val.cmp (key, ds...); } +template +static int +_hb_cmp_operator (const void *pkey, const void *pval) +{ + const K& key = * (const K*) pkey; + const V& val = * (const V*) pval; + + if (key < val) return -1; + if (key > val) return 1; + return 0; +} + template static inline bool hb_bsearch_impl (unsigned *pos, /* Out */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh b/src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh index 26262518070..d5d1326d9fa 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh @@ -39,10 +39,10 @@ struct hb_bit_set_invertible_t hb_bit_set_invertible_t () = default; hb_bit_set_invertible_t (const hb_bit_set_invertible_t& o) = default; - hb_bit_set_invertible_t (hb_bit_set_invertible_t&& other) : hb_bit_set_invertible_t () { hb_swap (*this, other); } + hb_bit_set_invertible_t (hb_bit_set_invertible_t&& other) noexcept : hb_bit_set_invertible_t () { hb_swap (*this, other); } hb_bit_set_invertible_t& operator= (const hb_bit_set_invertible_t& o) = default; - hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& other) { hb_swap (*this, other); return *this; } - friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b) + hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& other) noexcept { hb_swap (*this, other); return *this; } + friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b) noexcept { if (likely (!a.s.successful || !b.s.successful)) return; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh b/src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh index 1dbcce5cbd5..5f4c6f0afea 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh @@ -38,10 +38,10 @@ struct hb_bit_set_t ~hb_bit_set_t () = default; hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other, true); } - hb_bit_set_t ( hb_bit_set_t&& other) : hb_bit_set_t () { hb_swap (*this, other); } + hb_bit_set_t ( hb_bit_set_t&& other) noexcept : hb_bit_set_t () { hb_swap (*this, other); } hb_bit_set_t& operator= (const hb_bit_set_t& other) { set (other); return *this; } - hb_bit_set_t& operator= (hb_bit_set_t&& other) { hb_swap (*this, other); return *this; } - friend void swap (hb_bit_set_t &a, hb_bit_set_t &b) + hb_bit_set_t& operator= (hb_bit_set_t&& other) noexcept { hb_swap (*this, other); return *this; } + friend void swap (hb_bit_set_t &a, hb_bit_set_t &b) noexcept { if (likely (!a.successful || !b.successful)) return; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc index 265effba037..873d9b257ad 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc @@ -598,6 +598,11 @@ _open_resource_fork (const char *file_name, hb_mapped_file_t *file) * Creates a new blob containing the data from the * specified binary font file. * + * The filename is passed directly to the system on all platforms, + * except on Windows, where the filename is interpreted as UTF-8. + * Only if the filename is not valid UTF-8, it will be interpreted + * according to the system codepage. + * * Returns: An #hb_blob_t pointer with the content of the file, * or hb_blob_get_empty() if failed. * @@ -617,6 +622,11 @@ hb_blob_create_from_file (const char *file_name) * Creates a new blob containing the data from the * specified binary font file. * + * The filename is passed directly to the system on all platforms, + * except on Windows, where the filename is interpreted as UTF-8. + * Only if the filename is not valid UTF-8, it will be interpreted + * according to the system codepage. + * * Returns: An #hb_blob_t pointer with the content of the file, * or `NULL` if failed. * @@ -672,10 +682,19 @@ fail_without_close: if (unlikely (!file)) return nullptr; HANDLE fd; + int conversion; unsigned int size = strlen (file_name) + 1; wchar_t * wchar_file_name = (wchar_t *) hb_malloc (sizeof (wchar_t) * size); if (unlikely (!wchar_file_name)) goto fail_without_close; - mbstowcs (wchar_file_name, file_name, size); + + /* Assume file name is given in UTF-8 encoding */ + conversion = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, file_name, -1, wchar_file_name, size); + if (conversion <= 0) + { + /* Conversion failed due to invalid UTF-8 characters, + Repeat conversion based on system code page */ + mbstowcs(wchar_file_name, file_name, size); + } #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) { CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-verify.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-verify.cc index 15a53919def..671d6eda8c9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-verify.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-verify.cc @@ -149,7 +149,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, } assert (text_start < text_end); - if (0) + if (false) printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end); hb_buffer_clear_contents (fragment); @@ -288,7 +288,7 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, } assert (text_start < text_end); - if (0) + if (false) printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end); #if 0 diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc index 934c6c21294..d621a7cc55d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc @@ -309,6 +309,7 @@ hb_buffer_t::clear () deallocate_var_all (); serial = 0; + random_state = 1; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; } @@ -1359,6 +1360,49 @@ hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer) return buffer->not_found; } +/** + * hb_buffer_set_random_state: + * @buffer: An #hb_buffer_t + * @state: the new random state + * + * Sets the random state of the buffer. The state changes + * every time a glyph uses randomness (eg. the `rand` + * OpenType feature). This function together with + * hb_buffer_get_random_state() allow for transferring + * the current random state to a subsequent buffer, to + * get better randomness distribution. + * + * Defaults to 1 and when buffer contents are cleared. + * A value of 0 disables randomness during shaping. + * + * Since: 8.4.0 + **/ +void +hb_buffer_set_random_state (hb_buffer_t *buffer, + unsigned state) +{ + if (unlikely (hb_object_is_immutable (buffer))) + return; + + buffer->random_state = state; +} + +/** + * hb_buffer_get_random_state: + * @buffer: An #hb_buffer_t + * + * See hb_buffer_set_random_state(). + * + * Return value: + * The @buffer random state + * + * Since: 8.4.0 + **/ +unsigned +hb_buffer_get_random_state (const hb_buffer_t *buffer) +{ + return buffer->random_state; +} /** * hb_buffer_clear_contents: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h index 3573127ff00..f75fe96b214 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h @@ -487,6 +487,12 @@ hb_buffer_set_not_found_glyph (hb_buffer_t *buffer, HB_EXTERN hb_codepoint_t hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer); +HB_EXTERN void +hb_buffer_set_random_state (hb_buffer_t *buffer, + unsigned state); + +HB_EXTERN unsigned +hb_buffer_get_random_state (const hb_buffer_t *buffer); /* * Content API. diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh index f04ad58f116..0a198722d62 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh @@ -116,6 +116,7 @@ struct hb_buffer_t uint8_t allocated_var_bits; uint8_t serial; + uint32_t random_state; hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */ unsigned int max_len; /* Maximum allowed len. */ int max_ops; /* Maximum allowed operations. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh index 53226b227e9..a08b10b5ff1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh @@ -54,8 +54,8 @@ struct top_dict_values_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int charStringsOffset; - unsigned int FDArrayOffset; + int charStringsOffset; + int FDArrayOffset; }; struct dict_opset_t : opset_t @@ -157,11 +157,11 @@ struct top_dict_opset_t : dict_opset_t { switch (op) { case OpCode_CharStrings: - dictval.charStringsOffset = env.argStack.pop_uint (); + dictval.charStringsOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FDArray: - dictval.FDArrayOffset = env.argStack.pop_uint (); + dictval.FDArrayOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FontMatrix: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh index 915b10cf39a..55b1d3bf8d4 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh @@ -168,7 +168,7 @@ struct cff2_cs_interp_env_t : cs_interp_env_t protected: const int *coords; unsigned int num_coords; - const CFF2VariationStore *varStore; + const CFF2ItemVariationStore *varStore; unsigned int region_count; unsigned int ivs; hb_vector_t scalars; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-common.cc index 0c13c7d171f..4b8bae4422e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-common.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-common.cc @@ -996,7 +996,7 @@ hb_feature_to_string (hb_feature_t *feature, if (feature->value > 1) { s[len++] = '='; - len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value)); + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%" PRIu32, feature->value)); } assert (len < ARRAY_LENGTH (s)); len = hb_min (len, size - 1); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h index a9fe666b392..533de915627 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-common.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h @@ -47,14 +47,10 @@ # endif /* !__cplusplus */ #endif -#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \ - defined (_sgi) || defined (__sun) || defined (sun) || \ - defined (__digital__) || defined (__HP_cc) -# include -#elif defined (_AIX) +#if defined (_AIX) # include #elif defined (_MSC_VER) && _MSC_VER < 1600 -/* VS 2010 (_MSC_VER 1600) has stdint.h */ +/* VS 2010 (_MSC_VER 1600) has stdint.h */ typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; @@ -63,10 +59,11 @@ typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; -#elif defined (__KERNEL__) -# include -#else +#elif defined (_MSC_VER) && _MSC_VER < 1800 +/* VS 2013 (_MSC_VER 1800) has inttypes.h */ # include +#else +# include #endif #if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cplusplus.hh b/src/3rdparty/harfbuzz-ng/src/hb-cplusplus.hh index 531ef1b7c83..a640e192de7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-cplusplus.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-cplusplus.hh @@ -56,15 +56,15 @@ struct shared_ptr explicit shared_ptr (T *p = nullptr) : p (p) {} shared_ptr (const shared_ptr &o) : p (v::reference (o.p)) {} - shared_ptr (shared_ptr &&o) : p (o.p) { o.p = nullptr; } + shared_ptr (shared_ptr &&o) noexcept : p (o.p) { o.p = nullptr; } shared_ptr& operator = (const shared_ptr &o) { if (p != o.p) { destroy (); p = o.p; reference (); } return *this; } - shared_ptr& operator = (shared_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; } + shared_ptr& operator = (shared_ptr &&o) noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; } ~shared_ptr () { v::destroy (p); p = nullptr; } T* get() const { return p; } - void swap (shared_ptr &o) { std::swap (p, o.p); } - friend void swap (shared_ptr &a, shared_ptr &b) { std::swap (a.p, b.p); } + void swap (shared_ptr &o) noexcept { std::swap (p, o.p); } + friend void swap (shared_ptr &a, shared_ptr &b) noexcept { std::swap (a.p, b.p); } operator T * () const { return p; } T& operator * () const { return *get (); } @@ -98,16 +98,16 @@ struct unique_ptr explicit unique_ptr (T *p = nullptr) : p (p) {} unique_ptr (const unique_ptr &o) = delete; - unique_ptr (unique_ptr &&o) : p (o.p) { o.p = nullptr; } + unique_ptr (unique_ptr &&o) noexcept : p (o.p) { o.p = nullptr; } unique_ptr& operator = (const unique_ptr &o) = delete; - unique_ptr& operator = (unique_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; } + unique_ptr& operator = (unique_ptr &&o) noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; } ~unique_ptr () { v::destroy (p); p = nullptr; } T* get() const { return p; } T* release () { T* v = p; p = nullptr; return v; } - void swap (unique_ptr &o) { std::swap (p, o.p); } - friend void swap (unique_ptr &a, unique_ptr &b) { std::swap (a.p, b.p); } + void swap (unique_ptr &o) noexcept { std::swap (p, o.p); } + friend void swap (unique_ptr &a, unique_ptr &b) noexcept { std::swap (a.p, b.p); } operator T * () const { return p; } T& operator * () const { return *get (); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc b/src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc index 42764a244b1..6c90265d0b6 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc @@ -173,7 +173,7 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) t_DWriteCreateFactory p_DWriteCreateFactory; -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-function-type" #endif @@ -181,7 +181,7 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) p_DWriteCreateFactory = (t_DWriteCreateFactory) GetProcAddress (data->dwrite_dll, "DWriteCreateFactory"); -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-features.h b/src/3rdparty/harfbuzz-ng/src/hb-features.h new file mode 100644 index 00000000000..9199864195f --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-features.h @@ -0,0 +1,119 @@ +/* + * Copyright © 2022 Red Hat, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_FEATURES_H +#define HB_FEATURES_H + +HB_BEGIN_DECLS + +/** + * SECTION: hb-features + * @title: hb-features + * @short_description: Feature detection + * @include: hb-features.h + * + * Macros for detecting optional HarfBuzz features at build time. + **/ + +/** + * HB_HAS_CAIRO: + * + * Defined if Harfbuzz has been built with cairo support. + */ +# + +/** + * HB_HAS_CORETEXT: + * + * Defined if Harfbuzz has been built with CoreText support. + */ +#undef HB_HAS_CORETEXT + +/** + * HB_HAS_DIRECTWRITE: + * + * Defined if Harfbuzz has been built with DirectWrite support. + */ +#undef HB_HAS_DIRECTWRITE + +/** + * HB_HAS_FREETYPE: + * + * Defined if Harfbuzz has been built with Freetype support. + */ +#define HB_HAS_FREETYPE 1 + +/** + * HB_HAS_GDI: + * + * Defined if Harfbuzz has been built with GDI support. + */ +#undef HB_HAS_GDI + +/** + * HB_HAS_GLIB: + * + * Defined if Harfbuzz has been built with GLib support. + */ +#define HB_HAS_GLIB 1 + +/** + * HB_HAS_GOBJECT: + * + * Defined if Harfbuzz has been built with GObject support. + */ +#undef HB_HAS_GOBJECT + +/** + * HB_HAS_GRAPHITE: + * + * Defined if Harfbuzz has been built with Graphite support. + */ +#undef HB_HAS_GRAPHITE + +/** + * HB_HAS_ICU: + * + * Defined if Harfbuzz has been built with ICU support. + */ +#undef HB_HAS_ICU + +/** + * HB_HAS_UNISCRIBE: + * + * Defined if Harfbuzz has been built with Uniscribe support. + */ +#undef HB_HAS_UNISCRIBE + +/** + * HB_HAS_WASM: + * + * Defined if Harfbuzz has been built with WebAssembly support. + */ +#undef HB_HAS_WASM + + +HB_END_DECLS + +#endif /* HB_FEATURES_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.hh b/src/3rdparty/harfbuzz-ng/src/hb-font.hh index f503575c34a..4c8190b0dd1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.hh @@ -651,7 +651,7 @@ struct hb_font_t { if (get_glyph_name (glyph, s, size)) return; - if (size && snprintf (s, size, "gid%u", glyph) < 0) + if (size && snprintf (s, size, "gid%" PRIu32, glyph) < 0) *s = '\0'; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc b/src/3rdparty/harfbuzz-ng/src/hb-ft.cc index 955a9081e09..3de4a6d5d41 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ft.cc @@ -224,7 +224,7 @@ _hb_ft_hb_font_check_changed (hb_font_t *font, * * Sets the FT_Load_Glyph load flags for the specified #hb_font_t. * - * For more information, see + * For more information, see * * * This function works with #hb_font_t objects created by @@ -252,7 +252,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) * * Fetches the FT_Load_Glyph load flags of the specified #hb_font_t. * - * For more information, see + * For more information, see * * * This function works with #hb_font_t objects created by @@ -1118,10 +1118,10 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data * This variant of the function does not provide any life-cycle management. * * Most client programs should use hb_ft_face_create_referenced() - * (or, perhaps, hb_ft_face_create_cached()) instead. + * (or, perhaps, hb_ft_face_create_cached()) instead. * * If you know you have valid reasons not to use hb_ft_face_create_referenced(), - * then it is the client program's responsibility to destroy @ft_face + * then it is the client program's responsibility to destroy @ft_face * after the #hb_face_t face object has been destroyed. * * Return value: (transfer full): the new #hb_face_t face object @@ -1215,7 +1215,7 @@ hb_ft_face_finalize (void *arg) hb_face_t * hb_ft_face_create_cached (FT_Face ft_face) { - if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize)) + if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != hb_ft_face_finalize)) { if (ft_face->generic.finalizer) ft_face->generic.finalizer (ft_face); @@ -1241,13 +1241,13 @@ hb_ft_face_create_cached (FT_Face ft_face) * This variant of the function does not provide any life-cycle management. * * Most client programs should use hb_ft_font_create_referenced() - * instead. + * instead. * * If you know you have valid reasons not to use hb_ft_font_create_referenced(), - * then it is the client program's responsibility to destroy @ft_face + * then it is the client program's responsibility to destroy @ft_face * after the #hb_font_t font object has been destroyed. * - * HarfBuzz will use the @destroy callback on the #hb_font_t font object + * HarfBuzz will use the @destroy callback on the #hb_font_t font object * if it is supplied when you use this function. However, even if @destroy * is provided, it is the client program's responsibility to destroy @ft_face, * and it is the client program's responsibility to ensure that @ft_face is diff --git a/src/3rdparty/harfbuzz-ng/src/hb-icu.cc b/src/3rdparty/harfbuzz-ng/src/hb-icu.cc index e46401f7a61..3707ec30f84 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-icu.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-icu.cc @@ -93,15 +93,16 @@ hb_icu_script_to_script (UScriptCode script) UScriptCode hb_icu_script_from_script (hb_script_t script) { + UScriptCode out = USCRIPT_INVALID_CODE; + if (unlikely (script == HB_SCRIPT_INVALID)) - return USCRIPT_INVALID_CODE; + return out; - unsigned int numScriptCode = 1 + u_getIntPropertyMaxValue (UCHAR_SCRIPT); - for (unsigned int i = 0; i < numScriptCode; i++) - if (unlikely (hb_icu_script_to_script ((UScriptCode) i) == script)) - return (UScriptCode) i; + UErrorCode icu_err = U_ZERO_ERROR; + const unsigned char buf[5] = {HB_UNTAG (script), 0}; + uscript_getCode ((const char *) buf, &out, 1, &icu_err); - return USCRIPT_UNKNOWN; + return out; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-limits.hh b/src/3rdparty/harfbuzz-ng/src/hb-limits.hh index 25c1e71e133..7efc893eae0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-limits.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-limits.hh @@ -106,7 +106,7 @@ #endif #ifndef HB_COLRV1_MAX_EDGE_COUNT -#define HB_COLRV1_MAX_EDGE_COUNT 65536 +#define HB_COLRV1_MAX_EDGE_COUNT 2048 #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-map.hh b/src/3rdparty/harfbuzz-ng/src/hb-map.hh index 45a02b830c3..6521b1a41d8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-map.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-map.hh @@ -70,9 +70,9 @@ struct hb_hashmap_t alloc (o.population); hb_copy (o, *this); } - hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); } + hb_hashmap_t (hb_hashmap_t&& o) noexcept : hb_hashmap_t () { hb_swap (*this, o); } hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); alloc (o.population); hb_copy (o, *this); return *this; } - hb_hashmap_t& operator= (hb_hashmap_t&& o) { hb_swap (*this, o); return *this; } + hb_hashmap_t& operator= (hb_hashmap_t&& o) noexcept { hb_swap (*this, o); return *this; } hb_hashmap_t (std::initializer_list> lst) : hb_hashmap_t () { @@ -137,26 +137,23 @@ struct hb_hashmap_t }; hb_object_header_t header; - unsigned int successful : 1; /* Allocations successful */ - unsigned int population : 31; /* Not including tombstones. */ + bool successful; /* Allocations successful */ + unsigned short max_chain_length; + unsigned int population; /* Not including tombstones. */ unsigned int occupancy; /* Including tombstones. */ unsigned int mask; unsigned int prime; - unsigned int max_chain_length; item_t *items; - friend void swap (hb_hashmap_t& a, hb_hashmap_t& b) + friend void swap (hb_hashmap_t& a, hb_hashmap_t& b) noexcept { if (unlikely (!a.successful || !b.successful)) return; - unsigned tmp = a.population; - a.population = b.population; - b.population = tmp; - //hb_swap (a.population, b.population); + hb_swap (a.max_chain_length, b.max_chain_length); + hb_swap (a.population, b.population); hb_swap (a.occupancy, b.occupancy); hb_swap (a.mask, b.mask); hb_swap (a.prime, b.prime); - hb_swap (a.max_chain_length, b.max_chain_length); hb_swap (a.items, b.items); } void init () @@ -164,10 +161,10 @@ struct hb_hashmap_t hb_object_init (this); successful = true; + max_chain_length = 0; population = occupancy = 0; mask = 0; prime = 0; - max_chain_length = 0; items = nullptr; } void fini () @@ -558,7 +555,7 @@ struct hb_map_t : hb_hashmap_t lst) : hashmap (lst) {} diff --git a/src/3rdparty/harfbuzz-ng/src/hb-object.hh b/src/3rdparty/harfbuzz-ng/src/hb-object.hh index e2c2c3394cb..5cffe1666b9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-object.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-object.hh @@ -325,7 +325,7 @@ retry: hb_user_data_array_t *user_data = obj->header.user_data.get_acquire (); if (unlikely (!user_data)) { - user_data = (hb_user_data_array_t *) hb_calloc (sizeof (hb_user_data_array_t), 1); + user_data = (hb_user_data_array_t *) hb_calloc (1, sizeof (hb_user_data_array_t)); if (unlikely (!user_data)) return false; user_data->init (); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh index 6967bca3d4b..9c11f14344c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh @@ -985,6 +985,13 @@ struct SortedArrayOf : ArrayOf return_trace (ret); } + SortedArrayOf* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + SortedArrayOf* out = reinterpret_cast (ArrayOf::copy (c)); + return_trace (out); + } + template Type &bsearch (const T &x, Type ¬_found = Crap (Type)) { return *as_array ().bsearch (x, ¬_found); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh index 4fdba197ac7..c7c3264c086 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh @@ -41,10 +41,21 @@ using namespace OT; using objidx_t = hb_serialize_context_t::objidx_t; using whence_t = hb_serialize_context_t::whence_t; -/* utility macro */ -template -static inline const Type& StructAtOffsetOrNull (const void *P, unsigned int offset) -{ return offset ? StructAtOffset (P, offset) : Null (Type); } +/* CFF offsets can technically be negative */ +template +static inline const Type& StructAtOffsetOrNull (const void *P, int offset, hb_sanitize_context_t &sc, Ts&&... ds) +{ + if (!offset) return Null (Type); + + const char *p = (const char *) P + offset; + if (!sc.check_point (p)) return Null (Type); + + const Type &obj = *reinterpret_cast (p); + if (!obj.sanitize (&sc, std::forward (ds)...)) return Null (Type); + + return obj; +} + struct code_pair_t { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh index c869e90554b..1bbd4638410 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh @@ -763,9 +763,9 @@ struct cff1_top_dict_values_t : top_dict_values_t unsigned int ros_supplement; unsigned int cidCount; - unsigned int EncodingOffset; - unsigned int CharsetOffset; - unsigned int FDSelectOffset; + int EncodingOffset; + int CharsetOffset; + int FDSelectOffset; table_info_t privateDictInfo; }; @@ -821,24 +821,24 @@ struct cff1_top_dict_opset_t : top_dict_opset_t break; case OpCode_Encoding: - dictval.EncodingOffset = env.argStack.pop_uint (); + dictval.EncodingOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.EncodingOffset == 0)) return; break; case OpCode_charset: - dictval.CharsetOffset = env.argStack.pop_uint (); + dictval.CharsetOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.CharsetOffset == 0)) return; break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_Private: - dictval.privateDictInfo.offset = env.argStack.pop_uint (); + dictval.privateDictInfo.offset = env.argStack.pop_int (); dictval.privateDictInfo.size = env.argStack.pop_uint (); env.clear_args (); break; @@ -913,7 +913,7 @@ struct cff1_private_dict_values_base_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int subrsOffset; + int subrsOffset; const CFF1Subrs *localSubrs; }; @@ -948,7 +948,7 @@ struct cff1_private_dict_opset_t : dict_opset_t env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -990,7 +990,7 @@ struct cff1_private_dict_opset_subset_t : dict_opset_t break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -1090,8 +1090,8 @@ struct cff1 goto fail; hb_barrier (); - topDictIndex = &StructAtOffset (nameIndex, nameIndex->get_size ()); - if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0)) + topDictIndex = &StructAtOffsetOrNull (nameIndex, nameIndex->get_size (), sc); + if (topDictIndex == &Null (CFF1TopDictIndex) || (topDictIndex->count == 0)) goto fail; hb_barrier (); @@ -1108,20 +1108,18 @@ struct cff1 charset = &Null (Charset); else { - charset = &StructAtOffsetOrNull (cff, topDict.CharsetOffset); - if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc, &num_charset_entries))) goto fail; - hb_barrier (); + charset = &StructAtOffsetOrNull (cff, topDict.CharsetOffset, sc, &num_charset_entries); + if (unlikely (charset == &Null (Charset))) goto fail; } fdCount = 1; if (is_CID ()) { - fdArray = &StructAtOffsetOrNull (cff, topDict.FDArrayOffset); - fdSelect = &StructAtOffsetOrNull (cff, topDict.FDSelectOffset); - if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) || - (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count))) + fdArray = &StructAtOffsetOrNull (cff, topDict.FDArrayOffset, sc); + fdSelect = &StructAtOffsetOrNull (cff, topDict.FDSelectOffset, sc, fdArray->count); + if (unlikely (fdArray == &Null (CFF1FDArray) || + fdSelect == &Null (CFF1FDSelect))) goto fail; - hb_barrier (); fdCount = fdArray->count; } @@ -1140,27 +1138,19 @@ struct cff1 { if (!is_predef_encoding ()) { - encoding = &StructAtOffsetOrNull (cff, topDict.EncodingOffset); - if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) goto fail; - hb_barrier (); + encoding = &StructAtOffsetOrNull (cff, topDict.EncodingOffset, sc); + if (unlikely (encoding == &Null (Encoding))) goto fail; } } - stringIndex = &StructAtOffset (topDictIndex, topDictIndex->get_size ()); - if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc)) + stringIndex = &StructAtOffsetOrNull (topDictIndex, topDictIndex->get_size (), sc); + if (stringIndex == &Null (CFF1StringIndex)) goto fail; - hb_barrier (); - globalSubrs = &StructAtOffset (stringIndex, stringIndex->get_size ()); - if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc)) + globalSubrs = &StructAtOffsetOrNull (stringIndex, stringIndex->get_size (), sc); + charStrings = &StructAtOffsetOrNull (cff, topDict.charStringsOffset, sc); + if (charStrings == &Null (CFF1CharStrings)) goto fail; - hb_barrier (); - - charStrings = &StructAtOffsetOrNull (cff, topDict.charStringsOffset); - - if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc))) - goto fail; - hb_barrier (); num_glyphs = charStrings->count; if (num_glyphs != sc.get_num_glyphs ()) @@ -1188,19 +1178,13 @@ struct cff1 font->init (); if (unlikely (!font_interp.interpret (*font))) goto fail; PRIVDICTVAL *priv = &privateDicts[i]; - const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; - hb_barrier (); + const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); num_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); priv->init (); if (unlikely (!priv_interp.interpret (*priv))) goto fail; - priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null (CFF1Subrs) && - unlikely (!priv->localSubrs->sanitize (&sc))) - goto fail; - hb_barrier (); + priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset, sc); } } else /* non-CID */ @@ -1208,18 +1192,13 @@ struct cff1 cff1_top_dict_values_t *font = &topDict; PRIVDICTVAL *priv = &privateDicts[0]; - const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; - hb_barrier (); + const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); num_interp_env_t env (privDictStr); dict_interpreter_t priv_interp (env); priv->init (); if (unlikely (!priv_interp.interpret (*priv))) goto fail; - priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset); - if (priv->localSubrs != &Null (CFF1Subrs) && - unlikely (!priv->localSubrs->sanitize (&sc))) - goto fail; + priv->localSubrs = &StructAtOffsetOrNull (&privDictStr, priv->subrsOffset, sc); hb_barrier (); } @@ -1437,7 +1416,7 @@ struct cff1 hb_sorted_vector_t *names = glyph_names.get_acquire (); if (unlikely (!names)) { - names = (hb_sorted_vector_t *) hb_calloc (sizeof (hb_sorted_vector_t), 1); + names = (hb_sorted_vector_t *) hb_calloc (1, sizeof (hb_sorted_vector_t)); if (likely (names)) { names->init (); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh index 652748b7375..4b3bdc93159 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh @@ -111,7 +111,7 @@ struct CFF2FDSelect DEFINE_SIZE_MIN (2); }; -struct CFF2VariationStore +struct CFF2ItemVariationStore { bool sanitize (hb_sanitize_context_t *c) const { @@ -122,11 +122,11 @@ struct CFF2VariationStore varStore.sanitize (c)); } - bool serialize (hb_serialize_context_t *c, const CFF2VariationStore *varStore) + bool serialize (hb_serialize_context_t *c, const CFF2ItemVariationStore *varStore) { TRACE_SERIALIZE (this); unsigned int size_ = varStore->get_size (); - CFF2VariationStore *dest = c->allocate_size (size_); + CFF2ItemVariationStore *dest = c->allocate_size (size_); if (unlikely (!dest)) return_trace (false); hb_memcpy (dest, varStore, size_); return_trace (true); @@ -135,9 +135,9 @@ struct CFF2VariationStore unsigned int get_size () const { return HBUINT16::static_size + size; } HBUINT16 size; - VariationStore varStore; + ItemVariationStore varStore; - DEFINE_SIZE_MIN (2 + VariationStore::min_size); + DEFINE_SIZE_MIN (2 + ItemVariationStore::min_size); }; struct cff2_top_dict_values_t : top_dict_values_t<> @@ -150,8 +150,8 @@ struct cff2_top_dict_values_t : top_dict_values_t<> } void fini () { top_dict_values_t<>::fini (); } - unsigned int vstoreOffset; - unsigned int FDSelectOffset; + int vstoreOffset; + int FDSelectOffset; }; struct cff2_top_dict_opset_t : top_dict_opset_t<> @@ -169,11 +169,11 @@ struct cff2_top_dict_opset_t : top_dict_opset_t<> break; case OpCode_vstore: - dictval.vstoreOffset = env.argStack.pop_uint (); + dictval.vstoreOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -241,7 +241,7 @@ struct cff2_private_dict_values_base_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int subrsOffset; + int subrsOffset; const CFF2Subrs *localSubrs; unsigned int ivs; }; @@ -295,7 +295,7 @@ struct cff2_private_dict_opset_t : dict_opset_t env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_vsindexdict: @@ -344,7 +344,7 @@ struct cff2_private_dict_opset_subset_t : dict_opset_t return; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -426,18 +426,15 @@ struct cff2 if (unlikely (!top_interp.interpret (topDict))) goto fail; } - globalSubrs = &StructAtOffset (cff2, cff2->topDict + cff2->topDictSize); - varStore = &StructAtOffsetOrNull (cff2, topDict.vstoreOffset); - charStrings = &StructAtOffsetOrNull (cff2, topDict.charStringsOffset); - fdArray = &StructAtOffsetOrNull (cff2, topDict.FDArrayOffset); - fdSelect = &StructAtOffsetOrNull (cff2, topDict.FDSelectOffset); + globalSubrs = &StructAtOffsetOrNull (cff2, cff2->topDict + cff2->topDictSize, sc); + varStore = &StructAtOffsetOrNull (cff2, topDict.vstoreOffset, sc); + charStrings = &StructAtOffsetOrNull (cff2, topDict.charStringsOffset, sc); + fdArray = &StructAtOffsetOrNull (cff2, topDict.FDArrayOffset, sc); + fdSelect = &StructAtOffsetOrNull (cff2, topDict.FDSelectOffset, sc, fdArray->count); - if (((varStore != &Null (CFF2VariationStore)) && unlikely (!varStore->sanitize (&sc))) || - (charStrings == &Null (CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) || - (globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) || - (fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) || - !hb_barrier () || - (((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count))))) + if (charStrings == &Null (CFF2CharStrings) || + globalSubrs == &Null (CFF2Subrs) || + fdArray == &Null (CFF2FDArray)) goto fail; num_glyphs = charStrings->count; @@ -462,19 +459,13 @@ struct cff2 font->init (); if (unlikely (!font_interp.interpret (*font))) goto fail; - const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff2, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); - if (unlikely (!privDictStr.sanitize (&sc))) goto fail; - hb_barrier (); + const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff2, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); cff2_priv_dict_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); privateDicts[i].init (); if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail; - privateDicts[i].localSubrs = &StructAtOffsetOrNull (&privDictStr[0], privateDicts[i].subrsOffset); - if (privateDicts[i].localSubrs != &Null (CFF2Subrs) && - unlikely (!privateDicts[i].localSubrs->sanitize (&sc))) - goto fail; - hb_barrier (); + privateDicts[i].localSubrs = &StructAtOffsetOrNull (&privDictStr[0], privateDicts[i].subrsOffset, sc); } return; @@ -509,7 +500,7 @@ struct cff2 hb_blob_t *blob = nullptr; cff2_top_dict_values_t topDict; const CFF2Subrs *globalSubrs = nullptr; - const CFF2VariationStore *varStore = nullptr; + const CFF2ItemVariationStore *varStore = nullptr; const CFF2CharStrings *charStrings = nullptr; const CFF2FDArray *fdArray = nullptr; const CFF2FDSelect *fdSelect = nullptr; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh index e2e25818557..64d2b138804 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh @@ -41,6 +41,30 @@ namespace OT { +static inline uint8_t unicode_to_macroman (hb_codepoint_t u) +{ + uint16_t mapping[] = { + 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, + 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, + 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, + 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, + 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, + 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, + 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, + 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8, + 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, + 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, + 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02, + 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, + 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, + 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, + 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7 + }; + uint16_t *c = hb_bsearch (u, mapping, ARRAY_LENGTH (mapping), sizeof (mapping[0]), + _hb_cmp_operator); + return c ? (c - mapping) + 0x7F : 0; +} struct CmapSubtableFormat0 { @@ -1465,8 +1489,11 @@ struct EncodingRecord int ret; ret = platformID.cmp (other.platformID); if (ret) return ret; - ret = encodingID.cmp (other.encodingID); - if (ret) return ret; + if (other.encodingID != 0xFFFF) + { + ret = encodingID.cmp (other.encodingID); + if (ret) return ret; + } return 0; } @@ -1814,9 +1841,13 @@ struct cmap c->plan)); } - const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const + const CmapSubtable *find_best_subtable (bool *symbol = nullptr, + bool *mac = nullptr, + bool *macroman = nullptr) const { if (symbol) *symbol = false; + if (mac) *mac = false; + if (macroman) *macroman = false; const CmapSubtable *subtable; @@ -1841,6 +1872,20 @@ struct cmap if ((subtable = this->find_subtable (0, 1))) return subtable; if ((subtable = this->find_subtable (0, 0))) return subtable; + /* MacRoman subtable. */ + if ((subtable = this->find_subtable (1, 0))) + { + if (mac) *mac = true; + if (macroman) *macroman = true; + return subtable; + } + /* Any other Mac subtable; we just map ASCII for these. */ + if ((subtable = this->find_subtable (1, 0xFFFF))) + { + if (mac) *mac = true; + return subtable; + } + /* Meh. */ return &Null (CmapSubtable); } @@ -1852,8 +1897,8 @@ struct cmap accelerator_t (hb_face_t *face) { this->table = hb_sanitize_context_t ().reference_table (face); - bool symbol; - this->subtable = table->find_best_subtable (&symbol); + bool symbol, mac, macroman; + this->subtable = table->find_best_subtable (&symbol, &mac, ¯oman); this->subtable_uvs = &Null (CmapSubtableFormat14); { const CmapSubtable *st = table->find_subtable (0, 5); @@ -1862,6 +1907,7 @@ struct cmap } this->get_glyph_data = subtable; +#ifndef HB_NO_CMAP_LEGACY_SUBTABLES if (unlikely (symbol)) { switch ((unsigned) face->table.OS2->get_font_page ()) { @@ -1881,7 +1927,16 @@ struct cmap break; } } + else if (unlikely (macroman)) + { + this->get_glyph_funcZ = get_glyph_from_macroman; + } + else if (unlikely (mac)) + { + this->get_glyph_funcZ = get_glyph_from_ascii; + } else +#endif { switch (subtable->u.format) { /* Accelerate format 4 and format 12. */ @@ -1924,7 +1979,7 @@ struct cmap hb_codepoint_t *glyph, cache_t *cache = nullptr) const { - if (unlikely (!this->get_glyph_funcZ)) return 0; + if (unlikely (!this->get_glyph_funcZ)) return false; return _cached_get (unicode, glyph, cache); } @@ -2006,6 +2061,28 @@ struct cmap return false; } + template + HB_INTERNAL static bool get_glyph_from_ascii (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) + { + const Type *typed_obj = (const Type *) obj; + return codepoint < 0x80 && typed_obj->get_glyph (codepoint, glyph); + } + + template + HB_INTERNAL static bool get_glyph_from_macroman (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) + { + if (get_glyph_from_ascii (obj, codepoint, glyph)) + return true; + + const Type *typed_obj = (const Type *) obj; + unsigned c = unicode_to_macroman (codepoint); + return c && typed_obj->get_glyph (c, glyph); + } + private: hb_nonnull_ptr_t subtable; hb_nonnull_ptr_t subtable_uvs; @@ -2035,28 +2112,6 @@ struct cmap return &(this+result.subtable); } - const EncodingRecord *find_encodingrec (unsigned int platform_id, - unsigned int encoding_id) const - { - EncodingRecord key; - key.platformID = platform_id; - key.encodingID = encoding_id; - - return encodingRecord.as_array ().bsearch (key); - } - - bool find_subtable (unsigned format) const - { - auto it = - + hb_iter (encodingRecord) - | hb_map (&EncodingRecord::subtable) - | hb_map (hb_add (this)) - | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == format; }) - ; - - return it.len (); - } - public: bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc index b3677c6a4c0..1da869d697a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc @@ -208,12 +208,12 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) const OT::HVAR &HVAR = *hmtx.var_table; - const OT::VariationStore &varStore = &HVAR + HVAR.varStore; - OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; + const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; + OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; bool use_cache = font->num_coords; #else - OT::VariationStore::cache_t *varStore_cache = nullptr; + OT::ItemVariationStore::cache_t *varStore_cache = nullptr; bool use_cache = false; #endif @@ -277,7 +277,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, } #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::VariationStore::destroy_cache (varStore_cache); + OT::ItemVariationStore::destroy_cache (varStore_cache); #endif if (font->x_strength && !font->embolden_in_place) @@ -313,10 +313,10 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, { #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) const OT::VVAR &VVAR = *vmtx.var_table; - const OT::VariationStore &varStore = &VVAR + VVAR.varStore; - OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; + const OT::ItemVariationStore &varStore = &VVAR + VVAR.varStore; + OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; #else - OT::VariationStore::cache_t *varStore_cache = nullptr; + OT::ItemVariationStore::cache_t *varStore_cache = nullptr; #endif for (unsigned int i = 0; i < count; i++) @@ -327,7 +327,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, } #if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::VariationStore::destroy_cache (varStore_cache); + OT::ItemVariationStore::destroy_cache (varStore_cache); #endif } else diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh index 89640b43f15..48bd536121d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh @@ -145,6 +145,29 @@ struct hmtxvmtx table->minTrailingBearing = min_rsb; table->maxExtent = max_extent; } + + if (T::is_horizontal) + { + const auto &OS2 = *c->plan->source->table.OS2; + if (OS2.has_data () && + table->ascender == OS2.sTypoAscender && + table->descender == OS2.sTypoDescender && + table->lineGap == OS2.sTypoLineGap) + { + table->ascender = static_cast (roundf (OS2.sTypoAscender + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + table->descender = static_cast (roundf (OS2.sTypoDescender + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + table->lineGap = static_cast (roundf (OS2.sTypoLineGap + + MVAR.get_var (HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, + c->plan->normalized_coords.arrayZ, + c->plan->normalized_coords.length))); + } + } } #endif @@ -374,7 +397,7 @@ struct hmtxvmtx unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, hb_font_t *font, - VariationStore::cache_t *store_cache = nullptr) const + ItemVariationStore::cache_t *store_cache = nullptr) const { unsigned int advance = get_advance_without_var_unscaled (glyph); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh index a23b6377d19..02783990698 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh @@ -46,6 +46,12 @@ struct BaseCoordFormat1 return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + return_trace ((bool) c->serializer->embed (*this)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -67,6 +73,17 @@ struct BaseCoordFormat2 return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (c->serializer->check_assign (out->referenceGlyph, + c->plan->glyph_map->get (referenceGlyph), + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -86,7 +103,7 @@ struct BaseCoordFormat2 struct BaseCoordFormat3 { hb_position_t get_coord (hb_font_t *font, - const VariationStore &var_store, + const ItemVariationStore &var_store, hb_direction_t direction) const { const Device &device = this+deviceTable; @@ -96,6 +113,23 @@ struct BaseCoordFormat3 : font->em_scale_x (coordinate) + device.get_x_delta (font, var_store); } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + unsigned varidx = (this+deviceTable).get_variation_index (); + varidx_set.add (varidx); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, + this, 0, + hb_serialize_context_t::Head, + &c->plan->base_variation_idx_map)); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -120,7 +154,7 @@ struct BaseCoord bool has_data () const { return u.format; } hb_position_t get_coord (hb_font_t *font, - const VariationStore &var_store, + const ItemVariationStore &var_store, hb_direction_t direction) const { switch (u.format) { @@ -131,6 +165,27 @@ struct BaseCoord } } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + switch (u.format) { + case 3: u.format3.collect_variation_indices (varidx_set); + default:return; + } + } + + template + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { + if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format); + switch (u.format) { + case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); + case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); + default:return_trace (c->default_return_value ()); + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -161,12 +216,37 @@ struct FeatMinMaxRecord bool has_data () const { return tag; } + hb_tag_t get_feature_tag () const { return tag; } + void get_min_max (const BaseCoord **min, const BaseCoord **max) const { if (likely (min)) *min = &(this+minCoord); if (likely (max)) *max = &(this+maxCoord); } + void collect_variation_indices (const hb_subset_plan_t* plan, + const void *base, + hb_set_t& varidx_set /* OUT */) const + { + if (!plan->layout_features.has (tag)) + return; + + (base+minCoord).collect_variation_indices (varidx_set); + (base+maxCoord).collect_variation_indices (varidx_set); + } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + if (!(out->minCoord.serialize_subset (c, minCoord, base))) + return_trace (false); + + return_trace (out->maxCoord.serialize_subset (c, maxCoord, base)); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -206,6 +286,39 @@ struct MinMax } } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+minCoord).collect_variation_indices (varidx_set); + (this+maxCoord).collect_variation_indices (varidx_set); + for (const FeatMinMaxRecord& record : featMinMaxRecords) + record.collect_variation_indices (plan, this, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + if (!(out->minCoord.serialize_subset (c, minCoord, this)) || + !(out->maxCoord.serialize_subset (c, maxCoord, this))) + return_trace (false); + + unsigned len = 0; + for (const FeatMinMaxRecord& _ : featMinMaxRecords) + { + hb_tag_t feature_tag = _.get_feature_tag (); + if (!c->plan->layout_features.has (feature_tag)) + continue; + + if (!_.subset (c, this)) return false; + len++; + } + return_trace (c->serializer->check_assign (out->featMinMaxRecords.len, len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -240,6 +353,26 @@ struct BaseValues return this+baseCoords[baseline_tag_index]; } + void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const + { + for (const auto& _ : baseCoords) + (this+_).collect_variation_indices (varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + out->defaultIndex = defaultIndex; + + for (const auto& _ : baseCoords) + if (!subset_offset_array (c, out->baseCoords, this) (_)) + return_trace (false); + + return_trace (bool (out->baseCoords)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -270,6 +403,20 @@ struct BaseLangSysRecord const MinMax &get_min_max () const { return this+minMax; } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { (this+minMax).collect_variation_indices (plan, varidx_set); } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->minMax.serialize_subset (c, minMax, base)); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -300,6 +447,35 @@ struct BaseScript bool has_values () const { return baseValues; } bool has_min_max () const { return defaultMinMax; /* TODO What if only per-language is present? */ } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+baseValues).collect_variation_indices (varidx_set); + (this+defaultMinMax).collect_variation_indices (plan, varidx_set); + + for (const BaseLangSysRecord& _ : baseLangSysRecords) + _.collect_variation_indices (plan, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + if (baseValues && !out->baseValues.serialize_subset (c, baseValues, this)) + return_trace (false); + + if (defaultMinMax && !out->defaultMinMax.serialize_subset (c, defaultMinMax, this)) + return_trace (false); + + for (const auto& _ : baseLangSysRecords) + if (!_.subset (c, this)) return_trace (false); + + return_trace (c->serializer->check_assign (out->baseLangSysRecords.len, baseLangSysRecords.len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -332,9 +508,31 @@ struct BaseScriptRecord bool has_data () const { return baseScriptTag; } + hb_tag_t get_script_tag () const { return baseScriptTag; } + const BaseScript &get_base_script (const BaseScriptList *list) const { return list+baseScript; } + void collect_variation_indices (const hb_subset_plan_t* plan, + const void* list, + hb_set_t& varidx_set /* OUT */) const + { + if (!plan->layout_scripts.has (baseScriptTag)) + return; + + (list+baseScript).collect_variation_indices (plan, varidx_set); + } + + bool subset (hb_subset_context_t *c, + const void *base) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->baseScript.serialize_subset (c, baseScript, base)); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -361,6 +559,33 @@ struct BaseScriptList return record->has_data () ? record->get_base_script (this) : Null (BaseScript); } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + for (const BaseScriptRecord& _ : baseScriptRecords) + _.collect_variation_indices (plan, this, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + unsigned len = 0; + for (const BaseScriptRecord& _ : baseScriptRecords) + { + hb_tag_t script_tag = _.get_script_tag (); + if (!c->plan->layout_scripts.has (script_tag)) + continue; + + if (!_.subset (c, this)) return false; + len++; + } + return_trace (c->serializer->check_assign (out->baseScriptRecords.len, len, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -422,6 +647,20 @@ struct Axis return true; } + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { (this+baseScriptList).collect_variation_indices (plan, varidx_set); } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + out->baseTagList.serialize_copy (c->serializer, baseTagList, this); + return_trace (out->baseScriptList.serialize_subset (c, baseScriptList, this)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -453,8 +692,41 @@ struct BASE const Axis &get_axis (hb_direction_t direction) const { return HB_DIRECTION_IS_VERTICAL (direction) ? this+vAxis : this+hAxis; } - const VariationStore &get_var_store () const - { return version.to_int () < 0x00010001u ? Null (VariationStore) : this+varStore; } + bool has_var_store () const + { return version.to_int () >= 0x00010001u && varStore != 0; } + + const ItemVariationStore &get_var_store () const + { return version.to_int () < 0x00010001u ? Null (ItemVariationStore) : this+varStore; } + + void collect_variation_indices (const hb_subset_plan_t* plan, + hb_set_t& varidx_set /* OUT */) const + { + (this+hAxis).collect_variation_indices (plan, varidx_set); + (this+vAxis).collect_variation_indices (plan, varidx_set); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + out->version = version; + if (hAxis && !out->hAxis.serialize_subset (c, hAxis, this)) + return_trace (false); + + if (vAxis && !out->vAxis.serialize_subset (c, vAxis, this)) + return_trace (false); + + if (has_var_store ()) + { + if (!c->serializer->allocate_size> (Offset32To::static_size)) + return_trace (false); + return_trace (out->varStore.serialize_subset (c, varStore, this, c->plan->base_varstore_inner_maps.as_array ())); + } + + return_trace (true); + } bool get_baseline (hb_font_t *font, hb_tag_t baseline_tag, @@ -487,7 +759,7 @@ struct BASE &min_coord, &max_coord)) return false; - const VariationStore &var_store = get_var_store (); + const ItemVariationStore &var_store = get_var_store (); if (likely (min && min_coord)) *min = min_coord->get_coord (font, var_store, direction); if (likely (max && max_coord)) *max = max_coord->get_coord (font, var_store, direction); return true; @@ -510,7 +782,7 @@ struct BASE * of BASE table (may be NULL) */ Offset16TovAxis; /* Offset to vertical Axis table, from beginning * of BASE table (may be NULL) */ - Offset32To + Offset32To varStore; /* Offset to the table of Item Variation * Store--from beginning of BASE * header (may be NULL). Introduced diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh index 6b359cceb72..aba427368ca 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh @@ -188,7 +188,7 @@ struct hb_subset_layout_context_t : unsigned lookup_index_count; }; -struct VariationStore; +struct ItemVariationStore; struct hb_collect_variation_indices_context_t : hb_dispatch_context_t { @@ -3036,7 +3036,7 @@ struct VarData DEFINE_SIZE_ARRAY (6, regionIndices); }; -struct VariationStore +struct ItemVariationStore { friend struct item_variations_t; using cache_t = VarRegionList::cache_t; @@ -3141,7 +3141,7 @@ struct VariationStore } bool serialize (hb_serialize_context_t *c, - const VariationStore *src, + const ItemVariationStore *src, const hb_array_t &inner_maps) { TRACE_SERIALIZE (this); @@ -3197,7 +3197,7 @@ struct VariationStore return_trace (true); } - VariationStore *copy (hb_serialize_context_t *c) const + ItemVariationStore *copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); auto *out = c->start_embed (this); @@ -3227,7 +3227,7 @@ struct VariationStore return_trace (false); #endif - VariationStore *varstore_prime = c->serializer->start_embed (); + ItemVariationStore *varstore_prime = c->serializer->start_embed (); if (unlikely (!varstore_prime)) return_trace (false); varstore_prime->serialize (c->serializer, this, inner_maps); @@ -4030,13 +4030,13 @@ struct VariationDevice private: hb_position_t get_x_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { return font->em_scalef_x (get_delta (font, store, store_cache)); } hb_position_t get_y_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { return font->em_scalef_y (get_delta (font, store, store_cache)); } VariationDevice* copy (hb_serialize_context_t *c, @@ -4070,10 +4070,10 @@ struct VariationDevice private: float get_delta (hb_font_t *font, - const VariationStore &store, - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store, + ItemVariationStore::cache_t *store_cache = nullptr) const { - return store.get_delta (varIdx, font->coords, font->num_coords, (VariationStore::cache_t *) store_cache); + return store.get_delta (varIdx, font->coords, font->num_coords, (ItemVariationStore::cache_t *) store_cache); } protected: @@ -4097,8 +4097,8 @@ struct DeviceHeader struct Device { hb_position_t get_x_delta (hb_font_t *font, - const VariationStore &store=Null (VariationStore), - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store=Null (ItemVariationStore), + ItemVariationStore::cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -4115,8 +4115,8 @@ struct Device } } hb_position_t get_y_delta (hb_font_t *font, - const VariationStore &store=Null (VariationStore), - VariationStore::cache_t *store_cache = nullptr) const + const ItemVariationStore &store=Null (ItemVariationStore), + ItemVariationStore::cache_t *store_cache = nullptr) const { switch (u.b.format) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh index 499ad673e42..c65ea32b8a0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh @@ -708,8 +708,8 @@ struct hb_ot_apply_context_t : recurse_func_t recurse_func = nullptr; const GDEF &gdef; const GDEF::accelerator_t &gdef_accel; - const VariationStore &var_store; - VariationStore::cache_t *var_store_cache; + const ItemVariationStore &var_store; + ItemVariationStore::cache_t *var_store_cache; hb_set_digest_t digest; hb_direction_t direction; @@ -723,7 +723,6 @@ struct hb_ot_apply_context_t : bool auto_zwj = true; bool per_syllable = false; bool random = false; - uint32_t random_state = 1; unsigned new_syllables = (unsigned) -1; signed last_base = -1; // GPOS uses @@ -766,7 +765,7 @@ struct hb_ot_apply_context_t : ~hb_ot_apply_context_t () { #ifndef HB_NO_VAR - VariationStore::destroy_cache (var_store_cache); + ItemVariationStore::destroy_cache (var_store_cache); #endif } @@ -788,8 +787,8 @@ struct hb_ot_apply_context_t : uint32_t random_number () { /* http://www.cplusplus.com/reference/random/minstd_rand/ */ - random_state = random_state * 48271 % 2147483647; - return random_state; + buffer->random_state = buffer->random_state * 48271 % 2147483647; + return buffer->random_state; } bool match_properties_mark (hb_codepoint_t glyph, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc index 2eb8535db5a..a4c13abadf2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc @@ -2127,7 +2127,7 @@ hb_ot_layout_get_font_extents (hb_font_t *font, hb_tag_t language_tag, hb_font_extents_t *extents) { - hb_position_t min, max; + hb_position_t min = 0, max = 0; if (font->face->table.BASE->get_min_max (font, direction, script_tag, language_tag, HB_TAG_NONE, &min, &max)) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh index 32e497aef60..5839059fde0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh @@ -344,27 +344,20 @@ struct MathKern const MathValueRecord* kernValue = mathValueRecordsZ.arrayZ + heightCount; int sign = font->y_scale < 0 ? -1 : +1; - /* The description of the MathKern table is a ambiguous, but interpreting - * "between the two heights found at those indexes" for 0 < i < len as - * - * correctionHeight[i-1] < correction_height <= correctionHeight[i] - * - * makes the result consistent with the limit cases and we can just use the - * binary search algorithm of std::upper_bound: + /* According to OpenType spec (v1.9), except for the boundary cases, the index + * chosen for kern value should be i such that + * correctionHeight[i-1] <= correction_height < correctionHeight[i] + * We can use the binary search algorithm of std::upper_bound(). Or, we can + * use the internal hb_bsearch_impl. */ - unsigned int i = 0; - unsigned int count = heightCount; - while (count > 0) - { - unsigned int half = count / 2; - hb_position_t height = correctionHeight[i + half].get_y_value (font, this); - if (sign * height < sign * correction_height) - { - i += half + 1; - count -= half + 1; - } else - count = half; - } + unsigned int pos; + auto cmp = +[](const void* key, const void* p, + int sign, hb_font_t* font, const MathKern* mathKern) -> int { + return sign * *(hb_position_t*)key - sign * ((MathValueRecord*)p)->get_y_value(font, mathKern); + }; + unsigned int i = hb_bsearch_impl(&pos, correction_height, correctionHeight, + heightCount, MathValueRecord::static_size, + cmp, sign, font, this) ? pos + 1 : pos; return kernValue[i].get_x_value (font, this); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh index 8c2e696f56c..43b58d9bbf9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh @@ -223,7 +223,7 @@ struct OS2 } } - return num ? (unsigned) roundf (total_width / num) : 0; + return num ? (unsigned) roundf ((double) total_width / (double) num) : 0; } bool subset (hb_subset_context_t *c) const @@ -284,12 +284,12 @@ struct OS2 os2_prime->usWidthClass = width_class; } - if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES) - return_trace (true); - os2_prime->usFirstCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_min ()); os2_prime->usLastCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_max ()); + if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES) + return_trace (true); + _update_unicode_ranges (&c->plan->unicodes, os2_prime->ulUnicodeRange); return_trace (true); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc index 90f596ae79d..148830022ef 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc @@ -155,7 +155,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, #endif bool has_gpos = !disable_gpos && hb_ot_layout_has_positioning (face); if (false) - ; + {} #ifndef HB_NO_AAT_SHAPE /* Prefer GPOS over kerx if GSUB is present; * https://github.com/harfbuzz/harfbuzz/issues/3008 */ @@ -167,15 +167,16 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos)) { + if (false) {} #ifndef HB_NO_AAT_SHAPE - if (has_kerx) + else if (has_kerx) plan.apply_kerx = true; - else #endif #ifndef HB_NO_OT_KERN - if (hb_ot_layout_has_kerning (face)) + else if (hb_ot_layout_has_kerning (face)) plan.apply_kern = true; #endif + else {} } plan.apply_fallback_kern = !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.cc index 72dcc84df5e..d70746ed2bb 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.cc @@ -560,9 +560,9 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, DEBUG_MSG (ARABIC, nullptr, "%s stretch at (%u,%u,%u)", step == MEASURE ? "measuring" : "cutting", context, start, end); - DEBUG_MSG (ARABIC, nullptr, "rest of word: count=%u width %d", start - context, w_total); - DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%d", n_fixed, w_fixed); - DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%d", n_repeating, w_repeating); + DEBUG_MSG (ARABIC, nullptr, "rest of word: count=%u width %" PRId32, start - context, w_total); + DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%" PRId32, n_fixed, w_fixed); + DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%" PRId32, n_repeating, w_repeating); /* Number of additional times to repeat each repeating tile. */ int n_copies = 0; @@ -602,7 +602,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, if (info[k - 1].arabic_shaping_action() == STCH_REPEATING) repeat += n_copies; - DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %u; j=%u", + DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %" PRIu32 "; j=%u", repeat, info[k - 1].codepoint, j); pos[k - 1].x_advance = 0; for (unsigned int n = 0; n < repeat; n++) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh index 58b3cd74dff..e88c82a13c7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh @@ -349,7 +349,7 @@ struct AxisValueFormat4 struct AxisValue { - bool get_value (unsigned int axis_index) const + float get_value (unsigned int axis_index) const { switch (u.format) { @@ -357,7 +357,7 @@ struct AxisValue case 2: return u.format2.get_value (); case 3: return u.format3.get_value (); case 4: return u.format4.get_axis_record (axis_index).get_value (); - default:return 0; + default:return 0.f; } } @@ -485,7 +485,7 @@ struct STAT hb_array_t> axis_values = get_axis_value_offsets (); for (unsigned int i = 0; i < axis_values.length; i++) { - const AxisValue& axis_value = this+axis_values[i]; + const AxisValue& axis_value = this+offsetToAxisValueOffsets+axis_values[i]; if (axis_value.get_axis_index () == axis_index) { if (value) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh index 032a7c866c5..db92f4664a9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh @@ -6,8 +6,8 @@ * * on files with these headers: * - * - * File-Date: 2023-08-02 + * + * File-Date: 2024-03-07 */ #ifndef HB_OT_TAG_TABLE_HH @@ -31,7 +31,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('b','i',' ',' '), HB_TAG('B','I','S',' ')}, /* Bislama */ {HB_TAG('b','i',' ',' '), HB_TAG('C','P','P',' ')}, /* Bislama -> Creoles */ {HB_TAG('b','m',' ',' '), HB_TAG('B','M','B',' ')}, /* Bambara (Bamanankan) */ - {HB_TAG('b','n',' ',' '), HB_TAG('B','E','N',' ')}, /* Bengali */ + {HB_TAG('b','n',' ',' '), HB_TAG('B','E','N',' ')}, /* Bangla */ {HB_TAG('b','o',' ',' '), HB_TAG('T','I','B',' ')}, /* Tibetan */ {HB_TAG('b','r',' ',' '), HB_TAG('B','R','E',' ')}, /* Breton */ {HB_TAG('b','s',' ',' '), HB_TAG('B','O','S',' ')}, /* Bosnian */ @@ -64,7 +64,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('f','r',' ',' '), HB_TAG('F','R','A',' ')}, /* French */ {HB_TAG('f','y',' ',' '), HB_TAG('F','R','I',' ')}, /* Western Frisian -> Frisian */ {HB_TAG('g','a',' ',' '), HB_TAG('I','R','I',' ')}, /* Irish */ - {HB_TAG('g','d',' ',' '), HB_TAG('G','A','E',' ')}, /* Scottish Gaelic (Gaelic) */ + {HB_TAG('g','d',' ',' '), HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */ {HB_TAG('g','l',' ',' '), HB_TAG('G','A','L',' ')}, /* Galician */ {HB_TAG('g','n',' ',' '), HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */ {HB_TAG('g','u',' ',' '), HB_TAG('G','U','J',' ')}, /* Gujarati */ @@ -132,7 +132,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('m','l',' ',' '), HB_TAG('M','A','L',' ')}, /* Malayalam -> Malayalam Traditional */ {HB_TAG('m','l',' ',' '), HB_TAG('M','L','R',' ')}, /* Malayalam -> Malayalam Reformed */ {HB_TAG('m','n',' ',' '), HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */ - {HB_TAG('m','o',' ',' '), HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */ + {HB_TAG('m','o',' ',' '), HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) -> Romanian (Moldova) */ {HB_TAG('m','o',' ',' '), HB_TAG('R','O','M',' ')}, /* Moldavian (retired code) -> Romanian */ {HB_TAG('m','r',' ',' '), HB_TAG('M','A','R',' ')}, /* Marathi */ {HB_TAG('m','s',' ',' '), HB_TAG('M','L','Y',' ')}, /* Malay [macrolanguage] */ @@ -153,7 +153,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('o','c',' ',' '), HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */ {HB_TAG('o','j',' ',' '), HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] -> Ojibway */ {HB_TAG('o','m',' ',' '), HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */ - {HB_TAG('o','r',' ',' '), HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) [macrolanguage] */ + {HB_TAG('o','r',' ',' '), HB_TAG('O','R','I',' ')}, /* Odia [macrolanguage] */ {HB_TAG('o','s',' ',' '), HB_TAG('O','S','S',' ')}, /* Ossetian */ {HB_TAG('p','a',' ',' '), HB_TAG('P','A','N',' ')}, /* Punjabi */ {HB_TAG('p','i',' ',' '), HB_TAG('P','A','L',' ')}, /* Pali */ @@ -166,7 +166,7 @@ static const LangTag ot_languages2[] = { {HB_TAG('r','o',' ',' '), HB_TAG('R','O','M',' ')}, /* Romanian */ {HB_TAG('r','u',' ',' '), HB_TAG('R','U','S',' ')}, /* Russian */ {HB_TAG('r','w',' ',' '), HB_TAG('R','U','A',' ')}, /* Kinyarwanda */ - {HB_TAG('s','a',' ',' '), HB_TAG('S','A','N',' ')}, /* Sanskrit */ + {HB_TAG('s','a',' ',' '), HB_TAG('S','A','N',' ')}, /* Sanskrit [macrolanguage] */ {HB_TAG('s','c',' ',' '), HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */ {HB_TAG('s','d',' ',' '), HB_TAG('S','N','D',' ')}, /* Sindhi */ {HB_TAG('s','e',' ',' '), HB_TAG('N','S','M',' ')}, /* Northern Sami */ @@ -465,6 +465,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('c','l','d',' '), HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic -> Syriac */ {HB_TAG('c','l','e',' '), HB_TAG('C','C','H','N')}, /* Lealao Chinantec -> Chinantec */ {HB_TAG('c','l','j',' '), HB_TAG('Q','I','N',' ')}, /* Laitu Chin -> Chin */ + {HB_TAG('c','l','s',' '), HB_TAG('S','A','N',' ')}, /* Classical Sanskrit -> Sanskrit */ {HB_TAG('c','l','t',' '), HB_TAG('Q','I','N',' ')}, /* Lautu Chin -> Chin */ {HB_TAG('c','m','n',' '), HB_TAG('Z','H','S',' ')}, /* Mandarin Chinese -> Chinese, Simplified */ {HB_TAG('c','m','r',' '), HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin -> Chin */ @@ -637,7 +638,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('g','a','a',' '), HB_TAG('G','A','D',' ')}, /* Ga */ {HB_TAG('g','a','c',' '), HB_TAG('C','P','P',' ')}, /* Mixed Great Andamanese -> Creoles */ {HB_TAG('g','a','d',' '), HB_TAG_NONE }, /* Gaddang != Ga */ - {HB_TAG('g','a','e',' '), HB_TAG_NONE }, /* Guarequena != Scottish Gaelic (Gaelic) */ + {HB_TAG('g','a','e',' '), HB_TAG_NONE }, /* Guarequena != Scottish Gaelic */ /*{HB_TAG('g','a','g',' '), HB_TAG('G','A','G',' ')},*/ /* Gagauz */ {HB_TAG('g','a','l',' '), HB_TAG_NONE }, /* Galolen != Galician */ {HB_TAG('g','a','n',' '), HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese, Simplified */ @@ -1160,7 +1161,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('o','r','o',' '), HB_TAG_NONE }, /* Orokolo != Oromo */ {HB_TAG('o','r','r',' '), HB_TAG('I','J','O',' ')}, /* Oruma -> Ijo */ {HB_TAG('o','r','s',' '), HB_TAG('M','L','Y',' ')}, /* Orang Seletar -> Malay */ - {HB_TAG('o','r','y',' '), HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) */ + {HB_TAG('o','r','y',' '), HB_TAG('O','R','I',' ')}, /* Odia */ {HB_TAG('o','t','w',' '), HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */ {HB_TAG('o','u','a',' '), HB_TAG('B','B','R',' ')}, /* Tagargrent -> Berber */ {HB_TAG('p','a','a',' '), HB_TAG_NONE }, /* Papuan [collection] != Palestinian Aramaic */ @@ -1395,7 +1396,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('s','n','k',' '), HB_TAG('S','N','K',' ')},*/ /* Soninke */ {HB_TAG('s','o','g',' '), HB_TAG_NONE }, /* Sogdian != Sodo Gurage */ /*{HB_TAG('s','o','p',' '), HB_TAG('S','O','P',' ')},*/ /* Songe */ - {HB_TAG('s','p','v',' '), HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia (formerly Oriya) */ + {HB_TAG('s','p','v',' '), HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia */ {HB_TAG('s','p','y',' '), HB_TAG('K','A','L',' ')}, /* Sabaot -> Kalenjin */ {HB_TAG('s','r','b',' '), HB_TAG_NONE }, /* Sora != Serbian */ {HB_TAG('s','r','c',' '), HB_TAG('S','R','D',' ')}, /* Logudorese Sardinian -> Sardinian */ @@ -1533,6 +1534,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('v','l','s',' '), HB_TAG('F','L','E',' ')}, /* Vlaams -> Dutch (Flemish) */ {HB_TAG('v','m','w',' '), HB_TAG('M','A','K',' ')}, /* Makhuwa */ /*{HB_TAG('v','r','o',' '), HB_TAG('V','R','O',' ')},*/ /* Võro */ + {HB_TAG('v','s','n',' '), HB_TAG('S','A','N',' ')}, /* Vedic Sanskrit -> Sanskrit */ {HB_TAG('w','a','g',' '), HB_TAG_NONE }, /* Wa'ema != Wagdi */ /*{HB_TAG('w','a','r',' '), HB_TAG('W','A','R',' ')},*/ /* Waray (Philippines) -> Waray-Waray */ {HB_TAG('w','b','m',' '), HB_TAG('W','A',' ',' ')}, /* Wa */ @@ -2643,7 +2645,7 @@ out: /* Romanian; Moldova */ unsigned int i; hb_tag_t possible_tags[] = { - HB_TAG('M','O','L',' '), /* Moldavian */ + HB_TAG('M','O','L',' '), /* Romanian (Moldova) */ HB_TAG('R','O','M',' '), /* Romanian */ }; for (i = 0; i < 2 && i < *count; i++) @@ -2920,7 +2922,7 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("mn", -1); /* Mongolian [macrolanguage] */ case HB_TAG('M','N','K',' '): /* Maninka */ return hb_language_from_string ("man", -1); /* Mandingo [macrolanguage] */ - case HB_TAG('M','O','L',' '): /* Moldavian */ + case HB_TAG('M','O','L',' '): /* Romanian (Moldova) */ return hb_language_from_string ("ro-MD", -1); /* Romanian; Moldova */ case HB_TAG('M','O','N','T'): /* Thailand Mon */ return hb_language_from_string ("mnw-TH", -1); /* Mon; Thailand */ @@ -2958,6 +2960,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("ro", -1); /* Romanian */ case HB_TAG('R','O','Y',' '): /* Romany */ return hb_language_from_string ("rom", -1); /* Romany [macrolanguage] */ + case HB_TAG('S','A','N',' '): /* Sanskrit */ + return hb_language_from_string ("sa", -1); /* Sanskrit [macrolanguage] */ case HB_TAG('S','Q','I',' '): /* Albanian */ return hb_language_from_string ("sq", -1); /* Albanian [macrolanguage] */ case HB_TAG('S','R','B',' '): /* Serbian */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc index 53b6b38f66d..0c63756b14d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc @@ -547,7 +547,7 @@ hb_ot_tag_to_language (hb_tag_t tag) buf[3] = '-'; str += 4; } - snprintf (str, 16, "x-hbot-%08x", tag); + snprintf (str, 16, "x-hbot-%08" PRIx32, tag); return hb_language_from_string (&*buf, -1); } } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh index b2e5d87a3cf..9149959d792 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh @@ -57,7 +57,7 @@ struct avarV2Tail protected: Offset32To varIdxMap; /* Offset from the beginning of 'avar' table. */ - Offset32To varStore; /* Offset from the beginning of 'avar' table. */ + Offset32To varStore; /* Offset from the beginning of 'avar' table. */ public: DEFINE_SIZE_STATIC (8); @@ -230,7 +230,7 @@ struct SegmentMaps : Array16Of * duplicates here */ if (mapping.must_include ()) continue; - value_mappings.push (std::move (mapping)); + value_mappings.push (mapping); } AxisValueMap m; @@ -343,7 +343,7 @@ struct avar for (unsigned i = 0; i < coords_length; i++) coords[i] = out[i]; - OT::VariationStore::destroy_cache (var_store_cache); + OT::ItemVariationStore::destroy_cache (var_store_cache); #endif } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh index eff6df380f8..379e1640593 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh @@ -28,6 +28,7 @@ #include "hb-ot-layout-common.hh" #include "hb-priority-queue.hh" +#include "hb-subset-instancer-iup.hh" namespace OT { @@ -221,9 +222,9 @@ struct DeltaSetIndexMap }; -struct VarStoreInstancer +struct ItemVarStoreInstancer { - VarStoreInstancer (const VariationStore *varStore, + ItemVarStoreInstancer (const ItemVariationStore *varStore, const DeltaSetIndexMap *varIdxMap, hb_array_t coords) : varStore (varStore), varIdxMap (varIdxMap), coords (coords) {} @@ -235,7 +236,7 @@ struct VarStoreInstancer float operator() (uint32_t varIdx, unsigned short offset = 0) const { return coords ? varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords) : 0; } - const VariationStore *varStore; + const ItemVariationStore *varStore; const DeltaSetIndexMap *varIdxMap; hb_array_t coords; }; @@ -460,7 +461,7 @@ struct tuple_delta_t tuple_delta_t () = default; tuple_delta_t (const tuple_delta_t& o) = default; - friend void swap (tuple_delta_t& a, tuple_delta_t& b) + friend void swap (tuple_delta_t& a, tuple_delta_t& b) noexcept { hb_swap (a.axis_tuples, b.axis_tuples); hb_swap (a.indices, b.indices); @@ -471,10 +472,10 @@ struct tuple_delta_t hb_swap (a.compiled_peak_coords, b.compiled_peak_coords); } - tuple_delta_t (tuple_delta_t&& o) : tuple_delta_t () + tuple_delta_t (tuple_delta_t&& o) noexcept : tuple_delta_t () { hb_swap (*this, o); } - tuple_delta_t& operator = (tuple_delta_t&& o) + tuple_delta_t& operator = (tuple_delta_t&& o) noexcept { hb_swap (*this, o); return *this; @@ -609,7 +610,9 @@ struct tuple_delta_t const hb_map_t& axes_old_index_tag_map, const hb_hashmap_t*, unsigned>* shared_tuples_idx_map) { - if (!compiled_deltas) return false; + /* compiled_deltas could be empty after iup delta optimization, we can skip + * compiling this tuple and return true */ + if (!compiled_deltas) return true; unsigned cur_axis_count = axes_index_map.get_population (); /* allocate enough memory: 1 peak + 2 intermediate coords + fixed header size */ @@ -723,22 +726,28 @@ struct tuple_delta_t } bool compile_deltas () + { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas); } + + bool compile_deltas (const hb_vector_t &point_indices, + const hb_vector_t &x_deltas, + const hb_vector_t &y_deltas, + hb_vector_t &compiled_deltas /* OUT */) { hb_vector_t rounded_deltas; - if (unlikely (!rounded_deltas.alloc (indices.length))) + if (unlikely (!rounded_deltas.alloc (point_indices.length))) return false; - for (unsigned i = 0; i < indices.length; i++) + for (unsigned i = 0; i < point_indices.length; i++) { - if (!indices[i]) continue; - int rounded_delta = (int) roundf (deltas_x[i]); + if (!point_indices[i]) continue; + int rounded_delta = (int) roundf (x_deltas.arrayZ[i]); rounded_deltas.push (rounded_delta); } - if (!rounded_deltas) return false; + if (!rounded_deltas) return true; /* allocate enough memories 3 * num_deltas */ unsigned alloc_len = 3 * rounded_deltas.length; - if (deltas_y) + if (y_deltas) alloc_len *= 2; if (unlikely (!compiled_deltas.resize (alloc_len))) return false; @@ -746,14 +755,14 @@ struct tuple_delta_t unsigned i = 0; unsigned encoded_len = encode_delta_run (i, compiled_deltas.as_array (), rounded_deltas); - if (deltas_y) + if (y_deltas) { - /* reuse the rounded_deltas vector, check that deltas_y have the same num of deltas as deltas_x */ + /* reuse the rounded_deltas vector, check that y_deltas have the same num of deltas as x_deltas */ unsigned j = 0; - for (unsigned idx = 0; idx < indices.length; idx++) + for (unsigned idx = 0; idx < point_indices.length; idx++) { - if (!indices[idx]) continue; - int rounded_delta = (int) roundf (deltas_y[idx]); + if (!point_indices[idx]) continue; + int rounded_delta = (int) roundf (y_deltas.arrayZ[idx]); if (j >= rounded_deltas.length) return false; @@ -761,7 +770,7 @@ struct tuple_delta_t } if (j != rounded_deltas.length) return false; - /* reset i because we reuse rounded_deltas for deltas_y */ + /* reset i because we reuse rounded_deltas for y_deltas */ i = 0; encoded_len += encode_delta_run (i, compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas); } @@ -1020,6 +1029,171 @@ struct tuple_delta_t return true; } + bool optimize (const contour_point_vector_t& contour_points, + bool is_composite, + float tolerance = 0.5f) + { + unsigned count = contour_points.length; + if (deltas_x.length != count || + deltas_y.length != count) + return false; + + hb_vector_t opt_indices; + hb_vector_t rounded_x_deltas, rounded_y_deltas; + + if (unlikely (!rounded_x_deltas.alloc (count) || + !rounded_y_deltas.alloc (count))) + return false; + + for (unsigned i = 0; i < count; i++) + { + int rounded_x_delta = (int) roundf (deltas_x.arrayZ[i]); + int rounded_y_delta = (int) roundf (deltas_y.arrayZ[i]); + rounded_x_deltas.push (rounded_x_delta); + rounded_y_deltas.push (rounded_y_delta); + } + + if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, tolerance)) + return false; + + unsigned ref_count = 0; + for (bool ref_flag : opt_indices) + ref_count += ref_flag; + + if (ref_count == count) return true; + + hb_vector_t opt_deltas_x, opt_deltas_y; + bool is_comp_glyph_wo_deltas = (is_composite && ref_count == 0); + if (is_comp_glyph_wo_deltas) + { + if (unlikely (!opt_deltas_x.resize (count) || + !opt_deltas_y.resize (count))) + return false; + + opt_indices.arrayZ[0] = true; + for (unsigned i = 1; i < count; i++) + opt_indices.arrayZ[i] = false; + } + + hb_vector_t opt_point_data; + if (!compile_point_set (opt_indices, opt_point_data)) + return false; + hb_vector_t opt_deltas_data; + if (!compile_deltas (opt_indices, + is_comp_glyph_wo_deltas ? opt_deltas_x : deltas_x, + is_comp_glyph_wo_deltas ? opt_deltas_y : deltas_y, + opt_deltas_data)) + return false; + + hb_vector_t point_data; + if (!compile_point_set (indices, point_data)) + return false; + hb_vector_t deltas_data; + if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data)) + return false; + + if (opt_point_data.length + opt_deltas_data.length < point_data.length + deltas_data.length) + { + indices.fini (); + indices = std::move (opt_indices); + + if (is_comp_glyph_wo_deltas) + { + deltas_x.fini (); + deltas_x = std::move (opt_deltas_x); + + deltas_y.fini (); + deltas_y = std::move (opt_deltas_y); + } + } + return !indices.in_error () && !deltas_x.in_error () && !deltas_y.in_error (); + } + + static bool compile_point_set (const hb_vector_t &point_indices, + hb_vector_t& compiled_points /* OUT */) + { + unsigned num_points = 0; + for (bool i : point_indices) + if (i) num_points++; + + /* when iup optimization is enabled, num of referenced points could be 0 */ + if (!num_points) return true; + + unsigned indices_length = point_indices.length; + /* If the points set consists of all points in the glyph, it's encoded with a + * single zero byte */ + if (num_points == indices_length) + return compiled_points.resize (1); + + /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ + unsigned num_bytes = 2 + 3 *num_points; + if (unlikely (!compiled_points.resize (num_bytes, false))) + return false; + + unsigned pos = 0; + /* binary data starts with the total number of reference points */ + if (num_points < 0x80) + compiled_points.arrayZ[pos++] = num_points; + else + { + compiled_points.arrayZ[pos++] = ((num_points >> 8) | 0x80); + compiled_points.arrayZ[pos++] = num_points & 0xFF; + } + + const unsigned max_run_length = 0x7F; + unsigned i = 0; + unsigned last_value = 0; + unsigned num_encoded = 0; + while (i < indices_length && num_encoded < num_points) + { + unsigned run_length = 0; + unsigned header_pos = pos; + compiled_points.arrayZ[pos++] = 0; + + bool use_byte_encoding = false; + bool new_run = true; + while (i < indices_length && num_encoded < num_points && + run_length <= max_run_length) + { + // find out next referenced point index + while (i < indices_length && !point_indices[i]) + i++; + + if (i >= indices_length) break; + + unsigned cur_value = i; + unsigned delta = cur_value - last_value; + + if (new_run) + { + use_byte_encoding = (delta <= 0xFF); + new_run = false; + } + + if (use_byte_encoding && delta > 0xFF) + break; + + if (use_byte_encoding) + compiled_points.arrayZ[pos++] = delta; + else + { + compiled_points.arrayZ[pos++] = delta >> 8; + compiled_points.arrayZ[pos++] = delta & 0xFF; + } + i++; + last_value = cur_value; + run_length++; + num_encoded++; + } + + if (use_byte_encoding) + compiled_points.arrayZ[header_pos] = run_length - 1; + else + compiled_points.arrayZ[header_pos] = (run_length - 1) | 0x80; + } + return compiled_points.resize (pos, false); + } + static float infer_delta (float target_val, float prev_val, float next_val, float prev_delta, float next_delta) { if (prev_val == next_val) @@ -1071,41 +1245,41 @@ struct TupleVariationData private: /* referenced point set->compiled point data map */ - hb_hashmap_t*, hb_bytes_t> point_data_map; + hb_hashmap_t*, hb_vector_t> point_data_map; /* referenced point set-> count map, used in finding shared points */ hb_hashmap_t*, unsigned> point_set_count_map; /* empty for non-gvar tuples. - * shared_points_bytes is just a copy of some value in the point_data_map, + * shared_points_bytes is a pointer to some value in the point_data_map, * which will be freed during map destruction. Save it for serialization, so * no need to do find_shared_points () again */ - hb_bytes_t shared_points_bytes; + hb_vector_t *shared_points_bytes = nullptr; /* total compiled byte size as TupleVariationData format, initialized to its * min_size: 4 */ unsigned compiled_byte_size = 4; + /* for gvar iup delta optimization: whether this is a composite glyph */ + bool is_composite = false; + public: tuple_variations_t () = default; tuple_variations_t (const tuple_variations_t&) = delete; tuple_variations_t& operator=(const tuple_variations_t&) = delete; tuple_variations_t (tuple_variations_t&&) = default; tuple_variations_t& operator=(tuple_variations_t&&) = default; - ~tuple_variations_t () { fini (); } - void fini () - { - for (auto _ : point_data_map.values ()) - _.fini (); - - point_set_count_map.fini (); - tuple_vars.fini (); - } + ~tuple_variations_t () = default; explicit operator bool () const { return bool (tuple_vars); } unsigned get_var_count () const { - unsigned count = tuple_vars.length; - if (shared_points_bytes.length) + unsigned count = 0; + /* when iup delta opt is enabled, compiled_deltas could be empty and we + * should skip this tuple */ + for (auto& tuple: tuple_vars) + if (tuple.compiled_deltas) count++; + + if (shared_points_bytes && shared_points_bytes->length) count |= TupleVarCount::SharedPointNumbers; return count; } @@ -1119,26 +1293,27 @@ struct TupleVariationData bool is_gvar, const hb_map_t *axes_old_index_tag_map, const hb_vector_t &shared_indices, - const hb_array_t shared_tuples) + const hb_array_t shared_tuples, + bool is_composite_glyph) { do { const HBUINT8 *p = iterator.get_serialized_data (); unsigned int length = iterator.current_tuple->get_data_size (); if (unlikely (!iterator.var_data_bytes.check_range (p, length))) - { fini (); return false; } + return false; hb_hashmap_t axis_tuples; if (!iterator.current_tuple->unpack_axis_tuples (iterator.get_axis_count (), shared_tuples, axes_old_index_tag_map, axis_tuples) || axis_tuples.is_empty ()) - { fini (); return false; } + return false; hb_vector_t private_indices; bool has_private_points = iterator.current_tuple->has_private_points (); const HBUINT8 *end = p + length; if (has_private_points && !TupleVariationData::unpack_points (p, private_indices, end)) - { fini (); return false; } + return false; const hb_vector_t &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); @@ -1148,24 +1323,24 @@ struct TupleVariationData if (unlikely (!deltas_x.resize (num_deltas, false) || !TupleVariationData::unpack_deltas (p, deltas_x, end))) - { fini (); return false; } + return false; hb_vector_t deltas_y; if (is_gvar) { if (unlikely (!deltas_y.resize (num_deltas, false) || !TupleVariationData::unpack_deltas (p, deltas_y, end))) - { fini (); return false; } + return false; } tuple_delta_t var; var.axis_tuples = std::move (axis_tuples); if (unlikely (!var.indices.resize (point_count) || !var.deltas_x.resize (point_count, false))) - { fini (); return false; } + return false; if (is_gvar && unlikely (!var.deltas_y.resize (point_count, false))) - { fini (); return false; } + return false; for (unsigned i = 0; i < num_deltas; i++) { @@ -1178,6 +1353,8 @@ struct TupleVariationData } tuple_vars.push (std::move (var)); } while (iterator.move_to_next ()); + + is_composite = is_composite_glyph; return true; } @@ -1261,7 +1438,7 @@ struct TupleVariationData unsigned new_len = new_vars.length + out.length; if (unlikely (!new_vars.alloc (new_len, false))) - { fini (); return false;} + return false; for (unsigned i = 0; i < out.length; i++) new_vars.push (std::move (out[i])); @@ -1272,8 +1449,9 @@ struct TupleVariationData return true; } - /* merge tuple variations with overlapping tents */ - void merge_tuple_variations () + /* merge tuple variations with overlapping tents, if iup delta optimization + * is enabled, add default deltas to contour_points */ + bool merge_tuple_variations (contour_point_vector_t* contour_points = nullptr) { hb_vector_t new_vars; hb_hashmap_t*, unsigned> m; @@ -1281,7 +1459,15 @@ struct TupleVariationData for (const tuple_delta_t& var : tuple_vars) { /* if all axes are pinned, drop the tuple variation */ - if (var.axis_tuples.is_empty ()) continue; + if (var.axis_tuples.is_empty ()) + { + /* if iup_delta_optimize is enabled, add deltas to contour coords */ + if (contour_points && !contour_points->add_deltas (var.deltas_x, + var.deltas_y, + var.indices)) + return false; + continue; + } unsigned *idx; if (m.has (&(var.axis_tuples), &idx)) @@ -1291,98 +1477,14 @@ struct TupleVariationData else { new_vars.push (var); - m.set (&(var.axis_tuples), i); + if (!m.set (&(var.axis_tuples), i)) + return false; i++; } } tuple_vars.fini (); tuple_vars = std::move (new_vars); - } - - hb_bytes_t compile_point_set (const hb_vector_t &point_indices) - { - unsigned num_points = 0; - for (bool i : point_indices) - if (i) num_points++; - - unsigned indices_length = point_indices.length; - /* If the points set consists of all points in the glyph, it's encoded with a - * single zero byte */ - if (num_points == indices_length) - { - char *p = (char *) hb_calloc (1, sizeof (char)); - if (unlikely (!p)) return hb_bytes_t (); - - return hb_bytes_t (p, 1); - } - - /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ - unsigned num_bytes = 2 + 3 *num_points; - char *p = (char *) hb_calloc (num_bytes, sizeof (char)); - if (unlikely (!p)) return hb_bytes_t (); - - unsigned pos = 0; - /* binary data starts with the total number of reference points */ - if (num_points < 0x80) - p[pos++] = num_points; - else - { - p[pos++] = ((num_points >> 8) | 0x80); - p[pos++] = num_points & 0xFF; - } - - const unsigned max_run_length = 0x7F; - unsigned i = 0; - unsigned last_value = 0; - unsigned num_encoded = 0; - while (i < indices_length && num_encoded < num_points) - { - unsigned run_length = 0; - unsigned header_pos = pos; - p[pos++] = 0; - - bool use_byte_encoding = false; - bool new_run = true; - while (i < indices_length && num_encoded < num_points && - run_length <= max_run_length) - { - // find out next referenced point index - while (i < indices_length && !point_indices[i]) - i++; - - if (i >= indices_length) break; - - unsigned cur_value = i; - unsigned delta = cur_value - last_value; - - if (new_run) - { - use_byte_encoding = (delta <= 0xFF); - new_run = false; - } - - if (use_byte_encoding && delta > 0xFF) - break; - - if (use_byte_encoding) - p[pos++] = delta; - else - { - p[pos++] = delta >> 8; - p[pos++] = delta & 0xFF; - } - i++; - last_value = cur_value; - run_length++; - num_encoded++; - } - - if (use_byte_encoding) - p[header_pos] = run_length - 1; - else - p[header_pos] = (run_length - 1) | 0x80; - } - return hb_bytes_t (p, pos); + return true; } /* compile all point set and store byte data in a point_set->hb_bytes_t hashmap, @@ -1402,11 +1504,11 @@ struct TupleVariationData continue; } - hb_bytes_t compiled_data = compile_point_set (*points_set); - if (unlikely (compiled_data == hb_bytes_t ())) + hb_vector_t compiled_point_data; + if (!tuple_delta_t::compile_point_set (*points_set, compiled_point_data)) return false; - if (!point_data_map.set (points_set, compiled_data) || + if (!point_data_map.set (points_set, std::move (compiled_point_data)) || !point_set_count_map.set (points_set, 1)) return false; } @@ -1414,31 +1516,33 @@ struct TupleVariationData } /* find shared points set which saves most bytes */ - hb_bytes_t find_shared_points () + void find_shared_points () { unsigned max_saved_bytes = 0; - hb_bytes_t res{}; - for (const auto& _ : point_data_map.iter ()) + for (const auto& _ : point_data_map.iter_ref ()) { const hb_vector_t* points_set = _.first; unsigned data_length = _.second.length; + if (!data_length) continue; unsigned *count; if (unlikely (!point_set_count_map.has (points_set, &count) || *count <= 1)) - return hb_bytes_t (); + { + shared_points_bytes = nullptr; + return; + } unsigned saved_bytes = data_length * ((*count) -1); if (saved_bytes > max_saved_bytes) { max_saved_bytes = saved_bytes; - res = _.second; + shared_points_bytes = &(_.second); } } - return res; } - bool calc_inferred_deltas (contour_point_vector_t& contour_points) + bool calc_inferred_deltas (const contour_point_vector_t& contour_points) { for (tuple_delta_t& var : tuple_vars) if (!var.calc_inferred_deltas (contour_points)) @@ -1447,10 +1551,21 @@ struct TupleVariationData return true; } + bool iup_optimize (const contour_point_vector_t& contour_points) + { + for (tuple_delta_t& var : tuple_vars) + { + if (!var.optimize (contour_points, is_composite)) + return false; + } + return true; + } + public: bool instantiate (const hb_hashmap_t& normalized_axes_location, const hb_hashmap_t& axes_triple_distances, - contour_point_vector_t* contour_points = nullptr) + contour_point_vector_t* contour_points = nullptr, + bool optimize = false) { if (!tuple_vars) return true; if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances)) @@ -1460,7 +1575,14 @@ struct TupleVariationData if (!calc_inferred_deltas (*contour_points)) return false; - merge_tuple_variations (); + /* if iup delta opt is on, contour_points can't be null */ + if (optimize && !contour_points) + return false; + + if (!merge_tuple_variations (optimize ? contour_points : nullptr)) + return false; + + if (optimize && !iup_optimize (*contour_points)) return false; return !tuple_vars.in_error (); } @@ -1475,21 +1597,27 @@ struct TupleVariationData if (use_shared_points) { - shared_points_bytes = find_shared_points (); - compiled_byte_size += shared_points_bytes.length; + find_shared_points (); + if (shared_points_bytes) + compiled_byte_size += shared_points_bytes->length; } // compile delta and tuple var header for each tuple variation for (auto& tuple: tuple_vars) { const hb_vector_t* points_set = &(tuple.indices); - hb_bytes_t *points_data; + hb_vector_t *points_data; if (unlikely (!point_data_map.has (points_set, &points_data))) return false; + /* when iup optimization is enabled, num of referenced points could be 0 + * and thus the compiled points bytes is empty, we should skip compiling + * this tuple */ + if (!points_data->length) + continue; if (!tuple.compile_deltas ()) return false; - unsigned points_data_length = (*points_data != shared_points_bytes) ? points_data->length : 0; + unsigned points_data_length = (points_data != shared_points_bytes) ? points_data->length : 0; if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map, shared_tuples_idx_map)) return false; @@ -1513,18 +1641,24 @@ struct TupleVariationData bool serialize_var_data (hb_serialize_context_t *c, bool is_gvar) const { TRACE_SERIALIZE (this); - if (is_gvar) - shared_points_bytes.copy (c); + if (is_gvar && shared_points_bytes) + { + hb_bytes_t s (shared_points_bytes->arrayZ, shared_points_bytes->length); + s.copy (c); + } for (const auto& tuple: tuple_vars) { const hb_vector_t* points_set = &(tuple.indices); - hb_bytes_t *point_data; + hb_vector_t *point_data; if (!point_data_map.has (points_set, &point_data)) return_trace (false); - if (!is_gvar || *point_data != shared_points_bytes) - point_data->copy (c); + if (!is_gvar || point_data != shared_points_bytes) + { + hb_bytes_t s (point_data->arrayZ, point_data->length); + s.copy (c); + } tuple.compiled_deltas.as_array ().copy (c); if (c->in_error ()) return_trace (false); @@ -1711,13 +1845,15 @@ struct TupleVariationData const hb_map_t *axes_old_index_tag_map, const hb_vector_t &shared_indices, const hb_array_t shared_tuples, - tuple_variations_t& tuple_variations /* OUT */) const + tuple_variations_t& tuple_variations, /* OUT */ + bool is_composite_glyph = false) const { return tuple_variations.create_from_tuple_var_data (iterator, tupleVarCount, point_count, is_gvar, axes_old_index_tag_map, shared_indices, - shared_tuples); + shared_tuples, + is_composite_glyph); } bool serialize (hb_serialize_context_t *c, @@ -1831,7 +1967,7 @@ struct item_variations_t const hb_map_t& get_varidx_map () const { return varidx_map; } - bool instantiate (const VariationStore& varStore, + bool instantiate (const ItemVariationStore& varStore, const hb_subset_plan_t *plan, bool optimize=true, bool use_no_variation_idx=true, @@ -1845,7 +1981,7 @@ struct item_variations_t } /* keep below APIs public only for unit test: test-item-varstore */ - bool create_from_item_varstore (const VariationStore& varStore, + bool create_from_item_varstore (const ItemVariationStore& varStore, const hb_map_t& axes_old_index_tag_map, const hb_array_t inner_maps = hb_array_t ()) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh index 1c7a1f6c1e9..59aad57e37c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh @@ -101,10 +101,15 @@ struct glyph_variations_t continue; } + bool is_composite_glyph = false; +#ifdef HB_EXPERIMENTAL_API + is_composite_glyph = plan->composite_new_gids.has (new_gid); +#endif if (!p->decompile_tuple_variations (all_contour_points->length, true /* is_gvar */, iterator, &(plan->axes_old_index_tag_map), shared_indices, shared_tuples, - tuple_vars /* OUT */)) + tuple_vars, /* OUT */ + is_composite_glyph)) return false; glyph_variations.push (std::move (tuple_vars)); } @@ -114,13 +119,17 @@ struct glyph_variations_t bool instantiate (const hb_subset_plan_t *plan) { unsigned count = plan->new_to_old_gid_list.length; + bool iup_optimize = false; +#ifdef HB_EXPERIMENTAL_API + iup_optimize = plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS; +#endif for (unsigned i = 0; i < count; i++) { hb_codepoint_t new_gid = plan->new_to_old_gid_list[i].first; contour_point_vector_t *all_points; if (!plan->new_gid_contour_points_map.has (new_gid, &all_points)) return false; - if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points)) + if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points, iup_optimize)) return false; } return true; @@ -340,7 +349,8 @@ struct gvar const glyph_variations_t& glyph_vars, Iterator it, unsigned axis_count, - unsigned num_glyphs) const + unsigned num_glyphs, + bool force_long_offsets) const { TRACE_SERIALIZE (this); gvar *out = c->allocate_min (); @@ -352,7 +362,7 @@ struct gvar out->glyphCountX = hb_min (0xFFFFu, num_glyphs); unsigned glyph_var_data_size = glyph_vars.compiled_byte_size (); - bool long_offset = glyph_var_data_size & ~0xFFFFu; + bool long_offset = glyph_var_data_size & ~0xFFFFu || force_long_offsets; out->flags = long_offset ? 1 : 0; HBUINT8 *glyph_var_data_offsets = c->allocate_size ((long_offset ? 4 : 2) * (num_glyphs + 1), false); @@ -393,7 +403,12 @@ struct gvar unsigned axis_count = c->plan->axes_index_map.get_population (); unsigned num_glyphs = c->plan->num_output_glyphs (); auto it = hb_iter (c->plan->new_to_old_gid_list); - return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs)); + + bool force_long_offsets = false; +#ifdef HB_EXPERIMENTAL_API + force_long_offsets = c->plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS; +#endif + return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs, force_long_offsets)); } bool subset (hb_subset_context_t *c) const @@ -429,7 +444,7 @@ struct gvar } bool long_offset = (subset_data_size & ~0xFFFFu); - #ifdef HB_EXPERIMENTAL_API +#ifdef HB_EXPERIMENTAL_API long_offset = long_offset || (c->plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS); #endif out->flags = long_offset ? 1 : 0; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh index 53a4642d383..33a4e1a40e6 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh @@ -188,7 +188,7 @@ struct hvarvvar_subset_plan_t ~hvarvvar_subset_plan_t() { fini (); } void init (const hb_array_t &index_maps, - const VariationStore &_var_store, + const ItemVariationStore &_var_store, const hb_subset_plan_t *plan) { index_map_plans.resize (index_maps.length); @@ -263,7 +263,7 @@ struct hvarvvar_subset_plan_t hb_inc_bimap_t outer_map; hb_vector_t inner_maps; hb_vector_t index_map_plans; - const VariationStore *var_store; + const ItemVariationStore *var_store; protected: hb_vector_t inner_sets; @@ -296,7 +296,7 @@ struct HVARVVAR rsbMap.sanitize (c, this)); } - const VariationStore& get_var_store () const + const ItemVariationStore& get_var_store () const { return this+varStore; } void listup_index_maps (hb_vector_t &index_maps) const @@ -384,7 +384,7 @@ struct HVARVVAR float get_advance_delta_unscaled (hb_codepoint_t glyph, const int *coords, unsigned int coord_count, - VariationStore::cache_t *store_cache = nullptr) const + ItemVariationStore::cache_t *store_cache = nullptr) const { uint32_t varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, @@ -405,7 +405,7 @@ struct HVARVVAR public: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ - Offset32To + Offset32To varStore; /* Offset to item variation store table. */ Offset32To advMap; /* Offset to advance var-idx mapping. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh index 6d697776189..1f0401d1d33 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh @@ -56,7 +56,7 @@ struct VariationValueRecord public: Tag valueTag; /* Four-byte tag identifying a font-wide measure. */ - VarIdx varIdx; /* Outer/inner index into VariationStore item. */ + VarIdx varIdx; /* Outer/inner index into ItemVariationStore item. */ public: DEFINE_SIZE_STATIC (8); @@ -106,7 +106,7 @@ struct MVAR out->valueRecordCount = valueRecordCount; item_variations_t item_vars; - const VariationStore& src_var_store = this+varStore; + const ItemVariationStore& src_var_store = this+varStore; if (!item_vars.instantiate (src_var_store, c->plan)) return_trace (false); @@ -159,7 +159,7 @@ protected: HBUINT16 valueRecordSize;/* The size in bytes of each value record — * must be greater than zero. */ HBUINT16 valueRecordCount;/* The number of value records — may be zero. */ - Offset16To + Offset16To varStore; /* Offset to item variation store table. */ UnsizedArrayOf valuesZ; /* Array of value records. The records must be diff --git a/src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh b/src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh index 9b962a29d9b..274d5df4c54 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh @@ -163,7 +163,7 @@ struct hb_priority_queue_t goto repeat; } - void swap (unsigned a, unsigned b) + void swap (unsigned a, unsigned b) noexcept { assert (a < heap.length); assert (b < heap.length); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-repacker.hh b/src/3rdparty/harfbuzz-ng/src/hb-repacker.hh index e9cd376ad37..ed40f271ccb 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-repacker.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-repacker.hh @@ -238,6 +238,54 @@ bool _try_isolating_subgraphs (const hb_vector_t& over return true; } +static inline +bool _resolve_shared_overflow(const hb_vector_t& overflows, + int overflow_index, + graph_t& sorted_graph) +{ + const graph::overflow_record_t& r = overflows[overflow_index]; + + // Find all of the parents in overflowing links that link to this + // same child node. We will then try duplicating the child node and + // re-assigning all of these parents to the duplicate. + hb_set_t parents; + parents.add(r.parent); + for (int i = overflow_index - 1; i >= 0; i--) { + const graph::overflow_record_t& r2 = overflows[i]; + if (r2.child == r.child) { + parents.add(r2.parent); + } + } + + unsigned result = sorted_graph.duplicate(&parents, r.child); + if (result == (unsigned) -1 && parents.get_population() > 2) { + // All links to the child are overflowing, so we can't include all + // in the duplication. Remove one parent from the duplication. + // Remove the lowest index parent, which will be the closest to the child. + parents.del(parents.get_min()); + result = sorted_graph.duplicate(&parents, r.child); + } + + if (result == (unsigned) -1) return result; + + if (parents.get_population() > 1) { + // If the duplicated node has more than one parent pre-emptively raise it's priority to the maximum. + // This will place it close to the parents. Node's with only one parent, don't need this as normal overflow + // resolution will raise priority if needed. + // + // Reasoning: most of the parents to this child are likely at the same layer in the graph. Duplicating + // the child will theoretically allow it to be placed closer to it's parents. However, due to the shortest + // distance sort by default it's placement will remain in the same layer, thus it will remain in roughly the + // same position (and distance from parents) as the original child node. The overflow resolution will attempt + // to move nodes closer, but only for non-shared nodes. Since this node is shared, it will simply be given + // further duplication which defeats the attempt to duplicate with multiple parents. To fix this we + // pre-emptively raise priority now which allows the duplicated node to pack into the same layer as it's parents. + sorted_graph.vertices_[result].give_max_priority(); + } + + return result; +} + static inline bool _process_overflows (const hb_vector_t& overflows, hb_set_t& priority_bumped_parents, @@ -254,7 +302,7 @@ bool _process_overflows (const hb_vector_t& overflows, { // The child object is shared, we may be able to eliminate the overflow // by duplicating it. - if (sorted_graph.duplicate (r.parent, r.child) == (unsigned) -1) continue; + if (!_resolve_shared_overflow(overflows, i, sorted_graph)) continue; return true; } @@ -388,7 +436,7 @@ template inline hb_blob_t* hb_resolve_overflows (const T& packed, hb_tag_t table_tag, - unsigned max_rounds = 20, + unsigned max_rounds = 32, bool recalculate_extensions = false) { graph_t sorted_graph (packed); if (sorted_graph.in_error ()) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh b/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh index 15eccb6a09a..e988451eb36 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh @@ -91,7 +91,27 @@ struct hb_serialize_context_t } #endif - friend void swap (object_t& a, object_t& b) + bool add_virtual_link (objidx_t objidx) + { + if (!objidx) + return false; + + auto& link = *virtual_links.push (); + if (virtual_links.in_error ()) + return false; + + link.objidx = objidx; + // Remaining fields were previously zero'd by push(): + // link.width = 0; + // link.is_signed = 0; + // link.whence = 0; + // link.position = 0; + // link.bias = 0; + + return true; + } + + friend void swap (object_t& a, object_t& b) noexcept { hb_swap (a.head, b.head); hb_swap (a.tail, b.tail); @@ -156,9 +176,9 @@ struct hb_serialize_context_t object_t *next; auto all_links () const HB_AUTO_RETURN - (( hb_concat (this->real_links, this->virtual_links) )); + (( hb_concat (real_links, virtual_links) )); auto all_links_writer () HB_AUTO_RETURN - (( hb_concat (this->real_links.writer (), this->virtual_links.writer ()) )); + (( hb_concat (real_links.writer (), virtual_links.writer ()) )); }; struct snapshot_t @@ -469,16 +489,40 @@ struct hb_serialize_context_t assert (current); - auto& link = *current->virtual_links.push (); - if (current->virtual_links.in_error ()) + if (!current->add_virtual_link(objidx)) err (HB_SERIALIZE_ERROR_OTHER); + } - link.width = 0; - link.objidx = objidx; - link.is_signed = 0; - link.whence = 0; - link.position = 0; - link.bias = 0; + objidx_t last_added_child_index() const { + if (unlikely (in_error ())) return (objidx_t) -1; + + assert (current); + if (!bool(current->real_links)) { + return (objidx_t) -1; + } + + return current->real_links[current->real_links.length - 1].objidx; + } + + // For the current object ensure that the sub-table bytes for child objidx are always placed + // after the subtable bytes for any other existing children. This only ensures that the + // repacker will not move the target subtable before the other children + // (by adding virtual links). It is up to the caller to ensure the initial serialization + // order is correct. + void repack_last(objidx_t objidx) { + if (unlikely (in_error ())) return; + + if (!objidx) + return; + + assert (current); + for (auto& l : current->real_links) { + if (l.objidx == objidx) { + continue; + } + + packed[l.objidx]->add_virtual_link(objidx); + } } template diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.hh b/src/3rdparty/harfbuzz-ng/src/hb-set.hh index ff2a170d2d1..ce69ea2c9b2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-set.hh @@ -44,10 +44,10 @@ struct hb_sparseset_t ~hb_sparseset_t () { fini (); } hb_sparseset_t (const hb_sparseset_t& other) : hb_sparseset_t () { set (other); } - hb_sparseset_t (hb_sparseset_t&& other) : hb_sparseset_t () { s = std::move (other.s); } + hb_sparseset_t (hb_sparseset_t&& other) noexcept : hb_sparseset_t () { s = std::move (other.s); } hb_sparseset_t& operator = (const hb_sparseset_t& other) { set (other); return *this; } - hb_sparseset_t& operator = (hb_sparseset_t&& other) { s = std::move (other.s); return *this; } - friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) { hb_swap (a.s, b.s); } + hb_sparseset_t& operator = (hb_sparseset_t&& other) noexcept { s = std::move (other.s); return *this; } + friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) noexcept { hb_swap (a.s, b.s); } hb_sparseset_t (std::initializer_list lst) : hb_sparseset_t () { @@ -166,7 +166,7 @@ struct hb_set_t : hb_sparseset_t ~hb_set_t () = default; hb_set_t () : sparseset () {}; hb_set_t (const hb_set_t &o) : sparseset ((sparseset &) o) {}; - hb_set_t (hb_set_t&& o) : sparseset (std::move ((sparseset &) o)) {} + hb_set_t (hb_set_t&& o) noexcept : sparseset (std::move ((sparseset &) o)) {} hb_set_t& operator = (const hb_set_t&) = default; hb_set_t& operator = (hb_set_t&&) = default; hb_set_t (std::initializer_list lst) : sparseset (lst) {} diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc index abc108e5715..eb5cb0c625e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc @@ -248,7 +248,7 @@ struct cff2_subr_subsetter_t : subr_subsetter_t normalized_coords) : c (c), varStore (varStore), normalized_coords (normalized_coords) {} @@ -284,7 +284,7 @@ struct cff2_private_blend_encoder_param_t unsigned ivs = 0; unsigned region_count = 0; hb_vector_t scalars; - const CFF2VariationStore *varStore = nullptr; + const CFF2ItemVariationStore *varStore = nullptr; hb_array_t normalized_coords; }; @@ -378,7 +378,7 @@ struct cff2_private_dict_blend_opset_t : dict_opset_t struct cff2_private_dict_op_serializer_t : op_serializer_t { cff2_private_dict_op_serializer_t (bool desubroutinize_, bool drop_hints_, bool pinned_, - const CFF::CFF2VariationStore* varStore_, + const CFF::CFF2ItemVariationStore* varStore_, hb_array_t normalized_coords_) : desubroutinize (desubroutinize_), drop_hints (drop_hints_), pinned (pinned_), varStore (varStore_), normalized_coords (normalized_coords_) {} @@ -416,7 +416,7 @@ struct cff2_private_dict_op_serializer_t : op_serializer_t const bool desubroutinize; const bool drop_hints; const bool pinned; - const CFF::CFF2VariationStore* varStore; + const CFF::CFF2ItemVariationStore* varStore; hb_array_t normalized_coords; }; @@ -628,10 +628,10 @@ OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c, } /* variation store */ - if (varStore != &Null (CFF2VariationStore) && + if (varStore != &Null (CFF2ItemVariationStore) && !plan.pinned) { - auto *dest = c->push (); + auto *dest = c->push (); if (unlikely (!dest->serialize (c, varStore))) { c->pop_discard (); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc index 1e0a89a630d..68a3e77788e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc @@ -24,6 +24,7 @@ * Google Author(s): Garret Rieger, Rod Sheeter, Behdad Esfahbod */ +#include "hb-subset-instancer-solver.hh" #include "hb-subset.hh" #include "hb-set.hh" #include "hb-utf.hh" @@ -50,7 +51,6 @@ hb_subset_input_t::hb_subset_input_t () HB_TAG ('k', 'e', 'r', 'n'), // Copied from fontTools: - HB_TAG ('B', 'A', 'S', 'E'), HB_TAG ('J', 'S', 'T', 'F'), HB_TAG ('D', 'S', 'I', 'G'), HB_TAG ('E', 'B', 'D', 'T'), @@ -417,6 +417,46 @@ hb_subset_input_keep_everything (hb_subset_input_t *input) } #ifndef HB_NO_VAR +/** + * hb_subset_input_pin_all_axes_to_default: (skip) + * @input: a #hb_subset_input_t object. + * @face: a #hb_face_t object. + * + * Pin all axes to default locations in the given subset input object. + * + * All axes in a font must be pinned. Additionally, `CFF2` table, if present, + * will be de-subroutinized. + * + * Return value: `true` if success, `false` otherwise + * + * Since: 8.3.1 + **/ +HB_EXTERN hb_bool_t +hb_subset_input_pin_all_axes_to_default (hb_subset_input_t *input, + hb_face_t *face) +{ + unsigned axis_count = hb_ot_var_get_axis_count (face); + if (!axis_count) return false; + + hb_ot_var_axis_info_t *axis_infos = (hb_ot_var_axis_info_t *) hb_calloc (axis_count, sizeof (hb_ot_var_axis_info_t)); + if (unlikely (!axis_infos)) return false; + + (void) hb_ot_var_get_axis_infos (face, 0, &axis_count, axis_infos); + + for (unsigned i = 0; i < axis_count; i++) + { + hb_tag_t axis_tag = axis_infos[i].tag; + float default_val = axis_infos[i].default_value; + if (!input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val))) + { + hb_free (axis_infos); + return false; + } + } + hb_free (axis_infos); + return true; +} + /** * hb_subset_input_pin_axis_to_default: (skip) * @input: a #hb_subset_input_t object. @@ -481,16 +521,13 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, * @input: a #hb_subset_input_t object. * @face: a #hb_face_t object. * @axis_tag: Tag of the axis - * @axis_min_value: Minimum value of the axis variation range to set - * @axis_max_value: Maximum value of the axis variation range to set - * @axis_def_value: Default value of the axis variation range to set, in case of - * null, it'll be determined automatically + * @axis_min_value: Minimum value of the axis variation range to set, if NaN the existing min will be used. + * @axis_max_value: Maximum value of the axis variation range to set if NaN the existing max will be used. + * @axis_def_value: Default value of the axis variation range to set, if NaN the existing default will be used. * * Restricting the range of variation on an axis in the given subset input object. * New min/default/max values will be clamped if they're not within the fvar axis range. - * If the new default value is null: - * If the fvar axis default value is within the new range, then new default - * value is the same as original default value. + * * If the fvar axis default value is not within the new range, the new default * value will be changed to the new min or max value, whichever is closer to the fvar * axis default. @@ -509,21 +546,57 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_tag_t axis_tag, float axis_min_value, float axis_max_value, - float *axis_def_value /* IN, maybe NULL */) + float axis_def_value) { - if (axis_min_value > axis_max_value) - return false; - hb_ot_var_axis_info_t axis_info; if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) return false; - float new_min_val = hb_clamp(axis_min_value, axis_info.min_value, axis_info.max_value); - float new_max_val = hb_clamp(axis_max_value, axis_info.min_value, axis_info.max_value); - float new_default_val = axis_def_value ? *axis_def_value : axis_info.default_value; - new_default_val = hb_clamp(new_default_val, new_min_val, new_max_val); + float min = !std::isnan(axis_min_value) ? axis_min_value : axis_info.min_value; + float max = !std::isnan(axis_max_value) ? axis_max_value : axis_info.max_value; + float def = !std::isnan(axis_def_value) ? axis_def_value : axis_info.default_value; + + if (min > max) + return false; + + float new_min_val = hb_clamp(min, axis_info.min_value, axis_info.max_value); + float new_max_val = hb_clamp(max, axis_info.min_value, axis_info.max_value); + float new_default_val = hb_clamp(def, new_min_val, new_max_val); return input->axes_location.set (axis_tag, Triple (new_min_val, new_default_val, new_max_val)); } + +/** + * hb_subset_input_get_axis_range: (skip) + * @input: a #hb_subset_input_t object. + * @axis_tag: Tag of the axis + * @axis_min_value: Set to the previously configured minimum value of the axis variation range. + * @axis_max_value: Set to the previously configured maximum value of the axis variation range. + * @axis_def_value: Set to the previously configured default value of the axis variation range. + * + * Gets the axis range assigned by previous calls to hb_subset_input_set_axis_range. + * + * Return value: `true` if a range has been set for this axis tag, `false` otherwise. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_bool_t +hb_subset_input_get_axis_range (hb_subset_input_t *input, + hb_tag_t axis_tag, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value) + +{ + Triple* triple; + if (!input->axes_location.has(axis_tag, &triple)) { + return false; + } + + *axis_min_value = triple->minimum; + *axis_def_value = triple->middle; + *axis_max_value = triple->maximum; + return true; +} #endif #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-iup.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-iup.cc new file mode 100644 index 00000000000..35a964d0826 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-iup.cc @@ -0,0 +1,532 @@ +/* + * Copyright © 2024 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb-subset-instancer-iup.hh" + +/* This file is a straight port of the following: + * + * https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/varLib/iup.py + * + * Where that file returns optimzied deltas vector, we return optimized + * referenced point indices. + */ + +constexpr static unsigned MAX_LOOKBACK = 8; + +static void _iup_contour_bound_forced_set (const hb_array_t contour_points, + const hb_array_t x_deltas, + const hb_array_t y_deltas, + hb_set_t& forced_set, /* OUT */ + float tolerance = 0.f) +{ + unsigned len = contour_points.length; + unsigned next_i = 0; + for (int i = len - 1; i >= 0; i--) + { + unsigned last_i = (len + i -1) % len; + for (unsigned j = 0; j < 2; j++) + { + float cj, lcj, ncj; + int dj, ldj, ndj; + if (j == 0) + { + cj = contour_points.arrayZ[i].x; + dj = x_deltas.arrayZ[i]; + lcj = contour_points.arrayZ[last_i].x; + ldj = x_deltas.arrayZ[last_i]; + ncj = contour_points.arrayZ[next_i].x; + ndj = x_deltas.arrayZ[next_i]; + } + else + { + cj = contour_points.arrayZ[i].y; + dj = y_deltas.arrayZ[i]; + lcj = contour_points.arrayZ[last_i].y; + ldj = y_deltas.arrayZ[last_i]; + ncj = contour_points.arrayZ[next_i].y; + ndj = y_deltas.arrayZ[next_i]; + } + + float c1, c2; + int d1, d2; + if (lcj <= ncj) + { + c1 = lcj; + c2 = ncj; + d1 = ldj; + d2 = ndj; + } + else + { + c1 = ncj; + c2 = lcj; + d1 = ndj; + d2 = ldj; + } + + bool force = false; + if (c1 == c2) + { + if (abs (d1 - d2) > tolerance && abs (dj) > tolerance) + force = true; + } + else if (c1 <= cj && cj <= c2) + { + if (!(hb_min (d1, d2) - tolerance <= dj && + dj <= hb_max (d1, d2) + tolerance)) + force = true; + } + else + { + if (d1 != d2) + { + if (cj < c1) + { + if (abs (dj) > tolerance && + abs (dj - d1) > tolerance && + ((dj - tolerance < d1) != (d1 < d2))) + force = true; + } + else + { + if (abs (dj) > tolerance && + abs (dj - d2) > tolerance && + ((d2 < dj + tolerance) != (d1 < d2))) + force = true; + } + } + } + + if (force) + { + forced_set.add (i); + break; + } + } + next_i = i; + } +} + +template +static bool rotate_array (const hb_array_t& org_array, + int k, + hb_vector_t& out) +{ + unsigned n = org_array.length; + if (!n) return true; + if (unlikely (!out.resize (n, false))) + return false; + + unsigned item_size = hb_static_size (T); + if (k < 0) + k = n - (-k) % n; + else + k %= n; + + hb_memcpy ((void *) out.arrayZ, (const void *) (org_array.arrayZ + n - k), k * item_size); + hb_memcpy ((void *) (out.arrayZ + k), (const void *) org_array.arrayZ, (n - k) * item_size); + return true; +} + +static bool rotate_set (const hb_set_t& org_set, + int k, + unsigned n, + hb_set_t& out) +{ + if (!n) return false; + k %= n; + if (k < 0) + k = n + k; + + if (k == 0) + { + out.set (org_set); + } + else + { + for (auto v : org_set) + out.add ((v + k) % n); + } + return !out.in_error (); +} + +/* Given two reference coordinates (start and end of contour_points array), + * output interpolated deltas for points in between */ +static bool _iup_segment (const hb_array_t contour_points, + const hb_array_t x_deltas, + const hb_array_t y_deltas, + const contour_point_t& p1, const contour_point_t& p2, + int p1_dx, int p2_dx, + int p1_dy, int p2_dy, + hb_vector_t& interp_x_deltas, /* OUT */ + hb_vector_t& interp_y_deltas /* OUT */) +{ + unsigned n = contour_points.length; + if (unlikely (!interp_x_deltas.resize (n, false) || + !interp_y_deltas.resize (n, false))) + return false; + + for (unsigned j = 0; j < 2; j++) + { + float x1, x2, d1, d2; + float *out; + if (j == 0) + { + x1 = p1.x; + x2 = p2.x; + d1 = p1_dx; + d2 = p2_dx; + out = interp_x_deltas.arrayZ; + } + else + { + x1 = p1.y; + x2 = p2.y; + d1 = p1_dy; + d2 = p2_dy; + out = interp_y_deltas.arrayZ; + } + + if (x1 == x2) + { + if (d1 == d2) + { + for (unsigned i = 0; i < n; i++) + out[i] = d1; + } + else + { + for (unsigned i = 0; i < n; i++) + out[i] = 0.f; + } + continue; + } + + if (x1 > x2) + { + hb_swap (x1, x2); + hb_swap (d1, d2); + } + + float scale = (d2 - d1) / (x2 - x1); + for (unsigned i = 0; i < n; i++) + { + float x = j == 0 ? contour_points.arrayZ[i].x : contour_points.arrayZ[i].y; + float d; + if (x <= x1) + d = d1; + else if (x >= x2) + d = d2; + else + d = d1 + (x - x1) * scale; + + out[i] = d; + } + } + return true; +} + +static bool _can_iup_in_between (const hb_array_t contour_points, + const hb_array_t x_deltas, + const hb_array_t y_deltas, + const contour_point_t& p1, const contour_point_t& p2, + int p1_dx, int p2_dx, + int p1_dy, int p2_dy, + float tolerance) +{ + hb_vector_t interp_x_deltas, interp_y_deltas; + if (!_iup_segment (contour_points, x_deltas, y_deltas, + p1, p2, p1_dx, p2_dx, p1_dy, p2_dy, + interp_x_deltas, interp_y_deltas)) + return false; + + unsigned num = contour_points.length; + + for (unsigned i = 0; i < num; i++) + { + float dx = x_deltas.arrayZ[i] - interp_x_deltas.arrayZ[i]; + float dy = y_deltas.arrayZ[i] - interp_y_deltas.arrayZ[i]; + + if (sqrtf ((float)dx * dx + (float)dy * dy) > tolerance) + return false; + } + return true; +} + +static bool _iup_contour_optimize_dp (const contour_point_vector_t& contour_points, + const hb_vector_t& x_deltas, + const hb_vector_t& y_deltas, + const hb_set_t& forced_set, + float tolerance, + unsigned lookback, + hb_vector_t& costs, /* OUT */ + hb_vector_t& chain /* OUT */) +{ + unsigned n = contour_points.length; + if (unlikely (!costs.resize (n, false) || + !chain.resize (n, false))) + return false; + + lookback = hb_min (lookback, MAX_LOOKBACK); + + for (unsigned i = 0; i < n; i++) + { + unsigned best_cost = (i == 0 ? 1 : costs.arrayZ[i-1] + 1); + + costs.arrayZ[i] = best_cost; + chain.arrayZ[i] = (i == 0 ? -1 : i - 1); + + if (i > 0 && forced_set.has (i - 1)) + continue; + + int lookback_index = hb_max ((int) i - (int) lookback + 1, -1); + for (int j = i - 2; j >= lookback_index; j--) + { + unsigned cost = j == -1 ? 1 : costs.arrayZ[j] + 1; + /* num points between i and j */ + unsigned num_points = i - j - 1; + unsigned p1 = (j == -1 ? n - 1 : j); + if (cost < best_cost && + _can_iup_in_between (contour_points.as_array ().sub_array (j + 1, num_points), + x_deltas.as_array ().sub_array (j + 1, num_points), + y_deltas.as_array ().sub_array (j + 1, num_points), + contour_points.arrayZ[p1], contour_points.arrayZ[i], + x_deltas.arrayZ[p1], x_deltas.arrayZ[i], + y_deltas.arrayZ[p1], y_deltas.arrayZ[i], + tolerance)) + { + best_cost = cost; + costs.arrayZ[i] = best_cost; + chain.arrayZ[i] = j; + } + + if (j > 0 && forced_set.has (j)) + break; + } + } + return true; +} + +static bool _iup_contour_optimize (const hb_array_t contour_points, + const hb_array_t x_deltas, + const hb_array_t y_deltas, + hb_array_t opt_indices, /* OUT */ + float tolerance = 0.f) +{ + unsigned n = contour_points.length; + if (opt_indices.length != n || + x_deltas.length != n || + y_deltas.length != n) + return false; + + bool all_within_tolerance = true; + for (unsigned i = 0; i < n; i++) + { + int dx = x_deltas.arrayZ[i]; + int dy = y_deltas.arrayZ[i]; + if (sqrtf ((float)dx * dx + (float)dy * dy) > tolerance) + { + all_within_tolerance = false; + break; + } + } + + /* If all are within tolerance distance, do nothing, opt_indices is + * initilized to false */ + if (all_within_tolerance) + return true; + + /* If there's exactly one point, return it */ + if (n == 1) + { + opt_indices.arrayZ[0] = true; + return true; + } + + /* If all deltas are exactly the same, return just one (the first one) */ + bool all_deltas_are_equal = true; + for (unsigned i = 1; i < n; i++) + if (x_deltas.arrayZ[i] != x_deltas.arrayZ[0] || + y_deltas.arrayZ[i] != y_deltas.arrayZ[0]) + { + all_deltas_are_equal = false; + break; + } + + if (all_deltas_are_equal) + { + opt_indices.arrayZ[0] = true; + return true; + } + + /* else, solve the general problem using Dynamic Programming */ + hb_set_t forced_set; + _iup_contour_bound_forced_set (contour_points, x_deltas, y_deltas, forced_set, tolerance); + + if (!forced_set.is_empty ()) + { + int k = n - 1 - forced_set.get_max (); + if (k < 0) + return false; + + hb_vector_t rot_x_deltas, rot_y_deltas; + contour_point_vector_t rot_points; + hb_set_t rot_forced_set; + if (!rotate_array (contour_points, k, rot_points) || + !rotate_array (x_deltas, k, rot_x_deltas) || + !rotate_array (y_deltas, k, rot_y_deltas) || + !rotate_set (forced_set, k, n, rot_forced_set)) + return false; + + hb_vector_t costs; + hb_vector_t chain; + + if (!_iup_contour_optimize_dp (rot_points, rot_x_deltas, rot_y_deltas, + rot_forced_set, tolerance, n, + costs, chain)) + return false; + + hb_set_t solution; + int index = n - 1; + while (index != -1) + { + solution.add (index); + index = chain.arrayZ[index]; + } + + if (solution.is_empty () || + forced_set.get_population () > solution.get_population ()) + return false; + + for (unsigned i : solution) + opt_indices.arrayZ[i] = true; + + hb_vector_t rot_indices; + const hb_array_t opt_indices_array (opt_indices.arrayZ, opt_indices.length); + rotate_array (opt_indices_array, -k, rot_indices); + + for (unsigned i = 0; i < n; i++) + opt_indices.arrayZ[i] = rot_indices.arrayZ[i]; + } + else + { + hb_vector_t repeat_x_deltas, repeat_y_deltas; + contour_point_vector_t repeat_points; + + if (unlikely (!repeat_x_deltas.resize (n * 2, false) || + !repeat_y_deltas.resize (n * 2, false) || + !repeat_points.resize (n * 2, false))) + return false; + + unsigned contour_point_size = hb_static_size (contour_point_t); + for (unsigned i = 0; i < n; i++) + { + hb_memcpy ((void *) repeat_x_deltas.arrayZ, (const void *) x_deltas.arrayZ, n * sizeof (float)); + hb_memcpy ((void *) (repeat_x_deltas.arrayZ + n), (const void *) x_deltas.arrayZ, n * sizeof (float)); + + hb_memcpy ((void *) repeat_y_deltas.arrayZ, (const void *) y_deltas.arrayZ, n * sizeof (float)); + hb_memcpy ((void *) (repeat_y_deltas.arrayZ + n), (const void *) y_deltas.arrayZ, n * sizeof (float)); + + hb_memcpy ((void *) repeat_points.arrayZ, (const void *) contour_points.arrayZ, n * contour_point_size); + hb_memcpy ((void *) (repeat_points.arrayZ + n), (const void *) contour_points.arrayZ, n * contour_point_size); + } + + hb_vector_t costs; + hb_vector_t chain; + if (!_iup_contour_optimize_dp (repeat_points, repeat_x_deltas, repeat_y_deltas, + forced_set, tolerance, n, + costs, chain)) + return false; + + unsigned best_cost = n + 1; + int len = costs.length; + hb_set_t best_sol; + for (int start = n - 1; start < len; start++) + { + hb_set_t solution; + int i = start; + int lookback = start - (int) n; + while (i > lookback) + { + solution.add (i % n); + i = chain.arrayZ[i]; + } + if (i == lookback) + { + unsigned cost_i = i < 0 ? 0 : costs.arrayZ[i]; + unsigned cost = costs.arrayZ[start] - cost_i; + if (cost <= best_cost) + { + best_sol.set (solution); + best_cost = cost; + } + } + } + + for (unsigned i = 0; i < n; i++) + if (best_sol.has (i)) + opt_indices.arrayZ[i] = true; + } + return true; +} + +bool iup_delta_optimize (const contour_point_vector_t& contour_points, + const hb_vector_t& x_deltas, + const hb_vector_t& y_deltas, + hb_vector_t& opt_indices, /* OUT */ + float tolerance) +{ + if (!opt_indices.resize (contour_points.length)) + return false; + + hb_vector_t end_points; + unsigned count = contour_points.length; + if (unlikely (!end_points.alloc (count))) + return false; + + for (unsigned i = 0; i < count - 4; i++) + if (contour_points.arrayZ[i].is_end_point) + end_points.push (i); + + /* phantom points */ + for (unsigned i = count - 4; i < count; i++) + end_points.push (i); + + if (end_points.in_error ()) return false; + + unsigned start = 0; + for (unsigned end : end_points) + { + unsigned len = end - start + 1; + if (!_iup_contour_optimize (contour_points.as_array ().sub_array (start, len), + x_deltas.as_array ().sub_array (start, len), + y_deltas.as_array ().sub_array (start, len), + opt_indices.as_array ().sub_array (start, len), + tolerance)) + return false; + start = end + 1; + } + return true; +} diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-iup.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-iup.hh new file mode 100644 index 00000000000..7eac5935a46 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-iup.hh @@ -0,0 +1,37 @@ +/* + * Copyright © 2024 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_SUBSET_INSTANCER_IUP_HH +#define HB_SUBSET_INSTANCER_IUP_HH + +#include "hb-subset-plan.hh" +/* given contour points and deltas, optimize a set of referenced points within error + * tolerance. Returns optimized referenced point indices */ +HB_INTERNAL bool iup_delta_optimize (const contour_point_vector_t& contour_points, + const hb_vector_t& x_deltas, + const hb_vector_t& y_deltas, + hb_vector_t& opt_indices, /* OUT */ + float tolerance = 0.f); + +#endif /* HB_SUBSET_INSTANCER_IUP_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc index 4876bc43797..70783c0a0d8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc @@ -256,7 +256,10 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) */ float newUpper = peak + (1 - gain) * (upper - peak); assert (axisMax <= newUpper); // Because outGain > gain - if (newUpper <= axisDef + (axisMax - axisDef) * 2) + /* Disabled because ots doesn't like us: + * https://github.com/fonttools/fonttools/issues/3350 */ + + if (false && (newUpper <= axisDef + (axisMax - axisDef) * 2)) { upper = newUpper; if (!negative && axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh index 71da80e3875..74416b92f98 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh @@ -140,6 +140,15 @@ HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t, bounds_height_vec) //map: new_gid -> contour points vector HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(), new_gid_contour_points_map) +//new gids set for composite glyphs +HB_SUBSET_PLAN_MEMBER (hb_set_t, composite_new_gids) + +//Old BASE item variation index -> (New varidx, 0) mapping +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E()>), base_variation_idx_map) + +//BASE table varstore retained varidx mapping +HB_SUBSET_PLAN_MEMBER (hb_vector_t, base_varstore_inner_maps) + #ifdef HB_EXPERIMENTAL_API // name table overrides map: hb_ot_name_record_ids_t-> name string new value or // None to indicate should remove diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc index 5786223196d..068fddaeddd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc @@ -32,6 +32,7 @@ #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" +#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-layout-gsub-table.hh" @@ -431,6 +432,52 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan) gdef.destroy (); gpos.destroy (); } + +#ifndef HB_NO_BASE +/* used by BASE table only, delta is always set to 0 in the output map */ +static inline void +_remap_variation_indices (const hb_set_t& indices, + unsigned subtable_count, + hb_hashmap_t>& variation_idx_delta_map /* OUT */) +{ + unsigned new_major = 0, new_minor = 0; + unsigned last_major = (indices.get_min ()) >> 16; + for (unsigned idx : indices) + { + uint16_t major = idx >> 16; + if (major >= subtable_count) break; + if (major != last_major) + { + new_minor = 0; + ++new_major; + } + + unsigned new_idx = (new_major << 16) + new_minor; + variation_idx_delta_map.set (idx, hb_pair_t (new_idx, 0)); + ++new_minor; + last_major = major; + } +} + +static inline void +_collect_base_variation_indices (hb_subset_plan_t* plan) +{ + hb_blob_ptr_t base = plan->source_table (); + if (!base->has_var_store ()) + { + base.destroy (); + return; + } + + hb_set_t varidx_set; + base->collect_variation_indices (plan, varidx_set); + unsigned subtable_count = base->get_var_store ().get_sub_table_count (); + base.destroy (); + + _remap_variation_indices (varidx_set, subtable_count, plan->base_variation_idx_map); + _generate_varstore_inner_maps (varidx_set, subtable_count, plan->base_varstore_inner_maps); +} +#endif #endif static inline void @@ -994,8 +1041,8 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) OT::cff2::accelerator_t cff2 (plan->source); if (!cff2.is_valid ()) return; - hb_font_t *font = nullptr; - if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) + hb_font_t *font = _get_hb_font_with_variations (plan); + if (unlikely (!plan->check_success (font != nullptr))) { hb_font_destroy (font); return; @@ -1073,8 +1120,8 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) static bool _get_instance_glyphs_contour_points (hb_subset_plan_t *plan) { - /* contour_points vector only needed for updating gvar table (infer delta) - * during partial instancing */ + /* contour_points vector only needed for updating gvar table (infer delta and + * iup delta optimization) during partial instancing */ if (plan->user_axes_location.is_empty () || plan->all_axes_pinned) return true; @@ -1092,10 +1139,17 @@ _get_instance_glyphs_contour_points (hb_subset_plan_t *plan) } hb_codepoint_t old_gid = _.second; - if (unlikely (!glyf.glyph_for_gid (old_gid).get_all_points_without_var (plan->source, all_points))) + auto glyph = glyf.glyph_for_gid (old_gid); + if (unlikely (!glyph.get_all_points_without_var (plan->source, all_points))) return false; if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) return false; + +#ifdef HB_EXPERIMENTAL_API + /* composite new gids are only needed by iup delta optimization */ + if ((plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS) && glyph.is_composite ()) + plan->composite_new_gids.add (new_gid); +#endif } return true; } @@ -1205,6 +1259,13 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, if (!drop_tables.has (HB_OT_TAG_GDEF)) _remap_used_mark_sets (this, used_mark_sets_map); +#ifndef HB_NO_VAR +#ifndef HB_NO_BASE + if (!drop_tables.has (HB_OT_TAG_BASE)) + _collect_base_variation_indices (this); +#endif +#endif + if (unlikely (in_error ())) return; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh index 1f19a58c1ed..19a9fa69182 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh @@ -78,6 +78,13 @@ struct contour_point_t y = x * matrix[1] + y * matrix[3]; x = x_; } + + void add_delta (float delta_x, float delta_y) + { + x += delta_x; + y += delta_y; + } + HB_ALWAYS_INLINE void translate (const contour_point_t &p) { x += p.x; y += p.y; } @@ -99,6 +106,22 @@ struct contour_point_vector_t : hb_vector_t unsigned count = a.length; hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0])); } + + bool add_deltas (const hb_vector_t deltas_x, + const hb_vector_t deltas_y, + const hb_vector_t indices) + { + if (indices.length != deltas_x.length || + indices.length != deltas_y.length) + return false; + + for (unsigned i = 0; i < indices.length; i++) + { + if (!indices.arrayZ[i]) continue; + arrayZ[i].add_delta (deltas_x.arrayZ[i], deltas_y.arrayZ[i]); + } + return true; + } }; namespace OT { @@ -147,7 +170,7 @@ struct hb_subset_plan_t bool gsub_insert_catch_all_feature_variation_rec; bool gpos_insert_catch_all_feature_variation_rec; - // whether GDEF VarStore is retained + // whether GDEF ItemVariationStore is retained mutable bool has_gdef_varstore; #define HB_SUBSET_PLAN_MEMBER(Type, Name) Type Name; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc index 06e77dd8eb5..f10ef54dbdc 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc @@ -48,6 +48,7 @@ #include "hb-ot-cff2-table.hh" #include "hb-ot-vorg-table.hh" #include "hb-ot-name-table.hh" +#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-var-avar-table.hh" @@ -503,6 +504,7 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_CBLC: return _subset (plan, buf); case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */ case HB_OT_TAG_MATH: return _subset (plan, buf); + case HB_OT_TAG_BASE: return _subset (plan, buf); #ifndef HB_NO_SUBSET_CFF case HB_OT_TAG_CFF1: return _subset (plan, buf); @@ -548,6 +550,7 @@ _subset_table (hb_subset_plan_t *plan, } #endif return _passthrough (plan, tag); + default: if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) return _passthrough (plan, tag); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.h b/src/3rdparty/harfbuzz-ng/src/hb-subset.h index d79e7f762a0..73dcae4660b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.h @@ -76,6 +76,8 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; * @HB_SUBSET_FLAGS_IFTB_REQUIREMENTS: If set enforce requirements on the output subset * to allow it to be used with incremental font transfer IFTB patches. Primarily, * this forces all outline data to use long (32 bit) offsets. Since: EXPERIMENTAL + * @HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS: If set perform IUP delta optimization on the + * remaining gvar table's deltas. Since: EXPERIMENTAL * * List of boolean properties that can be configured on the subset input. * @@ -95,6 +97,7 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE = 0x00000200u, #ifdef HB_EXPERIMENTAL_API HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00000400u, + HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS = 0x00000800u, #endif } hb_subset_flags_t; @@ -170,6 +173,10 @@ HB_EXTERN void hb_subset_input_set_flags (hb_subset_input_t *input, unsigned value); +HB_EXTERN hb_bool_t +hb_subset_input_pin_all_axes_to_default (hb_subset_input_t *input, + hb_face_t *face); + HB_EXTERN hb_bool_t hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, hb_face_t *face, @@ -182,13 +189,20 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, float axis_value); #ifdef HB_EXPERIMENTAL_API +HB_EXTERN hb_bool_t +hb_subset_input_get_axis_range (hb_subset_input_t *input, + hb_tag_t axis_tag, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value); + HB_EXTERN hb_bool_t hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_face_t *face, hb_tag_t axis_tag, float axis_min_value, float axis_max_value, - float *axis_def_value); + float axis_def_value); HB_EXTERN hb_bool_t hb_subset_input_override_name_table (hb_subset_input_t *input, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-vector.hh b/src/3rdparty/harfbuzz-ng/src/hb-vector.hh index dfe1b7d1c7e..c0cc7063ff0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-vector.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-vector.hh @@ -78,7 +78,7 @@ struct hb_vector_t if (unlikely (in_error ())) return; copy_array (o); } - hb_vector_t (hb_vector_t &&o) + hb_vector_t (hb_vector_t &&o) noexcept { allocated = o.allocated; length = o.length; @@ -122,7 +122,7 @@ struct hb_vector_t resize (0); } - friend void swap (hb_vector_t& a, hb_vector_t& b) + friend void swap (hb_vector_t& a, hb_vector_t& b) noexcept { hb_swap (a.allocated, b.allocated); hb_swap (a.length, b.length); @@ -139,7 +139,7 @@ struct hb_vector_t return *this; } - hb_vector_t& operator = (hb_vector_t &&o) + hb_vector_t& operator = (hb_vector_t &&o) noexcept { hb_swap (*this, o); return *this; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h index b08dd1f09f4..68681874ca5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-version.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h @@ -47,7 +47,7 @@ HB_BEGIN_DECLS * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 3 +#define HB_VERSION_MINOR 4 /** * HB_VERSION_MICRO: * @@ -60,7 +60,7 @@ HB_BEGIN_DECLS * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "8.3.0" +#define HB_VERSION_STRING "8.4.0" /** * HB_VERSION_ATLEAST: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-wasm-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-wasm-shape.cc index a70b7666465..a8b91879a43 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-wasm-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-wasm-shape.cc @@ -240,7 +240,7 @@ acquire_shape_plan (hb_face_t *face, goto fail; } - func = wasm_runtime_lookup_function (module_inst, "shape_plan_create", nullptr); + func = wasm_runtime_lookup_function (module_inst, "shape_plan_create"); if (func) { wasm_val_t results[1]; @@ -297,7 +297,7 @@ release_shape_plan (const hb_wasm_face_data_t *face_data, if (plan->wasm_shape_planptr) { - auto *func = wasm_runtime_lookup_function (module_inst, "shape_plan_destroy", nullptr); + auto *func = wasm_runtime_lookup_function (module_inst, "shape_plan_destroy"); if (func) { wasm_val_t arguments[1]; @@ -395,7 +395,7 @@ retry: goto fail; } - func = wasm_runtime_lookup_function (module_inst, "shape", nullptr); + func = wasm_runtime_lookup_function (module_inst, "shape"); if (unlikely (!func)) { DEBUG_MSG (WASM, module_inst, "Shape function not found."); diff --git a/src/3rdparty/harfbuzz-ng/src/hb.hh b/src/3rdparty/harfbuzz-ng/src/hb.hh index 972608d6a30..0ceeb99f500 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb.hh @@ -64,6 +64,7 @@ #pragma GCC diagnostic error "-Wbitwise-instead-of-logical" #pragma GCC diagnostic error "-Wcast-align" #pragma GCC diagnostic error "-Wcast-function-type" +#pragma GCC diagnostic error "-Wcast-function-type-strict" #pragma GCC diagnostic error "-Wconstant-conversion" #pragma GCC diagnostic error "-Wcomma" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" @@ -177,6 +178,11 @@ #define HB_EXTERN __declspec (dllexport) extern #endif +// https://github.com/harfbuzz/harfbuzz/pull/4619 +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS 1 +#endif + #include "hb.h" #define HB_H_IN #include "hb-ot.h" @@ -212,6 +218,12 @@ #include #endif +#ifndef PRId32 +# define PRId32 "d" +# define PRIu32 "u" +# define PRIx32 "x" +#endif + #define HB_PASTE1(a,b) a##b #define HB_PASTE(a,b) HB_PASTE1(a,b)