Browse Source

chore: update patches

Keeley Hammond 6 months ago
parent
commit
d1ba48fbe0

+ 0 - 3
patches/v8/.patches

@@ -1,6 +1,3 @@
 chore_allow_customizing_microtask_policy_per_context.patch
 deps_add_v8_object_setinternalfieldfornodecore.patch
 fix_disable_scope_reuse_associated_dchecks.patch
-cherry-pick-9542895cdd3d.patch
-cherry-pick-259a5f8fed67.patch
-cherry-pick-81155a8f3b20.patch

+ 0 - 70
patches/v8/cherry-pick-259a5f8fed67.patch

@@ -1,70 +0,0 @@
-From 259a5f8fed6737ffcd573f92ab6953f389c13797 Mon Sep 17 00:00:00 2001
-From: Victor Gomes <[email protected]>
-Date: Mon, 30 Sep 2024 12:25:31 +0200
-Subject: [PATCH] [maglev] Add stable map dependency when loading map from closure
-
-Fixed: 369630648
-Change-Id: Ib298eca15e2a9ca8bb12db685a60c5f94a9dc1cc
-Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5891221
-Reviewed-by: Olivier Flückiger <[email protected]>
-Auto-Submit: Victor Gomes <[email protected]>
-Commit-Queue: Olivier Flückiger <[email protected]>
-Cr-Commit-Position: refs/heads/main@{#96334}
----
-
-diff --git a/src/maglev/maglev-graph-builder.cc b/src/maglev/maglev-graph-builder.cc
-index 774a557..88430df 100644
---- a/src/maglev/maglev-graph-builder.cc
-+++ b/src/maglev/maglev-graph-builder.cc
-@@ -7012,15 +7012,21 @@
- 
- void MaglevGraphBuilder::VisitGetSuperConstructor() {
-   ValueNode* active_function = GetAccumulator();
--  ValueNode* map_proto;
-+  // TODO(victorgomes): Maybe BuildLoadTaggedField should support constants
-+  // instead.
-   if (compiler::OptionalHeapObjectRef constant =
-           TryGetConstant(active_function)) {
--    map_proto = GetConstant(constant->map(broker()).prototype(broker()));
--  } else {
--    ValueNode* map =
--        BuildLoadTaggedField(active_function, HeapObject::kMapOffset);
--    map_proto = BuildLoadTaggedField(map, Map::kPrototypeOffset);
-+    compiler::MapRef map = constant->map(broker());
-+    if (map.is_stable()) {
-+      broker()->dependencies()->DependOnStableMap(map);
-+      ValueNode* map_proto = GetConstant(map.prototype(broker()));
-+      StoreRegister(iterator_.GetRegisterOperand(0), map_proto);
-+      return;
-+    }
-   }
-+  ValueNode* map =
-+      BuildLoadTaggedField(active_function, HeapObject::kMapOffset);
-+  ValueNode* map_proto = BuildLoadTaggedField(map, Map::kPrototypeOffset);
-   StoreRegister(iterator_.GetRegisterOperand(0), map_proto);
- }
- 
-diff --git a/test/mjsunit/maglev/regress-369630648.js b/test/mjsunit/maglev/regress-369630648.js
-new file mode 100644
-index 0000000..e467fee
---- /dev/null
-+++ b/test/mjsunit/maglev/regress-369630648.js
-@@ -0,0 +1,18 @@
-+// Copyright 2024 the V8 project authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+//
-+// Flags: --allow-natives-syntax --no-lazy-feedback-allocation
-+
-+class C extends Array {
-+  constructor() {
-+      (() => (() => super())())();
-+  }
-+}
-+%PrepareFunctionForOptimization(C);
-+new C();
-+new C();
-+%OptimizeFunctionOnNextCall(C);
-+new C();
-+C.__proto__ = [1];
-+assertThrows(() => { new C() }, TypeError);

+ 0 - 283
patches/v8/cherry-pick-81155a8f3b20.patch

@@ -1,283 +0,0 @@
-From 81155a8f3b20fbfc7e36c2419f5326f1d0ad7d75 Mon Sep 17 00:00:00 2001
-From: Victor Gomes <[email protected]>
-Date: Wed, 02 Oct 2024 10:59:42 +0200
-Subject: [PATCH] [turbofan] Consider WasmStruct in InferHasInPrototypeChain
-
-Drive-by: add some CHECKs in not _clearly_ safe uses of AsJSObject
-to turn possible vulnerablities into crashes.
-
-Fixed: 367818758
-Change-Id: Ib0464658152ce87141fa137dc6562f17b84bb6be
-Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5901846
-Reviewed-by: Nico Hartmann <[email protected]>
-Auto-Submit: Victor Gomes <[email protected]>
-Commit-Queue: Nico Hartmann <[email protected]>
-Cr-Commit-Position: refs/heads/main@{#96386}
----
-
-diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc
-index 8d40875..595f4ad 100644
---- a/src/compiler/access-info.cc
-+++ b/src/compiler/access-info.cc
-@@ -925,6 +925,7 @@
-       return PropertyAccessInfo::NotFound(zone(), receiver_map, holder);
-     }
- 
-+    CHECK(prototype.IsJSObject());
-     holder = prototype.AsJSObject();
-     map = map_prototype_map;
- 
-diff --git a/src/compiler/heap-refs.cc b/src/compiler/heap-refs.cc
-index c1c7b1a..e6272d8 100644
---- a/src/compiler/heap-refs.cc
-+++ b/src/compiler/heap-refs.cc
-@@ -1690,6 +1690,7 @@
-   if (!expected_receiver_type->IsTemplateFor(prototype.object()->map())) {
-     return not_found;
-   }
-+  CHECK(prototype.IsJSObject());
-   return HolderLookupResult(CallOptimization::kHolderFound,
-                             prototype.AsJSObject());
- }
-diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc
-index 7f74e12..e0a1e83 100644
---- a/src/compiler/js-native-context-specialization.cc
-+++ b/src/compiler/js-native-context-specialization.cc
-@@ -882,7 +882,9 @@
-       // might be a different object each time, so it's much simpler to include
-       // {prototype}. That does, however, mean that we must check {prototype}'s
-       // map stability.
--      if (!prototype.map(broker()).is_stable()) return kMayBeInPrototypeChain;
-+      if (!prototype.IsJSObject() || !prototype.map(broker()).is_stable()) {
-+        return kMayBeInPrototypeChain;
-+      }
-       last_prototype = prototype.AsJSObject();
-     }
-     WhereToStart start = result == NodeProperties::kUnreliableMaps
-diff --git a/test/mjsunit/wasm/regress-367818758.js b/test/mjsunit/wasm/regress-367818758.js
-new file mode 100644
-index 0000000..69e8290
---- /dev/null
-+++ b/test/mjsunit/wasm/regress-367818758.js
-@@ -0,0 +1,221 @@
-+// Copyright 2024 the V8 project authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+//
-+// Flags: --allow-natives-syntax
-+
-+var kWasmH0 = 0;
-+var kWasmH1 = 0x61;
-+var kWasmH2 = 0x73;
-+var kWasmH3 = 0x6d;
-+var kWasmV0 = 0x1;
-+var kWasmV1 = 0;
-+var kWasmV2 = 0;
-+var kWasmV3 = 0;
-+let kTypeSectionCode = 1;        // Function signature declarations
-+let kFunctionSectionCode = 3;    // Function declarations
-+let kExportSectionCode = 7;      // Exports
-+let kCodeSectionCode = 10;       // Function code
-+let kWasmFunctionTypeForm = 0x60;
-+let kWasmStructTypeForm = 0x5f;
-+let kNoSuperType = 0xFFFFFFFF;
-+let kWasmI32 = 0x7f;
-+let kWasmExternRef = -0x11;
-+let kLeb128Mask = 0x7f;
-+let kExternalFunction = 0;
-+function makeSig(params, results) {
-+  return {params: params, results: results};
-+}
-+const kWasmOpcodes = {
-+  'End': 0x0b,
-+  'I32Const': 0x41,
-+};
-+function defineWasmOpcode(name, value) {
-+  Object.defineProperty(globalThis, name, {value: value});
-+}
-+for (let name in kWasmOpcodes) {
-+  defineWasmOpcode(`kExpr${name}`, kWasmOpcodes[name]);
-+}
-+const kPrefixOpcodes = {
-+  'GC': 0xfb,
-+};
-+for (let prefix in kPrefixOpcodes) {
-+  defineWasmOpcode(`k${prefix}Prefix`, kPrefixOpcodes[prefix]);
-+}
-+let kExprStructNew = 0x00;
-+let kExprExternConvertAny = 0x1b;
-+class Binary {
-+  constructor() {
-+    this.length = 0;
-+    this.buffer = new Uint8Array(8192);
-+  }
-+  trunc_buffer() {
-+    return new Uint8Array(this.buffer.buffer, 0, this.length);
-+  }
-+  emit_u8(val) {
-+    this.buffer[this.length++] = val;
-+  }
-+  emit_leb_u(val) {
-+      let v = val & 0xff;
-+        this.buffer[this.length++] = v;
-+  }
-+  emit_u32v(val) {
-+    this.emit_leb_u(val);
-+  }
-+  emit_bytes(data) {
-+    this.buffer.set(data, this.length);
-+    this.length += data.length;
-+  }
-+  emit_string(string) {
-+    let string_utf8 = string;
-+    this.emit_u32v(string_utf8.length);
-+    for (let i = 0; i < string_utf8.length; i++) {
-+      this.emit_u8(string_utf8.charCodeAt(i));
-+    }
-+  }
-+  emit_type(type) {
-+      this.emit_u8(type >= 0 ? type : type & kLeb128Mask);
-+  }
-+  emit_header() {
-+    this.emit_bytes([
-+      kWasmH0, kWasmH1, kWasmH2, kWasmH3, kWasmV0, kWasmV1, kWasmV2, kWasmV3
-+    ]);
-+  }
-+  emit_section(section_code, content_generator) {
-+    this.emit_u8(section_code);
-+    const section = new Binary;
-+    content_generator(section);
-+    this.emit_u32v(section.length);
-+    this.emit_bytes(section.trunc_buffer());
-+  }
-+}
-+class WasmFunctionBuilder {
-+  constructor(module, name, type_index, arg_names) {
-+    this.module = module;
-+    this.name = name;
-+    this.type_index = type_index;
-+  }
-+  exportAs(name) {
-+    this.module.addExport(name, this.index);
-+  }
-+  exportFunc() {
-+    this.exportAs(this.name);
-+    return this;
-+  }
-+  addBody(body) {
-+    this.body = body.concat([kExprEnd]);
-+  }
-+}
-+function makeField(type, mutability) {
-+  return {type: type, mutability: mutability};
-+}
-+class WasmStruct {
-+  constructor(fields) {
-+    this.fields = fields;
-+  }
-+}
-+class WasmModuleBuilder {
-+  constructor() {
-+    this.types = [];
-+    this.exports = [];
-+    this.functions = [];
-+  }
-+  addType(type, supertype_idx = kNoSuperType, is_final = true,
-+      is_shared = false) {
-+    var type_copy = {params: type.params, results: type.results,
-+                     is_final: is_final, is_shared: is_shared,
-+                     supertype: supertype_idx};
-+    this.types.push(type_copy);
-+    return this.types.length - 1;
-+  }
-+  addStruct(fields = kNoSuperType = false, is_shared = false) {
-+    this.types.push(new WasmStruct(fields));
-+  }
-+  addFunction(name, type, arg_names) {
-+    let type_index =typeof type == 'number' ? type : this.addType(type);
-+    let func = new WasmFunctionBuilder(this, name, type_index);
-+    this.functions.push(func);
-+    return func;
-+  }
-+  addExport(name, index) {
-+    this.exports.push({name: name, kind: kExternalFunction, index: index});
-+  }
-+  toBuffer() {
-+    let binary = new Binary;
-+    let wasm = this;
-+    binary.emit_header();
-+      binary.emit_section(kTypeSectionCode, section => {
-+        let length_with_groups = wasm.types.length;
-+        section.emit_u32v(length_with_groups);
-+        for (let i = 0; i < wasm.types.length; i++) {
-+          let type = wasm.types[i];
-+          if (type instanceof WasmStruct) {
-+            section.emit_u8(kWasmStructTypeForm);
-+            section.emit_u32v(type.fields.length);
-+            for (let field of type.fields) {
-+              section.emit_type(field.type);
-+              section.emit_u8();
-+            }
-+          } else {
-+            section.emit_u8(kWasmFunctionTypeForm);
-+            section.emit_u32v();
-+            section.emit_u32v(type.results.length);
-+            for (let result of type.results) {
-+              section.emit_type(result);
-+            }
-+          }
-+        }
-+      });
-+      binary.emit_section(kFunctionSectionCode, section => {
-+        section.emit_u32v(wasm.functions.length);
-+        for (let func of wasm.functions) {
-+          section.emit_u32v(func.type_index);
-+        }
-+      });
-+    var exports_count = wasm.exports.length;
-+      binary.emit_section(kExportSectionCode, section => {
-+        section.emit_u32v(exports_count);
-+        for (let exp of wasm.exports) {
-+          section.emit_string(exp.name);
-+          section.emit_u8();
-+          section.emit_u32v();
-+        }
-+      });
-+      binary.emit_section(kCodeSectionCode, section => {
-+        section.emit_u32v(wasm.functions.length);
-+        for (let func of wasm.functions) {
-+            section.emit_u32v(func.body.length + 1);
-+            section.emit_u8();  // 0 locals.
-+          section.emit_bytes(func.body);
-+        }
-+      });
-+    return binary.trunc_buffer();
-+  }
-+  instantiate() {
-+    let module = this.toModule();
-+    let instance = new WebAssembly.Instance(module);
-+    return instance;
-+  }
-+  toModule() {
-+    return new WebAssembly.Module(this.toBuffer());
-+  }
-+}
-+let builder = new WasmModuleBuilder();
-+let struct_type = builder.addStruct([makeField(kWasmI32)]);
-+builder.addFunction('MakeStruct', makeSig([], [kWasmExternRef])).exportFunc()
-+       .addBody([kExprI32Const, 42, kGCPrefix, kExprStructNew, struct_type,
-+                 kGCPrefix, kExprExternConvertAny]);
-+let instance = builder.instantiate();
-+let evil_wasm_object = instance.exports.MakeStruct();
-+function evil_ctor(){
-+}
-+function evil_cast_jit(evil_o){
-+    global_collect_node_info = evil_o; // get nodeinfo from PropertyCellStore
-+    return evil_o instanceof evil_ctor;
-+}
-+evil_ctor.prototype = evil_wasm_object;
-+%PrepareFunctionForOptimization(evil_cast_jit);
-+evil_cast_jit(new evil_ctor());
-+evil_cast_jit(new evil_ctor());
-+%OptimizeFunctionOnNextCall(evil_cast_jit);
-+evil_cast_jit();

+ 0 - 146
patches/v8/cherry-pick-9542895cdd3d.patch

@@ -1,146 +0,0 @@
-From 9542895cdd3dbd97da3d9032ddb36fd4feb612e4 Mon Sep 17 00:00:00 2001
-From: Jakob Kummerow <[email protected]>
-Date: Tue, 24 Sep 2024 17:34:49 +0200
-Subject: [PATCH] [wasm][streaming] Properly check max module size
-
-and allow d8-based tests for it.
-
-Fixed: 368241697
-Change-Id: Iddc9f7e669de7a1d79dccbc99bcc5fb43dad67a1
-Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5886728
-Reviewed-by: Clemens Backes <[email protected]>
-Reviewed-by: Matthias Liedtke <[email protected]>
-Auto-Submit: Jakob Kummerow <[email protected]>
-Commit-Queue: Jakob Kummerow <[email protected]>
-Cr-Commit-Position: refs/heads/main@{#96272}
----
-
-diff --git a/src/wasm/streaming-decoder.cc b/src/wasm/streaming-decoder.cc
-index 40a1180..f3745b4 100644
---- a/src/wasm/streaming-decoder.cc
-+++ b/src/wasm/streaming-decoder.cc
-@@ -294,6 +294,10 @@
-   if (!full_wire_bytes_.back().empty()) {
-     size_t total_length = 0;
-     for (auto& bytes : full_wire_bytes_) total_length += bytes.size();
-+    if (ok()) {
-+      // {DecodeSectionLength} enforces this with graceful error reporting.
-+      CHECK_LE(total_length, max_module_size());
-+    }
-     auto all_bytes = base::OwnedVector<uint8_t>::NewForOverwrite(total_length);
-     uint8_t* ptr = all_bytes.begin();
-     for (auto& bytes : full_wire_bytes_) {
-@@ -627,6 +631,18 @@
- AsyncStreamingDecoder::DecodeSectionLength::NextWithValue(
-     AsyncStreamingDecoder* streaming) {
-   TRACE_STREAMING("DecodeSectionLength(%zu)\n", value_);
-+  // Check if this section fits into the overall module length limit.
-+  // Note: {this->module_offset_} is the position of the section ID byte,
-+  // {streaming->module_offset_} is the start of the section's payload (i.e.
-+  // right after the just-decoded section length varint).
-+  // The latter can already exceed the max module size, when the previous
-+  // section barely fit into it, and this new section's ID or length crossed
-+  // the threshold.
-+  uint32_t payload_start = streaming->module_offset();
-+  size_t max_size = max_module_size();
-+  if (payload_start > max_size || max_size - payload_start < value_) {
-+    return streaming->ToErrorState();
-+  }
-   SectionBuffer* buf =
-       streaming->CreateNewBuffer(module_offset_, section_id_, value_,
-                                  buffer().SubVector(0, bytes_consumed_));
-diff --git a/src/wasm/wasm-engine.cc b/src/wasm/wasm-engine.cc
-index 94f1cc2..5d989e8 100644
---- a/src/wasm/wasm-engine.cc
-+++ b/src/wasm/wasm-engine.cc
-@@ -2088,10 +2088,11 @@
- 
- // {max_module_size} is declared in wasm-limits.h.
- size_t max_module_size() {
--  // Clamp the value of --wasm-max-module-size between 16 and just below 2GB.
-+  // Clamp the value of --wasm-max-module-size between 16 and the maximum
-+  // that the implementation supports.
-   constexpr size_t kMin = 16;
--  constexpr size_t kMax = RoundDown<kSystemPointerSize>(size_t{kMaxInt});
--  static_assert(kMin <= kV8MaxWasmModuleSize && kV8MaxWasmModuleSize <= kMax);
-+  constexpr size_t kMax = kV8MaxWasmModuleSize;
-+  static_assert(kMin <= kV8MaxWasmModuleSize);
-   return std::clamp(v8_flags.wasm_max_module_size.value(), kMin, kMax);
- }
- 
-diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc
-index cf05965..4b77039 100644
---- a/src/wasm/wasm-js.cc
-+++ b/src/wasm/wasm-js.cc
-@@ -202,8 +202,8 @@
- #undef GET_FIRST_ARGUMENT_AS
- 
- i::wasm::ModuleWireBytes GetFirstArgumentAsBytes(
--    const v8::FunctionCallbackInfo<v8::Value>& info, ErrorThrower* thrower,
--    bool* is_shared) {
-+    const v8::FunctionCallbackInfo<v8::Value>& info, size_t max_length,
-+    ErrorThrower* thrower, bool* is_shared) {
-   DCHECK(i::ValidateCallbackInfo(info));
-   const uint8_t* start = nullptr;
-   size_t length = 0;
-@@ -234,7 +234,6 @@
-   if (length == 0) {
-     thrower->CompileError("BufferSource argument is empty");
-   }
--  size_t max_length = i::wasm::max_module_size();
-   if (length > max_length) {
-     // The spec requires a CompileError for implementation-defined limits, see
-     // https://webassembly.github.io/spec/js-api/index.html#limits.
-@@ -644,7 +643,8 @@
-       new AsyncCompilationResolver(isolate, context, promise_resolver));
- 
-   bool is_shared = false;
--  auto bytes = GetFirstArgumentAsBytes(info, &thrower, &is_shared);
-+  auto bytes = GetFirstArgumentAsBytes(info, i::wasm::max_module_size(),
-+                                       &thrower, &is_shared);
-   if (thrower.error()) {
-     resolver->OnCompilationFailed(thrower.Reify());
-     return;
-@@ -676,8 +676,11 @@
-       v8::WasmStreaming::Unpack(info.GetIsolate(), info.Data());
- 
-   bool is_shared = false;
-+  // We don't check the buffer length up front, to allow d8 to test that the
-+  // streaming decoder implementation handles overly large inputs correctly.
-+  size_t unlimited = std::numeric_limits<size_t>::max();
-   i::wasm::ModuleWireBytes bytes =
--      GetFirstArgumentAsBytes(info, &thrower, &is_shared);
-+      GetFirstArgumentAsBytes(info, unlimited, &thrower, &is_shared);
-   if (thrower.error()) {
-     streaming->Abort(Utils::ToLocal(thrower.Reify()));
-     return;
-@@ -778,7 +781,8 @@
-   ErrorThrower thrower(i_isolate, "WebAssembly.validate()");
- 
-   bool is_shared = false;
--  auto bytes = GetFirstArgumentAsBytes(info, &thrower, &is_shared);
-+  auto bytes = GetFirstArgumentAsBytes(info, i::wasm::max_module_size(),
-+                                       &thrower, &is_shared);
- 
-   v8::ReturnValue<v8::Value> return_value = info.GetReturnValue();
- 
-@@ -857,7 +861,8 @@
-   }
- 
-   bool is_shared = false;
--  auto bytes = GetFirstArgumentAsBytes(info, &thrower, &is_shared);
-+  auto bytes = GetFirstArgumentAsBytes(info, i::wasm::max_module_size(),
-+                                       &thrower, &is_shared);
- 
-   if (thrower.error()) {
-     return;
-@@ -1175,7 +1180,8 @@
-   }
- 
-   bool is_shared = false;
--  auto bytes = GetFirstArgumentAsBytes(info, &thrower, &is_shared);
-+  auto bytes = GetFirstArgumentAsBytes(info, i::wasm::max_module_size(),
-+                                       &thrower, &is_shared);
-   if (thrower.error()) {
-     resolver->OnInstantiationFailed(thrower.Reify());
-     return;