Break ecma deps (#400)

* Refactor realm constructor

* Refactor types.js to not depend on methods/

* Fix errors, add verifier to prevent cycles

* Fixed comments

* Fixing tests

* Fix merge bug
This commit is contained in:
Christopher Blappert 2017-04-14 15:09:34 -07:00 committed by GitHub
parent 5a8113463c
commit 1ef90a22e9
11 changed files with 193 additions and 50 deletions

74
flow-typed/npm/madge_vx.x.x.js vendored Normal file
View File

@ -0,0 +1,74 @@
// flow-typed signature: 32868b4ac1295c82a95fdb7416c1ac3f
// flow-typed version: <<STUB>>/madge_v^1.6.0/flow_v0.44.0
/**
* This is an autogenerated libdef stub for:
*
* 'madge'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'madge' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'madge/bin/cli' {
declare module.exports: any;
}
declare module 'madge/lib/api' {
declare module.exports: any;
}
declare module 'madge/lib/cyclic' {
declare module.exports: any;
}
declare module 'madge/lib/graph' {
declare module.exports: any;
}
declare module 'madge/lib/log' {
declare module.exports: any;
}
declare module 'madge/lib/output' {
declare module.exports: any;
}
declare module 'madge/lib/tree' {
declare module.exports: any;
}
// Filename aliases
declare module 'madge/bin/cli.js' {
declare module.exports: $Exports<'madge/bin/cli'>;
}
declare module 'madge/lib/api.js' {
declare module.exports: $Exports<'madge/lib/api'>;
}
declare module 'madge/lib/cyclic.js' {
declare module.exports: $Exports<'madge/lib/cyclic'>;
}
declare module 'madge/lib/graph.js' {
declare module.exports: $Exports<'madge/lib/graph'>;
}
declare module 'madge/lib/log.js' {
declare module.exports: $Exports<'madge/lib/log'>;
}
declare module 'madge/lib/output.js' {
declare module.exports: $Exports<'madge/lib/output'>;
}
declare module 'madge/lib/tree.js' {
declare module.exports: $Exports<'madge/lib/tree'>;
}

View File

@ -29,8 +29,9 @@
"test": "npm run test-serializer && npm run test-sourcemaps && npm run test-test262 && npm run test-internal",
"repl": "node lib/repl.js",
"prepack": "node lib/run_util.js",
"validate": "npm run build && npm run lint && npm run flow && npm test",
"prepublish": "npm run build"
"validate": "npm run build && npm run lint && npm run depcheck && npm run flow && npm test",
"prepublish": "npm run build",
"depcheck": "node lib/scripts/detect_bad_deps.js"
},
"dependencies": {
"babel-core": "^6.8.0",
@ -67,9 +68,10 @@
"eslint-plugin-flow-header": "^0.1.1",
"eslint-plugin-flowtype": "^2.20.0",
"eslint-plugin-header": "^1.0.0",
"flow-bin": "^0.43.0",
"flow-bin": "^0.44.0",
"graceful-fs": "^4.1.11",
"kcheck": "^2.0.0",
"madge": "^1.6.0",
"webpack": "^2.3.3"
},
"engines": {

32
src/construct_realm.js Normal file
View File

@ -0,0 +1,32 @@
/**
* 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 { Realm } from "./realm.js";
import { initialize as initializeIntrinsics } from "./intrinsics/index.js";
import initializeGlobal from "./global.js";
import type { RealmOptions } from "./types.js";
import * as evaluators from "./evaluators/index.js";
import { NewGlobalEnvironment } from "./methods/index.js";
import { Generator } from "./utils/generator.js";
export default function(opts: RealmOptions = {}): Realm {
let r = new Realm(opts);
let i = r.intrinsics;
initializeIntrinsics(i, r);
r.$GlobalObject = initializeGlobal(r);
for (let name in evaluators) r.evaluators[name] = evaluators[name];
r.$GlobalEnv = NewGlobalEnvironment(r, r.$GlobalObject, r.$GlobalObject);
if (opts.partial) {
r.generator = new Generator(r);
}
return r;
}

View File

@ -16,11 +16,11 @@ import { Value, ObjectValue, NumberValue, EmptyValue, NullValue, StringValue, Un
import { OrdinaryCreateFromConstructor } from "../methods/create.js";
import { Construct, SpeciesConstructor } from "../methods/construct.js";
import { IsConstructor } from "../methods/index.js";
import { ToIndexPartial, ToBooleanPartial, ToNumber } from "../methods/to.js";
import { ElementSize, ElementConv } from "../types.js";
import { ToIndexPartial, ToBooleanPartial, ToNumber, ElementConv } from "./to.js";
import { IsDetachedBuffer } from "../methods/is.js";
import { ThrowIfInternalSlotNotWritable } from "../methods/properties.js";
import invariant from "../invariant.js";
import { ElementSize } from "../types.js";
// ECMA262 6.2.6.1
export function CreateByteDataBlock(realm: Realm, size: number): DataBlock {

View File

@ -22,6 +22,16 @@ import { ThrowCompletion } from "../completions.js";
import { Value, ConcreteValue, PrimitiveValue, UndefinedValue, BooleanValue, ObjectValue, SymbolValue, StringValue, NumberValue, NullValue, AbstractValue, AbstractObjectValue } from "../values/index.js";
import invariant from "../invariant.js";
export const ElementConv = {
Int8: ToInt8,
Int16: ToInt16,
Int32: ToInt32,
Uint8: ToUint8,
Uint16: ToUint16,
Uint32: ToUint32,
Uint8Clamped: ToUint8Clamp
};
type numberOrValue = number | Value;
function modulo(x: number, y: number): number {

View File

@ -13,20 +13,17 @@ import type { RealmOptions, Intrinsics, Compatibility, PropertyBinding, Descript
import type { NativeFunctionValue, FunctionValue } from "./values/index.js";
import { Value, ObjectValue, AbstractValue, AbstractObjectValue, StringValue } from "./values/index.js";
import { TypesDomain, ValuesDomain } from "./domains/index.js";
import { initialize as initializeIntrinsics } from "./intrinsics/index.js";
import { LexicalEnvironment, Reference, GlobalEnvironmentRecord } from "./environment.js";
import type { Binding } from "./environment.js";
import { cloneDescriptor, GetValue, NewGlobalEnvironment, Construct, ThrowIfMightHaveBeenDeleted } from "./methods/index.js";
import { cloneDescriptor, GetValue, Construct, ThrowIfMightHaveBeenDeleted } from "./methods/index.js";
import type { NormalCompletion } from "./completions.js";
import { Completion, IntrospectionThrowCompletion, ThrowCompletion, AbruptCompletion } from "./completions.js";
import invariant from "./invariant.js";
import initializeGlobal from "./global.js";
import seedrandom from "seedrandom";
import { Generator, PreludeGenerator } from "./utils/generator.js";
import type { BabelNode, BabelNodeSourceLocation, BabelNodeExpression } from "babel-types";
import type { EnvironmentRecord } from "./environment.js";
import * as t from "babel-types";
import * as evaluators from "./evaluators/index.js";
export type Bindings = Map<Binding, void | Value>;
export type EvaluationResult = Completion | Reference | Value;
@ -97,7 +94,7 @@ export function construct_empty_effects(realm: Realm): Effects {
}
export class Realm {
constructor(opts: RealmOptions = {}) {
constructor(opts: RealmOptions) {
this.isReadOnly = false;
this.isPartial = !!opts.partial;
if (opts.mathRandomSeed !== undefined) {
@ -115,23 +112,21 @@ export class Realm {
this.start = Date.now();
this.compatibility = opts.compatibility || "browser";
let i = this.intrinsics = ({}: any);
initializeIntrinsics(i, this);
this.$GlobalObject = initializeGlobal(this);
this.$GlobalEnv = NewGlobalEnvironment(this, this.$GlobalObject, this.$GlobalObject);
this.$TemplateMap = [];
if (this.isPartial) {
this.preludeGenerator = new PreludeGenerator();
this.generator = new Generator(this);
ObjectValue.setupTrackedPropertyAccessors();
}
this.evaluators = Object.create(null);
for (let name in evaluators) this.evaluators[name] = evaluators[name];
this.tracers = [];
// These get initialized in construct_realm to avoid the dependency
this.intrinsics = ({}: any);
this.$GlobalObject = (({}: any): ObjectValue);
this.evaluators = (Object.create(null): any);
this.$GlobalEnv = ((undefined: any): LexicalEnvironment);
}
start: number;

View File

@ -14,6 +14,7 @@ import { Get } from "./methods/index.js";
import { ToStringPartial, InstanceofOperator } from "./methods/index.js";
import { AbruptCompletion, ThrowCompletion } from "./completions.js";
import { Value, ObjectValue } from "./values/index.js";
import construct_realm from "./construct_realm.js";
// $FlowFixMe: Why does Flow not know about this Node module?
let repl = require("repl");
@ -44,7 +45,7 @@ function serialize(realm: Realm, res: Value | AbruptCompletion): any {
return res;
}
let realm = new Realm();
let realm = construct_realm();
repl.start({
prompt: "> ",

View File

@ -0,0 +1,37 @@
/**
* 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 madge from "madge";
// NB: This doesn't prevent cycles using "import type" because those are
// erased in the lib folder but madge doesn't work with flow type imports.
madge('./lib/').then((res) => {
let deps = res.obj();
let idx_deps = res.depends('intrinsics/index');
if (idx_deps.length !== 1 || idx_deps[0] !== 'construct_realm') {
console.log("Invalid Dependency: Intrinsics index depends on " + idx_deps[0]);
process.exit(1);
}
for (let dep in deps) {
// Nothing in intrinsics/ecma262 depends on anything but intrinsics/index except Error.
if (dep.startsWith("intrinsics/ecma262") && dep !== "intrinsics/ecma262/Error") {
let ext_deps =
res.depends(dep).filter(
(depend) => depend !== "intrinsics/index" && !depend.startsWith("intrinsics/ecma262"));
if (ext_deps.length > 0) {
console.log("Invalid Dependency: " + dep + " depends on " + ext_deps);
process.exit(1);
}
}
}
});

View File

@ -12,6 +12,7 @@
import { ThrowCompletion } from "../completions.js";
import { ObjectValue, StringValue } from "../values/index.js";
import { Realm, ExecutionContext } from "../realm.js";
import construct_realm from "../construct_realm.js";
import { DetachArrayBuffer } from "../methods/arraybuffer.js";
import { ToStringPartial } from "../methods/to.js";
import { Get } from "../methods/get.js";
@ -896,7 +897,7 @@ function prepareTest(
function createRealm(timeout: number): { realm: Realm, $: ObjectValue } {
// Create a new realm.
let realm = new Realm({ timeout: timeout * 1000 });
let realm = construct_realm({ timeout: timeout * 1000 });
let executionContext = new ExecutionContext();
executionContext.realm = realm;
realm.pushContext(executionContext);
@ -919,8 +920,11 @@ function createRealm(timeout: number): { realm: Realm, $: ObjectValue } {
$.defineNativeProperty("global", realm.$GlobalObject);
realm.$GlobalObject.defineNativeProperty("$", $);
realm.$GlobalObject.defineNativeMethod("print", 1, (context, [arg]) => { });
let glob = ((realm.$GlobalObject: any): ObjectValue);
glob.defineNativeProperty("$", $);
glob.defineNativeMethod("print", 1, (context, [arg]) => {
return realm.intrinsics.undefined;
});
return { realm, $ };
}

View File

@ -11,6 +11,7 @@
import { GlobalEnvironmentRecord, DeclarativeEnvironmentRecord } from "../environment.js";
import { Realm, ExecutionContext } from "../realm.js";
import construct_realm from "../construct_realm.js";
import type { RealmOptions, Descriptor, PropertyBinding } from "../types.js";
import { IsUnresolvableReference, ResolveBinding, ToLength, IsArray, Get } from "../methods/index.js";
import { Completion } from "../completions.js";
@ -56,7 +57,7 @@ function isSameNode(left, right) {
export class Serializer {
constructor(realmOptions: RealmOptions = {}, serializerOptions: SerializerOptions = {}) {
this.realm = new Realm(realmOptions);
this.realm = construct_realm(realmOptions);
invariant(this.realm.isPartial);
this.logger = new Logger(this.realm, !!serializerOptions.internalDebug);
this.modules = new Modules(this.realm, this.logger);

View File

@ -9,9 +9,20 @@
/* @flow */
import type { NumberValue, BooleanValue, NativeFunctionValue, FunctionValue, StringValue, SymbolValue, UndefinedValue, NullValue, EmptyValue, Value } from "./values/index.js";
import { ObjectValue, AbstractObjectValue } from "./values/index.js";
import { ToInt8, ToInt16, ToInt32, ToUint8, ToUint16, ToUint32, ToUint8Clamp } from "./methods/to.js";
import type { NumberValue, BooleanValue, NativeFunctionValue, FunctionValue, StringValue, SymbolValue, UndefinedValue, NullValue, EmptyValue, Value, AbstractObjectValue } from "./values/index.js";
import { ObjectValue } from "./values/index.js";
export const ElementSize = {
Float32: 4,
Float64: 8,
Int8: 1,
Int16: 2,
Int32: 4,
Uint8: 1,
Uint16: 2,
Uint32: 4,
Uint8Clamped: 1
};
export type IterationKind = "key+value" | "value" | "key";
@ -29,32 +40,8 @@ export type RealmOptions = {
export type AbstractTime = "early" | "late";
//
export type ElementType = "Float32" | "Float64" | "Int8" | "Int16" | "Int32" | "Uint8" | "Uint16" | "Uint32" | "Uint8Clamped";
export const ElementSize = {
Float32: 4,
Float64: 8,
Int8: 1,
Int16: 2,
Int32: 4,
Uint8: 1,
Uint16: 2,
Uint32: 4,
Uint8Clamped: 1
};
export const ElementConv = {
Int8: ToInt8,
Int16: ToInt16,
Int32: ToInt32,
Uint8: ToUint8,
Uint16: ToUint16,
Uint32: ToUint32,
Uint8Clamped: ToUint8Clamp
};
//
declare class _CallableObjectValue extends ObjectValue {