Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fetch): accept arraybuffer in consume_body #20406

Merged
merged 4 commits into from Mar 24, 2018

Conversation

kwonoj
Copy link
Contributor

@kwonoj kwonoj commented Mar 23, 2018

Related to #20346.

I realized I am not sufficiently knowledgeable about codebases and have high confidence this PR is not ready to be accepted. Raising it as PR early to possibly ask some suggestions around codebases.

If this PR seems unrecoverable by code review, please feel freely close and unassign me from issue 🙏

This PR tries to implement #20346, updating Body idl and implements corresponding implementation in body.rs for fetch. Criteria for changes may includes

  • does run_array_buffer_data_algorithm implementation is legit for allocating arraybuffer? (probably not)
  • does run_array_buffer_data_algorithm implementation is acceptable for handling error, by naively returning Error::JSFailed?
  • there are some number of wpt test started to PASS with this PR. Is this legit side effect, or something incorrect by current implementation?
  • etcs, vice versa

  • There are tests for these changes OR
  • These changes do not require tests because _____
  • wpt test has changed in PR, need to be reviewed.

This change is Reviewable

@jdm jdm added the S-awaiting-review There is new code that needs to be reviewed. label Mar 24, 2018
@jdm jdm self-assigned this Mar 24, 2018
Copy link
Member

@jdm jdm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your code was doing the right thing, just not in the most efficient way. All of the tests that now pass are tests that were either directly testing the arrayBuffer() behaviour or relying on arrayBuffer() to test the behaviour of the Fetch API, so this is a great result!

}

pub enum FetchedData {
Text(String),
Json(JSValue),
BlobData(DomRoot<Blob>),
FormData(DomRoot<FormData>),
ArrayBuffer(Heap<JSVal>),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To ensure this code is GC-safe, we should use RootedTraceableBox<Heap<JSVal>>, and use it for the Json variant as well.

}

// https://fetch.spec.whatwg.org/#concept-body-consume-body
#[allow(unrooted_must_root)]
pub fn consume_body<T: BodyOperations + DomObject>(object: &T, body_type: BodyType) -> Rc<Promise> {
let promise = Promise::new(&object.global());


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove this blank line.

@@ -166,6 +176,26 @@ fn run_form_data_algorithm(root: &GlobalScope, bytes: Vec<u8>, mime: &[u8]) -> F
}
}

#[allow(unsafe_code)]
fn run_array_buffer_data_algorithm(cx: *mut JSContext, bytes: Vec<u8>) -> Fallible<FetchedData> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should be marked unsafe, since it accepts a raw pointer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've specified unsafe scope here as similar to other places - mainly cause specifying fn itself as unsafe will raises compilation error as unsafe invocation is propagated in line 116.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New errors are fine; we can add #[allow(unsafe_code)] on the containing functions. We want to avoid declaring functions as safe when it is trivially possible to pass an invalid pointer that would trigger a crash.

unsafe {
match ArrayBuffer::create(cx, CreateWith::Slice(&bytes), array_buffer_ptr.handle_mut()) {
Ok(_) => {
let mut arraybuffer = Some(FetchedData::ArrayBuffer(Heap::default()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is a bit jumbled, but the basic idea is correct. What about:

rooted!(in(cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>());
let arraybuffer = ArrayBuffer::create(cx, CreateWith::Slice(&bytes), array_buffer_ptr.handle_mut());
if arraybuffer.is_err() {
    return Err(Error::JSFailed);
}
let rooted_heap = RootedTraceableBox::from_box(Heap::boxed(array_buffer_ptr.get()));
Ok(FetchedData::ArrayBuffer(rooted_heap))

@jdm jdm added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Mar 24, 2018
@kwonoj kwonoj force-pushed the feat-fetch-body-arraybuffer branch from 2a12369 to f2b0cd4 Compare March 24, 2018 06:44
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Mar 24, 2018
Copy link
Contributor Author

@kwonoj kwonoj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdm Appreciate for taking time to review! 🙇‍♂️ I tried to update code as much as suggested, and left few question / comments around changes.

@@ -166,6 +176,26 @@ fn run_form_data_algorithm(root: &GlobalScope, bytes: Vec<u8>, mime: &[u8]) -> F
}
}

#[allow(unsafe_code)]
fn run_array_buffer_data_algorithm(cx: *mut JSContext, bytes: Vec<u8>) -> Fallible<FetchedData> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've specified unsafe scope here as similar to other places - mainly cause specifying fn itself as unsafe will raises compilation error as unsafe invocation is propagated in line 116.

if arraybuffer.is_err() {
return Err(Error::JSFailed);
}
let rooted_heap = RootedTraceableBox::from_box(Heap::boxed(jsval::ObjectValue(array_buffer_ptr.get())));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appreciate for suggestion and tried to update code as suggested, except creating boxed heap using ObjectValue - since type of ArrayBuffer is RootedTraceableBox<Heap<JSVal>>, using ptr directly creates RootedTraceableBox<Heap<mut *JSObject>>.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, let's make it a bit cleaner then - store RootedTraceableBox<Heap<*mut JSObject>> and get rid of the jsval::ObjectValue.

}

pub enum FetchedData {
Text(String),
Json(JSValue),
BlobData(DomRoot<Blob>),
FormData(DomRoot<FormData>),
ArrayBuffer(RootedTraceableBox<Heap<JSVal>>),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm bit unsure if I understood #20406 (comment) fully around use it for the Json variant as well. - would you mind elaborate bit more?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean that the existing Json(JSValue) is similarly GC-unsafe, and it should store a RootedTraceableBox<Heap<JSVal>> instead.

@jdm jdm added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Mar 24, 2018
@kwonoj kwonoj force-pushed the feat-fetch-body-arraybuffer branch from f2b0cd4 to 80304a1 Compare March 24, 2018 15:57
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Mar 24, 2018
Copy link
Contributor Author

@kwonoj kwonoj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdm now type for Arraybuffer updated to Heap<*mut JSObect>, also added commit for updating types for JSON as well.

}

pub enum FetchedData {
Text(String),
Json(JSValue),
Json(RootedTraceableBox<Heap<JSValue>>),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated Json to store RootedTraceableBox<Heap> as suggested. Still it stores JSValue instead of JSVal, by JSVal doesn't meet trait bounds for RootedTraceableBox.

@@ -104,6 +112,9 @@ fn run_package_data_algorithm<T: BodyOperations + DomObject>(object: &T,
BodyType::Json => run_json_data_algorithm(cx, bytes),
BodyType::Blob => run_blob_data_algorithm(&global, bytes, mime),
BodyType::FormData => run_form_data_algorithm(&global, bytes, mime),
BodyType::ArrayBuffer => unsafe {
run_array_buffer_data_algorithm(cx, bytes)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now run_array_buffer_data_algorithm is declared as unsafe fn, and this match arm uses unsafe scope.

@jdm
Copy link
Member

jdm commented Mar 24, 2018

@bors-servo r+
Thanks!

@bors-servo
Copy link
Contributor

📌 Commit 80304a1 has been approved by jdm

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. labels Mar 24, 2018
@@ -1,5 +1,3 @@
[response-stream-disturbed-5.html]
type: testharness
[Getting a body reader after consuming as arrayBuffer]
expected: FAIL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this file be deleted altogether?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be automatically in the future.

@bors-servo
Copy link
Contributor

⌛ Testing commit 80304a1 with merge 23b2f42...

bors-servo pushed a commit that referenced this pull request Mar 24, 2018
feat(fetch): accept arraybuffer in consume_body

<!-- Please describe your changes on the following line: -->
Related to #20346.

I realized I am not sufficiently knowledgeable about codebases and have high confidence this PR is not ready to be accepted. Raising it as PR early to possibly ask some suggestions around codebases.

If this PR seems unrecoverable by code review, please feel freely close and unassign me from issue 🙏

This PR tries to implement #20346, updating `Body` idl and implements corresponding implementation in `body.rs` for `fetch`. Criteria for changes may includes

- does `run_array_buffer_data_algorithm` implementation is legit for allocating arraybuffer? (probably not)
- does `run_array_buffer_data_algorithm` implementation is acceptable for handling error, by naively returning `Error::JSFailed`?
- there are some number of wpt test started to PASS with this PR. Is this legit side effect, or something incorrect by current implementation?
- etcs, vice versa

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #20346 (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
- wpt test has changed in PR, need to be reviewed.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20406)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

☀️ Test successful - android, arm32, arm64, linux-dev, linux-rel-css, linux-rel-wpt, mac-dev-unit, mac-rel-css1, mac-rel-css2, mac-rel-wpt1, mac-rel-wpt2, mac-rel-wpt3, mac-rel-wpt4, windows-msvc-dev
Approved by: jdm
Pushing 23b2f42 to master...

@bors-servo bors-servo merged commit 80304a1 into servo:master Mar 24, 2018
@highfive highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Mar 24, 2018
@kwonoj kwonoj deleted the feat-fetch-body-arraybuffer branch March 27, 2018 05:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement the arraybuffer API for Fetch bodies
5 participants