Skip to content

Commit

Permalink
Fix Error creation process to check and trigger Error relevant callba…
Browse files Browse the repository at this point in the history
…cks correctly

Signed-off-by: HyukWoo Park <hyukwoo.park@samsung.com>
  • Loading branch information
clover2123 authored and ksh8281 committed May 14, 2024
1 parent 77f0c49 commit 57c23d6
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 50 deletions.
28 changes: 12 additions & 16 deletions src/builtins/BuiltinError.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand All @@ -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;
}

Expand All @@ -82,17 +81,14 @@ 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, \
ObjectPropertyDescriptor(message.toString(state), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectStructurePropertyDescriptor::ConfigurablePresent))); \
} \
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
Expand Down Expand Up @@ -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()) {
Expand All @@ -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;
}
Expand Down
64 changes: 42 additions & 22 deletions src/runtime/ErrorObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#include "Context.h"
#include "SandBox.h"
#include "NativeFunctionObject.h"
#ifdef ENABLE_EXTENDED_API
#include "VMInstance.h"
#endif

namespace Escargot {

Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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
Expand Down
22 changes: 11 additions & 11 deletions src/runtime/ErrorObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 0 additions & 1 deletion src/runtime/ObjectStructure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 57c23d6

Please sign in to comment.