v8-extras-geometry

An exploration of using V8 extras to implement the Geometry spec

Stars
6
Committers
1

V8 Extras Geometry

This is a proof-of-concept, untested implementation of some parts of the Geometry spec using V8 extras.

It's specifically written in a fashion that might be amenable to code generation, with the -generated.js files being all something that a sufficiently-smart code generator could write, and the -impl.js files being something a human would write. In some cases, the -generated.js files actually are generated, by the scripts in the scripts/ directory.

Inspiration for this type of "Web IDL bindings in JavaScript" can be seen in the jsdom project, and its webidl2js library.

What's missing

Web IDL mixins (e.g. Element implements ChildNode) are a bit tricky to do correctly as well, and might be worth exploring. The Geometry spec does not have any of those, however.

Classes that are not [Exposed=(Window,Worker)] need a bit more infrastructure in place to only expose in the appropriate globals. I'm not sure what that would look like yet.

The DOMMatrixReadOnly implementation is largely a stub designed to see how multiply() would work. It is missing most of the "generated" code; the impl code has many TODOs; and some of the generated semantics are a bit sketchy. In particular it's not clear that the "generated" code for the overload resolution algorithm in the constructor is correct or realistic.

Miscellaneous notes

File execution order

This would be coded into Chrome's .gn files, given that we have no other way of expressing dependencies for now, until JavaScript modules land and V8 extras support them:

  • web-idl-setup.js
  • DOMPointReadOnly-impl.js
  • DOMPoint-impl.js
  • DOMRectReadOnly-impl.js
  • DOMRect-impl.js
  • DOMMatrixReadOnly-impl.js
  • DOMPointInit-generated.js
  • DOMRectInit-generated.js
  • DOMMatrixInit-generated.js
  • DOMPointReadOnly-generated.js
  • DOMPoint-generated.js
  • DOMRectReadOnly-generated.js
  • DOMRect-generated.js
  • DOMMatrixReadOnly-generated.js

Dictionaries

Dictionaries are represented as Object.create(null) objects. Absent dictionary entries are represented by undefined instead of having their properties be absent; there's no way in Web IDL for a dictionary entry to be present but undefined, and this route ensures a consistent object shape.

Conversions

The Geometry spec is rather light on conversions, using unrestricted double everywhere, for which the conversion is just ToNumber(x) (i.e. +x). In the generated files, we use a more general framework:

dict.x = binding.webIDL.conversions['unrestricted double'](value_x);

However, in cases like this (and others, such as various numeric types, object, any, etc.) it's probably wise to inline the conversion code directly:

dict.x = +value_x;

Brand checking

Brand checking is currently performed via an array that contains string brands:

if (!this[_brands].includes('DOMPointReadOnly')) {

(The brands are installed by the constructor.) There are several possibly-better designs here, such as using a Set, or using numeric brands instead of string ones.

One rather different possibility, which jsdom uses, is consolidating the brand-checking mechanism with the backing implementation class; that is, something brand-checks as a DOMPointReadOnly if and only if it has a backing implementation that is instanceof DOMPointReadOnlyImpl. This can be slightly messy with inheritance and Web IDL mixins, however, so I did not include it here.