mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Don't slice a sliced blob (#36866)
When slicing a blob that is already sliced we should reference it's parent's data instead of creating a subview into the sliced blob. This keeps the blob ancestry chain small and reduces the number of blobs that we have to resolve. Testing: Includes a new crashtest Fixes: https://github.com/servo/servo/issues/36843 [try run](https://github.com/simonwuelker/servo/actions/runs/14844873660) --------- Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
parent
3b806ca424
commit
54c2818974
7 changed files with 76 additions and 69 deletions
|
@ -7,7 +7,7 @@ use std::ptr;
|
|||
use std::rc::Rc;
|
||||
|
||||
use base::id::{BlobId, BlobIndex};
|
||||
use constellation_traits::BlobImpl;
|
||||
use constellation_traits::{BlobData, BlobImpl};
|
||||
use dom_struct::dom_struct;
|
||||
use encoding_rs::UTF_8;
|
||||
use js::jsapi::JSObject;
|
||||
|
@ -33,7 +33,7 @@ use crate::dom::readablestream::ReadableStream;
|
|||
use crate::realms::{AlreadyInRealm, InRealm};
|
||||
use crate::script_runtime::CanGc;
|
||||
|
||||
// https://w3c.github.io/FileAPI/#blob
|
||||
/// <https://w3c.github.io/FileAPI/#dfn-Blob>
|
||||
#[dom_struct]
|
||||
pub(crate) struct Blob {
|
||||
reflector_: Reflector,
|
||||
|
@ -198,7 +198,7 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
|
|||
self.get_stream(can_gc)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/FileAPI/#slice-method-algo
|
||||
/// <https://w3c.github.io/FileAPI/#slice-method-algo>
|
||||
fn Slice(
|
||||
&self,
|
||||
start: Option<i64>,
|
||||
|
@ -206,11 +206,24 @@ impl BlobMethods<crate::DomTypeHolder> for Blob {
|
|||
content_type: Option<DOMString>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<Blob> {
|
||||
let type_string =
|
||||
normalize_type_string(content_type.unwrap_or(DOMString::from("")).as_ref());
|
||||
let rel_pos = RelativePos::from_opts(start, end);
|
||||
let blob_impl = BlobImpl::new_sliced(rel_pos, self.blob_id, type_string);
|
||||
Blob::new(&self.global(), blob_impl, can_gc)
|
||||
let global = self.global();
|
||||
let type_string = normalize_type_string(&content_type.unwrap_or_default());
|
||||
|
||||
// If our parent is already a sliced blob then we reference the data from the grandparent instead,
|
||||
// to keep the blob ancestry chain short.
|
||||
let (parent, range) = match *global.get_blob_data(&self.blob_id) {
|
||||
BlobData::Sliced(grandparent, parent_range) => {
|
||||
let range = RelativePos {
|
||||
start: parent_range.start + start.unwrap_or_default(),
|
||||
end: end.map(|end| end + parent_range.start).or(parent_range.end),
|
||||
};
|
||||
(grandparent, range)
|
||||
},
|
||||
_ => (self.blob_id, RelativePos::from_opts(start, end)),
|
||||
};
|
||||
|
||||
let blob_impl = BlobImpl::new_sliced(range, parent, type_string);
|
||||
Blob::new(&global, blob_impl, can_gc)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/FileAPI/#text-method-algo
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue