tc39 / proposal-binary-ast

Binary AST proposal for ECMAScript
963 stars 23 forks source link

Introduce interface attribute [Skippable] #24

Open Yoric opened 6 years ago

Yoric commented 6 years ago

The following is a proposal to make clearer in the specifications which parts may be skipped and which may not.

Current state

In the current state of things, all lists may be skipped. This was decided because it was clear that hardcoding arbitrary interface names in the detokenizer was a bad idea, and because the only alternatives were allowing all interfaces to be skipped or allowing all lists to be skipped.

This is generally a waste of bytes, as we don't care about skipping most lists.

Proposal

Attribute

We add an extended attribute [Skippable] to interfaces. A [Skippable] interface is one in which

  1. the encoder stores the byte-length of the node, so that we can easily jump ahead;
  2. the semantics promise that skipping causes no bad surprises (i.e. captured names, lexically declared variables, etc. are all well-defined).

I'm not entirely clear about clause 2. at this stage, but I imagine that there are (or will be in the future) subsets of Asserted*Scope that are only useful when skipping. If so, this means that we only need them in a [Skippable] interface.

Example

Now, we redefine FunctionDeclaration as follows:

typedef (EagerFunctionDeclaration or SkippableFunctionDeclaration) FunctionDeclaration;

interface EagerFunctionDeclaration {
    // ...
    // Pretty much what we currently have in `FunctionDeclaration`, unless we realize
    // that some of the data is needed only for skipping.
}

[Skippable] interface SkippableFunctionDeclaration {
    // Here, insert any attribute that may be useful for skipping.
    // For instance, we could imagine an instruction for the parser to enqueue
    // the node for background processing, with a given priority.
    attribute EagerFunctionDeclaration content;
}

We apply the same treatment to other functions/method/getter/setter/...

Expected benefits

  1. We give the encoder one more optimization lever, since the encoder may decide between EagerFunctionDeclaration and SkippableFunctionDeclaration.
  2. We have a mechanism to extend laziness to other constructions, for instance large JSON objects.
  3. We have a clearer manner of specifying/checking which parts of the semantics may be affected by the Binary AST.
  4. We have a clearer manner of specifying the (de)tokenizer.
  5. We improve file size.
syg commented 6 years ago

I believe this is the right way forward too. IMO the biggest gain here is that it makes adoption a lot more practical. Old codebases have an option to get faster loading and streaming compilation (fingers crossed!) without opting into backwards incompatible Early Error semantics.

Yoric commented 6 years ago

I'll work on adding support for this in the encoder and decoder.