Skip to content

Conversation

@JakeChampion
Copy link
Contributor

This is part of the solution for #113 - that issue shows that all our built-in classes are not extendable within applications' JavaScript.

This pull-request changes our Request to use JS_NewObjectForConstructor when the construction has come from the applications' JavaScript, which assigns the correct prototype to the instance being constructed (taking into account extends in JavaScript)

I've also added a test which confirms that the correct prototype has been assigned when extending from Request

bool constructor(JSContext *cx, unsigned argc, Value *vp) {
REQUEST_HANDLER_ONLY("The Request builtin");
CTOR_HEADER("Request", 1);
RootedObject requestInstance(cx, JS_NewObjectForConstructor(cx, &class_, args));
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 had to move the constructor to below the use of the class macro because the constructor implementation now needs access to &class_ which is defined within the class macro

Comment on lines 4208 to 4215
JSObject *create(JSContext *cx, RequestHandle request_handle, BodyHandle body_handle,
bool is_downstream) {
RootedObject request(cx, JS_NewObjectWithGivenProto(cx, &class_, proto_obj));
if (!request)
RootedObject requestInstance(cx, JS_NewObjectWithGivenProto(cx, &class_, proto_obj));
if (!requestInstance)
return nullptr;

JS::SetReservedSlot(request, Slots::Request, JS::Int32Value(request_handle.handle));
JS::SetReservedSlot(request, Slots::Headers, JS::NullValue());
JS::SetReservedSlot(request, Slots::Body, JS::Int32Value(body_handle.handle));
JS::SetReservedSlot(request, Slots::BodyStream, JS::NullValue());
JS::SetReservedSlot(request, Slots::HasBody, JS::FalseValue());
JS::SetReservedSlot(request, Slots::BodyUsed, JS::FalseValue());
JS::SetReservedSlot(request, Slots::Method, JS::StringValue(GET_atom));
JS::SetReservedSlot(request, Slots::CacheOverride, JS::NullValue());
JS::SetReservedSlot(request, Slots::IsDownstream, JS::BooleanValue(is_downstream));
return Request::create(cx, requestInstance, request_handle, body_handle, is_downstream);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method exists for use within the prepare_downstream_request function, which should always use the runtime's Request implementation and not one which could be supplied by the applications' JS

Copy link
Contributor

@elliottt elliottt left a comment

Choose a reason for hiding this comment

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

This looks great! I had one question about the new create overload introduced, but feel free to reply and merge if it's benign.

…s instead of JS_NewObjectWithGivenProto as JS_NewObjectForConstructor will use the callee to determine parentage and

[[Prototype]], which allows applications to extend from Request
@JakeChampion JakeChampion force-pushed the jake/extend-builtins branch from ffb443e to f61ebe2 Compare June 21, 2022 10:59
@JakeChampion JakeChampion merged commit c7f07bf into main Jun 21, 2022
@JakeChampion JakeChampion deleted the jake/extend-builtins branch June 21, 2022 11:31
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.

3 participants