From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 16 Aug 2023 19:15:29 +0200
Subject: fix: assert module in the renderer process

When creating a Node.js Environment, embedders have the option to disable Node.js'
default overriding of Error.prepareStackTrace. However, the assert module depends on
a WeakMap that is populated with the error stacktraces in the overridden function.

This adds handling to fall back to the default implementation if Error.prepareStackTrace
if the override has been disabled.

This will be upstreamed.

diff --git a/lib/internal/assert/utils.js b/lib/internal/assert/utils.js
index 13e41d67c635c27bd5e69eb4960eace34beaef0d..9a99c9ca93907630f9f3ba7ba24577a11465661c 100644
--- a/lib/internal/assert/utils.js
+++ b/lib/internal/assert/utils.js
@@ -24,6 +24,7 @@ const AssertionError = require('internal/assert/assertion_error');
 const { openSync, closeSync, readSync } = require('fs');
 const { EOL } = require('internal/constants');
 const { BuiltinModule } = require('internal/bootstrap/realm');
+const { getEmbedderOptions } = require('internal/options');
 const { isError } = require('internal/util');
 
 const errorCache = new SafeMap();
@@ -166,8 +167,16 @@ function getErrMessage(message, fn) {
   ErrorCaptureStackTrace(err, fn);
   if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = tmpLimit;
 
-  overrideStackTrace.set(err, (_, stack) => stack);
-  const call = err.stack[0];
+  let call;
+  if (getEmbedderOptions().hasPrepareStackTraceCallback) {
+    overrideStackTrace.set(err, (_, stack) => stack);
+    call = err.stack[0];
+  } else {
+    const tmpPrepare = Error.prepareStackTrace;
+    Error.prepareStackTrace = (_, stack) => stack;
+    call = err.stack[0];
+    Error.prepareStackTrace = tmpPrepare;
+  }
 
   let filename = call.getFileName();
   const line = call.getLineNumber() - 1;
diff --git a/src/node_options.cc b/src/node_options.cc
index e3509abbc3bf84ac0edcd495eb3dde6219dbfc2d..8afded658c3f569de7b329ea9dddc11010748cf9 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -1566,14 +1566,16 @@ void GetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
   }
   Isolate* isolate = args.GetIsolate();
 
-  constexpr size_t kOptionsSize = 4;
+  constexpr size_t kOptionsSize = 5;
   std::array<Local<Name>, kOptionsSize> names = {
+      FIXED_ONE_BYTE_STRING(env->isolate(), "hasPrepareStackTraceCallback"),
       FIXED_ONE_BYTE_STRING(env->isolate(), "shouldNotRegisterESMLoader"),
       FIXED_ONE_BYTE_STRING(env->isolate(), "noGlobalSearchPaths"),
       FIXED_ONE_BYTE_STRING(env->isolate(), "noBrowserGlobals"),
       FIXED_ONE_BYTE_STRING(env->isolate(), "hasEmbedderPreload")};
 
   std::array<Local<Value>, kOptionsSize> values = {
+      Boolean::New(isolate, env->prepare_stack_trace_callback().IsEmpty()),
       Boolean::New(isolate, env->should_not_register_esm_loader()),
       Boolean::New(isolate, env->no_global_search_paths()),
       Boolean::New(isolate, env->no_browser_globals()),
