Commit a7a978415cc for nodejs

commit a7a978415cc690fc1f751800a2a8052d4d02f289
Author: Aviv Keller <me@aviv.sh>
Date:   Thu Oct 1 22:56:48 2026 -0400

    deps: V8: cherry-pick c795f5948568

    Original commit message:

        [immutable-array-buffer] Fix check order in TypedArray.prototype.set

        According to the spec, TypedArray.prototype.set checks
        IsImmutableBuffer(target.[[ViewedArrayBuffer]]) before converting
        the offset argument to integer and before reading from the source
        object.

        Additionally, when setting from a TypedArray source, reading from an
        immutable source TypedArray is permitted, so the source array should
        be validated using TypedArrayAccessMode::kRead rather than kWrite.

        Drive-By: Add a fast case for Smi indices where the steps are not
                  observable and we can fold all checks.

        TAG=agy
        CONV=94aa3be8-9990-41fe-a565-c62e3daa9a42

        Bug: 450237486
        Change-Id: I21790be90cde9a96ba7c1f573f034016d9c29850
        Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/8252528
        Reviewed-by: Igor Sheludko <ishell@chromium.org>
        Commit-Queue: Igor Sheludko <ishell@chromium.org>
        Auto-Submit: Olivier Flückiger <olivf@chromium.org>
        Cr-Commit-Position: refs/heads/main@{#109366}

    Refs: https://github.com/v8/v8/commit/c795f5948568dc7c5cce585928b9a6acb307ca82
    PR-URL: https://github.com/nodejs/node/pull/66380
    Reviewed-By: Richard Lau <richard.lau@ibm.com>
    Reviewed-By: Anna Henningsen <anna@addaleax.net>

diff --git a/common.gypi b/common.gypi
index ce50adc016e..841dc0288cd 100644
--- a/common.gypi
+++ b/common.gypi
@@ -44,7 +44,7 @@

     # Reset this number to 0 on major V8 upgrades.
     # Increment by one for each non-official patch applied to deps/v8.
-    'v8_embedder_string': '-node.36',
+    'v8_embedder_string': '-node.37',

     ##### V8 defaults for Node.js #####

diff --git a/deps/v8/src/builtins/typed-array-set.tq b/deps/v8/src/builtins/typed-array-set.tq
index 6fe170ede86..51562299edc 100644
--- a/deps/v8/src/builtins/typed-array-set.tq
+++ b/deps/v8/src/builtins/typed-array-set.tq
@@ -46,32 +46,61 @@ transitioning javascript builtin TypedArrayPrototypeSet(
   }

   try {
-    // 5. Let targetOffset be ? ToInteger(offset).
-    // 6. If targetOffset < 0, throw a RangeError exception.
-    let targetOffsetOverflowed: bool = false;
+    let attachedTargetAndLength: ValidJSTypedArrayAndLength;
     let targetOffset: uintptr = 0;
-    if (arguments.length > 1) {
-      const offsetArg = arguments[1];
-      try {
-        targetOffset = ToUintPtr(offsetArg)
-        // On values less than zero throw RangeError immediately.
-            otherwise OffsetOutOfBounds,
-            // On UintPtr or SafeInteger range overflow throw RangeError after
-            // performing observable steps to follow the spec.
-            OffsetOverflow, OffsetOverflow;
-      } label OffsetOverflow {
-        targetOffsetOverflowed = true;
+    let targetOffsetOverflowed: bool = false;
+
+    // If the offset argument is not provided then the targetOffset is 0.
+    const offsetArg: JSAny =
+        arguments.length > 1 ? arguments[1] : SmiConstant(0);
+    typeswitch (offsetArg) {
+      case (offsetSmi: Smi): {
+        // 5. Let targetOffset be ? ToInteger(offset).
+        // 6. If targetOffset < 0, throw a RangeError exception.
+        if (offsetSmi < 0) goto OffsetOutOfBounds;
+        targetOffset = Unsigned(SmiUntag(offsetSmi));
+
+        // For Smi offsets, integer conversion has no side effects, so step 4
+        // (IsImmutableBuffer check) can be deferred and combined with steps 7-9
+        // in EnsureValidAndReadLength without observable differences.
+        // 4. If IsImmutableBuffer(target.[[ViewedArrayBuffer]]) is true, throw
+        //    a TypeError exception.
+        // 7. Let targetBuffer be target.[[ViewedArrayBuffer]].
+        // 8. If IsDetachedBuffer(targetBuffer) is true, throw a TypeError
+        //    exception.
+        // 9. Let targetLength be target.[[ArrayLength]].
+        attachedTargetAndLength = EnsureValidAndReadLength(
+            target, TypedArrayAccessMode::kWrite) otherwise Fail;
+      }
+      case (offsetOther: JSAny): {
+        // 4. If IsImmutableBuffer(target.[[ViewedArrayBuffer]]) is true, throw
+        //    a TypeError exception.
+        if (IsImmutableArrayBuffer(target.buffer)) deferred {
+            goto Fail;
+          }
+
+        // 5. Let targetOffset be ? ToInteger(offset).
+        // 6. If targetOffset < 0, throw a RangeError exception.
+        try {
+          targetOffset = ToUintPtr(offsetOther)
+          // On values less than zero throw RangeError immediately.
+              otherwise OffsetOutOfBounds,
+              // On UintPtr or SafeInteger range overflow throw RangeError after
+              // performing observable steps to follow the spec.
+              OffsetOverflow, OffsetOverflow;
+        } label OffsetOverflow {
+          targetOffsetOverflowed = true;
+        }
+
+        // 7. Let targetBuffer be target.[[ViewedArrayBuffer]].
+        // 8. If IsDetachedBuffer(targetBuffer) is true, throw a TypeError
+        //    exception.
+        // 9. Let targetLength be target.[[ArrayLength]].
+        attachedTargetAndLength = EnsureValidAndReadLength(
+            target, TypedArrayAccessMode::kWrite) otherwise Fail;
       }
-    } else {
-      // If the offset argument is not provided then the targetOffset is 0.
     }

-    // 7. Let targetBuffer be target.[[ViewedArrayBuffer]].
-    // 8. If IsDetachedBuffer(targetBuffer) is true, throw a TypeError
-    //   exception.
-    const attachedTargetAndLength = EnsureValidAndReadLength(
-        target, TypedArrayAccessMode::kWrite) otherwise Fail;
-
     const overloadedArg = arguments[0];
     try {
       // 1. Choose SetTypedArrayFromTypedArray or SetTypedArrayFromArrayLike
@@ -86,7 +115,7 @@ transitioning javascript builtin TypedArrayPrototypeSet(
       // 5. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError
       //   exception.
       const attachedSourceAndLength =
-          EnsureValidAndReadLength(typedArray, TypedArrayAccessMode::kWrite)
+          EnsureValidAndReadLength(typedArray, TypedArrayAccessMode::kRead)
           otherwise Fail;
       TypedArrayPrototypeSetTypedArray(
           attachedTargetAndLength, attachedSourceAndLength, targetOffset,
diff --git a/deps/v8/test/mjsunit/immutable-arraybuffer.js b/deps/v8/test/mjsunit/immutable-arraybuffer.js
index 1a4619d53c0..a76ce4f7e5b 100644
--- a/deps/v8/test/mjsunit/immutable-arraybuffer.js
+++ b/deps/v8/test/mjsunit/immutable-arraybuffer.js
@@ -564,3 +564,47 @@ if (this.Worker) {
   assertEquals('OK', w.getMessage());
   w.terminate();
 }
+
+(function testTypedArraySetOrder() {
+  const ab = new ArrayBuffer(8);
+  const imm = ab.transferToImmutable();
+  const immTA = new Uint8Array(imm);
+
+  let offsetEvaluated = false;
+  const offset = {
+    valueOf() {
+      offsetEvaluated = true;
+      return 0;
+    }
+  };
+
+  let sourceRead = false;
+  const source = {
+    get length() {
+      sourceRead = true;
+      return 1;
+    },
+    get 0() {
+      sourceRead = true;
+      return 42;
+    }
+  };
+
+  // 1. Immutable target throws before offset conversion or source reading
+  assertThrows(() => immTA.set(source, offset), TypeError);
+  assertFalse(offsetEvaluated, "offset should not be evaluated for immutable target");
+  assertFalse(sourceRead, "source should not be read for immutable target");
+
+  // 2. Mutable target can read from immutable TypedArray source
+  const mutableTA = new Uint8Array(8);
+  assertDoesNotThrow(() => mutableTA.set(immTA));
+
+  // 3. Detached target evaluates offset before throwing TypeError
+  const detachedAb = new ArrayBuffer(8);
+  const detachedTA = new Uint8Array(detachedAb);
+  %ArrayBufferDetach(detachedAb);
+
+  offsetEvaluated = false;
+  assertThrows(() => detachedTA.set([1], offset), TypeError);
+  assertTrue(offsetEvaluated, "offset should be evaluated for detached target");
+})();