secret
Last active

The Completion Type

  • Download Gist
completion-type.md
Markdown

ECMAScript describes an internal type to describe the semantics of various statements, it's called The Completion Specification Type.

Note: This is not a language data type, it exist in the specification only for expository purposes.

Values of the Completion type are triples of the form of (type, value, target), where:

  • type can be normal, break, continue, return, or throw.
  • value can be any language value or empty.
  • target can be any Identifier or empty.

It's basically a way to manage the flow of control for SourceElements (Statements and FunctionDeclarations).

Normal Completion

A normal completion is returned when source element doesn't alter the flow of control, for example, a VariableStatement, a Block statement, the Empty Statement, the debugger statement (when no debugger attached), a FunctionDeclaration (which is not a statement, but a SourceElement) etc. the returned completion result of them has no observable effect on the control flow, (normal, empty, empty).

The value element

The value element of the triplet is used when certain statements a value after their completion, for example, the ExpressionStatement:

20;
// (normal, 20, empty)
// Program -> SourceElement -> Statement -> ExpressionStatement -> NumericLiteral

Or the Block statement, it returns the completion of the last statement within the block:

{10; 20; 30;}
// (normal, 30, empty)
// Program -> SourceElement -> Statement -> BlockStatement -> ExpressionStatement -> NumericLiteral (10)
//                                                         -> ExpressionStatement -> NumericLiteral (20)
//                                                         -> ExpressionStatement -> NumericLiteral (30)

The eval function evaluates the Program code passed to it and it examines the last completion, if the completion was normal and the value not empty the value is returned, for example:

eval("{10;20;30;}") === 30; // true

If the completion value is empty, eval will explicitly return undefined, e.g.:

eval("function foo(){}") === undefined; // true
// Program -> SourceElement -> FunctionDeclaration

As we saw early, FunctionDeclarations return (normal, empty, empty), while a ExpressionStatement returns (normal, GetValue(exprRef), empty):

typeof eval("(function f(){})") == "function"; // true, exprRef was a function object
// Program -> SourceElement -> Statement -> ExpressionStatement -> PrimaryExpression -> FunctionExpression

The parentheses form a PrimaryExpression that is part of an ExpressionStatement.

Abrupt Completion

If the completion type if other than normal is known also as an "abrupt completion".

For example:

function foo() {
  return 5;
}
foo();

The return statement inside foo will produce a completion that looks like this: (return, 4, empty).

The target value

The last element on the triplet, the target value is only used by the break and continue statements.

It is to reference an identifier of a LabelledStatement, for example:

foo: while(true) {
  while(true) {
    break foo;
  }
}

The completion result of the above break statement would be (break, empty, foo), since the flow of control is transfered from within the second while to outside, at the level of the foo label.

You can see more details about how this internal type is used, on all other statements that perform nonlocal transfers of control as break, continue, return and throw.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.