mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Eliminate duplicated code
Signed-off-by: HyukWoo Park <hyukwoo.park@samsung.com>
This commit is contained in:
parent
2046b1faa9
commit
de4c7eb0db
14 changed files with 129 additions and 290 deletions
|
|
@ -26,6 +26,7 @@
|
|||
#include "runtime/Global.h"
|
||||
#include "runtime/BigInt.h"
|
||||
#include "runtime/Platform.h"
|
||||
#include "runtime/PromiseObject.h"
|
||||
|
||||
namespace Escargot {
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue