Implement SuperCall.

Summary:
This now works in the repl:
```
$ yarn repl
yarn repl v0.24.6
$ node lib/repl-cli.js
> class Foo { constructor() { this.x = 2 }}
undefined
> let f = new Foo()
undefined
> f
{ x: 2 }
> class Bar extends Foo { constructor() { super() } }
undefined
> let b = new Bar()
undefined
> b
{ x: 2 }
```
Closes https://github.com/facebook/prepack/pull/762

Differential Revision: D5339029

Pulled By: hermanventer

fbshipit-source-id: 6ad6b7f80b95bf5edd5ba2c5971dc8a82912dd14
This commit is contained in:
wdhorton 2017-06-28 15:08:39 -07:00 committed by Facebook Github Bot
parent eef868f084
commit 50a8d90902
3 changed files with 82 additions and 2 deletions

View File

@ -622,7 +622,7 @@ function handleFinished(
}
// exit status
if (!args.filterString && (numPassedES5 < 22874 || numPassedES6 < 9411 || numTimeouts > 0)) {
if (!args.filterString && (numPassedES5 < 22882 || numPassedES6 < 9633 || numTimeouts > 0)) {
console.log(chalk.red("Overall failure. Expected more tests to pass!"));
return 1;
} else {
@ -1002,7 +1002,6 @@ function runTest(
case "TODO: YieldExpression":
case "Unknown node ArrayPattern":
case "expected single name":
case "Unsupported node type Super":
return null;
default:
if (err.value && err.value.$Prototype &&

View File

@ -34,8 +34,13 @@ import type { BabelNode, BabelNodeCallExpression, BabelNodeExpression, BabelNode
import invariant from "../invariant.js";
import * as t from "babel-types";
import { TypesDomain, ValuesDomain } from "../domains/index.js";
import SuperCall from './SuperCall';
export default function (ast: BabelNodeCallExpression, strictCode: boolean, env: LexicalEnvironment, realm: Realm): Completion | Value | Reference {
if (ast.callee.type === 'Super') {
return SuperCall(ast.arguments, strictCode, env, realm);
}
// ECMA262 12.3.4.1
realm.setNextExecutionContextLocation(ast.loc);

View File

@ -0,0 +1,76 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
/* @flow */
import type { Realm } from "../realm.js";
import type { LexicalEnvironment } from "../environment.js";
import { FunctionEnvironmentRecord } from '../environment.js';
import { Completion } from "../completions.js";
import { Value, UndefinedValue, ObjectValue } from "../values/index.js";
import { Reference } from "../environment.js";
import { GetNewTarget, ArgumentListEvaluation, Construct, GetThisEnvironment, IsConstructor } from "../methods/index.js";
import invariant from "../invariant.js";
function GetSuperConstructor(realm: Realm) {
// 1. Let envRec be GetThisEnvironment( ).
let envRec = GetThisEnvironment(realm);
// 2. Assert: envRec is a function Environment Record.
invariant(envRec instanceof FunctionEnvironmentRecord);
// 3. Let activeFunction be envRec.[[FunctionObject]].
let activeFunction = envRec.$FunctionObject;
// 4. Let superConstructor be activeFunction.[[GetPrototypeOf]]().
let superConstructor = activeFunction.$GetPrototypeOf();
// 5. ReturnIfAbrupt(superConstructor).
// 6. If IsConstructor(superConstructor) is false, throw a TypeError exception.
if (!IsConstructor(realm, superConstructor)) {
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "super called outside of constructor");
}
invariant(superConstructor instanceof ObjectValue);
// 7. Return superConstructor.
return superConstructor;
}
// ECMA262 12.3.5.1
export default function SuperCall(Arguments: Array<BabelNode>, strictCode: boolean, env: LexicalEnvironment, realm: Realm): Completion | Value | Reference {
// 1. Let newTarget be GetNewTarget().
let newTarget = GetNewTarget(realm);
// 2. If newTarget is undefined, throw a ReferenceError exception.
if (newTarget instanceof UndefinedValue) {
throw realm.createErrorThrowCompletion(realm.intrinsics.ReferenceError, "newTarget is undefined");
}
// 3. Let func be GetSuperConstructor().
let func = GetSuperConstructor(realm);
// 4. ReturnIfAbrupt(func).
// 5. Let argList be ArgumentListEvaluation of Arguments.
let argList = ArgumentListEvaluation(realm, strictCode, env, Arguments);
// 6. ReturnIfAbrupt(argList).
// 7. Let result be Construct(func, argList, newTarget).
let result = Construct(realm, func, argList, newTarget);
// 8. ReturnIfAbrupt(result).
// 9. Let thisER be GetThisEnvironment( ).
let thisER = GetThisEnvironment(realm);
// 10. Return thisER.BindThisValue(result).
return thisER.BindThisValue(result);
}