From 57c23d62f0d1ceae744896f28108cff2a982a860 Mon Sep 17 00:00:00 2001 From: HyukWoo Park Date: Wed, 21 Feb 2024 17:15:46 +0900 Subject: [PATCH] Fix Error creation process to check and trigger Error relevant callbacks correctly Signed-off-by: HyukWoo Park --- src/builtins/BuiltinError.cpp | 28 +++++++-------- src/runtime/ErrorObject.cpp | 64 +++++++++++++++++++++------------ src/runtime/ErrorObject.h | 22 ++++++------ src/runtime/ObjectStructure.cpp | 1 - 4 files changed, 65 insertions(+), 50 deletions(-) diff --git a/src/builtins/BuiltinError.cpp b/src/builtins/BuiltinError.cpp index 87ec71299..a71bdc060 100644 --- a/src/builtins/BuiltinError.cpp +++ b/src/builtins/BuiltinError.cpp @@ -52,7 +52,12 @@ static Value builtinErrorConstructor(ExecutionState& state, Value thisValue, siz Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* { return constructorRealm->globalObject()->errorPrototype(); }); + +#if defined(ENABLE_EXTENDED_API) + ErrorObject* obj = new ErrorObject(state, proto, String::emptyString, true, state.context()->vmInstance()->isErrorCreationCallbackRegistered()); +#else ErrorObject* obj = new ErrorObject(state, proto, String::emptyString); +#endif Value message = argv[0]; if (!message.isUndefined()) { @@ -63,12 +68,6 @@ static Value builtinErrorConstructor(ExecutionState& state, Value thisValue, siz Value options = argc > 1 ? argv[1] : Value(); installErrorCause(state, obj, options); -#if defined(ENABLE_EXTENDED_API) - if (UNLIKELY(state.context()->vmInstance()->isErrorCreationCallbackRegistered())) { - state.context()->vmInstance()->triggerErrorCreationCallback(state, obj); - } -#endif - return obj; } @@ -82,7 +81,7 @@ static Value builtinErrorConstructor(ExecutionState& state, Value thisValue, siz Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* { \ return constructorRealm->globalObject()->lowerCaseErrorName##ErrorPrototype(); \ }); \ - ErrorObject* obj = new errorName##ErrorObject(state, proto, String::emptyString); \ + ErrorObject* obj = new errorName##ErrorObject(state, proto, String::emptyString, true, state.context()->vmInstance()->isErrorCreationCallbackRegistered()); \ Value message = argv[0]; \ if (!message.isUndefined()) { \ obj->defineOwnPropertyThrowsException(state, state.context()->staticStrings().message, \ @@ -90,9 +89,6 @@ static Value builtinErrorConstructor(ExecutionState& state, Value thisValue, siz } \ Value options = argc > 1 ? argv[1] : Value(); \ installErrorCause(state, obj, options); \ - if (UNLIKELY(state.context()->vmInstance()->isErrorCreationCallbackRegistered())) { \ - state.context()->vmInstance()->triggerErrorCreationCallback(state, obj); \ - } \ return obj; \ } #else @@ -134,7 +130,13 @@ static Value builtinAggregateErrorConstructor(ExecutionState& state, Value thisV Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* { return constructorRealm->globalObject()->aggregateErrorPrototype(); }); + +#if defined(ENABLE_EXTENDED_API) + ErrorObject* O = new AggregateErrorObject(state, proto, String::emptyString, true, state.context()->vmInstance()->isErrorCreationCallbackRegistered()); +#else ErrorObject* O = new AggregateErrorObject(state, proto, String::emptyString); +#endif + Value message = argv[1]; // If message is not undefined, then if (!message.isUndefined()) { @@ -155,12 +157,6 @@ static Value builtinAggregateErrorConstructor(ExecutionState& state, Value thisV O->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, String::fromASCII("errors")), ObjectPropertyDescriptor(Value(Object::createArrayFromList(state, errorsList.size(), errorsList.data())), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); -#if defined(ENABLE_EXTENDED_API) - if (UNLIKELY(state.context()->vmInstance()->isErrorCreationCallbackRegistered())) { - state.context()->vmInstance()->triggerErrorCreationCallback(state, O); - } -#endif - // Return O. return O; } diff --git a/src/runtime/ErrorObject.cpp b/src/runtime/ErrorObject.cpp index cc07fc397..dbdba7503 100644 --- a/src/runtime/ErrorObject.cpp +++ b/src/runtime/ErrorObject.cpp @@ -22,6 +22,9 @@ #include "Context.h" #include "SandBox.h" #include "NativeFunctionObject.h" +#ifdef ENABLE_EXTENDED_API +#include "VMInstance.h" +#endif namespace Escargot { @@ -158,22 +161,39 @@ static Value builtinErrorObjectStackInfoSet(ExecutionState& state, Value thisVal return Value(); } -ErrorObject::ErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo) +ErrorObject::ErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo, bool triggerCallback) : DerivedObject(state, proto) , m_stackTraceData(nullptr) { + UNUSED_PARAMETER(triggerCallback); + Context* context = state.context(); + if (errorMessage->length()) { defineOwnPropertyThrowsException(state, state.context()->staticStrings().message, ObjectPropertyDescriptor(errorMessage, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); } - Context* context = state.context(); +#if defined(ENABLE_EXTENDED_API) + if (UNLIKELY(triggerCallback)) { + ASSERT(context->vmInstance()->isErrorCreationCallbackRegistered()); + // trigger ErrorCreationCallback + context->vmInstance()->triggerErrorCreationCallback(state, this); + if (this->hasOwnProperty(state, ObjectPropertyName(context->staticStrings().stack))) { + // if ErrorCreationCallback is registered and this callback already inserts `stack` property for the created ErrorObject, + // we just ignore adding `stack` data here + return; + } + } +#endif + JSGetterSetter gs( new NativeFunctionObject(state, NativeFunctionInfo(context->staticStrings().stack, builtinErrorObjectStackInfoGet, 0, NativeFunctionInfo::Strict)), new NativeFunctionObject(state, NativeFunctionInfo(context->staticStrings().stack, builtinErrorObjectStackInfoSet, 0, NativeFunctionInfo::Strict))); ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent); defineOwnProperty(state, ObjectPropertyName(context->staticStrings().stack), desc); + if (fillStackInfo) { + // fill stack info at the creation of Error object rather than the moment of thrown updateStackTraceData(state); } } @@ -185,54 +205,54 @@ void ErrorObject::updateStackTraceData(ExecutionState& state) setStackTraceData(StackTraceData::create(stackTraceDataVector)); } -ReferenceErrorObject::ReferenceErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo) - : ErrorObject(state, proto, errorMessage, fillStackInfo) +ReferenceErrorObject::ReferenceErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo, bool triggerCallback) + : ErrorObject(state, proto, errorMessage, fillStackInfo, triggerCallback) { } -TypeErrorObject::TypeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo) - : ErrorObject(state, proto, errorMessage, fillStackInfo) +TypeErrorObject::TypeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo, bool triggerCallback) + : ErrorObject(state, proto, errorMessage, fillStackInfo, triggerCallback) { } -RangeErrorObject::RangeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo) - : ErrorObject(state, proto, errorMessage, fillStackInfo) +RangeErrorObject::RangeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo, bool triggerCallback) + : ErrorObject(state, proto, errorMessage, fillStackInfo, triggerCallback) { } -SyntaxErrorObject::SyntaxErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo) - : ErrorObject(state, proto, errorMessage, fillStackInfo) +SyntaxErrorObject::SyntaxErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo, bool triggerCallback) + : ErrorObject(state, proto, errorMessage, fillStackInfo, triggerCallback) { } -URIErrorObject::URIErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo) - : ErrorObject(state, proto, errorMessage, fillStackInfo) +URIErrorObject::URIErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo, bool triggerCallback) + : ErrorObject(state, proto, errorMessage, fillStackInfo, triggerCallback) { } -EvalErrorObject::EvalErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo) - : ErrorObject(state, proto, errorMessage, fillStackInfo) +EvalErrorObject::EvalErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo, bool triggerCallback) + : ErrorObject(state, proto, errorMessage, fillStackInfo, triggerCallback) { } -AggregateErrorObject::AggregateErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo) - : ErrorObject(state, proto, errorMessage, fillStackInfo) +AggregateErrorObject::AggregateErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo, bool triggerCallback) + : ErrorObject(state, proto, errorMessage, fillStackInfo, triggerCallback) { } #if defined(ENABLE_WASM) -WASMCompileErrorObject::WASMCompileErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo) - : ErrorObject(state, proto, errorMessage, fillStackInfo) +WASMCompileErrorObject::WASMCompileErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo, bool triggerCallback) + : ErrorObject(state, proto, errorMessage, fillStackInfo, triggerCallback) { } -WASMLinkErrorObject::WASMLinkErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo) - : ErrorObject(state, proto, errorMessage, fillStackInfo) +WASMLinkErrorObject::WASMLinkErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo, bool triggerCallback) + : ErrorObject(state, proto, errorMessage, fillStackInfo, triggerCallback) { } -WASMRuntimeErrorObject::WASMRuntimeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo) - : ErrorObject(state, proto, errorMessage, fillStackInfo) +WASMRuntimeErrorObject::WASMRuntimeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo, bool triggerCallback) + : ErrorObject(state, proto, errorMessage, fillStackInfo, triggerCallback) { } #endif diff --git a/src/runtime/ErrorObject.h b/src/runtime/ErrorObject.h index 329a3de05..549c4b86e 100644 --- a/src/runtime/ErrorObject.h +++ b/src/runtime/ErrorObject.h @@ -171,7 +171,7 @@ class ErrorObject : public DerivedObject { static void throwBuiltinError(ExecutionState& state, ErrorCode code, String* objectName, bool prototype, String* functionName, const char* templateString); static void throwBuiltinError(ExecutionState& state, ErrorCode code, String* errorMessage); - ErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true); + ErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true, bool triggerCallback = false); void updateStackTraceData(ExecutionState& state); virtual bool isErrorObject() const @@ -195,53 +195,53 @@ class ErrorObject : public DerivedObject { class ReferenceErrorObject : public ErrorObject { public: - ReferenceErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true); + ReferenceErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true, bool triggerCallback = false); }; class TypeErrorObject : public ErrorObject { public: - TypeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true); + TypeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true, bool triggerCallback = false); }; class SyntaxErrorObject : public ErrorObject { public: - SyntaxErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true); + SyntaxErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true, bool triggerCallback = false); }; class RangeErrorObject : public ErrorObject { public: - RangeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true); + RangeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true, bool triggerCallback = false); }; class URIErrorObject : public ErrorObject { public: - URIErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true); + URIErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true, bool triggerCallback = false); }; class EvalErrorObject : public ErrorObject { public: - EvalErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true); + EvalErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true, bool triggerCallback = false); }; class AggregateErrorObject : public ErrorObject { public: - AggregateErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true); + AggregateErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true, bool triggerCallback = false); }; #if defined(ENABLE_WASM) class WASMCompileErrorObject : public ErrorObject { public: - WASMCompileErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true); + WASMCompileErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true, bool triggerCallback = false); }; class WASMLinkErrorObject : public ErrorObject { public: - WASMLinkErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true); + WASMLinkErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true, bool triggerCallback = false); }; class WASMRuntimeErrorObject : public ErrorObject { public: - WASMRuntimeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true); + WASMRuntimeErrorObject(ExecutionState& state, Object* proto, String* errorMessage, bool fillStackInfo = true, bool triggerCallback = false); }; #endif } // namespace Escargot diff --git a/src/runtime/ObjectStructure.cpp b/src/runtime/ObjectStructure.cpp index 612532fd2..ac556c92a 100644 --- a/src/runtime/ObjectStructure.cpp +++ b/src/runtime/ObjectStructure.cpp @@ -56,7 +56,6 @@ ObjectStructure* ObjectStructure::create(Context* ctx, ObjectStructureItemTightV bool hasSymbol = false; bool hasNonAtomicPropertyName = false; bool hasEnumerableProperty = true; - bool isInlineCacheable = true; for (size_t i = 0; i < properties.size(); i++) { const ObjectStructurePropertyName& propertyName = properties[i].m_propertyName;