Skip to content

Commit aae80db

Browse files
committed
refactor: migrate require_internal_slot! from downcast_ref to downcast
Switch the require_internal_slot! macro to use JsObject::downcast instead of downcast_ref, returning JsObject<T> (owned handle) rather than Ref<T>. This prevents GcRefCell borrow panics by ensuring borrows are only held for the duration of specific read/write operations. Updated all call sites across 20 built-in modules to use .borrow().data() / .borrow_mut().data_mut() for inner field access: - Date (renamed macro binding to date_obj in setters to avoid shadowing) - Temporal (Duration, Instant, PlainDate, PlainDateTime, PlainTime, PlainMonthDay, PlainYearMonth, ZonedDateTime) - ArrayBuffer, SharedArrayBuffer, DataView, TypedArray - WeakRef, WeakMap, WeakSet - Intl (Collator, Segmenter, Segments)
1 parent fb5096a commit aae80db

File tree

20 files changed

+729
-644
lines changed

20 files changed

+729
-644
lines changed

core/engine/src/builtins/array_buffer/mod.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -496,12 +496,12 @@ impl ArrayBuffer {
496496
// 1. Let O be the this value.
497497
// 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
498498
// 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
499-
require_internal_slot!(buf = this, Self, "ArrayBuffer");
499+
let buf = require_internal_slot!(this, Self, "ArrayBuffer");
500500

501501
// 4. If IsDetachedBuffer(O) is true, return +0𝔽.
502502
// 5. Let length be O.[[ArrayBufferByteLength]].
503503
// 6. Return 𝔽(length).
504-
Ok(buf.len().into())
504+
Ok(buf.borrow().data().len().into())
505505
}
506506

507507
/// [`get ArrayBuffer.prototype.maxByteLength`][spec].
@@ -515,10 +515,12 @@ impl ArrayBuffer {
515515
// 1. Let O be the this value.
516516
// 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
517517
// 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
518-
require_internal_slot!(buf = this, Self, "ArrayBuffer");
518+
let buf = require_internal_slot!(this, Self, "ArrayBuffer");
519519

520520
// 4. If IsDetachedBuffer(O) is true, return +0𝔽.
521-
let Some(data) = buf.bytes() else {
521+
let buf_data = buf.borrow();
522+
let buf_data = buf_data.data();
523+
let Some(data) = buf_data.bytes() else {
522524
return Ok(JsValue::from(0));
523525
};
524526

@@ -527,7 +529,7 @@ impl ArrayBuffer {
527529
// 6. Else,
528530
// a. Let length be O.[[ArrayBufferMaxByteLength]].
529531
// 7. Return 𝔽(length).
530-
Ok(buf.max_byte_len.unwrap_or(data.len() as u64).into())
532+
Ok(buf_data.max_byte_len.unwrap_or(data.len() as u64).into())
531533
}
532534

533535
/// [`get ArrayBuffer.prototype.resizable`][spec].
@@ -541,10 +543,10 @@ impl ArrayBuffer {
541543
// 1. Let O be the this value.
542544
// 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
543545
// 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
544-
require_internal_slot!(buf = this, Self, "ArrayBuffer");
546+
let buf = require_internal_slot!(this, Self, "ArrayBuffer");
545547

546548
// 4. If IsFixedLengthArrayBuffer(O) is false, return true; otherwise return false.
547-
Ok(JsValue::from(!buf.is_fixed_len()))
549+
Ok(JsValue::from(!buf.borrow().data().is_fixed_len()))
548550
}
549551

550552
/// [`get ArrayBuffer.prototype.detached`][spec].
@@ -559,10 +561,10 @@ impl ArrayBuffer {
559561
// 1. Let O be the this value.
560562
// 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
561563
// 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
562-
require_internal_slot!(buf = this, Self, "ArrayBuffer");
564+
let buf = require_internal_slot!(this, Self, "ArrayBuffer");
563565

564566
// 4. Return IsDetachedBuffer(O).
565-
Ok(buf.is_detached().into())
567+
Ok(buf.borrow().data().is_detached().into())
566568
}
567569

568570
/// [`ArrayBuffer.prototype.resize ( newLength )`][spec].

core/engine/src/builtins/array_buffer/shared.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,10 @@ impl SharedArrayBuffer {
225225
// 1. Let O be the this value.
226226
// 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
227227
// 3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
228-
require_internal_slot!(buf = this, Self, "SharedArrayBuffer");
228+
let buf = require_internal_slot!(this, Self, "SharedArrayBuffer");
229229

230230
// 4. Let length be ArrayBufferByteLength(O, seq-cst).
231-
let len = buf.bytes(Ordering::SeqCst).len() as u64;
231+
let len = buf.borrow().data().bytes(Ordering::SeqCst).len() as u64;
232232

233233
// 5. Return 𝔽(length).
234234
Ok(len.into())
@@ -245,10 +245,10 @@ impl SharedArrayBuffer {
245245
// 1. Let O be the this value.
246246
// 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
247247
// 3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
248-
require_internal_slot!(buf = this, Self, "SharedArrayBuffer");
248+
let buf = require_internal_slot!(this, Self, "SharedArrayBuffer");
249249

250250
// 4. If IsFixedLengthArrayBuffer(O) is false, return true; otherwise return false.
251-
Ok(JsValue::from(!buf.is_fixed_len()))
251+
Ok(JsValue::from(!buf.borrow().data().is_fixed_len()))
252252
}
253253

254254
/// [`get SharedArrayBuffer.prototype.maxByteLength`][spec].
@@ -262,14 +262,14 @@ impl SharedArrayBuffer {
262262
// 1. Let O be the this value.
263263
// 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
264264
// 3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
265-
require_internal_slot!(buf = this, Self, "SharedArrayBuffer");
265+
let buf = require_internal_slot!(this, Self, "SharedArrayBuffer");
266266

267267
// 4. If IsFixedLengthArrayBuffer(O) is true, then
268268
// a. Let length be O.[[ArrayBufferByteLength]].
269269
// 5. Else,
270270
// a. Let length be O.[[ArrayBufferMaxByteLength]].
271271
// 6. Return 𝔽(length).
272-
Ok(buf.data.buffer.len().into())
272+
Ok(buf.borrow().data().data.buffer.len().into())
273273
}
274274

275275
/// [`SharedArrayBuffer.prototype.grow ( newLength )`][spec].

core/engine/src/builtins/dataview/mod.rs

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -331,10 +331,11 @@ impl DataView {
331331
) -> JsResult<JsValue> {
332332
// 1. Let O be the this value.
333333
// 2. Perform ? RequireInternalSlot(O, [[DataView]]).
334-
require_internal_slot!(view = this, Self, "DataView");
334+
let view = require_internal_slot!(this, Self, "DataView");
335335
// 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
336336
// 4. Let buffer be O.[[ViewedArrayBuffer]].
337-
let buffer = view.viewed_array_buffer.clone();
337+
let view_data = view.borrow();
338+
let buffer = view_data.data().viewed_array_buffer.clone();
338339
// 5. Return buffer.
339340
Ok(buffer.into())
340341
}
@@ -357,22 +358,24 @@ impl DataView {
357358
// 1. Let O be the this value.
358359
// 2. Perform ? RequireInternalSlot(O, [[DataView]]).
359360
// 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
360-
require_internal_slot!(view = this, Self, "DataView");
361+
let view = require_internal_slot!(this, Self, "DataView");
361362

362363
// 4. Let viewRecord be MakeDataViewWithBufferWitnessRecord(O, seq-cst).
363364
// 5. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
364-
let buffer = view.viewed_array_buffer.as_buffer();
365+
let view_data = view.borrow();
366+
let buffer = view_data.data().viewed_array_buffer.as_buffer();
365367
let Some(slice) = buffer
366368
.bytes(Ordering::SeqCst)
367-
.filter(|s| !view.is_out_of_bounds(s.len()))
369+
.filter(|s| !view.borrow().data().is_out_of_bounds(s.len()))
368370
else {
369371
return Err(JsNativeError::typ()
370372
.with_message("view out of bounds for its inner buffer")
371373
.into());
372374
};
373375

374376
// 6. Let size be GetViewByteLength(viewRecord).
375-
let size = view.byte_length(slice.len());
377+
let view_data = view.borrow();
378+
let size = view_data.data().byte_length(slice.len());
376379

377380
// 7. Return 𝔽(size).
378381
Ok(size.into())
@@ -396,15 +399,16 @@ impl DataView {
396399
) -> JsResult<JsValue> {
397400
// 1. Let O be the this value.
398401
// 2. Perform ? RequireInternalSlot(O, [[DataView]]).
399-
require_internal_slot!(view = this, Self, "DataView");
402+
let view = require_internal_slot!(this, Self, "DataView");
400403

401404
// 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
402-
let buffer = view.viewed_array_buffer.as_buffer();
405+
let view_data = view.borrow();
406+
let buffer = view_data.data().viewed_array_buffer.as_buffer();
403407
// 4. Let viewRecord be MakeDataViewWithBufferWitnessRecord(O, seq-cst).
404408
// 5. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
405409
if buffer
406410
.bytes(Ordering::SeqCst)
407-
.filter(|b| !view.is_out_of_bounds(b.len()))
411+
.filter(|b| !view.borrow().data().is_out_of_bounds(b.len()))
408412
.is_none()
409413
{
410414
return Err(JsNativeError::typ()
@@ -413,7 +417,8 @@ impl DataView {
413417
}
414418

415419
// 6. Let offset be O.[[ByteOffset]].
416-
let offset = view.byte_offset;
420+
let view_data = view.borrow();
421+
let offset = view_data.data().byte_offset;
417422
// 7. Return 𝔽(offset).
418423
Ok(offset.into())
419424
}
@@ -436,7 +441,7 @@ impl DataView {
436441
) -> JsResult<JsValue> {
437442
// 1. Perform ? RequireInternalSlot(view, [[DataView]]).
438443
// 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
439-
require_internal_slot!(view = view, Self, "DataView");
444+
let view = require_internal_slot!(view, Self, "DataView");
440445

441446
// 3. Let getIndex be ? ToIndex(requestIndex).
442447
let get_index = request_index.to_index(context)?;
@@ -447,21 +452,24 @@ impl DataView {
447452
// 6. Let viewRecord be MakeDataViewWithBufferWitnessRecord(view, unordered).
448453
// 7. NOTE: Bounds checking is not a synchronizing operation when view's backing buffer is a growable SharedArrayBuffer.
449454
// 8. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
450-
let buffer = view.viewed_array_buffer.as_buffer();
455+
let view_data = view.borrow();
456+
let buffer = view_data.data().viewed_array_buffer.as_buffer();
451457
let Some(data) = buffer
452458
.bytes(Ordering::Relaxed)
453-
.filter(|buf| !view.is_out_of_bounds(buf.len()))
459+
.filter(|buf| !view.borrow().data().is_out_of_bounds(buf.len()))
454460
else {
455461
return Err(JsNativeError::typ()
456462
.with_message("view out of bounds for its inner buffer")
457463
.into());
458464
};
459465

460466
// 5. Let viewOffset be view.[[ByteOffset]].
461-
let view_offset = view.byte_offset;
467+
let view_data = view.borrow();
468+
let view_offset = view_data.data().byte_offset;
462469

463470
// 9. Let viewSize be GetViewByteLength(viewRecord).
464-
let view_size = view.byte_length(data.len());
471+
let view_data = view.borrow();
472+
let view_size = view_data.data().byte_length(data.len());
465473

466474
// 10. Let elementSize be the Element Size value specified in Table 71 for Element Type type.
467475
let element_size = size_of::<T>() as u64;
@@ -774,7 +782,7 @@ impl DataView {
774782
) -> JsResult<JsValue> {
775783
// 1. Perform ? RequireInternalSlot(view, [[DataView]]).
776784
// 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
777-
require_internal_slot!(view = view, Self, "DataView");
785+
let view = require_internal_slot!(view, Self, "DataView");
778786

779787
// 3. Let getIndex be ? ToIndex(requestIndex).
780788
let get_index = request_index.to_index(context)?;
@@ -789,22 +797,28 @@ impl DataView {
789797
// 8. Let viewRecord be MakeDataViewWithBufferWitnessRecord(view, unordered).
790798
// 9. NOTE: Bounds checking is not a synchronizing operation when view's backing buffer is a growable SharedArrayBuffer.
791799
// 10. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
792-
let mut buffer = view.viewed_array_buffer.as_buffer_mut();
800+
let viewed_buffer = {
801+
let view_data = view.borrow();
802+
view_data.data().viewed_array_buffer.clone()
803+
};
804+
let mut buffer = viewed_buffer.as_buffer_mut();
793805

794806
let Some(mut data) = buffer
795807
.bytes(Ordering::Relaxed)
796-
.filter(|buf| !view.is_out_of_bounds(buf.len()))
808+
.filter(|buf| !view.borrow().data().is_out_of_bounds(buf.len()))
797809
else {
798810
return Err(JsNativeError::typ()
799811
.with_message("view out of bounds for its inner buffer")
800812
.into());
801813
};
802814

803815
// 11. Let viewSize be GetViewByteLength(viewRecord).
804-
let view_size = view.byte_length(data.len());
816+
let view_data = view.borrow();
817+
let view_size = view_data.data().byte_length(data.len());
805818

806819
// 7. Let viewOffset be view.[[ByteOffset]].
807-
let view_offset = view.byte_offset;
820+
let view_data = view.borrow();
821+
let view_offset = view_data.data().byte_offset;
808822

809823
// 12. Let elementSize be the Element Size value specified in Table 71 for Element Type type.
810824
let elem_size = size_of::<T>();

0 commit comments

Comments
 (0)