Eliminate duplicated code

Signed-off-by: HyukWoo Park <hyukwoo.park@samsung.com>
This commit is contained in:
HyukWoo Park 2023-03-27 10:34:52 +09:00 committed by Patrick Kim
commit de4c7eb0db
14 changed files with 129 additions and 290 deletions

View file

@ -26,6 +26,7 @@
#include "runtime/Global.h"
#include "runtime/BigInt.h"
#include "runtime/Platform.h"
#include "runtime/PromiseObject.h"
namespace Escargot {

View file

@ -247,9 +247,9 @@ static Value builtinPromiseRace(ExecutionState& state, Value thisValue, size_t a
// ReturnIfAbrupt(promiseCapability).
PromiseReaction::Capability promiseCapability = PromiseObject::newPromiseCapability(state, C);
// Let promiseResolve be GetPromiseResolve(C).
Value promiseResolve;
Value resolve;
try {
promiseResolve = getPromiseResolve(state, C);
resolve = getPromiseResolve(state, C);
} catch (const Value& v) {
Value thrownValue = v;
// If value is an abrupt completion,
@ -261,9 +261,9 @@ static Value builtinPromiseRace(ExecutionState& state, Value thisValue, size_t a
// Let iteratorRecord be GetIterator(iterable).
// IfAbruptRejectPromise(iteratorRecord, promiseCapability).
IteratorRecord* iteratorRecord;
IteratorRecord* record;
try {
iteratorRecord = IteratorObject::getIterator(state, argv[0]);
record = IteratorObject::getIterator(state, argv[0]);
} catch (const Value& v) {
Value thrownValue = v;
// If value is an abrupt completion,
@ -281,17 +281,17 @@ static Value builtinPromiseRace(ExecutionState& state, Value thisValue, size_t a
// Let next be IteratorStep(iteratorRecord).
Optional<Object*> next;
try {
next = IteratorObject::iteratorStep(state, iteratorRecord);
next = IteratorObject::iteratorStep(state, record);
} catch (const Value& e) {
// If next is an abrupt completion, set iteratorRecord.[[done]] to true.
// ReturnIfAbrupt(next).
iteratorRecord->m_done = true;
record->m_done = true;
state.throwException(e);
}
// If next is false, then
if (!next.hasValue()) {
// Set iteratorRecord.[[done]] to true.
iteratorRecord->m_done = true;
record->m_done = true;
// Return resultCapability.[[Promise]].
result = promiseCapability.m_promise;
break;
@ -303,13 +303,13 @@ static Value builtinPromiseRace(ExecutionState& state, Value thisValue, size_t a
nextValue = IteratorObject::iteratorValue(state, next.value());
} catch (const Value& e) {
// If next is an abrupt completion, set iteratorRecord.[[done]] to true.
iteratorRecord->m_done = true;
record->m_done = true;
// ReturnIfAbrupt(next).
state.throwException(e);
}
// Let nextPromise be Invoke(C, "resolve", «nextValue»).
Value nextPromise = Object::call(state, promiseResolve, C, 1, &nextValue);
Value nextPromise = Object::call(state, resolve, C, 1, &nextValue);
// Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
Object* nextPromiseObject = nextPromise.toObject(state);
Value argv[] = { Value(promiseCapability.m_resolveFunction), Value(promiseCapability.m_rejectFunction) };
@ -321,8 +321,8 @@ static Value builtinPromiseRace(ExecutionState& state, Value thisValue, size_t a
// If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
// IfAbruptRejectPromise(result, promiseCapability).
try {
if (!iteratorRecord->m_done) {
result = IteratorObject::iteratorClose(state, iteratorRecord, exceptionValue, true);
if (!record->m_done) {
result = IteratorObject::iteratorClose(state, record, exceptionValue, true);
}
} catch (const Value& v) {
exceptionValue = v;

View file

@ -1300,14 +1300,8 @@ static Value builtinStringRaw(ExecutionState& state, Value thisValue, size_t arg
}
}
// https://www.ecma-international.org/ecma-262/8.0/#sec-string.prototype.padstart
// 21.1.3.14String.prototype.padStart( maxLength [ , fillString ] )
static Value builtinStringPadStart(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
static Value stringPad(ExecutionState& state, String* S, size_t argc, Value* argv, bool isPadStart)
{
// Let O be ? RequireObjectCoercible(this value).
// Let S be ? ToString(O).
RESOLVE_THIS_BINDING_TO_STRING(S, String, padStart);
// Let intMaxLength be ? ToLength(maxLength).
// Let stringLength be the number of elements in S.
uint64_t intMaxLength = 0;
@ -1349,63 +1343,34 @@ static Value builtinStringPadStart(ExecutionState& state, Value thisValue, size_
truncatedStringFiller = truncatedStringFiller->substring(0, fillLen);
// Return a new String value computed by the concatenation of truncatedStringFiller and S.
sb.appendString(truncatedStringFiller);
sb.appendString(S);
if (isPadStart) {
sb.appendString(truncatedStringFiller);
sb.appendString(S);
} else {
sb.appendString(S);
sb.appendString(truncatedStringFiller);
}
return sb.finalize(&state);
}
// https://www.ecma-international.org/ecma-262/8.0/#sec-string.prototype.padstart
// 21.1.3.14String.prototype.padStart( maxLength [ , fillString ] )
static Value builtinStringPadStart(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
// Let O be ? RequireObjectCoercible(this value).
// Let S be ? ToString(O).
RESOLVE_THIS_BINDING_TO_STRING(S, String, padStart);
return stringPad(state, S, argc, argv, true);
}
// https://www.ecma-international.org/ecma-262/8.0/#sec-string.prototype.padend
// 21.1.3.13String.prototype.padEnd( maxLength [ , fillString ] )
static Value builtinStringPadEnd(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
// Let O be ? RequireObjectCoercible(this value).
// Let S be ? ToString(O).
RESOLVE_THIS_BINDING_TO_STRING(S, String, padStart);
// Let intMaxLength be ? ToLength(maxLength).
// Let stringLength be the number of elements in S.
uint64_t intMaxLength = 0;
if (argc >= 1) {
intMaxLength = argv[0].toLength(state);
}
uint64_t stringLength = S->length();
// If intMaxLength is not greater than stringLength, return S.
if (intMaxLength <= stringLength) {
return S;
}
// If fillString is undefined, let filler be a String consisting solely of the code unit 0x0020 (SPACE).
// Else, let filler be ? ToString(fillString).
String* filler;
if (argc >= 2 && (!argv[1].isUndefined())) {
filler = argv[1].toString(state);
} else {
filler = state.context()->staticStrings().asciiTable[0x20].string();
}
// If filler is the empty String, return S.
if (filler->length() == 0) {
return S;
}
// Let fillLen be intMaxLength - stringLength.
uint64_t fillLen = intMaxLength - stringLength;
// Let truncatedStringFiller be a new String value consisting of repeated concatenations of filler truncated to length fillLen.
StringBuilder sb;
while (sb.contentLength() < fillLen) {
sb.appendString(filler);
}
// Build the string, than truncate the characters over fillLen
String* truncatedStringFiller = sb.finalize(&state);
truncatedStringFiller = truncatedStringFiller->substring(0, fillLen);
// Return a new String value computed by the concatenation of S and truncatedStringFiller.
sb.appendString(S);
sb.appendString(truncatedStringFiller);
return sb.finalize(&state);
RESOLVE_THIS_BINDING_TO_STRING(S, String, padEnd);
return stringPad(state, S, argc, argv, false);
}
// http://www.ecma-international.org/ecma-262/6.0/#sec-createhtml

View file

@ -33,61 +33,46 @@ static Value builtinWeakMapConstructor(ExecutionState& state, Value thisValue, s
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::GlobalObject_ConstructorRequiresNew);
}
// Let map be ? OrdinaryCreateFromConstructor(NewTarget, "%MapPrototype%", « [[MapData]] »).
// Set map's [[MapData]] internal slot to a new empty List.
Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* {
return constructorRealm->globalObject()->weakMapPrototype();
});
WeakMapObject* map = new WeakMapObject(state, proto);
// If iterable is not present, or is either undefined or null, return map.
WeakMapObject* weakMap = new WeakMapObject(state, proto);
if (argc == 0 || argv[0].isUndefinedOrNull()) {
return map;
return weakMap;
}
Value iterable = argv[0];
// Let adder be ? Get(map, "set").
Value adder = map->Object::get(state, ObjectPropertyName(state.context()->staticStrings().set)).value(state, map);
// If IsCallable(adder) is false, throw a TypeError exception.
if (!adder.isCallable()) {
Value add = weakMap->Object::get(state, ObjectPropertyName(state.context()->staticStrings().set)).value(state, weakMap);
if (!add.isCallable()) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::NOT_Callable);
}
// Let iteratorRecord be ? GetIterator(iterable).
auto iteratorRecord = IteratorObject::getIterator(state, iterable);
while (true) {
auto next = IteratorObject::iteratorStep(state, iteratorRecord);
if (!next.hasValue()) {
return map;
return weakMap;
}
Value nextItem = IteratorObject::iteratorValue(state, next.value());
if (!nextItem.isObject()) {
ErrorObject* errorobj = ErrorObject::createError(state, ErrorCode::TypeError, new ASCIIString("TypeError"));
return IteratorObject::iteratorClose(state, iteratorRecord, errorobj, true);
ErrorObject* error = ErrorObject::createError(state, ErrorCode::TypeError, new ASCIIString("TypeError"));
return IteratorObject::iteratorClose(state, iteratorRecord, error, true);
}
try {
// Let k be Get(nextItem, "0").
// If k is an abrupt completion, return ? IteratorClose(iter, k).
Value k = nextItem.asObject()->getIndexedProperty(state, Value(0)).value(state, nextItem);
// Let v be Get(nextItem, "1").
// If v is an abrupt completion, return ? IteratorClose(iter, v).
Value v = nextItem.asObject()->getIndexedProperty(state, Value(1)).value(state, nextItem);
// Let status be Call(adder, map, « k.[[Value]], v.[[Value]] »).
Value argv[2] = { k, v };
Object::call(state, adder, map, 2, argv);
Object::call(state, add, weakMap, 2, argv);
} catch (const Value& v) {
// we should save thrown value bdwgc cannot track thrown value
Value exceptionValue = v;
// If status is an abrupt completion, return ? IteratorClose(iteratorRecord, status).
return IteratorObject::iteratorClose(state, iteratorRecord, exceptionValue, true);
Value exception = v;
return IteratorObject::iteratorClose(state, iteratorRecord, exception, true);
}
}
return map;
return weakMap;
}
#define RESOLVE_THIS_BINDING_TO_WEAKMAP(NAME, OBJ, BUILT_IN_METHOD) \

View file

@ -30,62 +30,48 @@ namespace Escargot {
// https://www.ecma-international.org/ecma-262/10.0/#sec-weakset-constructor
static Value builtinWeakSetConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
// If NewTarget is undefined, throw a TypeError exception.
if (!newTarget.hasValue()) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::GlobalObject_ConstructorRequiresNew);
}
// Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakSetPrototype%", « [[WeakSetData]] »).
// Set set's [[WeakSetData]] internal slot to a new empty List.
Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* {
return constructorRealm->globalObject()->weakSetPrototype();
});
WeakSetObject* set = new WeakSetObject(state, proto);
// If iterable is not present, let iterable be undefined.
WeakSetObject* weakSet = new WeakSetObject(state, proto);
Value iterable;
if (argc > 0) {
iterable = argv[0];
}
// If iterable is either undefined or null, return set.
if (iterable.isUndefinedOrNull()) {
return set;
return weakSet;
}
// Let adder be ? Get(set, "add").
Value adder = set->get(state, ObjectPropertyName(state.context()->staticStrings().add)).value(state, set);
// If IsCallable(adder) is false, throw a TypeError exception.
if (!adder.isCallable()) {
Value add = weakSet->get(state, ObjectPropertyName(state.context()->staticStrings().add)).value(state, weakSet);
if (!add.isCallable()) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::NOT_Callable);
}
// Let iteratorRecord be ? GetIterator(iterable).
auto iteratorRecord = IteratorObject::getIterator(state, iterable);
// Repeat
while (true) {
// Let next be ? IteratorStep(iteratorRecord).
auto next = IteratorObject::iteratorStep(state, iteratorRecord);
// If next is false, return set.
if (!next.hasValue()) {
return set;
return weakSet;
}
// Let nextValue be ? IteratorValue(next).
Value nextValue = IteratorObject::iteratorValue(state, next.value());
// Let status be Call(adder, set, « nextValue »).
try {
Value argv[1] = { nextValue };
Object::call(state, adder, set, 1, argv);
Object::call(state, add, weakSet, 1, argv);
} catch (const Value& v) {
// we should save thrown value bdwgc cannot track thrown value
Value exceptionValue = v;
// If status is an abrupt completion, return ? IteratorClose(iteratorRecord, status).
return IteratorObject::iteratorClose(state, iteratorRecord, exceptionValue, true);
}
}
return set;
return weakSet;
}
#define RESOLVE_THIS_BINDING_TO_WEAKSET(NAME, OBJ, BUILT_IN_METHOD) \

View file

@ -1,5 +1,4 @@
/*
static void setObjectPreComputedCaseOperationCacheMiss(ExecutionState& state, Object* obj, const Value& willBeObject, const Value& value, SetObjectPreComputedCase* code, ByteCodeBlock* block);
* Copyright (c) 2016-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or

View file

@ -167,125 +167,29 @@ InterpretedCodeBlock* InterpretedCodeBlock::createInterpretedCodeBlock(Context*
}
InterpretedCodeBlock::InterpretedCodeBlock(Context* ctx, Script* script, StringView src, ASTScopeContext* scopeCtx, bool isEvalCode, bool isEvalCodeInFunction)
: CodeBlock(ctx)
, m_script(script)
, m_src(src)
, m_byteCodeBlock(nullptr)
, m_parent(nullptr)
, m_children(nullptr)
, m_functionStart(1, 1, 0)
#if !(defined NDEBUG) || defined ESCARGOT_DEBUGGER
, m_bodyEndLOC(SIZE_MAX, SIZE_MAX, SIZE_MAX)
#endif
, m_functionLength(0)
, m_parameterCount(0)
, m_identifierOnStackCount(0)
, m_identifierOnHeapCount(0)
, m_lexicalBlockStackAllocatedIdentifierMaximumDepth(0)
, m_functionBodyBlockIndex(0)
, m_lexicalBlockIndexFunctionLocatedIn(0)
, m_isFunctionNameUsedBySelf(false)
, m_isFunctionNameSaveOnHeap(false)
, m_isFunctionNameExplicitlyDeclared(false)
, m_canUseIndexedVariableStorage(false)
, m_canAllocateVariablesOnStack(false)
, m_canAllocateEnvironmentOnStack(false)
, m_hasDescendantUsesNonIndexedVariableStorage(false)
, m_hasEval(false)
, m_hasWith(false)
, m_isStrict(false)
, m_inWith(false)
, m_isEvalCode(false)
, m_isEvalCodeInFunction(false)
, m_usesArgumentsObject(false)
, m_isFunctionExpression(false)
, m_isFunctionDeclaration(false)
, m_isArrowFunctionExpression(false)
, m_isOneExpressionOnlyVirtualArrowFunctionExpression(false)
, m_isFunctionBodyOnlyVirtualArrowFunctionExpression(false)
, m_isClassConstructor(false)
, m_isDerivedClassConstructor(false)
, m_isObjectMethod(false)
, m_isClassMethod(false)
, m_isClassStaticMethod(false)
, m_isGenerator(false)
, m_isAsync(false)
, m_needsVirtualIDOperation(false)
, m_hasArrowParameterPlaceHolder(false)
, m_hasParameterOtherThanIdentifier(false)
, m_allowSuperCall(false)
, m_allowSuperProperty(false)
, m_allowArguments(false)
, m_hasDynamicSourceCode(false)
#ifdef ESCARGOT_DEBUGGER
, m_markDebugging(ctx->inDebuggingCodeMode())
#endif
#ifndef NDEBUG
, m_scopeContext(scopeCtx)
#endif
: InterpretedCodeBlock(ctx, script)
{
m_src = src;
m_functionStart = ExtendedNodeLOC(1, 1, 0);
#ifndef NDEBUG
m_scopeContext = scopeCtx;
#endif
recordGlobalParsingInfo(scopeCtx, isEvalCode, isEvalCodeInFunction);
}
InterpretedCodeBlock::InterpretedCodeBlock(Context* ctx, Script* script, StringView src, ASTScopeContext* scopeCtx, InterpretedCodeBlock* parentBlock, bool isEvalCode, bool isEvalCodeInFunction)
: CodeBlock(ctx)
, m_script(script)
, m_src(StringView(src, scopeCtx->m_functionStartLOC.index, scopeCtx->m_bodyEndLOC.index))
, m_byteCodeBlock(nullptr)
, m_parent(parentBlock)
, m_children(nullptr)
, m_functionName(scopeCtx->m_functionName)
, m_functionStart(scopeCtx->m_functionStartLOC)
#if !(defined NDEBUG) || defined ESCARGOT_DEBUGGER
, m_bodyEndLOC(SIZE_MAX, SIZE_MAX, SIZE_MAX)
#endif
, m_functionLength(scopeCtx->m_functionLength)
, m_parameterCount(scopeCtx->m_parameterCount)
, m_identifierOnStackCount(0)
, m_identifierOnHeapCount(0)
, m_lexicalBlockStackAllocatedIdentifierMaximumDepth(0)
, m_functionBodyBlockIndex(0)
, m_lexicalBlockIndexFunctionLocatedIn(scopeCtx->m_lexicalBlockIndexFunctionLocatedIn)
, m_isFunctionNameUsedBySelf(false)
, m_isFunctionNameSaveOnHeap(false)
, m_isFunctionNameExplicitlyDeclared(false)
, m_canUseIndexedVariableStorage(false)
, m_canAllocateVariablesOnStack(false)
, m_canAllocateEnvironmentOnStack(false)
, m_hasDescendantUsesNonIndexedVariableStorage(false)
, m_hasEval(false)
, m_hasWith(false)
, m_isStrict(false)
, m_inWith(false)
, m_isEvalCode(false)
, m_isEvalCodeInFunction(false)
, m_usesArgumentsObject(false)
, m_isFunctionExpression(false)
, m_isFunctionDeclaration(false)
, m_isArrowFunctionExpression(false)
, m_isOneExpressionOnlyVirtualArrowFunctionExpression(false)
, m_isFunctionBodyOnlyVirtualArrowFunctionExpression(false)
, m_isClassConstructor(false)
, m_isDerivedClassConstructor(false)
, m_isObjectMethod(false)
, m_isClassMethod(false)
, m_isClassStaticMethod(false)
, m_isGenerator(false)
, m_isAsync(false)
, m_needsVirtualIDOperation(false)
, m_hasArrowParameterPlaceHolder(false)
, m_hasParameterOtherThanIdentifier(false)
, m_allowSuperCall(false)
, m_allowSuperProperty(false)
, m_allowArguments(false)
, m_hasDynamicSourceCode(false)
#ifdef ESCARGOT_DEBUGGER
, m_markDebugging(ctx->inDebuggingCodeMode())
#endif
#ifndef NDEBUG
, m_scopeContext(scopeCtx)
#endif
: InterpretedCodeBlock(ctx, script)
{
m_src = StringView(src, scopeCtx->m_functionStartLOC.index, scopeCtx->m_bodyEndLOC.index);
m_parent = parentBlock;
m_functionName = scopeCtx->m_functionName;
m_functionStart = scopeCtx->m_functionStartLOC;
m_functionLength = scopeCtx->m_functionLength;
m_parameterCount = scopeCtx->m_parameterCount;
m_lexicalBlockIndexFunctionLocatedIn = scopeCtx->m_lexicalBlockIndexFunctionLocatedIn;
#ifndef NDEBUG
m_scopeContext = scopeCtx;
#endif
recordFunctionParsingInfo(scopeCtx, isEvalCode, isEvalCodeInFunction);
}

View file

@ -80,7 +80,7 @@ public:
// per iteration block
size_t iterationLexicalBlockIndexBefore = newContext.m_lexicalBlockIndex;
ByteCodeBlock::ByteCodeLexicalBlockContext iterationBlockContext;
uint8_t tmpIdentifierNode[sizeof(IdentifierNode)];
uint8_t tempNode[sizeof(IdentifierNode)];
if (m_iterationLexicalBlockIndex != LEXICAL_BLOCK_INDEX_MAX) {
InterpretedCodeBlock::BlockInfo* bi = codeBlock->m_codeBlock->blockInfo(m_iterationLexicalBlockIndex);
@ -90,7 +90,7 @@ public:
}
for (size_t i = 0; i < bi->m_identifiers.size(); i++) {
IdentifierNode* id = new (tmpIdentifierNode) IdentifierNode(bi->m_identifiers[i].m_name);
IdentifierNode* id = new (tempNode) IdentifierNode(bi->m_identifiers[i].m_name);
id->m_loc = m_loc;
id->generateExpressionByteCode(codeBlock, &newContext, nameRegisters[i]);
}
@ -104,7 +104,7 @@ public:
size_t reverse = bi->m_identifiers.size() - 1;
for (size_t i = 0; i < bi->m_identifiers.size(); i++, reverse--) {
IdentifierNode* id = new (tmpIdentifierNode) IdentifierNode(bi->m_identifiers[reverse].m_name);
IdentifierNode* id = new (tempNode) IdentifierNode(bi->m_identifiers[reverse].m_name);
id->m_loc = m_loc;
newContext.m_isLexicallyDeclaredBindingInitialization = m_hasLexicalDeclarationOnInit;
id->generateStoreByteCode(codeBlock, &newContext, nameRegisters[reverse], true);
@ -166,7 +166,7 @@ public:
}
for (size_t i = 0; i < bi->m_identifiers.size(); i++) {
IdentifierNode* id = new (tmpIdentifierNode) IdentifierNode(bi->m_identifiers[i].m_name);
IdentifierNode* id = new (tempNode) IdentifierNode(bi->m_identifiers[i].m_name);
id->m_loc = m_loc;
id->generateExpressionByteCode(codeBlock, &newContext, nameRegisters[i]);
}
@ -177,7 +177,7 @@ public:
size_t reverse = bi->m_identifiers.size() - 1;
for (size_t i = 0; i < bi->m_identifiers.size(); i++, reverse--) {
IdentifierNode* id = new (tmpIdentifierNode) IdentifierNode(bi->m_identifiers[reverse].m_name);
IdentifierNode* id = new (tempNode) IdentifierNode(bi->m_identifiers[reverse].m_name);
id->m_loc = m_loc;
newContext.m_isLexicallyDeclaredBindingInitialization = m_hasLexicalDeclarationOnInit;
id->generateStoreByteCode(codeBlock, &newContext, nameRegisters[reverse], true);

View file

@ -45,6 +45,17 @@ public:
m_argument->generateStoreByteCode(codeBlock, context, storeIndex, false);
}
virtual void iterateChildrenIdentifier(const std::function<void(AtomicString name, bool isAssignment)>& fn) override
{
m_argument->iterateChildrenIdentifierAssigmentCase(fn);
}
virtual void iterateChildren(const std::function<void(Node* node)>& fn) override
{
fn(this);
m_argument->iterateChildren(fn);
}
virtual void generateResultNotRequiredExpressionByteCode(ByteCodeBlock* codeBlock, ByteCodeGenerateContext* context) override
{
if (m_argument->isIdentifier()) {
@ -63,18 +74,6 @@ public:
context->giveUpRegister();
}
virtual void iterateChildrenIdentifier(const std::function<void(AtomicString name, bool isAssignment)>& fn) override
{
m_argument->iterateChildrenIdentifierAssigmentCase(fn);
}
virtual void iterateChildren(const std::function<void(Node* node)>& fn) override
{
fn(this);
m_argument->iterateChildren(fn);
}
private:
Node* m_argument;
};

View file

@ -45,6 +45,17 @@ public:
m_argument->generateStoreByteCode(codeBlock, context, storeIndex, false);
}
virtual void iterateChildrenIdentifier(const std::function<void(AtomicString name, bool isAssignment)>& fn) override
{
m_argument->iterateChildrenIdentifierAssigmentCase(fn);
}
virtual void iterateChildren(const std::function<void(Node* node)>& fn) override
{
fn(this);
m_argument->iterateChildren(fn);
}
virtual void generateResultNotRequiredExpressionByteCode(ByteCodeBlock* codeBlock, ByteCodeGenerateContext* context) override
{
if (m_argument->isIdentifier()) {
@ -63,18 +74,6 @@ public:
context->giveUpRegister();
}
virtual void iterateChildrenIdentifier(const std::function<void(AtomicString name, bool isAssignment)>& fn) override
{
m_argument->iterateChildrenIdentifierAssigmentCase(fn);
}
virtual void iterateChildren(const std::function<void(Node* node)>& fn) override
{
fn(this);
m_argument->iterateChildren(fn);
}
private:
Node* m_argument;
};

View file

@ -1722,23 +1722,22 @@ public:
// wrap right expression with arrow function
result = this->finalize(startNode, builder.createArrowFunctionExpressionNode(subCodeBlockIndex));
} else {
auto startNode = this->createNode();
auto node = this->createNode();
InterpretedCodeBlock* currentTarget = this->codeBlock;
size_t orgIndex = this->lookahead.start;
InterpretedCodeBlock* childBlock = currentTarget->childBlockAt(this->subCodeBlockIndex);
this->scanner->index = childBlock->src().length() + childBlock->functionStart().index - currentTarget->functionStart().index;
this->scanner->lineNumber = childBlock->functionStart().line;
this->scanner->lineStart = childBlock->functionStart().index - childBlock->functionStart().column;
this->scanner->lineNumber = childBlock->functionStart().line;
this->lookahead.lineNumber = this->scanner->lineNumber;
this->lookahead.lineStart = this->scanner->lineStart;
this->lookahead.lineNumber = this->scanner->lineNumber;
this->nextToken();
// increase subCodeBlockIndex because parsing of an internal function is skipped
this->subCodeBlockIndex++;
result = this->finalize(startNode, builder.createArrowFunctionExpressionNode(subCodeBlockIndex));
result = this->finalize(node, builder.createArrowFunctionExpressionNode(subCodeBlockIndex));
}
return result;
@ -3605,7 +3604,6 @@ public:
} else {
auto startNode = this->createNode();
InterpretedCodeBlock* currentTarget = this->codeBlock;
size_t orgIndex = this->lookahead.start;
InterpretedCodeBlock* childBlock = currentTarget->childBlockAt(this->subCodeBlockIndex);
this->scanner->index = childBlock->src().length() + childBlock->functionStart().index - currentTarget->functionStart().index;

View file

@ -146,6 +146,10 @@ public:
m_bufferData.buffer = str;
}
void* operator new(size_t size) = delete;
void* operator new(size_t, void* ptr) = delete;
void* operator new[](size_t size) = delete;
virtual char16_t charAt(const size_t idx) const
{
return m_bufferData.uncheckedCharAtFor8Bit(idx);
@ -157,13 +161,13 @@ public:
}
// unused
virtual UTF16StringData toUTF16StringData() const
virtual UTF8StringData toUTF8StringData() const
{
RELEASE_ASSERT_NOT_REACHED();
}
// unused
virtual UTF8StringData toUTF8StringData() const
virtual UTF16StringData toUTF16StringData() const
{
RELEASE_ASSERT_NOT_REACHED();
}
@ -173,10 +177,6 @@ public:
{
RELEASE_ASSERT_NOT_REACHED();
}
void* operator new(size_t size) = delete;
void* operator new(size_t, void* ptr) = delete;
void* operator new[](size_t size) = delete;
};
void AtomicString::init(AtomicStringMap* map, const LChar* src, size_t len)

View file

@ -499,19 +499,19 @@ bool Value::equalsToByTheSameValueAlgorithm(ExecutionState& ec, const Value& val
return false;
}
PointerValue* o = asPointerValue();
PointerValue* o1 = asPointerValue();
PointerValue* o2 = val.asPointerValue();
if (o->isString()) {
if (o1->isString()) {
if (!o2->isString()) {
return false;
}
return *o->asString() == *o2->asString();
return *o1->asString() == *o2->asString();
}
if (UNLIKELY(o->isBigInt())) {
if (UNLIKELY(o1->isBigInt())) {
if (!o2->isBigInt()) {
return false;
}
return o->asBigInt()->equals(o2->asBigInt());
return o1->asBigInt()->equals(o2->asBigInt());
}
}

View file

@ -109,27 +109,26 @@ char32_t readUTF8Sequence(const char*& sequence, bool& valid, int& charlen)
unsigned length;
const char sch = *sequence;
valid = true;
if ((sch & 0x80) == 0)
length = 1;
else {
unsigned char ch2 = static_cast<unsigned char>(*(sequence + 1));
if ((sch & 0xE0) == 0xC0
&& (ch2 & 0xC0) == 0x80)
if ((sch & 0xE0) == 0xC0 && (ch2 & 0xC0) == 0x80) {
length = 2;
else {
} else {
unsigned char ch3 = static_cast<unsigned char>(*(sequence + 2));
if ((sch & 0xF0) == 0xE0
&& (ch2 & 0xC0) == 0x80
&& (ch3 & 0xC0) == 0x80)
if ((sch & 0xF0) == 0xE0 && (ch2 & 0xC0) == 0x80 && (ch3 & 0xC0) == 0x80) {
length = 3;
else {
} else {
unsigned char ch4 = static_cast<unsigned char>(*(sequence + 3));
if ((sch & 0xF8) == 0xF0
&& (ch2 & 0xC0) == 0x80
&& (ch3 & 0xC0) == 0x80
&& (ch4 & 0xC0) == 0x80)
if ((sch & 0xF8) == 0xF0 && (ch2 & 0xC0) == 0x80
&& (ch3 & 0xC0) == 0x80 && (ch4 & 0xC0) == 0x80) {
length = 4;
else {
} else {
valid = false;
sequence++;
return -1;
@ -143,16 +142,20 @@ char32_t readUTF8Sequence(const char*& sequence, bool& valid, int& charlen)
switch (length) {
case 4:
ch += static_cast<unsigned char>(*sequence++);
ch <<= 6; // Fall through.
ch <<= 6;
// Fall through.
case 3:
ch += static_cast<unsigned char>(*sequence++);
ch <<= 6; // Fall through.
ch <<= 6;
// Fall through.
case 2:
ch += static_cast<unsigned char>(*sequence++);
ch <<= 6; // Fall through.
ch <<= 6;
// Fall through.
case 1:
ch += static_cast<unsigned char>(*sequence++);
}
return ch - offsetsFromUTF8[length - 1];
}