Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions Source/JavaScriptCore/runtime/ErrorInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,10 @@ bool ErrorInstance::materializeErrorInfoIfNeeded(VM& vm)
m_errorInfoMaterialized = true;
DeferGCForAWhile deferGC(vm);

// The lazy properties count as present from creation: an error that is already
// non-extensible here still gets them.
bool wasExtensible = isStructureExtensible();

JSValue stack;
if (!m_stackPropertyAlreadyMaterialized)
stack = fn(vm, *m_stackTrace.get(), m_lineColumn.line, m_lineColumn.column, m_sourceURL, this, this->bunErrorData());
Expand All @@ -452,15 +456,32 @@ bool ErrorInstance::materializeErrorInfoIfNeeded(VM& vm)
m_stackString = String();
}

auto attributes = static_cast<unsigned>(PropertyAttribute::DontEnum);

putDirect(vm, vm.propertyNames->line, jsNumber(m_lineColumn.line), attributes);
putDirect(vm, vm.propertyNames->column, jsNumber(m_lineColumn.column), attributes);
// fn can run user code (Error.prepareStackTrace), which can freeze this error or make one
// of these properties non-configurable. putDirect() checks nothing. So a property that is
// absent is not added to an error that became non-extensible, and a non-configurable
// property keeps its attributes. It takes the value only if an assignment could store it.
bool becameNonExtensible = wasExtensible && !isStructureExtensible();
auto putUnlessLocked = [&](PropertyName propertyName, JSValue value) {
unsigned attributes = static_cast<unsigned>(PropertyAttribute::DontEnum);
unsigned currentAttributes;
if (isValidOffset(structure()->get(vm, propertyName, currentAttributes))) {
if (currentAttributes & PropertyAttribute::DontDelete) {
if (currentAttributes & PropertyAttribute::ReadOnlyOrAccessorOrCustomAccessorOrValue)
return;
attributes = currentAttributes;
}
} else if (becameNonExtensible)
return;
putDirect(vm, propertyName, value, attributes);
};

putUnlessLocked(vm.propertyNames->line, jsNumber(m_lineColumn.line));
putUnlessLocked(vm.propertyNames->column, jsNumber(m_lineColumn.column));
if (!m_sourceURL.isEmpty())
putDirect(vm, vm.propertyNames->sourceURL, jsString(vm, WTF::move(m_sourceURL)), attributes);
putUnlessLocked(vm.propertyNames->sourceURL, jsString(vm, WTF::move(m_sourceURL)));

if (!m_stackPropertyAlreadyMaterialized)
putDirect(vm, vm.propertyNames->stack, stack, attributes);
putUnlessLocked(vm.propertyNames->stack, stack);
return true;
}

Expand Down
Loading