mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Implement new config for smaller device
* In small config, we turn off SyntaxChecker for small binary size * CompressibleString should get VMInstance instead of Context * If ICU is disabled, we don't need unicode information in yarr * Remove unused variable in yarr(RegExpJitTables) * Fix lz4 compile error Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
parent
11e469c6fa
commit
ccdf475f9b
18 changed files with 186 additions and 2741 deletions
|
|
@ -85,6 +85,18 @@ IF (${ESCARGOT_OUTPUT} STREQUAL "shared_lib" AND ${ESCARGOT_HOST} STREQUAL "andr
|
|||
SET (ESCARGOT_LDFLAGS ${ESCARGOT_LDFLAGS} -shared)
|
||||
ENDIF()
|
||||
|
||||
IF (NOT DEFINED ESCARGOT_SMALL_CONFIG)
|
||||
SET (ESCARGOT_SMALL_CONFIG OFF)
|
||||
ENDIF()
|
||||
|
||||
IF (NOT DEFINED ESCARGOT_GC_SMALL_CONFIG)
|
||||
SET (ESCARGOT_GC_SMALL_CONFIG OFF)
|
||||
ENDIF()
|
||||
|
||||
IF (${ESCARGOT_SMALL_CONFIG} STREQUAL "ON")
|
||||
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DESCARGOT_SMALL_CONFIG)
|
||||
ENDIF()
|
||||
|
||||
IF (NOT DEFINED ESCARGOT_LIBICU_SUPPORT)
|
||||
SET (ESCARGOT_LIBICU_SUPPORT ON)
|
||||
ENDIF()
|
||||
|
|
@ -132,6 +144,9 @@ IF (${ESCARGOT_HOST} STREQUAL "tizen_obs")
|
|||
ENDIF()
|
||||
|
||||
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DENABLE_COMPRESSIBLE_STRING)
|
||||
IF (${ESCARGOT_SMALL_CONFIG} STREQUAL "ON")
|
||||
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DLZ4_MEMORY_USAGE=16 -DLZ4_HEAPMODE=1)
|
||||
ENDIF()
|
||||
|
||||
IF (ESCARGOT_CODE_CACHE)
|
||||
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DENABLE_CODE_CACHE)
|
||||
|
|
|
|||
|
|
@ -73,6 +73,10 @@ SET (ESCARGOT_SRC_LIST
|
|||
# GCUTIL
|
||||
SET (GCUTIL_CFLAGS ${ESCARGOT_GCUTIL_CFLAGS})
|
||||
|
||||
IF (${ESCARGOT_GC_SMALL_CONFIG} STREQUAL "ON")
|
||||
SET (GCUTIL_CFLAGS ${GCUTIL_CFLAGS} -DSMALL_CONFIG)
|
||||
ENDIF()
|
||||
|
||||
IF (${ESCARGOT_OUTPUT} STREQUAL "shared_lib")
|
||||
SET (GCUTIL_CFLAGS ${GCUTIL_CFLAGS} ${ESCARGOT_CXXFLAGS_SHAREDLIB})
|
||||
ELSEIF (${ESCARGOT_OUTPUT} STREQUAL "static_lib")
|
||||
|
|
|
|||
|
|
@ -277,24 +277,24 @@ bool StringRef::isCompressibleStringEnabled()
|
|||
}
|
||||
|
||||
#if defined(ENABLE_COMPRESSIBLE_STRING)
|
||||
StringRef* StringRef::createFromUTF8ToCompressibleString(ContextRef* context, const char* s, size_t len)
|
||||
StringRef* StringRef::createFromUTF8ToCompressibleString(VMInstanceRef* instance, const char* s, size_t len)
|
||||
{
|
||||
return toRef(String::fromUTF8ToCompressibleString(toImpl(context), s, len));
|
||||
return toRef(String::fromUTF8ToCompressibleString(toImpl(instance), s, len));
|
||||
}
|
||||
|
||||
StringRef* StringRef::createFromUTF16ToCompressibleString(ContextRef* context, const char16_t* s, size_t len)
|
||||
StringRef* StringRef::createFromUTF16ToCompressibleString(VMInstanceRef* instance, const char16_t* s, size_t len)
|
||||
{
|
||||
return toRef(new CompressibleString(toImpl(context), s, len));
|
||||
return toRef(new CompressibleString(toImpl(instance), s, len));
|
||||
}
|
||||
|
||||
StringRef* StringRef::createFromASCIIToCompressibleString(ContextRef* context, const char* s, size_t len)
|
||||
StringRef* StringRef::createFromASCIIToCompressibleString(VMInstanceRef* instance, const char* s, size_t len)
|
||||
{
|
||||
return toRef(new CompressibleString(toImpl(context), s, len));
|
||||
return toRef(new CompressibleString(toImpl(instance), s, len));
|
||||
}
|
||||
|
||||
StringRef* StringRef::createFromLatin1ToCompressibleString(ContextRef* context, const unsigned char* s, size_t len)
|
||||
StringRef* StringRef::createFromLatin1ToCompressibleString(VMInstanceRef* instance, const unsigned char* s, size_t len)
|
||||
{
|
||||
return toRef(new CompressibleString(toImpl(context), s, len));
|
||||
return toRef(new CompressibleString(toImpl(instance), s, len));
|
||||
}
|
||||
|
||||
void* StringRef::allocateStringDataBufferForCompressibleString(size_t byteLength)
|
||||
|
|
@ -302,32 +302,32 @@ void* StringRef::allocateStringDataBufferForCompressibleString(size_t byteLength
|
|||
return CompressibleString::allocateStringDataBuffer(byteLength);
|
||||
}
|
||||
|
||||
void StringRef::deallocateStringDataBufferForCompressibleString(void* ptr)
|
||||
void StringRef::deallocateStringDataBufferForCompressibleString(void* ptr, size_t byteLength)
|
||||
{
|
||||
CompressibleString::deallocateStringDataBuffer(ptr);
|
||||
CompressibleString::deallocateStringDataBuffer(ptr, byteLength);
|
||||
}
|
||||
|
||||
StringRef* StringRef::createFromAlreadyAllocatedBufferToCompressibleString(ContextRef* context, void* buffer, size_t stringLen, bool is8Bit)
|
||||
StringRef* StringRef::createFromAlreadyAllocatedBufferToCompressibleString(VMInstanceRef* instance, void* buffer, size_t stringLen, bool is8Bit)
|
||||
{
|
||||
return toRef(new CompressibleString(toImpl(context), buffer, stringLen, is8Bit));
|
||||
return toRef(new CompressibleString(toImpl(instance), buffer, stringLen, is8Bit));
|
||||
}
|
||||
|
||||
#else
|
||||
StringRef* StringRef::createFromUTF8ToCompressibleString(ContextRef* context, const char* s, size_t len)
|
||||
StringRef* StringRef::createFromUTF8ToCompressibleString(VMInstanceRef* instance, const char* s, size_t len)
|
||||
{
|
||||
ESCARGOT_LOG_ERROR("If you want to use this function, you should enable source compression");
|
||||
RELEASE_ASSERT_NOT_REACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StringRef* StringRef::createFromASCIIToCompressibleString(ContextRef* context, const char* s, size_t len)
|
||||
StringRef* StringRef::createFromASCIIToCompressibleString(VMInstanceRef* instance, const char* s, size_t len)
|
||||
{
|
||||
ESCARGOT_LOG_ERROR("If you want to use this function, you should enable source compression");
|
||||
RELEASE_ASSERT_NOT_REACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StringRef* StringRef::createFromLatin1ToCompressibleString(ContextRef* context, const unsigned char* s, size_t len)
|
||||
StringRef* StringRef::createFromLatin1ToCompressibleString(VMInstanceRef* instance, const unsigned char* s, size_t len)
|
||||
{
|
||||
ESCARGOT_LOG_ERROR("If you want to use this function, you should enable source compression");
|
||||
RELEASE_ASSERT_NOT_REACHED();
|
||||
|
|
@ -341,13 +341,13 @@ void* StringRef::allocateStringDataBufferForCompressibleString(size_t byteLength
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void StringRef::deallocateStringDataBufferForCompressibleString(void* ptr)
|
||||
void StringRef::deallocateStringDataBufferForCompressibleString(void* ptr, size_t byteLength)
|
||||
{
|
||||
ESCARGOT_LOG_ERROR("If you want to use this function, you should enable source compression");
|
||||
RELEASE_ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
StringRef* StringRef::createFromAlreadyAllocatedBufferToCompressibleString(ContextRef* context, void* buffer, size_t stringLen, bool is8Bit)
|
||||
StringRef* StringRef::createFromAlreadyAllocatedBufferToCompressibleString(VMInstanceRef* instance, void* buffer, size_t stringLen, bool is8Bit)
|
||||
{
|
||||
ESCARGOT_LOG_ERROR("If you want to use this function, you should enable source compression");
|
||||
RELEASE_ASSERT_NOT_REACHED();
|
||||
|
|
|
|||
|
|
@ -808,15 +808,14 @@ public:
|
|||
static StringRef* createExternalFromUTF16(const char16_t* s, size_t len);
|
||||
|
||||
// you can use these functions only if you enabled source compression
|
||||
// you don't need to use CompressibleString when string is small(~128KB)
|
||||
static bool isCompressibleStringEnabled();
|
||||
static StringRef* createFromUTF8ToCompressibleString(ContextRef* context, const char* s, size_t len);
|
||||
static StringRef* createFromUTF16ToCompressibleString(ContextRef* context, const char16_t* s, size_t len);
|
||||
static StringRef* createFromASCIIToCompressibleString(ContextRef* context, const char* s, size_t len);
|
||||
static StringRef* createFromLatin1ToCompressibleString(ContextRef* context, const unsigned char* s, size_t len);
|
||||
static StringRef* createFromUTF8ToCompressibleString(VMInstanceRef* instance, const char* s, size_t len);
|
||||
static StringRef* createFromUTF16ToCompressibleString(VMInstanceRef* instance, const char16_t* s, size_t len);
|
||||
static StringRef* createFromASCIIToCompressibleString(VMInstanceRef* instance, const char* s, size_t len);
|
||||
static StringRef* createFromLatin1ToCompressibleString(VMInstanceRef* instance, const unsigned char* s, size_t len);
|
||||
static void* allocateStringDataBufferForCompressibleString(size_t byteLength);
|
||||
static void deallocateStringDataBufferForCompressibleString(void* ptr);
|
||||
static StringRef* createFromAlreadyAllocatedBufferToCompressibleString(ContextRef* context, void* buffer, size_t stringLen, bool is8Bit /* is ASCII or Latin1 */);
|
||||
static void deallocateStringDataBufferForCompressibleString(void* ptr, size_t byteLength);
|
||||
static StringRef* createFromAlreadyAllocatedBufferToCompressibleString(VMInstanceRef* instance, void* buffer, size_t stringLen, bool is8Bit /* is ASCII or Latin1 */);
|
||||
|
||||
static StringRef* emptyString();
|
||||
|
||||
|
|
|
|||
|
|
@ -508,9 +508,13 @@ public:
|
|||
SyntaxChecker()
|
||||
: m_valueStringLiteral()
|
||||
{
|
||||
#if defined(ESCARGOT_SMALL_CONFIG)
|
||||
ASSERT_NOT_REACHED();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isNodeGenerator() { return false; }
|
||||
bool willGenerateByteCode() { return false; }
|
||||
SyntaxNode createIdentifierNode(const AtomicString& name)
|
||||
{
|
||||
return SyntaxNode(ASTNodeType::Identifier, name);
|
||||
|
|
@ -658,11 +662,27 @@ public:
|
|||
|
||||
MAKE_STACK_ALLOCATED();
|
||||
|
||||
NodeGenerator(ASTAllocator& allocator)
|
||||
NodeGenerator(ASTAllocator& allocator
|
||||
#if defined(ESCARGOT_SMALL_CONFIG)
|
||||
,
|
||||
bool willGenerateByteCode = true
|
||||
#endif
|
||||
)
|
||||
: m_allocator(allocator)
|
||||
#if defined(ESCARGOT_SMALL_CONFIG)
|
||||
, m_willGenerateByteCode(willGenerateByteCode)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
bool willGenerateByteCode()
|
||||
{
|
||||
#if defined(ESCARGOT_SMALL_CONFIG)
|
||||
return m_willGenerateByteCode;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
bool isNodeGenerator() { return true; }
|
||||
IdentifierNode* createIdentifierNode(const AtomicString& name)
|
||||
{
|
||||
|
|
@ -869,6 +889,9 @@ public:
|
|||
|
||||
private:
|
||||
ASTAllocator& m_allocator;
|
||||
#if defined(ESCARGOT_SMALL_CONFIG)
|
||||
bool m_willGenerateByteCode;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // Escargot
|
||||
|
|
|
|||
|
|
@ -57,8 +57,14 @@
|
|||
#define ASTSentinelNode typename ASTBuilder::ASTSentinelNode
|
||||
#define ASTNodeList typename ASTBuilder::ASTNodeList
|
||||
|
||||
#if defined(ESCARGOT_SMALL_CONFIG)
|
||||
#define NEW_FUNCTION_AST_BUILDER() NodeGenerator newBuilder(this->allocator, false);
|
||||
#else
|
||||
#define NEW_FUNCTION_AST_BUILDER() SyntaxChecker newBuilder;
|
||||
#endif
|
||||
|
||||
#define BEGIN_FUNCTION_SCANNING(name) \
|
||||
SyntaxChecker newBuilder; \
|
||||
NEW_FUNCTION_AST_BUILDER() \
|
||||
auto oldSubCodeBlockIndex = ++this->subCodeBlockIndex; \
|
||||
auto oldScopeContext = pushScopeContext(name); \
|
||||
LexicalBlockIndex lexicalBlockIndexBefore = this->lexicalBlockIndex; \
|
||||
|
|
@ -1025,7 +1031,7 @@ public:
|
|||
ALLOC_TOKEN(token);
|
||||
this->nextToken(token);
|
||||
// raw = this->getTokenRaw(token);
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
if (token->type == Token::NumericLiteralToken) {
|
||||
double d = token->valueNumberLiteral(this->scanner);
|
||||
if (this->context->inLoop || d == 0) {
|
||||
|
|
@ -1050,7 +1056,7 @@ public:
|
|||
// raw = this->getTokenRaw(token);
|
||||
{
|
||||
bool value = token->relatedSource(this->scanner->source) == "true";
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
this->insertNumeralLiteral(Value(value));
|
||||
}
|
||||
return this->finalize(node, builder.createLiteralNode(Value(value)));
|
||||
|
|
@ -1065,7 +1071,7 @@ public:
|
|||
this->nextToken(token);
|
||||
// token.value = null;
|
||||
// raw = this->getTokenRaw(token);
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
this->insertNumeralLiteral(Value(Value::Null));
|
||||
}
|
||||
return this->finalize(node, builder.createLiteralNode(Value(Value::Null)));
|
||||
|
|
@ -1388,7 +1394,7 @@ public:
|
|||
{
|
||||
// parseFormalParameters only scans the parameter list of function
|
||||
// should be invoked only during the global parsing (program)
|
||||
ASSERT(!builder.isNodeGenerator() && !this->isParsingSingleFunction);
|
||||
ASSERT(!builder.willGenerateByteCode() && !this->isParsingSingleFunction);
|
||||
|
||||
bool oldInParameterParsing = this->context->inParameterParsing;
|
||||
bool oldInParameterNameParsing = this->context->inParameterNameParsing;
|
||||
|
|
@ -1590,14 +1596,16 @@ public:
|
|||
{
|
||||
Value v;
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (token->type == Token::NumericLiteralToken) {
|
||||
double d = token->valueNumberLiteral(this->scanner);
|
||||
if (this->context->inLoop || d == 0) {
|
||||
this->insertNumeralLiteral(Value(d));
|
||||
if (builder.willGenerateByteCode()) {
|
||||
if (token->type == Token::NumericLiteralToken) {
|
||||
double d = token->valueNumberLiteral(this->scanner);
|
||||
if (this->context->inLoop || d == 0) {
|
||||
this->insertNumeralLiteral(Value(d));
|
||||
}
|
||||
v = Value(d);
|
||||
} else {
|
||||
v = token->valueStringLiteralToValue(this->scanner);
|
||||
}
|
||||
v = Value(d);
|
||||
} else {
|
||||
v = token->valueStringLiteralToValue(this->scanner);
|
||||
}
|
||||
} else {
|
||||
if (token->type == Token::StringLiteralToken) {
|
||||
|
|
@ -2272,7 +2280,7 @@ public:
|
|||
} else if (this->lookahead.type == Token::TemplateToken && this->lookahead.valueTemplate->head) {
|
||||
ASTNode quasi = this->parseTemplateLiteral(builder, true);
|
||||
ASTNode convertedNode = builder.convertTaggedTemplateExpressionToCallExpression(quasi, exprNode, this->taggedTemplateExpressionIndex, this->currentScopeContext, escargotContext->staticStrings().raw);
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
this->taggedTemplateExpressionIndex++;
|
||||
}
|
||||
|
||||
|
|
@ -2343,7 +2351,7 @@ public:
|
|||
} else if (this->lookahead.type == Token::TemplateToken && this->lookahead.valueTemplate->head) {
|
||||
ASTNode quasi = this->parseTemplateLiteral(builder, true);
|
||||
ASTNode convertedNode = builder.convertTaggedTemplateExpressionToCallExpression(quasi, exprNode, this->taggedTemplateExpressionIndex, this->currentScopeContext, escargotContext->staticStrings().raw);
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
this->taggedTemplateExpressionIndex++;
|
||||
}
|
||||
|
||||
|
|
@ -2973,8 +2981,11 @@ public:
|
|||
this->parseFunctionSourceElements(newBuilder);
|
||||
} else {
|
||||
auto oldNameCallback = this->nameDeclaredCallback;
|
||||
|
||||
#if defined(ESCARGOT_SMALL_CONFIG)
|
||||
this->isolateCoverGrammar(newBuilder, &Parser::parseAssignmentExpression<ASTBuilder, false>);
|
||||
#else
|
||||
this->isolateCoverGrammar(newBuilder, &Parser::parseAssignmentExpression<SyntaxChecker, false>);
|
||||
#endif
|
||||
|
||||
this->currentScopeContext->m_bodyEndLOC.index = this->lastMarker.index;
|
||||
#if !(defined NDEBUG) || defined ESCARGOT_DEBUGGER
|
||||
|
|
@ -4605,7 +4616,7 @@ public:
|
|||
{
|
||||
// parseFunctionSourceElements only scans the body of function
|
||||
// should be invoked only during the global parsing (program)
|
||||
ASSERT(!builder.isNodeGenerator() && !this->isParsingSingleFunction);
|
||||
ASSERT(!builder.willGenerateByteCode() && !this->isParsingSingleFunction);
|
||||
|
||||
// return empty node because the function body node is never used now
|
||||
ASTNode result = nullptr;
|
||||
|
|
@ -4722,7 +4733,7 @@ public:
|
|||
}
|
||||
}
|
||||
// in global scope, await is allowed
|
||||
if (UNLIKELY(isAsync && !builder.isNodeGenerator())) {
|
||||
if (UNLIKELY(isAsync && !builder.willGenerateByteCode())) {
|
||||
if (id->asIdentifier()->name().string()->equals("await")) {
|
||||
this->throwUnexpectedToken(*token, Messages::UnexpectedReserved);
|
||||
}
|
||||
|
|
@ -4930,7 +4941,7 @@ public:
|
|||
}
|
||||
}
|
||||
// in global scope, await is allowed
|
||||
if (UNLIKELY(isAsync && !builder.isNodeGenerator())) {
|
||||
if (UNLIKELY(isAsync && !builder.willGenerateByteCode())) {
|
||||
if (id->asIdentifier()->name().string()->equals("await")) {
|
||||
this->throwUnexpectedToken(*token, Messages::UnexpectedReserved);
|
||||
}
|
||||
|
|
@ -5633,7 +5644,7 @@ public:
|
|||
// import {bar}
|
||||
specifiers = this->parseNamedImports(builder);
|
||||
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
for (ASTSentinelNode specifier = specifiers.begin(); specifier != specifiers.end(); specifier = specifier->next()) {
|
||||
Script::ImportEntry entry;
|
||||
entry.m_importName = specifier->astNode()->asImportSpecifier()->imported()->name();
|
||||
|
|
@ -5645,7 +5656,7 @@ public:
|
|||
// import * as foo
|
||||
specifiers.append(this->allocator, this->parseImportNamespaceSpecifier(builder));
|
||||
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
Script::ImportEntry entry;
|
||||
entry.m_importName = this->escargotContext->staticStrings().asciiTable[(unsigned char)'*'];
|
||||
entry.m_localName = specifiers.back()->astNode()->asImportNamespaceSpecifier()->local()->name();
|
||||
|
|
@ -5655,7 +5666,7 @@ public:
|
|||
// import foo
|
||||
specifiers.append(this->allocator, this->parseImportDefaultSpecifier(builder));
|
||||
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
Script::ImportEntry entry;
|
||||
entry.m_importName = this->escargotContext->staticStrings().stringDefault;
|
||||
entry.m_localName = specifiers.back()->astNode()->asImportDefaultSpecifier()->local()->name();
|
||||
|
|
@ -5668,7 +5679,7 @@ public:
|
|||
// import foo, * as foo
|
||||
specifiers.append(this->allocator, this->parseImportNamespaceSpecifier(builder));
|
||||
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
Script::ImportEntry entry;
|
||||
entry.m_importName = this->escargotContext->staticStrings().asciiTable[(unsigned char)'*'];
|
||||
entry.m_localName = specifiers.back()->astNode()->asImportNamespaceSpecifier()->local()->name();
|
||||
|
|
@ -5678,7 +5689,7 @@ public:
|
|||
// import foo, {bar}
|
||||
auto v = this->parseNamedImports(builder);
|
||||
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
for (ASTSentinelNode n = v.begin(); n != v.end(); n = n->next()) {
|
||||
Script::ImportEntry entry;
|
||||
entry.m_importName = n->astNode()->asImportSpecifier()->imported()->name();
|
||||
|
|
@ -5706,7 +5717,7 @@ public:
|
|||
}
|
||||
this->consumeSemicolon();
|
||||
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
for (size_t i = 0; i < importEntrys.size(); i++) {
|
||||
importEntrys[i].m_moduleRequest = src->asLiteral()->value().asString();
|
||||
addDeclaredNameIntoContext(importEntrys[i].m_localName, this->lexicalBlockIndex, KeywordKind::ConstKeyword);
|
||||
|
|
@ -5821,7 +5832,7 @@ public:
|
|||
// export default function () {}
|
||||
ASTNode declaration = this->parseFunctionDeclaration<ASTBuilder, true>(builder);
|
||||
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
Script::ExportEntry entry;
|
||||
entry.m_exportName = this->escargotContext->staticStrings().stringDefault;
|
||||
AtomicString fnName = declaration->asFunctionDeclaration()->functionName();
|
||||
|
|
@ -5835,7 +5846,7 @@ public:
|
|||
// export default class foo {}
|
||||
auto classNode = this->parseClassExpression(builder);
|
||||
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
this->addImplicitName(classNode, this->escargotContext->staticStrings().stringDefault);
|
||||
|
||||
Script::ExportEntry entry;
|
||||
|
|
@ -5889,7 +5900,7 @@ public:
|
|||
}
|
||||
ASTNode src = this->parseModuleSpecifier(builder);
|
||||
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
Script::ExportEntry entry;
|
||||
entry.m_exportName = this->escargotContext->staticStrings().stringDefault;
|
||||
entry.m_moduleRequest = src->asLiteral()->value().asString();
|
||||
|
|
@ -5922,7 +5933,7 @@ public:
|
|||
|
||||
ASTNode src = this->parseModuleSpecifier(builder);
|
||||
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
Script::ExportEntry entry;
|
||||
entry.m_exportName = name;
|
||||
entry.m_moduleRequest = src->asLiteral()->value().asString();
|
||||
|
|
@ -5941,7 +5952,7 @@ public:
|
|||
// export var f = 1;
|
||||
auto oldNameCallback = this->nameDeclaredCallback;
|
||||
AtomicStringVector declaredNames;
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
this->nameDeclaredCallback = [&declaredNames](AtomicString name, LexicalBlockIndex, KeywordKind, bool) {
|
||||
for (size_t i = 0; i < declaredNames.size(); i++) {
|
||||
if (declaredNames[i] == name) {
|
||||
|
|
@ -6013,7 +6024,7 @@ public:
|
|||
this->consumeSemicolon();
|
||||
}
|
||||
|
||||
if (builder.isNodeGenerator()) {
|
||||
if (builder.willGenerateByteCode()) {
|
||||
for (ASTSentinelNode specifier = specifiers.begin(); specifier != specifiers.end(); specifier = specifier->next()) {
|
||||
Script::ExportEntry entry;
|
||||
if (seenFrom) {
|
||||
|
|
@ -6237,6 +6248,7 @@ FunctionNode* parseSingleFunction(::Escargot::Context* ctx, InterpretedCodeBlock
|
|||
NodeGenerator builder(ctx->astAllocator());
|
||||
|
||||
parser.trackUsingNames = false;
|
||||
parser.context->inFunctionBody = true;
|
||||
parser.context->allowLexicalDeclaration = true;
|
||||
parser.context->allowSuperCall = true;
|
||||
parser.context->allowSuperProperty = true;
|
||||
|
|
|
|||
|
|
@ -100,6 +100,13 @@ void ArrayBufferObject::allocateBuffer(ExecutionState& state, size_t bytelength)
|
|||
void ArrayBufferObject::attachBuffer(ExecutionState& state, void* buffer, size_t bytelength)
|
||||
{
|
||||
ASSERT(isDetachedBuffer());
|
||||
|
||||
// if buffer is null, the ArrayBuffer object still seems deatched
|
||||
if (buffer == nullptr) {
|
||||
ASSERT(bytelength == 0);
|
||||
buffer = m_context->vmInstance()->platform()->onArrayBufferObjectDataBufferMalloc(m_context, this, 0);
|
||||
}
|
||||
|
||||
m_data = (uint8_t*)buffer;
|
||||
m_bytelength = bytelength;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,68 +33,68 @@ void* CompressibleString::operator new(size_t size)
|
|||
static GC_descr descr;
|
||||
if (!typeInited) {
|
||||
GC_word obj_bitmap[GC_BITMAP_SIZE(CompressibleString)] = { 0 };
|
||||
GC_set_bit(obj_bitmap, GC_WORD_OFFSET(CompressibleString, m_context));
|
||||
GC_set_bit(obj_bitmap, GC_WORD_OFFSET(CompressibleString, m_vmInstance));
|
||||
descr = GC_make_descriptor(obj_bitmap, GC_WORD_LEN(CompressibleString));
|
||||
typeInited = true;
|
||||
}
|
||||
return GC_MALLOC_EXPLICITLY_TYPED(size, descr);
|
||||
}
|
||||
|
||||
CompressibleString::CompressibleString(Context* context)
|
||||
CompressibleString::CompressibleString(VMInstance* instance)
|
||||
: String()
|
||||
, m_isOwnerMayFreed(false)
|
||||
, m_isCompressed(false)
|
||||
, m_context(context)
|
||||
, m_vmInstance(instance)
|
||||
, m_lastUsedTickcount(fastTickCount())
|
||||
{
|
||||
m_bufferData.hasSpecialImpl = true;
|
||||
|
||||
auto& v = context->vmInstance()->compressibleStrings();
|
||||
auto& v = instance->compressibleStrings();
|
||||
v.push_back(this);
|
||||
GC_REGISTER_FINALIZER_NO_ORDER(this, [](void* obj, void*) {
|
||||
CompressibleString* self = (CompressibleString*)obj;
|
||||
if (self->isCompressed()) {
|
||||
self->m_compressedData.~CompressedDataVector();
|
||||
} else {
|
||||
deallocateStringDataBuffer(const_cast<void*>(self->m_bufferData.buffer));
|
||||
deallocateStringDataBuffer(const_cast<void*>(self->m_bufferData.buffer), self->m_bufferData.length * (self->m_bufferData.has8BitContent ? 1 : 2));
|
||||
}
|
||||
|
||||
if (!self->m_isOwnerMayFreed) {
|
||||
self->m_context->vmInstance()->compressibleStringsUncomressedBufferSize() -= self->decomressedBufferSize();
|
||||
self->m_vmInstance->compressibleStringsUncomressedBufferSize() -= self->decomressedBufferSize();
|
||||
|
||||
auto& v = self->m_context->vmInstance()->compressibleStrings();
|
||||
auto& v = self->m_vmInstance->compressibleStrings();
|
||||
v.erase(std::find(v.begin(), v.end(), self));
|
||||
}
|
||||
},
|
||||
nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
CompressibleString::CompressibleString(Context* context, const char* str, size_t len)
|
||||
: CompressibleString(context)
|
||||
CompressibleString::CompressibleString(VMInstance* instance, const char* str, size_t len)
|
||||
: CompressibleString(instance)
|
||||
{
|
||||
char* buf = (char*)allocateStringDataBuffer(sizeof(char) * len);
|
||||
memcpy(buf, str, len);
|
||||
initBufferAccessData(buf, len, true);
|
||||
}
|
||||
|
||||
CompressibleString::CompressibleString(Context* context, const LChar* str, size_t len)
|
||||
: CompressibleString(context)
|
||||
CompressibleString::CompressibleString(VMInstance* instance, const LChar* str, size_t len)
|
||||
: CompressibleString(instance)
|
||||
{
|
||||
char* buf = (char*)allocateStringDataBuffer(sizeof(char) * len);
|
||||
memcpy(buf, str, len);
|
||||
initBufferAccessData(buf, len, true);
|
||||
}
|
||||
|
||||
CompressibleString::CompressibleString(Context* context, const char16_t* str, size_t len)
|
||||
: CompressibleString(context)
|
||||
CompressibleString::CompressibleString(VMInstance* instance, const char16_t* str, size_t len)
|
||||
: CompressibleString(instance)
|
||||
{
|
||||
char* buf = (char*)allocateStringDataBuffer(sizeof(char) * len * 2);
|
||||
memcpy(buf, str, len * 2);
|
||||
initBufferAccessData(buf, len, false);
|
||||
}
|
||||
|
||||
CompressibleString::CompressibleString(Context* context, void* buffer, size_t stringLength, bool is8bit)
|
||||
: CompressibleString(context)
|
||||
CompressibleString::CompressibleString(VMInstance* instance, void* buffer, size_t stringLength, bool is8bit)
|
||||
: CompressibleString(instance)
|
||||
{
|
||||
initBufferAccessData(buffer, stringLength, is8bit);
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ void CompressibleString::initBufferAccessData(void* data, size_t len, bool is8bi
|
|||
m_bufferData.length = len;
|
||||
m_bufferData.buffer = data;
|
||||
|
||||
m_context->vmInstance()->compressibleStringsUncomressedBufferSize() += decomressedBufferSize();
|
||||
m_vmInstance->compressibleStringsUncomressedBufferSize() += decomressedBufferSize();
|
||||
}
|
||||
|
||||
UTF8StringDataNonGCStd CompressibleString::toNonGCUTF8StringData(int options) const
|
||||
|
|
@ -138,7 +138,7 @@ void* CompressibleString::allocateStringDataBuffer(size_t byteLength)
|
|||
return malloc(byteLength);
|
||||
}
|
||||
|
||||
void CompressibleString::deallocateStringDataBuffer(void* ptr)
|
||||
void CompressibleString::deallocateStringDataBuffer(void* ptr, size_t byteLength)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
|
@ -182,9 +182,9 @@ bool CompressibleString::compressWorker(void* callerSP)
|
|||
|
||||
#if defined(STACK_GROWS_DOWN)
|
||||
size_t* start = (size_t*)((size_t)callerSP & ~(sizeof(size_t) - 1));
|
||||
size_t* end = (size_t*)m_context->vmInstance()->stackStartAddress();
|
||||
size_t* end = (size_t*)m_vmInstance->stackStartAddress();
|
||||
#else
|
||||
size_t* start = (size_t*)m_context->vmInstance()->stackStartAddress();
|
||||
size_t* start = (size_t*)m_vmInstance->stackStartAddress();
|
||||
size_t* end = (size_t*)((size_t)callerSP & ~(sizeof(size_t) - 1));
|
||||
#endif
|
||||
|
||||
|
|
@ -217,13 +217,22 @@ bool CompressibleString::compressWorker(void* callerSP)
|
|||
m_compressedData.push_back(std::vector<char>(compBuffer.get(), compBuffer.get() + compressedLength));
|
||||
}
|
||||
|
||||
m_context->vmInstance()->compressibleStringsUncomressedBufferSize() -= decomressedBufferSize();
|
||||
m_vmInstance->compressibleStringsUncomressedBufferSize() -= decomressedBufferSize();
|
||||
|
||||
// immediately free the original string after compression when there is no reference on stack
|
||||
deallocateStringDataBuffer(const_cast<void*>(m_bufferData.buffer));
|
||||
deallocateStringDataBuffer(const_cast<void*>(m_bufferData.buffer), m_bufferData.length * (m_bufferData.has8BitContent ? 1 : 2));
|
||||
|
||||
m_bufferData.bufferAs8Bit = nullptr;
|
||||
m_isCompressed = true;
|
||||
|
||||
/*
|
||||
size_t compressedSize = 0;
|
||||
for (size_t i = 0; i < m_compressedData.size(); i ++) {
|
||||
compressedSize += m_compressedData[i].size();
|
||||
}
|
||||
ESCARGOT_LOG_INFO("CompressibleString::compressWorker %fKB -> %fKB\n", originByteLength / 1024.f, compressedSize / 1024.f);
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -255,7 +264,7 @@ void CompressibleString::decompressWorker()
|
|||
m_bufferData.bufferAs8Bit = const_cast<const char*>(dstBuffer);
|
||||
m_isCompressed = false;
|
||||
|
||||
m_context->vmInstance()->compressibleStringsUncomressedBufferSize() += decomressedBufferSize();
|
||||
m_vmInstance->compressibleStringsUncomressedBufferSize() += decomressedBufferSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,21 +26,21 @@
|
|||
|
||||
namespace Escargot {
|
||||
|
||||
class Context;
|
||||
class VMInstance;
|
||||
|
||||
class CompressibleString : public String {
|
||||
friend class VMInstance;
|
||||
|
||||
public:
|
||||
// 8bit string constructor
|
||||
CompressibleString(Context* context, const char* str, size_t len);
|
||||
CompressibleString(Context* context, const LChar* str, size_t len);
|
||||
CompressibleString(VMInstance* instance, const char* str, size_t len);
|
||||
CompressibleString(VMInstance* instance, const LChar* str, size_t len);
|
||||
|
||||
// 16bit string constructor
|
||||
CompressibleString(Context* context, const char16_t* str, size_t len);
|
||||
CompressibleString(VMInstance* instance, const char16_t* str, size_t len);
|
||||
|
||||
// from already allocated buffer
|
||||
CompressibleString(Context* context, void* buffer, size_t stringLength, bool is8bit);
|
||||
CompressibleString(VMInstance* instance, void* buffer, size_t stringLength, bool is8bit);
|
||||
|
||||
virtual bool isCompressibleString() override
|
||||
{
|
||||
|
|
@ -80,13 +80,13 @@ public:
|
|||
void operator delete[](void*) = delete;
|
||||
|
||||
static void* allocateStringDataBuffer(size_t byteLength);
|
||||
static void deallocateStringDataBuffer(void* ptr);
|
||||
static void deallocateStringDataBuffer(void* ptr, size_t byteLength);
|
||||
|
||||
bool compress();
|
||||
void decompress();
|
||||
|
||||
private:
|
||||
CompressibleString(Context* context);
|
||||
CompressibleString(VMInstance* instance);
|
||||
|
||||
void initBufferAccessData(void* data, size_t len, bool is8bit);
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ private:
|
|||
|
||||
bool m_isOwnerMayFreed;
|
||||
bool m_isCompressed;
|
||||
Context* m_context;
|
||||
VMInstance* m_vmInstance;
|
||||
uint64_t m_lastUsedTickcount;
|
||||
typedef std::vector<std::vector<char>> CompressedDataVector;
|
||||
CompressedDataVector m_compressedData;
|
||||
|
|
|
|||
|
|
@ -637,13 +637,13 @@ String* String::fromUTF8(const char* src, size_t len)
|
|||
}
|
||||
|
||||
#if defined(ENABLE_COMPRESSIBLE_STRING)
|
||||
String* String::fromUTF8ToCompressibleString(Context* context, const char* src, size_t len)
|
||||
String* String::fromUTF8ToCompressibleString(VMInstance* instance, const char* src, size_t len)
|
||||
{
|
||||
if (isAllASCII(src, len)) {
|
||||
return new CompressibleString(context, src, len);
|
||||
return new CompressibleString(instance, src, len);
|
||||
} else {
|
||||
auto s = utf8StringToUTF16StringNonGC(src, len);
|
||||
return new CompressibleString(context, s.data(), s.length());
|
||||
return new CompressibleString(instance, s.data(), s.length());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ class Latin1String;
|
|||
class UTF16String;
|
||||
class RopeString;
|
||||
class StringView;
|
||||
class Context;
|
||||
class VMInstance;
|
||||
|
||||
class StringWriteOption {
|
||||
public:
|
||||
|
|
@ -281,7 +281,7 @@ public:
|
|||
}
|
||||
static String* fromUTF8(const char* src, size_t len);
|
||||
#if defined(ENABLE_COMPRESSIBLE_STRING)
|
||||
static String* fromUTF8ToCompressibleString(Context* context, const char* src, size_t len);
|
||||
static String* fromUTF8ToCompressibleString(VMInstance* instance, const char* src, size_t len);
|
||||
#endif
|
||||
|
||||
size_t length() const
|
||||
|
|
|
|||
|
|
@ -482,6 +482,7 @@ void VMInstance::enterIdleMode()
|
|||
GC_gcollect_and_unmap();
|
||||
|
||||
#if defined(ENABLE_COMPRESSIBLE_STRING)
|
||||
// ESCARGOT_LOG_INFO("compressibleStringsUncomressedBufferSize before %lfKB\n", m_compressibleStringsUncomressedBufferSize/1024.f);
|
||||
auto& currentAllocatedCompressibleStrings = compressibleStrings();
|
||||
const size_t& currentAllocatedCompressibleStringsCount = currentAllocatedCompressibleStrings.size();
|
||||
|
||||
|
|
@ -490,6 +491,7 @@ void VMInstance::enterIdleMode()
|
|||
currentAllocatedCompressibleStrings[i]->compress();
|
||||
}
|
||||
}
|
||||
// ESCARGOT_LOG_INFO("compressibleStringsUncomressedBufferSize after %lfKB\n", m_compressibleStringsUncomressedBufferSize/1024.f);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -178,9 +178,9 @@ static OptionalRef<StringRef> builtinHelperFileRead(OptionalRef<ExecutionStateRe
|
|||
if (StringRef::isCompressibleStringEnabled()) {
|
||||
if (state) {
|
||||
if (hasNonLatin1Content) {
|
||||
src = StringRef::createFromUTF8ToCompressibleString(state->context(), utf8Str.data(), utf8Str.length());
|
||||
src = StringRef::createFromUTF8ToCompressibleString(state->context()->vmInstance(), utf8Str.data(), utf8Str.length());
|
||||
} else {
|
||||
src = StringRef::createFromLatin1ToCompressibleString(state->context(), str.data(), str.length());
|
||||
src = StringRef::createFromLatin1ToCompressibleString(state->context()->vmInstance(), str.data(), str.length());
|
||||
}
|
||||
} else {
|
||||
if (hasNonLatin1Content) {
|
||||
|
|
|
|||
|
|
@ -179,9 +179,9 @@ static OptionalRef<StringRef> builtinHelperFileRead(OptionalRef<ExecutionStateRe
|
|||
if (StringRef::isCompressibleStringEnabled()) {
|
||||
if (state) {
|
||||
if (hasNonLatin1Content) {
|
||||
src = StringRef::createFromUTF8ToCompressibleString(state->context(), utf8Str.data(), utf8Str.length());
|
||||
src = StringRef::createFromUTF8ToCompressibleString(state->context()->vmInstance(), utf8Str.data(), utf8Str.length());
|
||||
} else {
|
||||
src = StringRef::createFromLatin1ToCompressibleString(state->context(), str.data(), str.length());
|
||||
src = StringRef::createFromLatin1ToCompressibleString(state->context()->vmInstance(), str.data(), str.length());
|
||||
}
|
||||
} else {
|
||||
if (hasNonLatin1Content) {
|
||||
|
|
|
|||
2
third_party/lz4/lz4.cpp
vendored
2
third_party/lz4/lz4.cpp
vendored
|
|
@ -1385,7 +1385,7 @@ int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutp
|
|||
{
|
||||
int result;
|
||||
#if (LZ4_HEAPMODE)
|
||||
LZ4_stream_t* ctxPtr = ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
|
||||
LZ4_stream_t* ctxPtr = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
|
||||
if (ctxPtr == NULL)
|
||||
return 0;
|
||||
#else
|
||||
|
|
|
|||
2636
third_party/yarr/RegExpJitTables.h
vendored
2636
third_party/yarr/RegExpJitTables.h
vendored
File diff suppressed because it is too large
Load diff
15
third_party/yarr/YarrPattern.h
vendored
15
third_party/yarr/YarrPattern.h
vendored
|
|
@ -68,16 +68,7 @@ public:
|
|||
// they may have an optional m_table for faster lookups (which must match the
|
||||
// specified matches and ranges)
|
||||
CharacterClass()
|
||||
: m_table(0)
|
||||
, m_tableInverted(false)
|
||||
, m_hasNonBMPCharacters(false)
|
||||
, m_anyCharacter(false)
|
||||
{
|
||||
}
|
||||
CharacterClass(const char* table, bool inverted)
|
||||
: m_table(table)
|
||||
, m_tableInverted(inverted)
|
||||
, m_hasNonBMPCharacters(false)
|
||||
: m_hasNonBMPCharacters(false)
|
||||
, m_anyCharacter(false)
|
||||
{
|
||||
}
|
||||
|
|
@ -86,8 +77,6 @@ public:
|
|||
, m_ranges(ranges)
|
||||
, m_matchesUnicode(matchesUnicode)
|
||||
, m_rangesUnicode(rangesUnicode)
|
||||
, m_table(0)
|
||||
, m_tableInverted(false)
|
||||
, m_hasNonBMPCharacters(false)
|
||||
, m_anyCharacter(false)
|
||||
{
|
||||
|
|
@ -98,8 +87,6 @@ public:
|
|||
Vector<UChar32> m_matchesUnicode;
|
||||
Vector<CharacterRange> m_rangesUnicode;
|
||||
|
||||
const char* m_table;
|
||||
bool m_tableInverted : 1;
|
||||
bool m_hasNonBMPCharacters : 1;
|
||||
bool m_anyCharacter : 1;
|
||||
};
|
||||
|
|
|
|||
15
third_party/yarr/YarrUnicodeProperties.cpp
vendored
15
third_party/yarr/YarrUnicodeProperties.cpp
vendored
|
|
@ -60,10 +60,13 @@ struct HashTable {
|
|||
}
|
||||
};
|
||||
|
||||
#if defined(ENABLE_ICU)
|
||||
#include "UnicodePatternTables.h"
|
||||
#endif
|
||||
|
||||
Optional<BuiltInCharacterClassID> unicodeMatchPropertyValue(WTF::String unicodePropertyName, WTF::String unicodePropertyValue)
|
||||
{
|
||||
#if defined(ENABLE_ICU)
|
||||
int propertyIndex = -1;
|
||||
|
||||
if (unicodePropertyName == "Script" || unicodePropertyName == "sc")
|
||||
|
|
@ -77,10 +80,14 @@ Optional<BuiltInCharacterClassID> unicodeMatchPropertyValue(WTF::String unicodeP
|
|||
return nullptr;
|
||||
|
||||
return Optional<BuiltInCharacterClassID>(static_cast<BuiltInCharacterClassID>(static_cast<int>(BuiltInCharacterClassID::BaseUnicodePropertyID) + propertyIndex));
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
Optional<BuiltInCharacterClassID> unicodeMatchProperty(WTF::String unicodePropertyValue)
|
||||
{
|
||||
#if defined(ENABLE_ICU)
|
||||
int propertyIndex = -1;
|
||||
|
||||
propertyIndex = binaryPropertyHashTable.entry(unicodePropertyValue);
|
||||
|
|
@ -91,13 +98,21 @@ Optional<BuiltInCharacterClassID> unicodeMatchProperty(WTF::String unicodeProper
|
|||
return nullptr;
|
||||
|
||||
return Optional<BuiltInCharacterClassID>(static_cast<BuiltInCharacterClassID>(static_cast<int>(BuiltInCharacterClassID::BaseUnicodePropertyID) + propertyIndex));
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<CharacterClass> createUnicodeCharacterClassFor(BuiltInCharacterClassID unicodeClassID)
|
||||
{
|
||||
#if defined(ENABLE_ICU)
|
||||
unsigned unicodePropertyIndex = static_cast<unsigned>(unicodeClassID) - static_cast<unsigned>(BuiltInCharacterClassID::BaseUnicodePropertyID);
|
||||
|
||||
return createFunctions[unicodePropertyIndex]();
|
||||
#else
|
||||
RELEASE_ASSERT_NOT_REACHED();
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // namespace JSC::Yarr
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue