Skip to content

Instantly share code, notes, and snippets.

@cms
Created October 30, 2010 22:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cms/cb75423671f3d66f3c1b to your computer and use it in GitHub Desktop.
Save cms/cb75423671f3d66f3c1b to your computer and use it in GitHub Desktop.
The Completion Type

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment