Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (277237 => 277238)
--- trunk/Source/_javascript_Core/ChangeLog 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-05-09 02:18:25 UTC (rev 277238)
@@ -1,3 +1,47 @@
+2021-05-08 Ross Kirsling <[email protected]>
+
+ [JSC] Fix invalid exception checks after recent ErrorInstance changes
+ https://bugs.webkit.org/show_bug.cgi?id=225565
+
+ Reviewed by Alexey Shvayka.
+
+ r277221 and r277224 each introduced issues under validateExceptionChecks=1; this patch fixes them.
+
+ Of particular note:
+ The earlier patch sought to consolidate Error#cause logic under ErrorInstance::finishCreation.
+ This part must be undone as it is crucial that non-user-thrown errors be able to bypass that logic
+ (otherwise throwException itself would need to be exception-checked).
+
+ * runtime/AggregateError.cpp:
+ (JSC::createAggregateError):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::getProperty):
+ * runtime/Error.cpp:
+ (JSC::createError):
+ (JSC::createEvalError):
+ (JSC::createRangeError):
+ (JSC::createReferenceError):
+ (JSC::createSyntaxError):
+ (JSC::createTypeError):
+ (JSC::createURIError):
+ (JSC::createGetterTypeError):
+ * runtime/ErrorInstance.cpp:
+ (JSC::ErrorInstance::create):
+ (JSC::ErrorInstance::finishCreation):
+ * runtime/ErrorInstance.h:
+ (JSC::ErrorInstance::create):
+ * runtime/JSObject.h:
+ * runtime/JSObjectInlines.h:
+ (JSC::JSObject::getIfPropertyExists):
+ * runtime/NullSetterFunction.cpp:
+ (JSC::NullSetterFunctionInternal::JSC_DEFINE_HOST_FUNCTION):
+ * wasm/js/JSWebAssemblyCompileError.cpp:
+ (JSC::createJSWebAssemblyCompileError):
+ * wasm/js/JSWebAssemblyLinkError.cpp:
+ (JSC::createJSWebAssemblyLinkError):
+ * wasm/js/JSWebAssemblyRuntimeError.cpp:
+ (JSC::createJSWebAssemblyRuntimeError):
+
2021-05-08 Chris Dumez <[email protected]>
Port Filesystem::pathByAppendingComponent() & Filesystem:: pathByAppendingComponents() to std::filesystem
Modified: trunk/Source/_javascript_Core/runtime/AggregateError.cpp (277237 => 277238)
--- trunk/Source/_javascript_Core/runtime/AggregateError.cpp 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/AggregateError.cpp 2021-05-09 02:18:25 UTC (rev 277238)
@@ -49,6 +49,7 @@
RETURN_IF_EXCEPTION(scope, nullptr);
auto* error = ErrorInstance::create(globalObject, structure, message, options, appender, type, ErrorType::AggregateError, useCurrentFrame);
+ RETURN_IF_EXCEPTION(scope, nullptr);
error->putDirect(vm, vm.propertyNames->errors, array, static_cast<unsigned>(PropertyAttribute::DontEnum));
return error;
}
Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (277237 => 277238)
--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2021-05-09 02:18:25 UTC (rev 277238)
@@ -145,16 +145,11 @@
static ALWAYS_INLINE JSValue getProperty(JSGlobalObject* globalObject, JSObject* object, uint64_t index)
{
- VM& vm = globalObject->vm();
- auto scope = DECLARE_THROW_SCOPE(vm);
-
if (JSValue result = object->tryGetIndexQuickly(index))
return result;
// Don't return undefined if the property is not found.
- auto property = object->getIfPropertyExists(globalObject, Identifier::from(vm, index));
- RETURN_IF_EXCEPTION(scope, { });
- return property.valueOr(JSValue());
+ return object->getIfPropertyExists(globalObject, Identifier::from(globalObject->vm(), index));
}
static ALWAYS_INLINE void setLength(JSGlobalObject* globalObject, VM& vm, JSObject* obj, uint64_t value)
Modified: trunk/Source/_javascript_Core/runtime/Error.cpp (277237 => 277238)
--- trunk/Source/_javascript_Core/runtime/Error.cpp 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/Error.cpp 2021-05-09 02:18:25 UTC (rev 277238)
@@ -35,37 +35,37 @@
JSObject* createError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(), message, jsUndefined(), appender, TypeNothing, ErrorType::Error, true);
+ return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(), message, JSValue(), appender, TypeNothing, ErrorType::Error, true);
}
JSObject* createEvalError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::EvalError), message, jsUndefined(), appender, TypeNothing, ErrorType::EvalError, true);
+ return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::EvalError), message, JSValue(), appender, TypeNothing, ErrorType::EvalError, true);
}
JSObject* createRangeError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::RangeError), message, jsUndefined(), appender, TypeNothing, ErrorType::RangeError, true);
+ return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::RangeError), message, JSValue(), appender, TypeNothing, ErrorType::RangeError, true);
}
JSObject* createReferenceError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::ReferenceError), message, jsUndefined(), appender, TypeNothing, ErrorType::ReferenceError, true);
+ return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::ReferenceError), message, JSValue(), appender, TypeNothing, ErrorType::ReferenceError, true);
}
JSObject* createSyntaxError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::SyntaxError), message, jsUndefined(), appender, TypeNothing, ErrorType::SyntaxError, true);
+ return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::SyntaxError), message, JSValue(), appender, TypeNothing, ErrorType::SyntaxError, true);
}
JSObject* createTypeError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender, RuntimeType type)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message, jsUndefined(), appender, type, ErrorType::TypeError, true);
+ return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message, JSValue(), appender, type, ErrorType::TypeError, true);
}
JSObject* createNotEnoughArgumentsError(JSGlobalObject* globalObject, ErrorInstance::SourceAppender appender)
@@ -76,7 +76,7 @@
JSObject* createURIError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::URIError), message, jsUndefined(), appender, TypeNothing, ErrorType::URIError, true);
+ return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::URIError), message, JSValue(), appender, TypeNothing, ErrorType::URIError, true);
}
JSObject* createError(JSGlobalObject* globalObject, ErrorType errorType, const String& message)
@@ -113,7 +113,7 @@
static JSObject* createGetterTypeError(JSGlobalObject* globalObject, const String& message)
{
ASSERT(!message.isEmpty());
- auto* error = ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message, jsUndefined(), nullptr, TypeNothing, ErrorType::TypeError);
+ auto* error = ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message, JSValue(), nullptr, TypeNothing, ErrorType::TypeError);
error->setNativeGetterTypeError();
return error;
}
Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp (277237 => 277238)
--- trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp 2021-05-09 02:18:25 UTC (rev 277238)
@@ -52,7 +52,14 @@
String messageString = message.isUndefined() ? String() : message.toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, nullptr);
- return create(globalObject, vm, structure, messageString, options, appender, type, errorType, useCurrentFrame);
+ JSValue cause;
+ if (options.isObject()) {
+ // Since `throw undefined;` is valid, we need to distinguish the case where `cause` is an explicit undefined.
+ cause = asObject(options)->getIfPropertyExists(globalObject, vm.propertyNames->cause);
+ RETURN_IF_EXCEPTION(scope, nullptr);
+ }
+
+ return create(globalObject, vm, structure, messageString, cause, appender, type, errorType, useCurrentFrame);
}
static String appendSourceToErrorMessage(CallFrame* callFrame, ErrorInstance* exception, BytecodeIndex bytecodeIndex, const String& message)
@@ -107,11 +114,10 @@
return appender(message, codeBlock->source().provider()->getRange(start, stop).toString(), type, ErrorInstance::FoundApproximateSource);
}
-void ErrorInstance::finishCreation(VM& vm, JSGlobalObject* globalObject, const String& message, JSValue options, SourceAppender appender, RuntimeType type, bool useCurrentFrame)
+void ErrorInstance::finishCreation(VM& vm, JSGlobalObject* globalObject, const String& message, JSValue cause, SourceAppender appender, RuntimeType type, bool useCurrentFrame)
{
Base::finishCreation(vm);
ASSERT(inherits(vm, info()));
- auto scope = DECLARE_THROW_SCOPE(vm);
m_sourceAppender = appender;
m_runtimeTypeForCause = type;
@@ -135,13 +141,8 @@
if (!messageWithSource.isNull())
putDirect(vm, vm.propertyNames->message, jsString(vm, messageWithSource), static_cast<unsigned>(PropertyAttribute::DontEnum));
- if (options.isObject()) {
- // Since `throw undefined;` is valid, we need to distinguish the case where `cause` is an explicit undefined.
- auto cause = asObject(options)->getIfPropertyExists(globalObject, vm.propertyNames->cause);
- RETURN_IF_EXCEPTION(scope, void());
- if (cause)
- putDirect(vm, vm.propertyNames->cause, cause.value(), static_cast<unsigned>(PropertyAttribute::DontEnum));
- }
+ if (!cause.isEmpty())
+ putDirect(vm, vm.propertyNames->cause, cause, static_cast<unsigned>(PropertyAttribute::DontEnum));
}
// Based on ErrorPrototype's errorProtoFuncToString(), but is modified to
Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.h (277237 => 277238)
--- trunk/Source/_javascript_Core/runtime/ErrorInstance.h 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.h 2021-05-09 02:18:25 UTC (rev 277238)
@@ -54,10 +54,10 @@
return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
}
- static ErrorInstance* create(JSGlobalObject* globalObject, VM& vm, Structure* structure, const String& message, JSValue options, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, ErrorType errorType = ErrorType::Error, bool useCurrentFrame = true)
+ static ErrorInstance* create(JSGlobalObject* globalObject, VM& vm, Structure* structure, const String& message, JSValue cause, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, ErrorType errorType = ErrorType::Error, bool useCurrentFrame = true)
{
ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure, errorType);
- instance->finishCreation(vm, globalObject, message, options, appender, type, useCurrentFrame);
+ instance->finishCreation(vm, globalObject, message, cause, appender, type, useCurrentFrame);
return instance;
}
@@ -94,7 +94,7 @@
protected:
explicit ErrorInstance(VM&, Structure*, ErrorType);
- void finishCreation(VM&, JSGlobalObject*, const String& message, JSValue options, SourceAppender = nullptr, RuntimeType = TypeNothing, bool useCurrentFrame = true);
+ void finishCreation(VM&, JSGlobalObject*, const String& message, JSValue cause, SourceAppender = nullptr, RuntimeType = TypeNothing, bool useCurrentFrame = true);
static bool getOwnPropertySlot(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);
static void getOwnSpecialPropertyNames(JSObject*, JSGlobalObject*, PropertyNameArray&, DontEnumPropertiesMode);
Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (277237 => 277238)
--- trunk/Source/_javascript_Core/runtime/JSObject.h 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h 2021-05-09 02:18:25 UTC (rev 277238)
@@ -162,7 +162,7 @@
template<typename CallbackWhenNoException> typename std::result_of<CallbackWhenNoException(bool, PropertySlot&)>::type getPropertySlot(JSGlobalObject*, PropertyName, CallbackWhenNoException) const;
template<typename CallbackWhenNoException> typename std::result_of<CallbackWhenNoException(bool, PropertySlot&)>::type getPropertySlot(JSGlobalObject*, PropertyName, PropertySlot&, CallbackWhenNoException) const;
- Optional<JSValue> getIfPropertyExists(JSGlobalObject*, PropertyName);
+ JSValue getIfPropertyExists(JSGlobalObject*, PropertyName);
private:
static bool getOwnPropertySlotImpl(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);
Modified: trunk/Source/_javascript_Core/runtime/JSObjectInlines.h (277237 => 277238)
--- trunk/Source/_javascript_Core/runtime/JSObjectInlines.h 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/JSObjectInlines.h 2021-05-09 02:18:25 UTC (rev 277238)
@@ -191,7 +191,7 @@
return JSObject::getOwnPropertySlot(this, globalObject, propertyName, slot);
}
-inline Optional<JSValue> JSObject::getIfPropertyExists(JSGlobalObject* globalObject, PropertyName propertyName)
+inline JSValue JSObject::getIfPropertyExists(JSGlobalObject* globalObject, PropertyName propertyName)
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -198,14 +198,15 @@
PropertySlot slot(this, PropertySlot::InternalMethodType::HasProperty);
bool hasProperty = getPropertySlot(globalObject, propertyName, slot);
- EXCEPTION_ASSERT_UNUSED(scope, !scope.exception() || !hasProperty);
-
+ RETURN_IF_EXCEPTION(scope, { });
if (!hasProperty)
- return WTF::nullopt;
+ return { };
- return UNLIKELY(slot.isTaintedByOpaqueObject())
- ? get(globalObject, propertyName)
- : slot.getValue(globalObject, propertyName);
+ scope.release();
+ if (UNLIKELY(slot.isTaintedByOpaqueObject()))
+ return get(globalObject, propertyName);
+
+ return slot.getValue(globalObject, propertyName);
}
inline bool JSObject::mayInterceptIndexedAccesses(VM& vm)
Modified: trunk/Source/_javascript_Core/runtime/NullSetterFunction.cpp (277237 => 277238)
--- trunk/Source/_javascript_Core/runtime/NullSetterFunction.cpp 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/NullSetterFunction.cpp 2021-05-09 02:18:25 UTC (rev 277238)
@@ -94,7 +94,7 @@
auto scope = DECLARE_THROW_SCOPE(vm);
// This function is only called from IC. And we do not want to include this frame in Error's stack.
constexpr bool useCurrentFrame = false;
- throwException(globalObject, scope, ErrorInstance::create(globalObject, vm, globalObject->errorStructure(ErrorType::TypeError), ReadonlyPropertyWriteError, jsUndefined(), nullptr, TypeNothing, ErrorType::TypeError, useCurrentFrame));
+ throwException(globalObject, scope, ErrorInstance::create(globalObject, vm, globalObject->errorStructure(ErrorType::TypeError), ReadonlyPropertyWriteError, JSValue(), nullptr, TypeNothing, ErrorType::TypeError, useCurrentFrame));
return { };
}
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyCompileError.cpp (277237 => 277238)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyCompileError.cpp 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyCompileError.cpp 2021-05-09 02:18:25 UTC (rev 277238)
@@ -35,7 +35,7 @@
JSObject* createJSWebAssemblyCompileError(JSGlobalObject* globalObject, VM& vm, const String& message)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyCompileErrorStructure(), message, jsUndefined(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
+ return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyCompileErrorStructure(), message, JSValue(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyLinkError.cpp (277237 => 277238)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyLinkError.cpp 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyLinkError.cpp 2021-05-09 02:18:25 UTC (rev 277238)
@@ -35,7 +35,7 @@
JSObject* createJSWebAssemblyLinkError(JSGlobalObject* globalObject, VM& vm, const String& message)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyLinkErrorStructure(), message, jsUndefined(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
+ return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyLinkErrorStructure(), message, JSValue(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyRuntimeError.cpp (277237 => 277238)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyRuntimeError.cpp 2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyRuntimeError.cpp 2021-05-09 02:18:25 UTC (rev 277238)
@@ -35,7 +35,7 @@
JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject* globalObject, VM& vm, const String& message)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyRuntimeErrorStructure(), message, jsUndefined(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
+ return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyRuntimeErrorStructure(), message, JSValue(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
}
} // namespace JSC