mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
gcc version 5 cannot decide how many bits are require for enum well if there is enum has type. it generates warning but we don't need to set type into enum for gcc 5 Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
515 lines
15 KiB
C++
Executable file
515 lines
15 KiB
C++
Executable file
/*
|
|
* Copyright (c) 2016-present Samsung Electronics Co., Ltd
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
* USA
|
|
*/
|
|
|
|
#ifndef __Escargot__
|
|
#define __Escargot__
|
|
|
|
/* COMPILER() - the compiler being used to build the project */
|
|
// Outdated syntax: use defined()
|
|
// #define COMPILER(FEATURE) (defined COMPILER_##FEATURE && COMPILER_##FEATURE)
|
|
|
|
#if defined(__clang__)
|
|
#define COMPILER_CLANG 1
|
|
#elif defined(_MSC_VER)
|
|
#define COMPILER_MSVC 1
|
|
#elif (__GNUC__)
|
|
#define COMPILER_GCC 1
|
|
#else
|
|
#error "Compiler dectection failed"
|
|
#endif
|
|
|
|
#if defined(COMPILER_CLANG)
|
|
/* Check clang version */
|
|
#if __clang_major__ < 6
|
|
#error "Clang version is low (require clang version 6+)"
|
|
#endif
|
|
/* Keep strong enums turned off when building with clang-cl: We cannot yet build all of Blink without fallback to cl.exe, and strong enums are exposed at ABI boundaries. */
|
|
#undef COMPILER_SUPPORTS_CXX_STRONG_ENUMS
|
|
#else
|
|
#define COMPILER_SUPPORTS_CXX_OVERRIDE_CONTROL 1
|
|
#define COMPILER_QUIRK_FINAL_IS_CALLED_SEALED 1
|
|
#endif
|
|
|
|
#if defined(ENABLE_CODE_CACHE) && defined(ESCARGOT_DEBUGGER)
|
|
#error "Code Cache does not support Debugger mode"
|
|
#endif
|
|
|
|
/* ALWAYS_INLINE */
|
|
#ifndef ALWAYS_INLINE
|
|
#if defined(ESCARGOT_SMALL_CONFIG)
|
|
#define ALWAYS_INLINE inline
|
|
#else
|
|
#if (defined(COMPILER_GCC) || defined(COMPILER_CLANG)) && defined(NDEBUG) && !defined(COMPILER_MINGW)
|
|
#define ALWAYS_INLINE inline __attribute__((__always_inline__))
|
|
#elif defined(COMPILER_MSVC) && defined(NDEBUG)
|
|
#define ALWAYS_INLINE __forceinline
|
|
#else
|
|
#define ALWAYS_INLINE inline
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
/* NEVER_INLINE */
|
|
#ifndef NEVER_INLINE
|
|
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
#define NEVER_INLINE __attribute__((__noinline__))
|
|
#else
|
|
#define NEVER_INLINE
|
|
#endif
|
|
#endif
|
|
|
|
/* UNLIKELY */
|
|
#ifndef UNLIKELY
|
|
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
#define UNLIKELY(x) __builtin_expect((x), 0)
|
|
#else
|
|
#define UNLIKELY(x) (x)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* LIKELY */
|
|
#ifndef LIKELY
|
|
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
#define LIKELY(x) __builtin_expect((x), 1)
|
|
#else
|
|
#define LIKELY(x) (x)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* NO_RETURN */
|
|
#ifndef NO_RETURN
|
|
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
#define NO_RETURN __attribute((__noreturn__))
|
|
#elif defined(COMPILER_MSVC)
|
|
#define NO_RETURN __declspec(noreturn)
|
|
#else
|
|
#define NO_RETURN
|
|
#endif
|
|
#endif
|
|
|
|
/* EXPORT */
|
|
#ifndef EXPORT
|
|
#if defined(COMPILER_MSVC)
|
|
#define EXPORT __declspec(dllexport)
|
|
#else
|
|
#define EXPORT __attribute__((visibility("default")))
|
|
#endif
|
|
#endif
|
|
|
|
/* PREFETCH_READ */
|
|
#ifndef PREFETCH_READ
|
|
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
#define PREFETCH_READ(x) __builtin_prefetch((x), 0, 0)
|
|
#else
|
|
#define PREFETCH_READ(x)
|
|
#endif
|
|
#endif
|
|
|
|
/* LOG2 */
|
|
#ifndef FAST_LOG2_UINT
|
|
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
#define FAST_LOG2_UINT(x) ((unsigned)(8 * sizeof(unsigned long long) - __builtin_clzll((x)) - 1))
|
|
#else
|
|
#define FAST_LOG2_UINT(x) log2l(x)
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(COMPILER_MSVC)
|
|
#define strncasecmp _strnicmp
|
|
#define strcasecmp _stricmp
|
|
#endif
|
|
|
|
#ifndef ATTRIBUTE_NO_SANITIZE_ADDRESS
|
|
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
|
|
#else
|
|
#define ATTRIBUTE_NO_SANITIZE_ADDRESS
|
|
#endif
|
|
#endif
|
|
|
|
// #define OS(NAME) (defined OS_##NAME && OS_##NAME)
|
|
|
|
#ifdef _WIN32
|
|
#define OS_WINDOWS 1
|
|
#elif _WIN64
|
|
#define OS_WINDOWS 1
|
|
#elif __APPLE__
|
|
#include "TargetConditionals.h"
|
|
#if TARGET_IPHONE_SIMULATOR
|
|
#define OS_POSIX 1
|
|
#elif TARGET_OS_IPHONE
|
|
#define OS_POSIX 1
|
|
#elif TARGET_OS_MAC
|
|
#define OS_POSIX 1
|
|
#else
|
|
#error "Unknown Apple platform"
|
|
#endif
|
|
#elif __linux__
|
|
#define OS_POSIX 1
|
|
#elif __unix__ // all unices not caught above
|
|
#define OS_POSIX 1
|
|
#elif defined(_POSIX_VERSION)
|
|
#define OS_POSIX 1
|
|
#else
|
|
#error "failed to detect target OS"
|
|
#endif
|
|
|
|
#if defined(OS_WINDOWS)
|
|
#define NOMINMAX
|
|
#endif
|
|
|
|
/*
|
|
we need to mark enum as unsigned if needs.
|
|
because processing enum in msvc is little different
|
|
|
|
ex) enum Type { A, B };
|
|
struct Foo { Type type: 1; };
|
|
Foo f; f.type = 1;
|
|
if (f.type == Type::B) { puts("failed in msvc."); }
|
|
*/
|
|
#if defined(COMPILER_MSVC)
|
|
#define ENSURE_ENUM_UNSIGNED : unsigned int
|
|
#else
|
|
#define ENSURE_ENUM_UNSIGNED
|
|
#endif
|
|
|
|
#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
|
#define HAVE_BUILTIN_ATOMIC_FUNCTIONS
|
|
#endif
|
|
|
|
#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
|
|
#define CPU_X86_64
|
|
|
|
#elif defined(i386) || defined(__i386) || defined(__i386__) || defined(__IA32__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) || defined(__386)
|
|
#define CPU_X86
|
|
|
|
#elif defined(__arm__) || defined(__thumb__) || defined(_ARM) || defined(_M_ARM) || defined(_M_ARMT) || defined(__arm) || defined(__arm)
|
|
#define CPU_ARM
|
|
|
|
#elif defined(__aarch64__)
|
|
#define CPU_ARM64
|
|
|
|
#else
|
|
#error "Could't find cpu arch."
|
|
#endif
|
|
|
|
#include <algorithm>
|
|
#include <cassert>
|
|
#include <climits>
|
|
#include <clocale>
|
|
#include <cmath>
|
|
#include <csetjmp>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <cwchar>
|
|
#include <functional>
|
|
#include <limits>
|
|
#include <list>
|
|
#include <locale>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <set>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
#include <vector>
|
|
#include <random>
|
|
|
|
#if defined(COMPILER_MSVC)
|
|
#include <stddef.h>
|
|
#endif
|
|
|
|
#if defined(ENABLE_THREADING)
|
|
#include <thread>
|
|
#include <mutex>
|
|
#include <atomic>
|
|
#include <condition_variable>
|
|
#endif
|
|
|
|
extern "C" {
|
|
#include <libbf.h>
|
|
}
|
|
|
|
#ifndef ESCARGOT_BUILD_DATE
|
|
#define ESCARGOT_BUILD_DATE __DATE__
|
|
#endif
|
|
|
|
#ifdef ENABLE_ICU
|
|
#if defined(ENABLE_RUNTIME_ICU_BINDER)
|
|
typedef unsigned char LChar;
|
|
#include "RuntimeICUBinder.h"
|
|
#include "ICUPolyfill.h"
|
|
#else
|
|
#include <unicode/locid.h>
|
|
#include <unicode/uchar.h>
|
|
#include <unicode/ustring.h>
|
|
#include <unicode/datefmt.h>
|
|
#include <unicode/vtzone.h>
|
|
#include <unicode/unorm.h> // for normalize builtin function of String
|
|
#include <unicode/ucol.h> // for Intl
|
|
#include <unicode/urename.h> // for Intl
|
|
#include <unicode/unumsys.h> // for Intl
|
|
#include <unicode/udat.h> // for Intl
|
|
#include <unicode/udatpg.h> // for Intl
|
|
#include <unicode/unum.h> // for Intl
|
|
#include <unicode/upluralrules.h> // for Intl
|
|
#include <unicode/unumberformatter.h> // for Intl
|
|
#include <unicode/ureldatefmt.h> // for Intl
|
|
#include <unicode/uformattedvalue.h> // for Intl
|
|
#include <unicode/ucurr.h> // for Intl
|
|
#include <unicode/uloc.h> // for Intl
|
|
#include <unicode/uldnames.h> // for Intl
|
|
#include <unicode/ulistformatter.h> // for Intl
|
|
|
|
// FIXME replace these vzone decl into include
|
|
// I declare vzone api because there is no header file in include folder
|
|
extern "C" {
|
|
// VZone c api
|
|
struct VZone;
|
|
VZone* vzone_openID(const UChar* ID, int32_t idLength);
|
|
void vzone_close(VZone* zone);
|
|
UBool vzone_getTZURL(VZone* zone, UChar*& url, int32_t& urlLength);
|
|
void vzone_getOffset3(VZone* zone, UDate date, UBool local, int32_t& rawOffset,
|
|
int32_t& dstOffset, UErrorCode& ec);
|
|
int32_t vzone_getRawOffset(VZone* zone);
|
|
}
|
|
#endif
|
|
|
|
#else
|
|
|
|
typedef char16_t UChar;
|
|
typedef unsigned char LChar;
|
|
typedef int32_t UChar32;
|
|
|
|
// macros from icu
|
|
#define U16_IS_LEAD(c) (((c)&0xfffffc00) == 0xd800)
|
|
#define U16_IS_TRAIL(c) (((c)&0xfffffc00) == 0xdc00)
|
|
#define U16_SURROGATE_OFFSET ((0xd800 << 10UL) + 0xdc00 - 0x10000)
|
|
#define U16_GET_SUPPLEMENTARY(lead, trail) \
|
|
(((UChar32)(lead) << 10UL) + (UChar32)(trail)-U16_SURROGATE_OFFSET)
|
|
|
|
#define U16_NEXT(s, i, length, c) \
|
|
{ \
|
|
(c) = (s)[(i)++]; \
|
|
if (U16_IS_LEAD(c)) { \
|
|
uint16_t __c2; \
|
|
if ((i) != (length) && U16_IS_TRAIL(__c2 = (s)[(i)])) { \
|
|
++(i); \
|
|
(c) = U16_GET_SUPPLEMENTARY((c), __c2); \
|
|
} \
|
|
} \
|
|
}
|
|
#define U16_LENGTH(c) ((uint32_t)(c) <= 0xffff ? 1 : 2)
|
|
#define U_IS_BMP(c) ((uint32_t)(c) <= 0xffff)
|
|
#define UCHAR_MAX_VALUE 0x10ffff
|
|
#endif
|
|
|
|
#ifndef TRUE
|
|
#define TRUE 1
|
|
#endif
|
|
|
|
#ifndef FALSE
|
|
#define FALSE 0
|
|
#endif
|
|
|
|
#ifdef ESCARGOT_USE_CUSTOM_LOGGING
|
|
// use customized logging
|
|
#include <stdarg.h>
|
|
namespace Escargot {
|
|
void customEscargotInfoLogger(const char* format, ...);
|
|
void customEscargotErrorLogger(const char* format, ...);
|
|
} // namespace Escargot
|
|
#define ESCARGOT_LOG_INFO(...) ::Escargot::customEscargotInfoLogger(__VA_ARGS__);
|
|
#define ESCARGOT_LOG_ERROR(...) ::Escargot::customEscargotErrorLogger(__VA_ARGS__);
|
|
#else
|
|
// use default logging
|
|
#define ESCARGOT_LOG_INFO(...) fprintf(stdout, __VA_ARGS__);
|
|
#define ESCARGOT_LOG_ERROR(...) fprintf(stderr, __VA_ARGS__);
|
|
|
|
#if defined(ESCARGOT_ANDROID)
|
|
#include <android/log.h>
|
|
#undef ESCARGOT_LOG_ERROR
|
|
#define ESCARGOT_LOG_ERROR(...) __android_log_print(ANDROID_LOG_ERROR, "Escargot", __VA_ARGS__);
|
|
#endif
|
|
|
|
#if defined(ESCARGOT_TIZEN)
|
|
#include <dlog/dlog.h>
|
|
#undef ESCARGOT_LOG_INFO
|
|
#undef ESCARGOT_LOG_ERROR
|
|
#define ESCARGOT_LOG_INFO(...) dlog_print(DLOG_INFO, "Escargot", __VA_ARGS__);
|
|
#define ESCARGOT_LOG_ERROR(...) dlog_print(DLOG_ERROR, "Escargot", __VA_ARGS__);
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef CRASH
|
|
#define CRASH ASSERT_NOT_REACHED
|
|
#endif
|
|
|
|
#if defined(NDEBUG)
|
|
#define ASSERT(assertion) ((void)0)
|
|
#define ASSERT_NOT_REACHED() ((void)0)
|
|
#define ASSERT_STATIC(assertion, reason)
|
|
#else
|
|
#define ASSERT(assertion) assert(assertion);
|
|
#define ASSERT_NOT_REACHED() \
|
|
do { \
|
|
assert(false); \
|
|
} while (0)
|
|
#define ASSERT_STATIC(assertion, reason) static_assert(assertion, reason)
|
|
#endif
|
|
|
|
/* COMPILE_ASSERT */
|
|
#ifndef COMPILE_ASSERT
|
|
#define COMPILE_ASSERT(exp, name) static_assert((exp), #name)
|
|
#endif
|
|
|
|
#define RELEASE_ASSERT(assertion) \
|
|
do { \
|
|
if (!(assertion)) { \
|
|
ESCARGOT_LOG_ERROR("RELEASE_ASSERT at %s (%d)\n", __FILE__, __LINE__); \
|
|
abort(); \
|
|
} \
|
|
} while (0);
|
|
#define RELEASE_ASSERT_NOT_REACHED() \
|
|
do { \
|
|
ESCARGOT_LOG_ERROR("RELEASE_ASSERT_NOT_REACHED at %s (%d)\n", __FILE__, __LINE__); \
|
|
abort(); \
|
|
} while (0)
|
|
|
|
#if !defined(WARN_UNUSED_RETURN) && (defined(COMPILER_GCC) || defined(COMPILER_CLANG))
|
|
#define WARN_UNUSED_RETURN __attribute__((__warn_unused_result__))
|
|
#endif
|
|
|
|
#if !defined(WARN_UNUSED_RETURN)
|
|
#define WARN_UNUSED_RETURN
|
|
#endif
|
|
|
|
/* UNUSED_PARAMETER */
|
|
|
|
#if !defined(UNUSED_PARAMETER) && defined(COMPILER_MSVC)
|
|
#define UNUSED_PARAMETER(variable) (void)&variable
|
|
#endif
|
|
|
|
#if !defined(UNUSED_PARAMETER)
|
|
#define UNUSED_PARAMETER(variable) (void)variable
|
|
#endif
|
|
|
|
/* UNUSED_VARIABLE */
|
|
|
|
#if !defined(UNUSED_VARIABLE)
|
|
#define UNUSED_VARIABLE(variable) UNUSED_PARAMETER(variable)
|
|
#endif
|
|
|
|
#if !defined(FALLTHROUGH) && defined(COMPILER_GCC)
|
|
#if __GNUC__ >= 7
|
|
#define FALLTHROUGH __attribute__((fallthrough))
|
|
#else
|
|
#define FALLTHROUGH /* fall through */
|
|
#endif
|
|
#elif !defined(FALLTHROUGH) && defined(COMPILER_CLANG)
|
|
#define FALLTHROUGH /* fall through */
|
|
#else
|
|
#define FALLTHROUGH
|
|
#endif
|
|
|
|
#if defined(__BYTE_ORDER__) && __BYTE_ORDER == __LITTLE_ENDIAN || defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(_M_IX86) || defined(__ia64) || defined(__ia64__) || defined(_M_IA64) || defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || defined(ANDROID)
|
|
#define ESCARGOT_LITTLE_ENDIAN
|
|
// #pragma message "little endian"
|
|
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER == __BIG_ENDIAN || defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__)
|
|
#define ESCARGOT_BIG_ENDIAN
|
|
// #pragma message "big endian"
|
|
#else
|
|
#error "I don't know what architecture this is!"
|
|
#endif
|
|
|
|
#if defined(ENABLE_THREADING)
|
|
#if defined(COMPILER_MSVC)
|
|
#define MAY_THREAD_LOCAL __declspec(thread)
|
|
#else
|
|
#define MAY_THREAD_LOCAL __thread
|
|
#endif
|
|
#else
|
|
#define MAY_THREAD_LOCAL
|
|
#endif
|
|
|
|
|
|
#define MAKE_STACK_ALLOCATED() \
|
|
static void* operator new(size_t) = delete; \
|
|
static void* operator new[](size_t) = delete; \
|
|
static void operator delete(void*) = delete; \
|
|
static void operator delete[](void*) = delete;
|
|
|
|
#define ALLOCA(bytes, typenameWithoutPointer, ec) (typenameWithoutPointer*)(LIKELY(bytes < 512) ? alloca(bytes) : GC_MALLOC(bytes))
|
|
|
|
typedef uint16_t ByteCodeRegisterIndex;
|
|
#define REGISTER_INDEX_IN_BIT 16
|
|
#define REGISTER_LIMIT (std::numeric_limits<ByteCodeRegisterIndex>::max())
|
|
#define REGULAR_REGISTER_LIMIT (REGISTER_LIMIT / 2)
|
|
#define VARIABLE_LIMIT (REGISTER_LIMIT / 4)
|
|
#define BINDED_NUMERAL_VARIABLE_LIMIT (REGISTER_LIMIT / 4)
|
|
|
|
#ifndef KEEP_NUMERAL_LITERDATA_IN_REGISTERFILE_LIMIT
|
|
#define KEEP_NUMERAL_LITERDATA_IN_REGISTERFILE_LIMIT 16
|
|
#endif
|
|
|
|
typedef uint16_t LexicalBlockIndex;
|
|
#define LEXICAL_BLOCK_INDEX_MAX (std::numeric_limits<LexicalBlockIndex>::max())
|
|
|
|
#if !defined(STACK_GROWS_DOWN) && !defined(STACK_GROWS_UP)
|
|
#define STACK_GROWS_DOWN
|
|
#endif
|
|
|
|
#ifndef STACK_LIMIT_FROM_BASE
|
|
#define STACK_LIMIT_FROM_BASE (1024 * 1024 * 3) // 3MB
|
|
#endif
|
|
|
|
#ifndef STRING_MAXIMUM_LENGTH
|
|
#define STRING_MAXIMUM_LENGTH 1024 * 1024 * 512 // 512MB
|
|
#endif
|
|
|
|
#ifndef STRING_SUB_STRING_MIN_VIEW_LENGTH
|
|
#define STRING_SUB_STRING_MIN_VIEW_LENGTH 32
|
|
#endif
|
|
|
|
#ifndef STRING_BUILDER_INLINE_STORAGE_DEFAULT
|
|
#define STRING_BUILDER_INLINE_STORAGE_DEFAULT 24
|
|
#endif
|
|
|
|
#ifndef SCRIPT_FUNCTION_OBJECT_BYTECODE_SIZE_MAX
|
|
#define SCRIPT_FUNCTION_OBJECT_BYTECODE_SIZE_MAX 1024 * 256
|
|
#endif
|
|
|
|
#ifndef REGEXP_CACHE_SIZE_MAX
|
|
#define REGEXP_CACHE_SIZE_MAX 64
|
|
#endif
|
|
|
|
#ifndef ROPE_STRING_MIN_LENGTH
|
|
#define ROPE_STRING_MIN_LENGTH 24
|
|
#endif
|
|
|
|
#include "EscargotInfo.h"
|
|
#include "heap/Heap.h"
|
|
#include "util/Util.h"
|
|
#include "util/Optional.h"
|
|
|
|
#endif
|