boa
boa copied to clipboard
Should some object-specific operations be moved out of GcObject?
At some point (when working on the stack) we will need to operate on objects which are not GC managed. These would be objects that can live on the stack.
We have some functionality (such as call_construct
) living in GcObject and not in Object, does anyone know why this is?
My expectation is that all object functionality lives in Object, then GCObject acts as a GC wrapper (plus only has GC related functionality)
I agree with the sentiment. It is confusing that you can call some funcions directly from GcObject
but can't call several others without borrow()
. However, methods like https://github.com/boa-dev/boa/blob/a7ebfc8f3a7918166b2e5d959e8ca264a9c5936e/boa/src/object/internal_methods.rs#L109-L117 that self clone the Gc
reference makes refactoring a bit complicated. We have several options to solve this:
-
Move all
Object
methods toGcObject
. Now every method is centralized on a single place but this doesn't solve the problem about objects living on the stack. -
Separate internal object methods (
[[get]]
,[[set]]
, OrdinaryGet, OrdinarySet, etc.) from object operations (Get
,Set
,CreateProperty
). Internal methods would live onObject
, while object operations would live onGcObject
. However, this doesn't solve the problem about objects that live on the stack, so when those arrive we would need to refactorGcObject
again to extract the operations. -
The same solution as the previous one, but ditch the
GcObject
internal methods and create free functions that take object references as arguments. Maybe possibly create anObjectRef
trait thatGcObject
andStackObject
implement and make the functions generic. This solution follows more closely the spec and has the advantage of being very easy to refactor when stack objects arrive.
At some point (when working on the stack) we will need to operate on objects which are not GC managed. These would be objects that can live on the stack.
We have some functionality (such as
call_construct
) living in GcObject and not in Object, does anyone know why this is? My expectation is that all object functionality lives in Object, then GCObject acts as a GC wrapper (plus only has GC related functionality)
I don't think we can have this, since the way that objects are used implies they need to live into a well known location. For example if we create a object on the stack and clone it, first of all objects should shallow copy, and the object are not the same, even through they should, objects should only check if the pointer is the same not content.
Even with call_construct
we need to clone object to put it in environments. To even use an object in javascript it has to be converted to a value which has to be on the heap anyway.
Putting it on the stack would complicate and make some spec functionality impossible, that is why I moved operations to GcObject
(#835)
At some point (when working on the stack) we will need to operate on objects which are not GC managed. These would be objects that can live on the stack.
We have some functionality (such as
call_construct
) living in GcObject and not in Object, does anyone know why this is? My expectation is that all object functionality lives in Object, then GCObject acts as a GC wrapper (plus only has GC related functionality)I don't think we can have this, since the way that objects are used implies they need to live into a well known location. For example if we create a object on the stack and clone it, first of all objects should shallow copy, and the object are not the same, even through they should, objects should only check if the pointer is the same not content.
Even with
call_construct
we need to clone object to put it in environments. To even use an object in javascript it has to be converted to a value which has to be on the heap anyway.Putting it on the stack would complicate and make some spec functionality impossible, that is why I moved operations to
GcObject
(#835)
Even if we don't implement stack objects, I think the semantics of GcObject
should be closer to the idea of a fat pointer than a wrapper for an Object
.
Even if we don't implement stack objects, I think the semantics of
GcObject
should be closer to the idea of a fat pointer than a wrapper for anObject
.
Could you elaborate more on this? GcObject
is a pointer, it contains a Gc<Object>
Even if we don't implement stack objects, I think the semantics of
GcObject
should be closer to the idea of a fat pointer than a wrapper for anObject
.Could you elaborate more on this?
GcObject
is a pointer, it contains aGc<Object>
The current GcObject
doesn't exactly act as a pointer. You have some methods that should be callable as object.borrow().method()
but are called as object.method()
. Ideally you should only be able to call borrow
and borrow_mut
on GcObject
for it to be just a fat pointer, that way you don't need to decide if you should call borrow
or not when implementing a method related to Object
.
We follow the spec more closely now. Most of the JsObject operations are for the Object type.