From 61b90cae3f196ad83f950e152573430b1dbe24cb Mon Sep 17 00:00:00 2001 From: robobun Date: Tue, 28 Jul 2026 21:47:32 +0000 Subject: [PATCH] appendSourceToErrorMessage: skip builtin code blocks Builtin JS functions use @-prefixed private identifiers in their source text. In release builds their code blocks carry no expression info (BytecodeGenerator::emitExpressionInfo skips them) so the existing hasExpressionInfo() check already short-circuits here. ASSERT_ENABLED builds do emit expression info for builtins, and when a .@call() inside a builtin hits a non-callable value the Call IC slow path (throwNotAFunctionErrorFromCallIC) passes the builtin code block and bytecode index straight into appendSourceToErrorMessage, which then splices the private-identifier source text into the user-visible TypeError message: Iterator.from({}).next() // TypeError: @getWrapForValidIteratorInternalField(this, // @wrapForValidIteratorFieldIteratedNextMethod).@call is not a // function. (In '...') Bail out of source appending for builtin code blocks so ASSERT_ENABLED builds match release output: TypeError: undefined is not a function --- Source/JavaScriptCore/runtime/ErrorInstance.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.cpp b/Source/JavaScriptCore/runtime/ErrorInstance.cpp index 8cb916db573db..8d9b3a69187a1 100644 --- a/Source/JavaScriptCore/runtime/ErrorInstance.cpp +++ b/Source/JavaScriptCore/runtime/ErrorInstance.cpp @@ -83,6 +83,15 @@ String appendSourceToErrorMessage(CodeBlock* codeBlock, BytecodeIndex bytecodeIn if (!codeBlock->hasExpressionInfo() || message.isNull()) return message; + // Builtin source text contains @-prefixed private identifiers that should not appear in + // user-visible error messages. BytecodeGenerator::emitExpressionInfo skips private builtins in + // !ASSERT_ENABLED builds so those bail at the hasExpressionInfo() check above, but builtins can + // still carry expression info (ASSERT_ENABLED builds, and non-private builtins under + // USE(BUN_JSC_ADDITIONS)). Matches the isBuiltinFunction() check in + // FindFirstCallerFrameWithCodeblockFunctor so the two callers behave the same. + if (codeBlock->unlinkedCodeBlock()->isBuiltinFunction()) + return message; + auto info = codeBlock->expressionInfoForBytecodeIndex(bytecodeIndex); int expressionStart = info.divot - info.startOffset; int expressionStop = info.divot + info.endOffset;