mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-09-11 14:46:37 +03:00
Manually type all exported class methods. (#2231)
Summary: Release notes: None Found and fixed some minor issues. This fixes #2177. Pull Request resolved: https://github.com/facebook/prepack/pull/2231 Differential Revision: D8789870 Pulled By: NTillmann fbshipit-source-id: 4ea3de2cbac08dbf6538af344eade1c45d9b9afd
This commit is contained in:
parent
91847ea6ba
commit
f5c36ad249
@ -125,7 +125,7 @@ export class ForkedAbruptCompletion extends AbruptCompletion {
|
||||
return this.alternate.effects;
|
||||
}
|
||||
|
||||
updateConsequentKeepingCurrentEffects(newConsequent: AbruptCompletion) {
|
||||
updateConsequentKeepingCurrentEffects(newConsequent: AbruptCompletion): AbruptCompletion {
|
||||
let effects = this.consequent.effects;
|
||||
invariant(effects);
|
||||
newConsequent.effects = effects;
|
||||
@ -134,7 +134,7 @@ export class ForkedAbruptCompletion extends AbruptCompletion {
|
||||
return newConsequent;
|
||||
}
|
||||
|
||||
updateAlternateKeepingCurrentEffects(newAlternate: AbruptCompletion) {
|
||||
updateAlternateKeepingCurrentEffects(newAlternate: AbruptCompletion): AbruptCompletion {
|
||||
let effects = this.alternate.effects;
|
||||
invariant(effects);
|
||||
newAlternate.effects = effects;
|
||||
@ -249,7 +249,7 @@ export class PossiblyNormalCompletion extends NormalCompletion {
|
||||
|
||||
// TODO blappert: these functions are a copy of those in ForkedAbruptCompletion, but the two classes will be unified
|
||||
// soon
|
||||
updateConsequentKeepingCurrentEffects(newConsequent: Completion) {
|
||||
updateConsequentKeepingCurrentEffects(newConsequent: Completion): Completion {
|
||||
if (newConsequent instanceof NormalCompletion) this.value = newConsequent.value;
|
||||
let effects = this.consequentEffects;
|
||||
newConsequent.effects = effects;
|
||||
@ -258,7 +258,7 @@ export class PossiblyNormalCompletion extends NormalCompletion {
|
||||
return newConsequent;
|
||||
}
|
||||
|
||||
updateAlternateKeepingCurrentEffects(newAlternate: Completion) {
|
||||
updateAlternateKeepingCurrentEffects(newAlternate: Completion): Completion {
|
||||
if (newAlternate instanceof NormalCompletion) this.value = newAlternate.value;
|
||||
let effects = this.alternateEffects;
|
||||
newAlternate.effects = effects;
|
||||
|
@ -35,12 +35,12 @@ export class AdapterChannel {
|
||||
_prepackProcess: child_process.ChildProcess;
|
||||
|
||||
// Error handler for errors in files from the adapter channel
|
||||
_handleFileReadError(err: ?ErrnoError) {
|
||||
_handleFileReadError(err: ?ErrnoError): void {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
_processPrepackMessage(message: string) {
|
||||
_processPrepackMessage(message: string): void {
|
||||
let dbgResponse = this._marshaller.unmarshallResponse(message);
|
||||
if (dbgResponse.result.kind === "breakpoint-add") {
|
||||
this._eventEmitter.emit(DebugMessage.BREAKPOINT_ADD_ACKNOWLEDGE, dbgResponse.id, dbgResponse);
|
||||
@ -67,23 +67,23 @@ export class AdapterChannel {
|
||||
return true;
|
||||
}
|
||||
|
||||
_addRequestCallback(requestID: number, callback: DebuggerResponse => void) {
|
||||
_addRequestCallback(requestID: number, callback: DebuggerResponse => void): void {
|
||||
invariant(!this._pendingRequestCallbacks.has(requestID), "Request ID already exists in pending requests");
|
||||
this._pendingRequestCallbacks.set(requestID, callback);
|
||||
}
|
||||
|
||||
_processRequestCallback(response: DebuggerResponse) {
|
||||
_processRequestCallback(response: DebuggerResponse): void {
|
||||
let callback = this._pendingRequestCallbacks.get(response.id);
|
||||
invariant(callback !== undefined, "Request ID does not exist in pending requests: " + response.id);
|
||||
callback(response);
|
||||
this._pendingRequestCallbacks.delete(response.id);
|
||||
}
|
||||
|
||||
registerChannelEvent(event: string, listener: (response: DebuggerResponse) => void) {
|
||||
registerChannelEvent(event: string, listener: (response: DebuggerResponse) => void): void {
|
||||
this._eventEmitter.addListener(event, listener);
|
||||
}
|
||||
|
||||
launch(requestID: number, args: PrepackLaunchArguments, callback: DebuggerResponse => void) {
|
||||
launch(requestID: number, args: PrepackLaunchArguments, callback: DebuggerResponse => void): void {
|
||||
this.sendDebuggerStart(requestID);
|
||||
this.listenOnFile(this._processPrepackMessage.bind(this));
|
||||
let prepackCommand = args.sourceFiles.concat(args.prepackArguments);
|
||||
@ -123,73 +123,73 @@ export class AdapterChannel {
|
||||
this._addRequestCallback(requestID, callback);
|
||||
}
|
||||
|
||||
run(requestID: number, callback: DebuggerResponse => void) {
|
||||
run(requestID: number, callback: DebuggerResponse => void): void {
|
||||
this._queue.enqueue(this._marshaller.marshallContinueRequest(requestID));
|
||||
this.trySendNextRequest();
|
||||
this._addRequestCallback(requestID, callback);
|
||||
}
|
||||
|
||||
setBreakpoints(requestID: number, breakpoints: Array<Breakpoint>, callback: DebuggerResponse => void) {
|
||||
setBreakpoints(requestID: number, breakpoints: Array<Breakpoint>, callback: DebuggerResponse => void): void {
|
||||
this._queue.enqueue(this._marshaller.marshallSetBreakpointsRequest(requestID, breakpoints));
|
||||
this.trySendNextRequest();
|
||||
this._addRequestCallback(requestID, callback);
|
||||
}
|
||||
|
||||
getStackFrames(requestID: number, callback: DebuggerResponse => void) {
|
||||
getStackFrames(requestID: number, callback: DebuggerResponse => void): void {
|
||||
this._queue.enqueue(this._marshaller.marshallStackFramesRequest(requestID));
|
||||
this.trySendNextRequest();
|
||||
this._addRequestCallback(requestID, callback);
|
||||
}
|
||||
|
||||
getScopes(requestID: number, frameId: number, callback: DebuggerResponse => void) {
|
||||
getScopes(requestID: number, frameId: number, callback: DebuggerResponse => void): void {
|
||||
this._queue.enqueue(this._marshaller.marshallScopesRequest(requestID, frameId));
|
||||
this.trySendNextRequest();
|
||||
this._addRequestCallback(requestID, callback);
|
||||
}
|
||||
|
||||
getVariables(requestID: number, variablesReference: number, callback: DebuggerResponse => void) {
|
||||
getVariables(requestID: number, variablesReference: number, callback: DebuggerResponse => void): void {
|
||||
this._queue.enqueue(this._marshaller.marshallVariablesRequest(requestID, variablesReference));
|
||||
this.trySendNextRequest();
|
||||
this._addRequestCallback(requestID, callback);
|
||||
}
|
||||
|
||||
stepInto(requestID: number, callback: DebuggerResponse => void) {
|
||||
stepInto(requestID: number, callback: DebuggerResponse => void): void {
|
||||
this._queue.enqueue(this._marshaller.marshallStepIntoRequest(requestID));
|
||||
this.trySendNextRequest();
|
||||
this._addRequestCallback(requestID, callback);
|
||||
}
|
||||
|
||||
stepOver(requestID: number, callback: DebuggerResponse => void) {
|
||||
stepOver(requestID: number, callback: DebuggerResponse => void): void {
|
||||
this._queue.enqueue(this._marshaller.marshallStepOverRequest(requestID));
|
||||
this.trySendNextRequest();
|
||||
this._addRequestCallback(requestID, callback);
|
||||
}
|
||||
|
||||
stepOut(requestID: number, callback: DebuggerResponse => void) {
|
||||
stepOut(requestID: number, callback: DebuggerResponse => void): void {
|
||||
this._queue.enqueue(this._marshaller.marshallStepOutRequest(requestID));
|
||||
this.trySendNextRequest();
|
||||
this._addRequestCallback(requestID, callback);
|
||||
}
|
||||
|
||||
evaluate(requestID: number, frameId: void | number, expression: string, callback: DebuggerResponse => void) {
|
||||
evaluate(requestID: number, frameId: void | number, expression: string, callback: DebuggerResponse => void): void {
|
||||
this._queue.enqueue(this._marshaller.marshallEvaluateRequest(requestID, frameId, expression));
|
||||
this.trySendNextRequest();
|
||||
this._addRequestCallback(requestID, callback);
|
||||
}
|
||||
|
||||
writeOut(contents: string) {
|
||||
writeOut(contents: string): void {
|
||||
this._ioWrapper.writeOutSync(contents);
|
||||
}
|
||||
|
||||
sendDebuggerStart(requestID: number) {
|
||||
sendDebuggerStart(requestID: number): void {
|
||||
this.writeOut(this._marshaller.marshallDebuggerStart(requestID));
|
||||
}
|
||||
|
||||
listenOnFile(messageProcessor: (message: string) => void) {
|
||||
listenOnFile(messageProcessor: (message: string) => void): void {
|
||||
this._ioWrapper.readIn(this._handleFileReadError.bind(this), messageProcessor);
|
||||
}
|
||||
|
||||
clean() {
|
||||
clean(): void {
|
||||
this._ioWrapper.clearInFile();
|
||||
this._ioWrapper.clearOutFile();
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ export class FileIOWrapper {
|
||||
_isAdapter: boolean;
|
||||
|
||||
// Read in a message from the input asynchronously
|
||||
readIn(errorHandler: (err: ?ErrnoError) => void, messageProcessor: (message: string) => void) {
|
||||
readIn(errorHandler: (err: ?ErrnoError) => void, messageProcessor: (message: string) => void): void {
|
||||
fs.readFile(this._inFilePath, { encoding: "utf8" }, (err: ?ErrnoError, contents: string) => {
|
||||
if (err) {
|
||||
errorHandler(err);
|
||||
@ -70,15 +70,15 @@ export class FileIOWrapper {
|
||||
}
|
||||
|
||||
// Write out a message to the output synchronously
|
||||
writeOutSync(contents: string) {
|
||||
writeOutSync(contents: string): void {
|
||||
fs.writeFileSync(this._outFilePath, this._packager.package(contents));
|
||||
}
|
||||
|
||||
clearInFile() {
|
||||
clearInFile(): void {
|
||||
fs.writeFileSync(this._inFilePath, "");
|
||||
}
|
||||
|
||||
clearOutFile() {
|
||||
clearOutFile(): void {
|
||||
fs.writeFileSync(this._outFilePath, "");
|
||||
}
|
||||
}
|
||||
|
@ -44,11 +44,11 @@ export class BreakpointManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
addBreakpointMulti(breakpoints: Array<BreakpointType>) {
|
||||
addBreakpointMulti(breakpoints: Array<BreakpointType>): void {
|
||||
this._doBreakpointsAction(breakpoints, this._addBreakpoint.bind(this));
|
||||
}
|
||||
|
||||
_addBreakpoint(bp: BreakpointType) {
|
||||
_addBreakpoint(bp: BreakpointType): void {
|
||||
let breakpointMap = this._breakpointMaps.get(bp.filePath);
|
||||
if (!breakpointMap) {
|
||||
breakpointMap = new PerFileBreakpointMap(bp.filePath);
|
||||
@ -65,34 +65,34 @@ export class BreakpointManager {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
removeBreakpointMulti(breakpoints: Array<BreakpointType>) {
|
||||
removeBreakpointMulti(breakpoints: Array<BreakpointType>): void {
|
||||
this._doBreakpointsAction(breakpoints, this._removeBreakpoint.bind(this));
|
||||
}
|
||||
|
||||
_removeBreakpoint(bp: BreakpointType) {
|
||||
_removeBreakpoint(bp: BreakpointType): void {
|
||||
let breakpointMap = this._breakpointMaps.get(bp.filePath);
|
||||
if (breakpointMap) breakpointMap.removeBreakpoint(bp.line, bp.column);
|
||||
}
|
||||
|
||||
enableBreakpointMulti(breakpoints: Array<BreakpointType>) {
|
||||
enableBreakpointMulti(breakpoints: Array<BreakpointType>): void {
|
||||
this._doBreakpointsAction(breakpoints, this._enableBreakpoint.bind(this));
|
||||
}
|
||||
|
||||
_enableBreakpoint(bp: BreakpointType) {
|
||||
_enableBreakpoint(bp: BreakpointType): void {
|
||||
let breakpointMap = this._breakpointMaps.get(bp.filePath);
|
||||
if (breakpointMap) breakpointMap.enableBreakpoint(bp.line, bp.column);
|
||||
}
|
||||
|
||||
disableBreakpointMulti(breakpoints: Array<BreakpointType>) {
|
||||
disableBreakpointMulti(breakpoints: Array<BreakpointType>): void {
|
||||
this._doBreakpointsAction(breakpoints, this._disableBreakpoint.bind(this));
|
||||
}
|
||||
|
||||
_disableBreakpoint(bp: BreakpointType) {
|
||||
_disableBreakpoint(bp: BreakpointType): void {
|
||||
let breakpointMap = this._breakpointMaps.get(bp.filePath);
|
||||
if (breakpointMap) breakpointMap.disableBreakpoint(bp.line, bp.column);
|
||||
}
|
||||
|
||||
_doBreakpointsAction(breakpoints: Array<BreakpointType>, action: BreakpointType => void) {
|
||||
_doBreakpointsAction(breakpoints: Array<BreakpointType>, action: BreakpointType => void): void {
|
||||
for (let bp of breakpoints) {
|
||||
action(bp);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ export class DebugServer {
|
||||
/* ast: the current ast node we are stopped on
|
||||
/* reason: the reason the debuggee is stopping
|
||||
*/
|
||||
waitForRun(loc: void | BabelNodeSourceLocation) {
|
||||
waitForRun(loc: void | BabelNodeSourceLocation): void {
|
||||
let keepRunning = false;
|
||||
let request;
|
||||
while (!keepRunning) {
|
||||
@ -83,7 +83,7 @@ export class DebugServer {
|
||||
}
|
||||
|
||||
// Checking if the debugger needs to take any action on reaching this ast node
|
||||
checkForActions(ast: BabelNode) {
|
||||
checkForActions(ast: BabelNode): void {
|
||||
if (this._checkAndUpdateLastExecuted(ast)) {
|
||||
let stoppables: Array<StoppableObject> = this._stepManager.getAndDeleteCompletedSteppers(ast);
|
||||
let breakpoint = this._breakpointManager.getStoppableBreakpoint(ast);
|
||||
@ -101,7 +101,7 @@ export class DebugServer {
|
||||
|
||||
// Process a command from a debugger. Returns whether Prepack should unblock
|
||||
// if it is blocked
|
||||
processDebuggerCommand(request: DebuggerRequest, loc: void | BabelNodeSourceLocation) {
|
||||
processDebuggerCommand(request: DebuggerRequest, loc: void | BabelNodeSourceLocation): boolean {
|
||||
let requestID = request.id;
|
||||
let command = request.command;
|
||||
let args = request.arguments;
|
||||
@ -174,7 +174,11 @@ export class DebugServer {
|
||||
return false;
|
||||
}
|
||||
|
||||
processStackframesCommand(requestID: number, args: StackframeArguments, astLoc: void | BabelNodeSourceLocation) {
|
||||
processStackframesCommand(
|
||||
requestID: number,
|
||||
args: StackframeArguments,
|
||||
astLoc: void | BabelNodeSourceLocation
|
||||
): void {
|
||||
let frameInfos: Array<Stackframe> = [];
|
||||
let loc = this._getFrameLocation(astLoc ? astLoc : null);
|
||||
let fileName = loc.fileName;
|
||||
@ -222,7 +226,7 @@ export class DebugServer {
|
||||
};
|
||||
}
|
||||
|
||||
processScopesCommand(requestID: number, args: ScopesArguments) {
|
||||
processScopesCommand(requestID: number, args: ScopesArguments): void {
|
||||
// first check that frameId is in the valid range
|
||||
if (args.frameId < 0 || args.frameId >= this._realm.contextStack.length) {
|
||||
throw new DebuggerError("Invalid command", "Invalid frame id for scopes request: " + args.frameId);
|
||||
@ -264,18 +268,18 @@ export class DebugServer {
|
||||
}
|
||||
}
|
||||
|
||||
processVariablesCommand(requestID: number, args: VariablesArguments) {
|
||||
processVariablesCommand(requestID: number, args: VariablesArguments): void {
|
||||
let variables = this._variableManager.getVariablesByReference(args.variablesReference);
|
||||
this._channel.sendVariablesResponse(requestID, variables);
|
||||
}
|
||||
|
||||
processEvaluateCommand(requestID: number, args: EvaluateArguments) {
|
||||
processEvaluateCommand(requestID: number, args: EvaluateArguments): void {
|
||||
let evalResult = this._variableManager.evaluate(args.frameId, args.expression);
|
||||
this._channel.sendEvaluateResponse(requestID, evalResult);
|
||||
}
|
||||
|
||||
// actions that need to happen before Prepack can resume
|
||||
_onDebuggeeResume() {
|
||||
_onDebuggeeResume(): void {
|
||||
// resets the variable manager
|
||||
this._variableManager.clean();
|
||||
}
|
||||
@ -315,7 +319,7 @@ export class DebugServer {
|
||||
}
|
||||
|
||||
// Displays Prepack error message, then waits for user to run the program to continue (similar to a breakpoint).
|
||||
handlePrepackError(diagnostic: CompilerDiagnostic) {
|
||||
handlePrepackError(diagnostic: CompilerDiagnostic): void {
|
||||
invariant(diagnostic.location && diagnostic.location.source);
|
||||
// The following constructs the message and stop-instruction that is sent to the UI to actually stop the execution.
|
||||
let location = diagnostic.location;
|
||||
@ -350,7 +354,7 @@ export class DebugServer {
|
||||
}
|
||||
}
|
||||
|
||||
shutdown() {
|
||||
shutdown(): void {
|
||||
// clean the channel pipes
|
||||
this._channel.shutdown();
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ export class PerFileBreakpointMap {
|
||||
//map of line:column to Breakpoint objects
|
||||
_breakpoints: Map<string, Breakpoint>;
|
||||
|
||||
addBreakpoint(line: number, column: number = 0, temporary?: boolean, enabled?: boolean) {
|
||||
addBreakpoint(line: number, column: number = 0, temporary?: boolean, enabled?: boolean): void {
|
||||
let breakpoint = new Breakpoint(this._filePath, line, column, temporary, enabled);
|
||||
let key = this._getKey(line, column);
|
||||
this._breakpoints.set(key, breakpoint);
|
||||
@ -51,20 +51,20 @@ export class PerFileBreakpointMap {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
removeBreakpoint(line: number, column: number = 0) {
|
||||
removeBreakpoint(line: number, column: number = 0): void {
|
||||
let key = this._getKey(line, column);
|
||||
if (this._breakpoints.has(key)) {
|
||||
this._breakpoints.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
enableBreakpoint(line: number, column: number = 0) {
|
||||
enableBreakpoint(line: number, column: number = 0): void {
|
||||
let key = this._getKey(line, column);
|
||||
let breakpoint = this._breakpoints.get(key);
|
||||
if (breakpoint) breakpoint.enabled = true;
|
||||
}
|
||||
|
||||
disableBreakpoint(line: number, column: number = 0) {
|
||||
disableBreakpoint(line: number, column: number = 0): void {
|
||||
let key = this._getKey(line, column);
|
||||
let breakpoint = this._breakpoints.get(key);
|
||||
if (breakpoint) breakpoint.enabled = false;
|
||||
|
@ -30,7 +30,7 @@ export class ReferenceMap<T> {
|
||||
return this._mapping.get(reference);
|
||||
}
|
||||
|
||||
clean() {
|
||||
clean(): void {
|
||||
this._counter = 0;
|
||||
this._mapping = new Map();
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ export class Stepper {
|
||||
// NOTE: Only checks if a node has changed within the same callstack.
|
||||
// The same node in two different excutions contexts (e.g. recursive call)
|
||||
// will not be detected. Check the stackSize (via realm) in those cases.
|
||||
isAstLocationChanged(ast: BabelNode) {
|
||||
isAstLocationChanged(ast: BabelNode): boolean {
|
||||
let loc = ast.loc;
|
||||
if (!loc) return false;
|
||||
let filePath = loc.source;
|
||||
|
@ -26,7 +26,7 @@ export class SteppingManager {
|
||||
_keepOldSteppers: boolean;
|
||||
_steppers: Array<Stepper>;
|
||||
|
||||
processStepCommand(kind: "in" | "over" | "out", currentNodeLocation: BabelNodeSourceLocation) {
|
||||
processStepCommand(kind: "in" | "over" | "out", currentNodeLocation: BabelNodeSourceLocation): void {
|
||||
if (kind === "in") {
|
||||
this._processStepIn(currentNodeLocation);
|
||||
} else if (kind === "over") {
|
||||
@ -38,7 +38,7 @@ export class SteppingManager {
|
||||
}
|
||||
}
|
||||
|
||||
_processStepIn(loc: BabelNodeSourceLocation) {
|
||||
_processStepIn(loc: BabelNodeSourceLocation): void {
|
||||
invariant(loc && loc.source);
|
||||
if (!this._keepOldSteppers) {
|
||||
this._steppers = [];
|
||||
@ -48,7 +48,7 @@ export class SteppingManager {
|
||||
);
|
||||
}
|
||||
|
||||
_processStepOver(loc: BabelNodeSourceLocation) {
|
||||
_processStepOver(loc: BabelNodeSourceLocation): void {
|
||||
invariant(loc && loc.source);
|
||||
if (!this._keepOldSteppers) {
|
||||
this._steppers = [];
|
||||
@ -58,7 +58,7 @@ export class SteppingManager {
|
||||
);
|
||||
}
|
||||
|
||||
_processStepOut(loc: BabelNodeSourceLocation) {
|
||||
_processStepOut(loc: BabelNodeSourceLocation): void {
|
||||
invariant(loc && loc.source);
|
||||
if (!this._keepOldSteppers) {
|
||||
this._steppers = [];
|
||||
|
@ -95,7 +95,7 @@ export class DebugChannel {
|
||||
this.writeOut(this._marshaller.marshallEvaluateResponse(requestID, evalResult));
|
||||
}
|
||||
|
||||
shutdown() {
|
||||
shutdown(): void {
|
||||
this._ioWrapper.clearInFile();
|
||||
this._ioWrapper.clearOutFile();
|
||||
}
|
||||
|
@ -999,7 +999,7 @@ export class GlobalEnvironmentRecord extends EnvironmentRecord {
|
||||
}
|
||||
|
||||
// ECMA262 8.1.1.4.18
|
||||
CreateGlobalFunctionBinding(N: string, V: Value, D: boolean) {
|
||||
CreateGlobalFunctionBinding(N: string, V: Value, D: boolean): void {
|
||||
// 1. Let envRec be the global Environment Record for which the method was invoked.
|
||||
let envRec = this;
|
||||
|
||||
@ -1062,7 +1062,7 @@ export class LexicalEnvironment {
|
||||
parent: null | LexicalEnvironment;
|
||||
realm: Realm;
|
||||
|
||||
destroy() {
|
||||
destroy(): void {
|
||||
this.destroyed = true;
|
||||
// Once the containing environment is destroyed, we can no longer add or remove entries from the environmentRecord
|
||||
// (but we can update existing values).
|
||||
@ -1071,7 +1071,7 @@ export class LexicalEnvironment {
|
||||
}
|
||||
}
|
||||
|
||||
assignToGlobal(globalAst: BabelNodeLVal, rvalue: Value) {
|
||||
assignToGlobal(globalAst: BabelNodeLVal, rvalue: Value): void {
|
||||
let globalValue = this.evaluate(globalAst, false);
|
||||
Properties.PutValue(this.realm, globalValue, rvalue);
|
||||
}
|
||||
@ -1288,7 +1288,7 @@ export class LexicalEnvironment {
|
||||
return Environment.GetValue(this.realm, res);
|
||||
}
|
||||
|
||||
fixup_source_locations(ast: BabelNode, map: string) {
|
||||
fixup_source_locations(ast: BabelNode, map: string): void {
|
||||
const smc = new sourceMap.SourceMapConsumer(map);
|
||||
traverseFast(ast, node => {
|
||||
let loc = node.loc;
|
||||
@ -1320,7 +1320,7 @@ export class LexicalEnvironment {
|
||||
});
|
||||
}
|
||||
|
||||
fixup_filenames(ast: BabelNode) {
|
||||
fixup_filenames(ast: BabelNode): void {
|
||||
traverseFast(ast, node => {
|
||||
let loc = node.loc;
|
||||
if (!loc || !loc.source) {
|
||||
|
@ -561,7 +561,7 @@ export class CreateImplementation {
|
||||
return O.$DefineOwnProperty(P, newDesc);
|
||||
}
|
||||
|
||||
CopyDataProperties(realm: Realm, target: ObjectValue, source: Value, excluded: Array<PropertyKeyValue>) {
|
||||
CopyDataProperties(realm: Realm, target: ObjectValue, source: Value, excluded: Array<PropertyKeyValue>): ObjectValue {
|
||||
// Assert: Type(target) is Object.
|
||||
invariant(target instanceof ObjectValue, "Not an object value");
|
||||
|
||||
|
@ -75,7 +75,7 @@ export class EnvironmentImplementation {
|
||||
excludedNames: Array<PropertyKeyValue>,
|
||||
strictCode: boolean,
|
||||
environment: ?LexicalEnvironment
|
||||
) {
|
||||
): void | boolean | Value {
|
||||
let BindingIdentifier = ((property.argument: any): BabelNodeIdentifier);
|
||||
|
||||
// 1. Let restObj be ObjectCreate(%ObjectPrototype%).
|
||||
@ -110,7 +110,7 @@ export class EnvironmentImplementation {
|
||||
value: Value,
|
||||
strictCode: boolean,
|
||||
environment: ?LexicalEnvironment
|
||||
) {
|
||||
): Array<PropertyKeyValue> {
|
||||
// Base condition for recursive call below
|
||||
if (properties.length === 0) {
|
||||
return [];
|
||||
@ -403,7 +403,7 @@ export class EnvironmentImplementation {
|
||||
strictCode: boolean,
|
||||
body: Array<BabelNodeStatement>,
|
||||
env: LexicalEnvironment
|
||||
) {
|
||||
): void {
|
||||
// 1. Let envRec be env's EnvironmentRecord.
|
||||
let envRec = env.environmentRecord;
|
||||
|
||||
@ -461,7 +461,7 @@ export class EnvironmentImplementation {
|
||||
realm: Realm,
|
||||
G: ObjectValue | AbstractObjectValue,
|
||||
thisValue: ObjectValue | AbstractObjectValue
|
||||
) {
|
||||
): LexicalEnvironment {
|
||||
// 1. Let env be a new Lexical Environment.
|
||||
let env = new LexicalEnvironment(realm);
|
||||
|
||||
@ -565,7 +565,7 @@ export class EnvironmentImplementation {
|
||||
}
|
||||
|
||||
// ECMA262 8.3.1
|
||||
GetActiveScriptOrModule(realm: Realm) {
|
||||
GetActiveScriptOrModule(realm: Realm): any {
|
||||
// The GetActiveScriptOrModule abstract operation is used to determine the running script or module, based on the active function object.
|
||||
// GetActiveScriptOrModule performs the following steps:
|
||||
//
|
||||
@ -763,7 +763,7 @@ export class EnvironmentImplementation {
|
||||
iteratorRecord: { $Iterator: ObjectValue, $Done: boolean },
|
||||
strictCode: boolean,
|
||||
environment: void | LexicalEnvironment
|
||||
) {
|
||||
): void {
|
||||
let env = environment ? environment : realm.getRunningContext().lexicalEnvironment;
|
||||
|
||||
// Check if the last formal is a rest element. If so then we want to save the
|
||||
|
@ -109,7 +109,7 @@ export class HashSet<T: Equatable & Hashable> {
|
||||
invariant(false); // otherwise Flow thinks this method can return undefined
|
||||
}
|
||||
|
||||
expand() {
|
||||
expand(): void {
|
||||
let oldEntries = this._entries;
|
||||
let n = oldEntries.length;
|
||||
let m = n * 2;
|
||||
|
@ -220,7 +220,7 @@ export class JoinImplementation {
|
||||
realm: Realm,
|
||||
pnc: PossiblyNormalCompletion,
|
||||
subsequentEffects: Effects
|
||||
) {
|
||||
): void {
|
||||
let v = subsequentEffects.result;
|
||||
invariant(v instanceof SimpleNormalCompletion);
|
||||
pnc.value = v.value;
|
||||
@ -245,7 +245,7 @@ export class JoinImplementation {
|
||||
}
|
||||
}
|
||||
|
||||
updatePossiblyNormalCompletionWithValue(realm: Realm, pnc: PossiblyNormalCompletion, v: Value) {
|
||||
updatePossiblyNormalCompletionWithValue(realm: Realm, pnc: PossiblyNormalCompletion, v: Value): void {
|
||||
let nc = new SimpleNormalCompletion(v);
|
||||
pnc.value = v;
|
||||
if (pnc.consequent instanceof AbruptCompletion) {
|
||||
@ -321,7 +321,7 @@ export class JoinImplementation {
|
||||
joinCondition: AbstractValue,
|
||||
pnc: PossiblyNormalCompletion,
|
||||
nc: SimpleNormalCompletion
|
||||
) {
|
||||
): void {
|
||||
let v = nc.value;
|
||||
if (pnc.consequent instanceof AbruptCompletion) {
|
||||
if (pnc.alternate instanceof SimpleNormalCompletion) {
|
||||
@ -359,7 +359,7 @@ export class JoinImplementation {
|
||||
joinCondition: AbstractValue,
|
||||
pnc: PossiblyNormalCompletion,
|
||||
nc: SimpleNormalCompletion
|
||||
) {
|
||||
): void {
|
||||
let v = nc.value;
|
||||
if (pnc.consequent instanceof AbruptCompletion) {
|
||||
if (pnc.alternate instanceof SimpleNormalCompletion) {
|
||||
|
78
src/realm.js
78
src/realm.js
@ -115,8 +115,8 @@ export class Effects {
|
||||
}
|
||||
|
||||
export class Tracer {
|
||||
beginEvaluateForEffects(state: any) {}
|
||||
endEvaluateForEffects(state: any, effects: void | Effects) {}
|
||||
beginEvaluateForEffects(state: any): void {}
|
||||
endEvaluateForEffects(state: any, effects: void | Effects): void {}
|
||||
detourCall(
|
||||
F: FunctionValue,
|
||||
thisArgument: void | Value,
|
||||
@ -129,16 +129,16 @@ export class Tracer {
|
||||
thisArgument: void | Value,
|
||||
argumentsList: Array<Value>,
|
||||
newTarget: void | ObjectValue
|
||||
) {}
|
||||
): void {}
|
||||
afterCall(
|
||||
F: FunctionValue,
|
||||
thisArgument: void | Value,
|
||||
argumentsList: Array<Value>,
|
||||
newTarget: void | ObjectValue,
|
||||
result: void | Reference | Value | AbruptCompletion
|
||||
) {}
|
||||
beginOptimizingFunction(optimizedFunctionId: number, functionValue: FunctionValue) {}
|
||||
endOptimizingFunction(optimizedFunctionId: number) {}
|
||||
): void {}
|
||||
beginOptimizingFunction(optimizedFunctionId: number, functionValue: FunctionValue): void {}
|
||||
endOptimizingFunction(optimizedFunctionId: number): void {}
|
||||
}
|
||||
|
||||
export class ExecutionContext {
|
||||
@ -156,12 +156,12 @@ export class ExecutionContext {
|
||||
this.caller = context;
|
||||
}
|
||||
|
||||
setFunction(F: null | FunctionValue) {
|
||||
setFunction(F: null | FunctionValue): void {
|
||||
if (F instanceof ECMAScriptSourceFunctionValue) this.isStrict = F.$Strict;
|
||||
this.function = F;
|
||||
}
|
||||
|
||||
setLocation(loc: null | BabelNodeSourceLocation) {
|
||||
setLocation(loc: null | BabelNodeSourceLocation): void {
|
||||
if (!loc) return;
|
||||
this.loc = loc;
|
||||
}
|
||||
@ -487,15 +487,17 @@ export class Realm {
|
||||
Setting a realm read-only sets all contained environments to read-only, but
|
||||
all new environments (e.g. new ExecutionContexts) will be writeable.
|
||||
*/
|
||||
setReadOnly(readOnlyValue: boolean) {
|
||||
setReadOnly(readOnlyValue: boolean): boolean {
|
||||
let oldReadOnly = this.isReadOnly;
|
||||
this.isReadOnly = readOnlyValue;
|
||||
this.$GlobalEnv.environmentRecord.isReadOnly = readOnlyValue;
|
||||
this.contextStack.forEach(ctx => {
|
||||
ctx.setReadOnly(readOnlyValue);
|
||||
});
|
||||
return oldReadOnly;
|
||||
}
|
||||
|
||||
testTimeout() {
|
||||
testTimeout(): void {
|
||||
let timeout = this.timeout;
|
||||
if (timeout !== undefined && !--this.timeoutCounter) {
|
||||
this.timeoutCounter = this.timeoutCounterThreshold;
|
||||
@ -523,7 +525,7 @@ export class Realm {
|
||||
return context;
|
||||
}
|
||||
|
||||
clearBlockBindings(modifiedBindings: void | Bindings, environmentRecord: DeclarativeEnvironmentRecord) {
|
||||
clearBlockBindings(modifiedBindings: void | Bindings, environmentRecord: DeclarativeEnvironmentRecord): void {
|
||||
if (modifiedBindings === undefined) return;
|
||||
for (let b of modifiedBindings.keys()) {
|
||||
if (b.mightHaveBeenCaptured) continue;
|
||||
@ -531,7 +533,7 @@ export class Realm {
|
||||
}
|
||||
}
|
||||
|
||||
clearBlockBindingsFromCompletion(completion: Completion, environmentRecord: DeclarativeEnvironmentRecord) {
|
||||
clearBlockBindingsFromCompletion(completion: Completion, environmentRecord: DeclarativeEnvironmentRecord): void {
|
||||
if (completion instanceof PossiblyNormalCompletion) {
|
||||
this.clearBlockBindings(completion.alternateEffects.modifiedBindings, environmentRecord);
|
||||
this.clearBlockBindings(completion.consequentEffects.modifiedBindings, environmentRecord);
|
||||
@ -553,7 +555,7 @@ export class Realm {
|
||||
|
||||
// Call when a scope falls out of scope and should be destroyed.
|
||||
// Clears the Bindings corresponding to the disappearing Scope from ModifiedBindings
|
||||
onDestroyScope(lexicalEnvironment: LexicalEnvironment) {
|
||||
onDestroyScope(lexicalEnvironment: LexicalEnvironment): void {
|
||||
invariant(this.activeLexicalEnvironments.has(lexicalEnvironment));
|
||||
let modifiedBindings = this.modifiedBindings;
|
||||
if (modifiedBindings) {
|
||||
@ -578,7 +580,7 @@ export class Realm {
|
||||
this.contextStack.push(context);
|
||||
}
|
||||
|
||||
markVisibleLocalBindingsAsPotentiallyCaptured() {
|
||||
markVisibleLocalBindingsAsPotentiallyCaptured(): void {
|
||||
let context = this.getRunningContext();
|
||||
if (context.function === undefined) return;
|
||||
let lexEnv = context.lexicalEnvironment;
|
||||
@ -595,7 +597,7 @@ export class Realm {
|
||||
}
|
||||
}
|
||||
|
||||
clearFunctionBindings(modifiedBindings: void | Bindings, funcVal: FunctionValue) {
|
||||
clearFunctionBindings(modifiedBindings: void | Bindings, funcVal: FunctionValue): void {
|
||||
if (modifiedBindings === undefined) return;
|
||||
for (let b of modifiedBindings.keys()) {
|
||||
if (b.mightHaveBeenCaptured) continue;
|
||||
@ -604,7 +606,7 @@ export class Realm {
|
||||
}
|
||||
}
|
||||
|
||||
clearFunctionBindingsFromCompletion(completion: Completion, funcVal: FunctionValue) {
|
||||
clearFunctionBindingsFromCompletion(completion: Completion, funcVal: FunctionValue): void {
|
||||
if (completion instanceof PossiblyNormalCompletion) {
|
||||
this.clearFunctionBindings(completion.alternateEffects.modifiedBindings, funcVal);
|
||||
this.clearFunctionBindings(completion.consequentEffects.modifiedBindings, funcVal);
|
||||
@ -649,15 +651,15 @@ export class Realm {
|
||||
}
|
||||
}
|
||||
|
||||
assignToGlobal(name: BabelNodeLVal, value: Value) {
|
||||
assignToGlobal(name: BabelNodeLVal, value: Value): void {
|
||||
this.wrapInGlobalEnv(() => this.$GlobalEnv.assignToGlobal(name, value));
|
||||
}
|
||||
|
||||
deleteGlobalBinding(name: string) {
|
||||
deleteGlobalBinding(name: string): void {
|
||||
this.$GlobalEnv.environmentRecord.DeleteBinding(name);
|
||||
}
|
||||
|
||||
neverCheckProperty(object: ObjectValue | AbstractObjectValue, P: string) {
|
||||
neverCheckProperty(object: ObjectValue | AbstractObjectValue, P: string): boolean {
|
||||
return (
|
||||
P.startsWith("__") ||
|
||||
(object === this.$GlobalObject && P === "global") ||
|
||||
@ -675,7 +677,7 @@ export class Realm {
|
||||
return checkedBindingsObject;
|
||||
}
|
||||
|
||||
markPropertyAsChecked(object: ObjectValue | AbstractObjectValue, P: string) {
|
||||
markPropertyAsChecked(object: ObjectValue | AbstractObjectValue, P: string): void {
|
||||
invariant(!this.neverCheckProperty(object, P));
|
||||
let objectId = this._checkedObjectIds.get(object);
|
||||
if (objectId === undefined) this._checkedObjectIds.set(object, (objectId = this._checkedObjectIds.size));
|
||||
@ -704,7 +706,7 @@ export class Realm {
|
||||
reportSideEffectFunc:
|
||||
| null
|
||||
| ((sideEffectType: SideEffectType, binding: void | Binding | PropertyBinding, value: void | Value) => void)
|
||||
) {
|
||||
): T {
|
||||
let saved_createdObjectsTrackedForLeaks = this.createdObjectsTrackedForLeaks;
|
||||
let saved_reportSideEffectCallback = this.reportSideEffectCallback;
|
||||
// Track all objects (including function closures) created during
|
||||
@ -729,7 +731,7 @@ export class Realm {
|
||||
}
|
||||
}
|
||||
|
||||
isInPureScope() {
|
||||
isInPureScope(): boolean {
|
||||
return !!this.createdObjectsTrackedForLeaks;
|
||||
}
|
||||
|
||||
@ -1068,7 +1070,7 @@ export class Realm {
|
||||
_applyPropertiesToNewlyCreatedObjects(
|
||||
modifiedProperties: void | PropertyBindings,
|
||||
newlyCreatedObjects: CreatedObjects
|
||||
) {
|
||||
): void {
|
||||
if (modifiedProperties === undefined) return;
|
||||
modifiedProperties.forEach((desc, propertyBinding, m) => {
|
||||
if (newlyCreatedObjects.has(propertyBinding.object)) {
|
||||
@ -1078,7 +1080,7 @@ export class Realm {
|
||||
}
|
||||
|
||||
// populate the loop body generator with assignments that will update the phiNodes
|
||||
_emitLocalAssignments(gen: Generator, bindings: Bindings, newlyCreatedObjects: CreatedObjects) {
|
||||
_emitLocalAssignments(gen: Generator, bindings: Bindings, newlyCreatedObjects: CreatedObjects): void {
|
||||
let tvalFor: Map<any, AbstractValue> = new Map();
|
||||
bindings.forEach((binding, key, map) => {
|
||||
let val = binding.value;
|
||||
@ -1115,7 +1117,7 @@ export class Realm {
|
||||
}
|
||||
|
||||
// populate the loop body generator with assignments that will update properties modified inside the loop
|
||||
_emitPropertAssignments(gen: Generator, pbindings: PropertyBindings, newlyCreatedObjects: CreatedObjects) {
|
||||
_emitPropertAssignments(gen: Generator, pbindings: PropertyBindings, newlyCreatedObjects: CreatedObjects): void {
|
||||
function isSelfReferential(value: Value, pathNode: void | AbstractValue): boolean {
|
||||
if (value === pathNode) return true;
|
||||
if (value instanceof AbstractValue && pathNode !== undefined) {
|
||||
@ -1232,7 +1234,7 @@ export class Realm {
|
||||
return result;
|
||||
}
|
||||
|
||||
updateAbruptCompletions(priorEffects: Effects, c: PossiblyNormalCompletion) {
|
||||
updateAbruptCompletions(priorEffects: Effects, c: PossiblyNormalCompletion): void {
|
||||
if (c.consequent instanceof AbruptCompletion) {
|
||||
c.consequent.effects = this.composeEffects(priorEffects, c.consequentEffects);
|
||||
let alternate = c.alternate;
|
||||
@ -1245,7 +1247,7 @@ export class Realm {
|
||||
}
|
||||
}
|
||||
|
||||
wrapSavedCompletion(completion: PossiblyNormalCompletion) {
|
||||
wrapSavedCompletion(completion: PossiblyNormalCompletion): void {
|
||||
if (this.savedCompletion !== undefined) {
|
||||
if (completion.consequent instanceof AbruptCompletion) {
|
||||
completion.alternate = this.savedCompletion;
|
||||
@ -1357,7 +1359,7 @@ export class Realm {
|
||||
}
|
||||
}
|
||||
|
||||
incorporatePriorSavedCompletion(priorCompletion: void | PossiblyNormalCompletion) {
|
||||
incorporatePriorSavedCompletion(priorCompletion: void | PossiblyNormalCompletion): void {
|
||||
if (priorCompletion === undefined) return;
|
||||
// A completion that has been saved and that is still active, will always have savedEffects.
|
||||
invariant(priorCompletion.savedEffects !== undefined);
|
||||
@ -1383,7 +1385,7 @@ export class Realm {
|
||||
}
|
||||
}
|
||||
|
||||
captureEffects(completion: PossiblyNormalCompletion) {
|
||||
captureEffects(completion: PossiblyNormalCompletion): void {
|
||||
invariant(completion.savedEffects === undefined);
|
||||
completion.savedEffects = new Effects(
|
||||
new SimpleNormalCompletion(this.intrinsics.undefined),
|
||||
@ -1412,7 +1414,7 @@ export class Realm {
|
||||
);
|
||||
}
|
||||
|
||||
stopEffectCaptureAndUndoEffects(completion: PossiblyNormalCompletion) {
|
||||
stopEffectCaptureAndUndoEffects(completion: PossiblyNormalCompletion): void {
|
||||
// Roll back the state changes
|
||||
this.undoBindings(this.modifiedBindings);
|
||||
this.restoreProperties(this.modifiedProperties);
|
||||
@ -1431,7 +1433,7 @@ export class Realm {
|
||||
}
|
||||
|
||||
// Apply the given effects to the global state
|
||||
applyEffects(effects: Effects, leadingComment: string = "", appendGenerator: boolean = true) {
|
||||
applyEffects(effects: Effects, leadingComment: string = "", appendGenerator: boolean = true): void {
|
||||
invariant(
|
||||
effects.canBeApplied,
|
||||
"Effects have been applied and not properly reverted. It is not safe to apply them a second time."
|
||||
@ -1624,7 +1626,7 @@ export class Realm {
|
||||
return result;
|
||||
}
|
||||
|
||||
redoBindings(modifiedBindings: void | Bindings) {
|
||||
redoBindings(modifiedBindings: void | Bindings): void {
|
||||
if (modifiedBindings === undefined) return;
|
||||
modifiedBindings.forEach(({ hasLeaked, value }, binding, m) => {
|
||||
binding.hasLeaked = hasLeaked || false;
|
||||
@ -1632,7 +1634,7 @@ export class Realm {
|
||||
});
|
||||
}
|
||||
|
||||
undoBindings(modifiedBindings: void | Bindings) {
|
||||
undoBindings(modifiedBindings: void | Bindings): void {
|
||||
if (modifiedBindings === undefined) return;
|
||||
modifiedBindings.forEach((entry, binding, m) => {
|
||||
if (entry.hasLeaked === undefined) entry.hasLeaked = binding.hasLeaked;
|
||||
@ -1645,7 +1647,7 @@ export class Realm {
|
||||
// Restores each PropertyBinding in the given map to the value it
|
||||
// had when it was entered into the map and updates the map to record
|
||||
// the value the Binding had just before the call to this method.
|
||||
restoreProperties(modifiedProperties: void | PropertyBindings) {
|
||||
restoreProperties(modifiedProperties: void | PropertyBindings): void {
|
||||
if (modifiedProperties === undefined) return;
|
||||
modifiedProperties.forEach((desc, propertyBinding, m) => {
|
||||
let d = propertyBinding.descriptor;
|
||||
@ -1656,12 +1658,12 @@ export class Realm {
|
||||
|
||||
// Provide the realm with maps in which to track modifications.
|
||||
// A map can be set to undefined if no tracking is required.
|
||||
setModifiedMaps(modifiedBindings: void | Bindings, modifiedProperties: void | PropertyBindings) {
|
||||
setModifiedMaps(modifiedBindings: void | Bindings, modifiedProperties: void | PropertyBindings): void {
|
||||
this.modifiedBindings = modifiedBindings;
|
||||
this.modifiedProperties = modifiedProperties;
|
||||
}
|
||||
|
||||
rebuildObjectProperty(object: Value, key: string, propertyValue: Value, path: string) {
|
||||
rebuildObjectProperty(object: Value, key: string, propertyValue: Value, path: string): void {
|
||||
if (!(propertyValue instanceof AbstractValue)) return;
|
||||
if (propertyValue.kind === "abstractConcreteUnion") {
|
||||
let absVal = propertyValue.args.find(e => e instanceof AbstractValue);
|
||||
@ -1680,7 +1682,7 @@ export class Realm {
|
||||
}
|
||||
}
|
||||
|
||||
rebuildNestedProperties(abstractValue: AbstractValue | UndefinedValue, path: string) {
|
||||
rebuildNestedProperties(abstractValue: AbstractValue | UndefinedValue, path: string): void {
|
||||
if (!(abstractValue instanceof AbstractObjectValue)) return;
|
||||
if (abstractValue.values.isTop()) return;
|
||||
let template = abstractValue.getTemplate();
|
||||
@ -1717,7 +1719,7 @@ export class Realm {
|
||||
return previousValue;
|
||||
}
|
||||
|
||||
reportIntrospectionError(message?: void | string | StringValue) {
|
||||
reportIntrospectionError(message?: void | string | StringValue): void {
|
||||
if (message === undefined) message = "";
|
||||
if (typeof message === "string") message = new StringValue(this, message);
|
||||
invariant(message instanceof StringValue);
|
||||
|
@ -128,7 +128,11 @@ export class Emitter {
|
||||
// The dependency indicates what is being emitted; until this emission ends, other parties might have to wait for the dependency.
|
||||
// The targetBody is a wrapper that holds the sequence of statements that are going to be emitted.
|
||||
// If isChild, then we are starting a new emitting session as a branch off the previously active emitting session.
|
||||
beginEmitting(dependency: string | Generator | Value, targetBody: SerializedBody, isChild: boolean = false) {
|
||||
beginEmitting(
|
||||
dependency: string | Generator | Value,
|
||||
targetBody: SerializedBody,
|
||||
isChild: boolean = false
|
||||
): SerializedBody {
|
||||
invariant(!this._finalized);
|
||||
this._activeStack.push(dependency);
|
||||
if (dependency instanceof Value) {
|
||||
@ -146,12 +150,12 @@ export class Emitter {
|
||||
this._body = targetBody;
|
||||
return oldBody;
|
||||
}
|
||||
emit(statement: BabelNodeStatement) {
|
||||
emit(statement: BabelNodeStatement): void {
|
||||
invariant(!this._finalized);
|
||||
this._body.entries.push(statement);
|
||||
this._processCurrentBody();
|
||||
}
|
||||
finalizeCurrentBody() {
|
||||
finalizeCurrentBody(): void {
|
||||
invariant(!this._finalized);
|
||||
this._processCurrentBody();
|
||||
}
|
||||
@ -165,7 +169,7 @@ export class Emitter {
|
||||
oldBody: SerializedBody,
|
||||
valuesToProcess: void | Set<AbstractValue | ObjectValue>,
|
||||
isChild: boolean = false
|
||||
) {
|
||||
): SerializedBody {
|
||||
invariant(!this._finalized);
|
||||
let lastDependency = this._activeStack.pop();
|
||||
invariant(dependency === lastDependency);
|
||||
@ -206,10 +210,10 @@ export class Emitter {
|
||||
|
||||
return lastBody;
|
||||
}
|
||||
processValues(valuesToProcess: Set<AbstractValue | ObjectValue>) {
|
||||
processValues(valuesToProcess: Set<AbstractValue | ObjectValue>): void {
|
||||
for (let value of valuesToProcess) this._processValue(value);
|
||||
}
|
||||
finalize() {
|
||||
finalize(): void {
|
||||
invariant(!this._finalized);
|
||||
invariant(this._activeGeneratorStack.length === 1);
|
||||
invariant(this._activeGeneratorStack[0] === this._body);
|
||||
@ -236,7 +240,7 @@ export class Emitter {
|
||||
_isGeneratorBody(body: SerializedBody): boolean {
|
||||
return body.type === "MainGenerator" || body.type === "Generator" || body.type === "AdditionalFunction";
|
||||
}
|
||||
_processCurrentBody() {
|
||||
_processCurrentBody(): void {
|
||||
if (!this._isEmittingActiveGenerator() || this._body.processing) {
|
||||
return;
|
||||
}
|
||||
@ -250,7 +254,7 @@ export class Emitter {
|
||||
this._waitingForBodies.delete(this._body);
|
||||
this._body.processing = false;
|
||||
}
|
||||
_processValue(value: Value) {
|
||||
_processValue(value: Value): void {
|
||||
let a = this._waitingForValues.get(value);
|
||||
if (a === undefined) return;
|
||||
let currentBody = this._body;
|
||||
@ -416,7 +420,7 @@ export class Emitter {
|
||||
dependencies: Array<Value>,
|
||||
func: () => void,
|
||||
targetBody: SerializedBody
|
||||
) {
|
||||
): void {
|
||||
if (delayReason === undefined && this._isGeneratorBody(targetBody)) {
|
||||
delayReason = targetBody;
|
||||
}
|
||||
@ -447,14 +451,19 @@ export class Emitter {
|
||||
}
|
||||
}
|
||||
}
|
||||
_emitAfterWaitingForValue(reason: Value, dependencies: Array<Value>, targetBody: SerializedBody, func: () => void) {
|
||||
_emitAfterWaitingForValue(
|
||||
reason: Value,
|
||||
dependencies: Array<Value>,
|
||||
targetBody: SerializedBody,
|
||||
func: () => void
|
||||
): void {
|
||||
invariant(!this._finalized);
|
||||
invariant(!(reason instanceof AbstractValue && this.hasBeenDeclared(reason)) || this._activeValues.has(reason));
|
||||
let a = this._waitingForValues.get(reason);
|
||||
if (a === undefined) this._waitingForValues.set(reason, (a = []));
|
||||
a.push({ body: targetBody, dependencies, func });
|
||||
}
|
||||
_emitAfterWaitingForGeneratorBody(reason: SerializedBody, dependencies: Array<Value>, func: () => void) {
|
||||
_emitAfterWaitingForGeneratorBody(reason: SerializedBody, dependencies: Array<Value>, func: () => void): void {
|
||||
invariant(this._isGeneratorBody(reason));
|
||||
invariant(!this._finalized);
|
||||
invariant(this._activeGeneratorStack.includes(reason));
|
||||
@ -464,10 +473,10 @@ export class Emitter {
|
||||
}
|
||||
b.push({ dependencies, func });
|
||||
}
|
||||
emitNowOrAfterWaitingForDependencies(dependencies: Array<Value>, func: () => void, targetBody: SerializedBody) {
|
||||
emitNowOrAfterWaitingForDependencies(dependencies: Array<Value>, func: () => void, targetBody: SerializedBody): void {
|
||||
this.emitAfterWaiting(this.getReasonToWaitForDependencies(dependencies), dependencies, func, targetBody);
|
||||
}
|
||||
declare(value: AbstractValue | ObjectValue) {
|
||||
declare(value: AbstractValue | ObjectValue): void {
|
||||
invariant(!this._finalized);
|
||||
invariant(!this._activeValues.has(value));
|
||||
invariant(value instanceof ObjectValue || value.hasIdentifier());
|
||||
@ -478,7 +487,7 @@ export class Emitter {
|
||||
this._body.declaredValues.set(value, this._body);
|
||||
this._processValue(value);
|
||||
}
|
||||
emittingToAdditionalFunction() {
|
||||
emittingToAdditionalFunction(): boolean {
|
||||
// Whether we are directly or indirectly emitting to an additional function
|
||||
for (let b = this._body; b !== undefined; b = b.parentBody) if (b.type === "AdditionalFunction") return true;
|
||||
return false;
|
||||
@ -498,7 +507,7 @@ export class Emitter {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
declaredCount() {
|
||||
declaredCount(): number {
|
||||
let declaredValues = this._body.declaredValues;
|
||||
return declaredValues === undefined ? 0 : declaredValues.size;
|
||||
}
|
||||
@ -515,7 +524,7 @@ export class Emitter {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
getBodyReference() {
|
||||
getBodyReference(): BodyReference {
|
||||
invariant(!this._finalized);
|
||||
return new BodyReference(this._body, this._body.entries.length);
|
||||
}
|
||||
|
@ -44,11 +44,11 @@ export class GeneratorDAG {
|
||||
return this.createdObjects.get(value);
|
||||
}
|
||||
|
||||
add(parent: FunctionValue | "GLOBAL", generator: Generator) {
|
||||
add(parent: FunctionValue | "GLOBAL", generator: Generator): void {
|
||||
this._add(parent, generator);
|
||||
}
|
||||
|
||||
_add(parent: Generator | FunctionValue | "GLOBAL", generator: Generator) {
|
||||
_add(parent: Generator | FunctionValue | "GLOBAL", generator: Generator): void {
|
||||
let a = this.parents.get(generator);
|
||||
if (a === undefined) this.parents.set(generator, (a = []));
|
||||
if (!a.includes(parent)) a.push(parent);
|
||||
|
@ -192,7 +192,7 @@ export class LazyObjectsSerializer extends ResidualHeapSerializer {
|
||||
* The offspring checking is needed because object may be emitting in a "ConditionalAssignmentBranch" of
|
||||
* lazy object's initializer body.
|
||||
*/
|
||||
_isEmittingIntoLazyObjectInitializerBody(obj: ObjectValue) {
|
||||
_isEmittingIntoLazyObjectInitializerBody(obj: ObjectValue): boolean {
|
||||
const objLazyBody = this._lazyObjectInitializers.get(obj);
|
||||
return objLazyBody !== undefined && this.emitter.isCurrentBodyOffspringOf(objLazyBody);
|
||||
}
|
||||
|
@ -50,22 +50,27 @@ export class LoggingTracer extends Tracer {
|
||||
realm: Realm;
|
||||
nesting: Array<string>;
|
||||
|
||||
log(message: string) {
|
||||
log(message: string): void {
|
||||
console.log(`[calls] ${this.nesting.map(_ => " ").join("")}${message}`);
|
||||
}
|
||||
|
||||
beginEvaluateForEffects(state: any) {
|
||||
beginEvaluateForEffects(state: any): void {
|
||||
this.log(`>evaluate for effects`);
|
||||
this.nesting.push("(evaluate for effects)");
|
||||
}
|
||||
|
||||
endEvaluateForEffects(state: any, effects: void | Effects) {
|
||||
endEvaluateForEffects(state: any, effects: void | Effects): void {
|
||||
let name = this.nesting.pop();
|
||||
invariant(name === "(evaluate for effects)");
|
||||
this.log(`<evaluate for effects`);
|
||||
}
|
||||
|
||||
beforeCall(F: FunctionValue, thisArgument: void | Value, argumentsList: Array<Value>, newTarget: void | ObjectValue) {
|
||||
beforeCall(
|
||||
F: FunctionValue,
|
||||
thisArgument: void | Value,
|
||||
argumentsList: Array<Value>,
|
||||
newTarget: void | ObjectValue
|
||||
): void {
|
||||
let realm = this.realm;
|
||||
let name = describeValue(realm, F);
|
||||
this.log(`>${name}(${argumentsList.map(v => describeValue(realm, v)).join(", ")})`);
|
||||
@ -78,12 +83,12 @@ export class LoggingTracer extends Tracer {
|
||||
argumentsList: Array<Value>,
|
||||
newTarget: void | ObjectValue,
|
||||
result: void | Reference | Value | AbruptCompletion
|
||||
) {
|
||||
): void {
|
||||
let name = this.nesting.pop();
|
||||
this.log(`<${name}${result instanceof ThrowCompletion ? ": error" : ""}`);
|
||||
}
|
||||
|
||||
beginOptimizingFunction(optimizedFunctionId: number, functionValue: FunctionValue) {
|
||||
beginOptimizingFunction(optimizedFunctionId: number, functionValue: FunctionValue): void {
|
||||
this.log(
|
||||
`>Starting Optimized Function ${optimizedFunctionId} ${
|
||||
functionValue.intrinsicName ? functionValue.intrinsicName : "[unknown name]"
|
||||
@ -91,7 +96,7 @@ export class LoggingTracer extends Tracer {
|
||||
);
|
||||
}
|
||||
|
||||
endOptimizingFunction(optimizedFunctionId: number) {
|
||||
endOptimizingFunction(optimizedFunctionId: number): void {
|
||||
this.log(`<Ending Optimized Function ${optimizedFunctionId}`);
|
||||
}
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ export class Referentializer {
|
||||
}
|
||||
|
||||
// Cleans all scopes between passes of the serializer
|
||||
cleanInstance(instance: FunctionInstance) {
|
||||
cleanInstance(instance: FunctionInstance): void {
|
||||
instance.initializationStatements = [];
|
||||
for (let b of ((instance: any): FunctionInstance).residualFunctionBindings.values()) {
|
||||
let binding = ((b: any): ResidualFunctionBinding);
|
||||
|
@ -69,7 +69,7 @@ export class ResidualFunctionInitializers {
|
||||
return initializer.body;
|
||||
}
|
||||
|
||||
scrubFunctionInitializers() {
|
||||
scrubFunctionInitializers(): void {
|
||||
// Deleting trivial entries in order to avoid creating empty initialization functions that serve no purpose.
|
||||
for (let initializer of this.initializers.values())
|
||||
if (initializer.body.entries.length === 0) this.initializers.delete(initializer.id);
|
||||
@ -122,7 +122,7 @@ export class ResidualFunctionInitializers {
|
||||
return !!this.functionInitializerInfos.get(functionValue);
|
||||
}
|
||||
|
||||
factorifyInitializers(nameGenerator: NameGenerator) {
|
||||
factorifyInitializers(nameGenerator: NameGenerator): void {
|
||||
for (const initializer of this.initializers.values()) {
|
||||
factorifyObjects(initializer.body.entries, nameGenerator);
|
||||
}
|
||||
|
@ -15,6 +15,9 @@ import { FunctionValue, ECMAScriptSourceFunctionValue, ObjectValue } from "../va
|
||||
import type { SerializerOptions } from "../options.js";
|
||||
import * as t from "babel-types";
|
||||
import type {
|
||||
BabelNodeCallExpression,
|
||||
BabelNodeClassMethod,
|
||||
BabelNodeClassExpression,
|
||||
BabelNodeExpression,
|
||||
BabelNodeStatement,
|
||||
BabelNodeIdentifier,
|
||||
@ -22,7 +25,6 @@ import type {
|
||||
BabelNodeLVal,
|
||||
BabelNodeSpreadElement,
|
||||
BabelNodeFunctionExpression,
|
||||
BabelNodeClassExpression,
|
||||
BabelNodeArrowFunctionExpression,
|
||||
} from "babel-types";
|
||||
import type { FunctionBodyAstNode } from "../types.js";
|
||||
@ -46,12 +48,8 @@ import { Referentializer } from "./Referentializer.js";
|
||||
import { getOrDefault } from "./utils.js";
|
||||
|
||||
type ResidualFunctionsResult = {
|
||||
unstrictFunctionBodies: Array<
|
||||
BabelNodeFunctionExpression | BabelNodeClassExpression | BabelNodeArrowFunctionExpression
|
||||
>,
|
||||
strictFunctionBodies: Array<
|
||||
BabelNodeFunctionExpression | BabelNodeClassExpression | BabelNodeArrowFunctionExpression
|
||||
>,
|
||||
unstrictFunctionBodies: Array<BabelNodeFunctionExpression | BabelNodeArrowFunctionExpression>,
|
||||
strictFunctionBodies: Array<BabelNodeFunctionExpression | BabelNodeArrowFunctionExpression>,
|
||||
};
|
||||
|
||||
export class ResidualFunctions {
|
||||
@ -118,27 +116,27 @@ export class ResidualFunctions {
|
||||
referentializer: Referentializer;
|
||||
additionalFunctionPreludes: Map<FunctionValue, Array<BabelNodeStatement>>;
|
||||
|
||||
getStatistics() {
|
||||
getStatistics(): SerializerStatistics {
|
||||
invariant(this.realm.statistics instanceof SerializerStatistics, "serialization requires SerializerStatistics");
|
||||
return this.realm.statistics;
|
||||
}
|
||||
|
||||
addFunctionInstance(instance: FunctionInstance) {
|
||||
addFunctionInstance(instance: FunctionInstance): void {
|
||||
this.functionInstances.push(instance);
|
||||
let code = instance.functionValue.$ECMAScriptCode;
|
||||
invariant(code != null);
|
||||
getOrDefault(this.functions, code, () => []).push(instance);
|
||||
}
|
||||
|
||||
setFunctionPrototype(constructor: FunctionValue, prototypeId: BabelNodeIdentifier) {
|
||||
setFunctionPrototype(constructor: FunctionValue, prototypeId: BabelNodeIdentifier): void {
|
||||
this.functionPrototypes.set(constructor, prototypeId);
|
||||
}
|
||||
|
||||
addFunctionUsage(val: FunctionValue, bodyReference: BodyReference) {
|
||||
addFunctionUsage(val: FunctionValue, bodyReference: BodyReference): void {
|
||||
if (!this.firstFunctionUsages.has(val)) this.firstFunctionUsages.set(val, bodyReference);
|
||||
}
|
||||
|
||||
_shouldUseFactoryFunction(funcBody: BabelNodeBlockStatement, instances: Array<FunctionInstance>) {
|
||||
_shouldUseFactoryFunction(funcBody: BabelNodeBlockStatement, instances: Array<FunctionInstance>): boolean {
|
||||
invariant(instances.length > 0);
|
||||
function shouldInlineFunction(): boolean {
|
||||
if (instances[0].scopeInstances.size > 0) return false;
|
||||
@ -261,7 +259,11 @@ export class ResidualFunctions {
|
||||
});
|
||||
}
|
||||
|
||||
_createFunctionExpression(params: Array<BabelNodeLVal>, body: BabelNodeBlockStatement, isLexical: boolean) {
|
||||
_createFunctionExpression(
|
||||
params: Array<BabelNodeLVal>,
|
||||
body: BabelNodeBlockStatement,
|
||||
isLexical: boolean
|
||||
): BabelNodeFunctionExpression | BabelNodeArrowFunctionExpression {
|
||||
// Additional statements might be inserted at the beginning of the body, so we clone it.
|
||||
body = ((Object.assign({}, body): any): BabelNodeBlockStatement);
|
||||
return isLexical ? t.arrowFunctionExpression(params, body) : t.functionExpression(null, params, body);
|
||||
@ -296,11 +298,32 @@ export class ResidualFunctions {
|
||||
);
|
||||
this._sortFunctionByOriginalOrdering(functionEntries);
|
||||
this.getStatistics().functions = functionEntries.length;
|
||||
let unstrictFunctionBodies = [];
|
||||
let strictFunctionBodies = [];
|
||||
let unstrictFunctionBodies: Array<BabelNodeFunctionExpression | BabelNodeArrowFunctionExpression> = [];
|
||||
let strictFunctionBodies: Array<BabelNodeFunctionExpression | BabelNodeArrowFunctionExpression> = [];
|
||||
let registerFunctionStrictness = (
|
||||
node:
|
||||
| BabelNodeFunctionExpression
|
||||
| BabelNodeArrowFunctionExpression
|
||||
| BabelNodeClassMethod
|
||||
| BabelNodeClassExpression,
|
||||
strict: boolean
|
||||
) => {
|
||||
if (t.isFunctionExpression(node) || t.isArrowFunctionExpression(node)) {
|
||||
(strict ? strictFunctionBodies : unstrictFunctionBodies).push(
|
||||
((node: any): BabelNodeFunctionExpression | BabelNodeArrowFunctionExpression)
|
||||
);
|
||||
}
|
||||
};
|
||||
let funcNodes: Map<FunctionValue, BabelNodeFunctionExpression> = new Map();
|
||||
|
||||
let defineFunction = (instance, funcId, funcOrClassNode) => {
|
||||
let defineFunction = (
|
||||
instance: FunctionInstance,
|
||||
funcId: BabelNodeIdentifier,
|
||||
funcOrClassNode:
|
||||
| BabelNodeCallExpression
|
||||
| BabelNodeFunctionExpression
|
||||
| BabelNodeArrowFunctionExpression
|
||||
| BabelNodeClassExpression
|
||||
) => {
|
||||
let { functionValue } = instance;
|
||||
|
||||
if (instance.initializationStatements.length > 0) {
|
||||
@ -420,11 +443,10 @@ export class ResidualFunctions {
|
||||
let id = this.locationService.getLocation(funcValue);
|
||||
invariant(id !== undefined);
|
||||
|
||||
if (funcValue instanceof ECMAScriptSourceFunctionValue && funcValue.$Strict) {
|
||||
strictFunctionBodies.push(funcOrClassNode);
|
||||
} else {
|
||||
unstrictFunctionBodies.push(funcOrClassNode);
|
||||
}
|
||||
registerFunctionStrictness(
|
||||
funcOrClassNode,
|
||||
funcValue instanceof ECMAScriptSourceFunctionValue && funcValue.$Strict
|
||||
);
|
||||
defineFunction(instance, id, funcOrClassNode);
|
||||
}
|
||||
|
||||
@ -530,11 +552,7 @@ export class ResidualFunctions {
|
||||
let id = this.locationService.getLocation(functionValue);
|
||||
invariant(id !== undefined);
|
||||
|
||||
if (functionValue.$Strict) {
|
||||
strictFunctionBodies.push(funcOrClassNode);
|
||||
} else {
|
||||
unstrictFunctionBodies.push(funcOrClassNode);
|
||||
}
|
||||
registerFunctionStrictness(funcOrClassNode, functionValue.$Strict);
|
||||
invariant(id !== undefined);
|
||||
invariant(funcOrClassNode !== undefined);
|
||||
defineFunction(instance, id, funcOrClassNode);
|
||||
@ -620,11 +638,7 @@ export class ResidualFunctions {
|
||||
let factoryDeclaration = t.variableDeclaration("var", [t.variableDeclarator(factoryId, factoryNode)]);
|
||||
this.prelude.push(factoryDeclaration);
|
||||
|
||||
if (normalInstances[0].functionValue.$Strict) {
|
||||
strictFunctionBodies.push(factoryNode);
|
||||
} else {
|
||||
unstrictFunctionBodies.push(factoryNode);
|
||||
}
|
||||
registerFunctionStrictness(factoryNode, normalInstances[0].functionValue.$Strict);
|
||||
|
||||
for (let instance of normalInstances) {
|
||||
let { functionValue, residualFunctionBindings, insertionPoint } = instance;
|
||||
@ -672,11 +686,7 @@ export class ResidualFunctions {
|
||||
let childBody = t.blockStatement([t.returnStatement(t.callExpression(callee, callArgs))]);
|
||||
|
||||
funcNode = t.functionExpression(null, params, childBody);
|
||||
if (functionValue.$Strict) {
|
||||
strictFunctionBodies.push(funcNode);
|
||||
} else {
|
||||
unstrictFunctionBodies.push(funcNode);
|
||||
}
|
||||
registerFunctionStrictness(funcNode, functionValue.$Strict);
|
||||
} else {
|
||||
funcNode = t.callExpression(
|
||||
t.memberExpression(factoryId, t.identifier("bind")),
|
||||
|
@ -101,7 +101,7 @@ export class ResidualHeapGraphGenerator extends ResidualHeapVisitor {
|
||||
return val instanceof EmptyValue || val.isIntrinsic() || HeapInspector.isLeaf(val);
|
||||
}
|
||||
|
||||
_updateEdge(val: Value) {
|
||||
_updateEdge(val: Value): void {
|
||||
if (this._path.length > 0) {
|
||||
const parent = this._path[this._path.length - 1];
|
||||
this._edges.push({ fromId: this._getValueId(parent), toId: this._getValueId(val) });
|
||||
|
@ -60,7 +60,7 @@ export class ResidualHeapRefCounter extends ResidualHeapVisitor {
|
||||
return this._updateValueIncomingEdgeCount(val);
|
||||
}
|
||||
|
||||
_updateParentOutgoingEdgeCount() {
|
||||
_updateParentOutgoingEdgeCount(): void {
|
||||
const parent = this._path[this._path.length - 1];
|
||||
const edgeRecord = this._valueToEdgeRecord.get(parent);
|
||||
invariant(edgeRecord);
|
||||
@ -82,7 +82,7 @@ export class ResidualHeapRefCounter extends ResidualHeapVisitor {
|
||||
}
|
||||
|
||||
// Override.
|
||||
postProcessValue(val: Value) {
|
||||
postProcessValue(val: Value): void {
|
||||
if (this._shouldIgnore(val)) {
|
||||
return;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import type {
|
||||
BabelNodeBlockStatement,
|
||||
BabelNodeLVal,
|
||||
BabelNodeMemberExpression,
|
||||
BabelNodeSpreadElement,
|
||||
BabelVariableKind,
|
||||
BabelNodeFile,
|
||||
BabelNodeFunctionExpression,
|
||||
@ -293,7 +294,7 @@ export class ResidualHeapSerializer {
|
||||
objectPrototypeAlreadyEstablished: boolean = false,
|
||||
cleanupDummyProperties: ?Set<string>,
|
||||
skipPrototype: boolean = false
|
||||
) {
|
||||
): void {
|
||||
//inject symbols
|
||||
for (let [symbol, propertyBinding] of obj.symbols) {
|
||||
invariant(propertyBinding);
|
||||
@ -361,7 +362,7 @@ export class ResidualHeapSerializer {
|
||||
this.getStatistics().objectProperties += obj.properties.size;
|
||||
}
|
||||
|
||||
_emitObjectPrototype(obj: ObjectValue, objectPrototypeAlreadyEstablished: boolean) {
|
||||
_emitObjectPrototype(obj: ObjectValue, objectPrototypeAlreadyEstablished: boolean): void {
|
||||
let kind = obj.getKind();
|
||||
let proto = obj.$Prototype;
|
||||
if (objectPrototypeAlreadyEstablished) {
|
||||
@ -413,7 +414,7 @@ export class ResidualHeapSerializer {
|
||||
);
|
||||
}
|
||||
|
||||
_emitConstructorPrototype(func: FunctionValue) {
|
||||
_emitConstructorPrototype(func: FunctionValue): void {
|
||||
// If the original prototype object was mutated,
|
||||
// request its serialization here as this might be observable by
|
||||
// residual code.
|
||||
@ -463,7 +464,7 @@ export class ResidualHeapSerializer {
|
||||
return values;
|
||||
}
|
||||
|
||||
_emitPropertiesWithComputedNames(obj: ObjectValue, absVal: AbstractValue) {
|
||||
_emitPropertiesWithComputedNames(obj: ObjectValue, absVal: AbstractValue): void {
|
||||
if (absVal.kind === "widened property") return;
|
||||
if (absVal.kind === "template for prototype member expression") return;
|
||||
invariant(absVal.args.length === 3);
|
||||
@ -530,7 +531,7 @@ export class ResidualHeapSerializer {
|
||||
}
|
||||
|
||||
// Overridable.
|
||||
getSerializeObjectIdentifier(val: Value) {
|
||||
getSerializeObjectIdentifier(val: Value): BabelNodeIdentifier {
|
||||
return this.residualHeapValueIdentifiers.getIdentifierAndIncrementReferenceCount(val);
|
||||
}
|
||||
|
||||
@ -668,7 +669,7 @@ export class ResidualHeapSerializer {
|
||||
return t.expressionStatement(t.sequenceExpression(body));
|
||||
}
|
||||
|
||||
_serializeDeclarativeEnvironmentRecordBinding(residualFunctionBinding: ResidualFunctionBinding) {
|
||||
_serializeDeclarativeEnvironmentRecordBinding(residualFunctionBinding: ResidualFunctionBinding): void {
|
||||
if (!residualFunctionBinding.serializedValue) {
|
||||
let value = residualFunctionBinding.value;
|
||||
invariant(residualFunctionBinding.declarativeEnvironmentRecord);
|
||||
@ -954,7 +955,7 @@ export class ResidualHeapSerializer {
|
||||
return { body, commonAncestor };
|
||||
}
|
||||
|
||||
_getValueDebugName(val: Value) {
|
||||
_getValueDebugName(val: Value): string {
|
||||
let name;
|
||||
if (val instanceof FunctionValue) {
|
||||
name = val.getName();
|
||||
@ -1001,7 +1002,7 @@ export class ResidualHeapSerializer {
|
||||
bindingType: BabelVariableKind,
|
||||
id: BabelNodeLVal,
|
||||
init: BabelNodeExpression
|
||||
) {
|
||||
): void {
|
||||
if (emittingToResidualFunction) {
|
||||
let declar = t.variableDeclaration(bindingType, [t.variableDeclarator(id)]);
|
||||
this.getPrelude(referencingOnlyOptimizedFunction).push(declar);
|
||||
@ -1133,7 +1134,7 @@ export class ResidualHeapSerializer {
|
||||
return [desc.get, desc.set];
|
||||
}
|
||||
|
||||
_deleteProperty(location: BabelNodeLVal) {
|
||||
_deleteProperty(location: BabelNodeLVal): void {
|
||||
invariant(location.type === "MemberExpression");
|
||||
this.emitter.emit(
|
||||
t.expressionStatement(t.unaryExpression("delete", ((location: any): BabelNodeMemberExpression), true))
|
||||
@ -1193,7 +1194,7 @@ export class ResidualHeapSerializer {
|
||||
array: ObjectValue,
|
||||
indexPropertyLength: number,
|
||||
remainingProperties: Map<string, PropertyBinding>
|
||||
) {
|
||||
): Array<null | BabelNodeExpression | BabelNodeSpreadElement> {
|
||||
let elems = [];
|
||||
for (let i = 0; i < indexPropertyLength; i++) {
|
||||
let key = i + "";
|
||||
@ -1716,7 +1717,11 @@ export class ResidualHeapSerializer {
|
||||
return t.objectExpression(props);
|
||||
}
|
||||
|
||||
_serializeValueObjectViaConstructor(val: ObjectValue, skipPrototype: boolean, classConstructor?: Value) {
|
||||
_serializeValueObjectViaConstructor(
|
||||
val: ObjectValue,
|
||||
skipPrototype: boolean,
|
||||
classConstructor?: Value
|
||||
): BabelNodeExpression {
|
||||
let proto = val.$Prototype;
|
||||
this._emitObjectProperties(
|
||||
val,
|
||||
@ -1963,7 +1968,7 @@ export class ResidualHeapSerializer {
|
||||
}
|
||||
}
|
||||
|
||||
_serializeValueObjectBase(obj: ObjectValue) {
|
||||
_serializeValueObjectBase(obj: ObjectValue): void | BabelNodeExpression {
|
||||
if (obj instanceof ProxyValue) {
|
||||
return this._serializeValueProxy(obj);
|
||||
}
|
||||
@ -2009,7 +2014,7 @@ export class ResidualHeapSerializer {
|
||||
return res;
|
||||
}
|
||||
|
||||
_serializeGlobalBinding(boundName: string, binding: ResidualFunctionBinding) {
|
||||
_serializeGlobalBinding(boundName: string, binding: ResidualFunctionBinding): void {
|
||||
invariant(!binding.declarativeEnvironmentRecord);
|
||||
if (!binding.serializedValue) {
|
||||
binding.referentialized = true;
|
||||
@ -2023,7 +2028,7 @@ export class ResidualHeapSerializer {
|
||||
}
|
||||
}
|
||||
|
||||
_annotateGeneratorStatements(generator: Generator, statements: Array<BabelNodeStatement>) {
|
||||
_annotateGeneratorStatements(generator: Generator, statements: Array<BabelNodeStatement>): void {
|
||||
let comment = `generator "${generator.getName()}"`;
|
||||
let parent = this.generatorDAG.getParent(generator);
|
||||
if (parent instanceof Generator) {
|
||||
@ -2172,7 +2177,7 @@ export class ResidualHeapSerializer {
|
||||
return context;
|
||||
}
|
||||
|
||||
_shouldBeWrapped(body: Array<any>) {
|
||||
_shouldBeWrapped(body: Array<any>): boolean {
|
||||
for (let i = 0; i < body.length; i++) {
|
||||
let item = body[i];
|
||||
if (item.type === "ExpressionStatement") {
|
||||
@ -2203,7 +2208,7 @@ export class ResidualHeapSerializer {
|
||||
generator: Generator,
|
||||
functionValue: FunctionValue,
|
||||
additionalEffects: AdditionalFunctionEffects
|
||||
) {
|
||||
): Array<BabelNodeStatement> {
|
||||
let inAdditionalFunction = this.tryGetOptimizedFunctionRoot(functionValue);
|
||||
return this._withGeneratorScope(
|
||||
"AdditionalFunction",
|
||||
@ -2230,7 +2235,10 @@ export class ResidualHeapSerializer {
|
||||
// -- we don't overwrite anything they capture
|
||||
// PropertyBindings -- visit any property bindings that aren't to createdobjects
|
||||
// CreatedObjects -- should take care of itself
|
||||
_serializeAdditionalFunction(additionalFunctionValue: FunctionValue, additionalEffects: AdditionalFunctionEffects) {
|
||||
_serializeAdditionalFunction(
|
||||
additionalFunctionValue: FunctionValue,
|
||||
additionalEffects: AdditionalFunctionEffects
|
||||
): void {
|
||||
let { effects, transforms, generator, additionalRoots } = additionalEffects;
|
||||
// No function info means the function is dead code, also break recursive cycles where we've already started
|
||||
// serializing this value
|
||||
@ -2265,7 +2273,7 @@ export class ResidualHeapSerializer {
|
||||
this.rewrittenAdditionalFunctions.set(additionalFunctionValue, body);
|
||||
}
|
||||
|
||||
prepareAdditionalFunctionValues() {
|
||||
prepareAdditionalFunctionValues(): void {
|
||||
let additionalFVEffects = this.additionalFunctionValuesAndEffects;
|
||||
if (additionalFVEffects)
|
||||
for (let [additionalFunctionValue, { generator }] of additionalFVEffects.entries()) {
|
||||
@ -2413,7 +2421,7 @@ export class ResidualHeapSerializer {
|
||||
return t.file(t.program(ast_body, program_directives));
|
||||
}
|
||||
|
||||
_logScopes(scopes: Set<Scope>) {
|
||||
_logScopes(scopes: Set<Scope>): void {
|
||||
console.log(` referenced by ${scopes.size} scopes`);
|
||||
for (let s of scopes)
|
||||
if (s instanceof Generator) {
|
||||
@ -2426,7 +2434,7 @@ export class ResidualHeapSerializer {
|
||||
}
|
||||
}
|
||||
|
||||
_logSerializedResidualMismatches() {
|
||||
_logSerializedResidualMismatches(): void {
|
||||
let logValue = value => {
|
||||
console.log(describeValue(value));
|
||||
let scopes = this.residualValues.get(value);
|
||||
|
@ -27,12 +27,12 @@ export class ResidualHeapValueIdentifiers {
|
||||
this._populateIdentifierMap(values);
|
||||
}
|
||||
|
||||
initPass1() {
|
||||
initPass1(): void {
|
||||
this.collectValToRefCountOnly = true;
|
||||
this.valToRefCount = new Map();
|
||||
}
|
||||
|
||||
initPass2() {
|
||||
initPass2(): void {
|
||||
this.collectValToRefCountOnly = false;
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ export class ResidualHeapValueIdentifiers {
|
||||
refs: Map<Value, BabelNodeIdentifier>;
|
||||
_valueNameGenerator: NameGenerator;
|
||||
|
||||
_populateIdentifierMap(values: Iterator<Value>) {
|
||||
_populateIdentifierMap(values: Iterator<Value>): void {
|
||||
this.refs = new Map();
|
||||
for (const val of values) {
|
||||
this._setIdentifier(val, this._createNewIdentifier(val));
|
||||
@ -68,7 +68,7 @@ export class ResidualHeapValueIdentifiers {
|
||||
return id;
|
||||
}
|
||||
|
||||
deleteIdentifier(val: Value) {
|
||||
deleteIdentifier(val: Value): void {
|
||||
invariant(this.refs.has(val));
|
||||
this.refs.delete(val);
|
||||
}
|
||||
@ -80,7 +80,7 @@ export class ResidualHeapValueIdentifiers {
|
||||
return id;
|
||||
}
|
||||
|
||||
incrementReferenceCount(val: Value) {
|
||||
incrementReferenceCount(val: Value): void {
|
||||
if (this.collectValToRefCountOnly) {
|
||||
let valToRefCount = this.valToRefCount;
|
||||
invariant(valToRefCount !== undefined);
|
||||
@ -94,7 +94,7 @@ export class ResidualHeapValueIdentifiers {
|
||||
}
|
||||
}
|
||||
|
||||
needsIdentifier(val: Value) {
|
||||
needsIdentifier(val: Value): boolean {
|
||||
if (this.collectValToRefCountOnly || this.valToRefCount === undefined) return true;
|
||||
let refCount = this.valToRefCount.get(val);
|
||||
invariant(refCount !== undefined && refCount > 0);
|
||||
|
@ -180,7 +180,7 @@ export class ResidualHeapVisitor {
|
||||
// to the current common scope, visit the value in the scope it was
|
||||
// created --- this causes the value later to be serialized in its
|
||||
// creation scope, ensuring that the value has the right creation / life time.
|
||||
_registerAdditionalRoot(value: ObjectValue) {
|
||||
_registerAdditionalRoot(value: ObjectValue): void {
|
||||
let creationGenerator = this.generatorDAG.getCreator(value) || this.globalGenerator;
|
||||
|
||||
let additionalFunction = this._getAdditionalFunctionOfScope() || "GLOBAL";
|
||||
@ -242,7 +242,7 @@ export class ResidualHeapVisitor {
|
||||
|
||||
// Careful!
|
||||
// Only use _withScope when you know that the currently applied effects makes sense for the given (nested) scope!
|
||||
_withScope(scope: Scope, f: () => void) {
|
||||
_withScope(scope: Scope, f: () => void): void {
|
||||
let oldScope = this.scope;
|
||||
this.scope = scope;
|
||||
try {
|
||||
@ -253,18 +253,18 @@ export class ResidualHeapVisitor {
|
||||
}
|
||||
|
||||
// Queues up an action to be later processed in some arbitrary scope.
|
||||
_enqueueWithUnrelatedScope(scope: Scope, action: () => void | boolean) {
|
||||
_enqueueWithUnrelatedScope(scope: Scope, action: () => void | boolean): void {
|
||||
this.delayedActions.push({ scope, action });
|
||||
}
|
||||
|
||||
// Queues up visiting a value in some arbitrary scope.
|
||||
_visitInUnrelatedScope(scope: Scope, val: Value) {
|
||||
_visitInUnrelatedScope(scope: Scope, val: Value): void {
|
||||
let scopes = this.values.get(val);
|
||||
if (scopes !== undefined && scopes.has(scope)) return;
|
||||
this._enqueueWithUnrelatedScope(scope, () => this.visitValue(val));
|
||||
}
|
||||
|
||||
visitObjectProperty(binding: PropertyBinding) {
|
||||
visitObjectProperty(binding: PropertyBinding): void {
|
||||
let desc = binding.descriptor;
|
||||
let obj = binding.object;
|
||||
invariant(binding.key !== undefined, "Undefined keys should never make it here.");
|
||||
@ -329,7 +329,7 @@ export class ResidualHeapVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
visitObjectPrototype(obj: ObjectValue) {
|
||||
visitObjectPrototype(obj: ObjectValue): void {
|
||||
let proto = obj.$Prototype;
|
||||
|
||||
let kind = obj.getKind();
|
||||
@ -340,7 +340,7 @@ export class ResidualHeapVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
visitConstructorPrototype(func: Value) {
|
||||
visitConstructorPrototype(func: Value): void {
|
||||
// If the original prototype object was mutated,
|
||||
// request its serialization here as this might be observable by
|
||||
// residual code.
|
||||
@ -629,7 +629,7 @@ export class ResidualHeapVisitor {
|
||||
// function c() { return x.length + y.length; }
|
||||
// Here we need to make sure that a and b both initialize x and y because x and y will be in the same
|
||||
// captured scope because c captures both x and y.
|
||||
visitBinding(val: FunctionValue, residualFunctionBinding: ResidualFunctionBinding) {
|
||||
visitBinding(val: FunctionValue, residualFunctionBinding: ResidualFunctionBinding): void {
|
||||
let environment = residualFunctionBinding.declarativeEnvironmentRecord;
|
||||
if (environment === null) return;
|
||||
invariant(this.scope === val);
|
||||
@ -983,7 +983,7 @@ export class ResidualHeapVisitor {
|
||||
}
|
||||
|
||||
// Overridable hook for post-visiting the value.
|
||||
postProcessValue(val: Value) {}
|
||||
postProcessValue(val: Value): void {}
|
||||
|
||||
_mark(val: Value): boolean {
|
||||
let scopes = this.values.get(val);
|
||||
@ -1189,7 +1189,7 @@ export class ResidualHeapVisitor {
|
||||
// we don't overwrite anything they capture
|
||||
// PropertyBindings -- (property modifications) visit any property bindings to pre-existing objects
|
||||
// CreatedObjects -- should take care of itself
|
||||
_visitAdditionalFunction(functionValue: FunctionValue, additionalEffects: AdditionalFunctionEffects) {
|
||||
_visitAdditionalFunction(functionValue: FunctionValue, additionalEffects: AdditionalFunctionEffects): void {
|
||||
// Get Instance + Info
|
||||
invariant(functionValue instanceof ECMAScriptSourceFunctionValue);
|
||||
let code = functionValue.$ECMAScriptCode;
|
||||
@ -1230,7 +1230,7 @@ export class ResidualHeapVisitor {
|
||||
for (let instance of this.functionInstances.values()) referentializer.referentialize(instance);
|
||||
}
|
||||
|
||||
_visitUntilFixpoint() {
|
||||
_visitUntilFixpoint(): void {
|
||||
if (this.realm.react.verbose) {
|
||||
this.logger.logInformation(`Computing fixed point...`);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import { ResidualHeapSerializer } from "./ResidualHeapSerializer.js";
|
||||
import { canHoistReactElement } from "../react/hoisting.js";
|
||||
import * as t from "babel-types";
|
||||
import type { BabelNode, BabelNodeExpression } from "babel-types";
|
||||
import { AbstractValue, ObjectValue, SymbolValue, Value } from "../values/index.js";
|
||||
import { AbstractValue, AbstractObjectValue, ObjectValue, SymbolValue, Value } from "../values/index.js";
|
||||
import { convertExpressionToJSXIdentifier, convertKeyValueToJSXAttribute } from "../react/jsx.js";
|
||||
import { Logger } from "../utils/logger.js";
|
||||
import invariant from "../invariant.js";
|
||||
@ -79,7 +79,7 @@ export class ResidualReactElementSerializer {
|
||||
reactElementAst: BabelNodeExpression,
|
||||
hoistedCreateElementIdentifier: BabelNodeIdentifier,
|
||||
originalCreateElementIdentifier: BabelNodeIdentifier
|
||||
) {
|
||||
): void {
|
||||
// if the currentHoistedReactElements is not defined, we create it an emit the function call
|
||||
// this should only occur once per additional function
|
||||
if (this._lazilyHoistedNodes === undefined) {
|
||||
@ -107,7 +107,7 @@ export class ResidualReactElementSerializer {
|
||||
this._lazilyHoistedNodes.nodes.push({ id, astNode: reactElementAst });
|
||||
}
|
||||
|
||||
_getReactLibraryValue() {
|
||||
_getReactLibraryValue(): AbstractObjectValue | ObjectValue {
|
||||
let reactLibraryObject = this.realm.fbLibraries.react;
|
||||
// if there is no React library, then we should throw and error
|
||||
if (reactLibraryObject === undefined) {
|
||||
@ -116,7 +116,7 @@ export class ResidualReactElementSerializer {
|
||||
return reactLibraryObject;
|
||||
}
|
||||
|
||||
_getReactCreateElementValue() {
|
||||
_getReactCreateElementValue(): Value {
|
||||
let reactLibraryObject = this._getReactLibraryValue();
|
||||
return getProperty(this.realm, reactLibraryObject, "createElement");
|
||||
}
|
||||
@ -438,7 +438,7 @@ export class ResidualReactElementSerializer {
|
||||
return reactElementChild;
|
||||
}
|
||||
|
||||
serializeLazyHoistedNodes() {
|
||||
serializeLazyHoistedNodes(): Array<BabelNodeStatement> {
|
||||
const entries = [];
|
||||
if (this._lazilyHoistedNodes !== undefined) {
|
||||
let { id, nodes, createElementIdentifier } = this._lazilyHoistedNodes;
|
||||
|
@ -137,7 +137,7 @@ export class ResidualReactElementVisitor {
|
||||
determineIfReactElementCanBeHoisted(this.realm, reactElement, this.residualHeapVisitor);
|
||||
}
|
||||
|
||||
withCleanEquivalenceSet(func: () => void) {
|
||||
withCleanEquivalenceSet(func: () => void): void {
|
||||
let reactEquivalenceSet = this.reactEquivalenceSet;
|
||||
let reactElementEquivalenceSet = this.reactElementEquivalenceSet;
|
||||
let reactPropsEquivalenceSet = this.reactPropsEquivalenceSet;
|
||||
|
@ -108,7 +108,7 @@ export class Functions {
|
||||
throw new FatalError("Optimized Function Values must be functions or react elements");
|
||||
}
|
||||
|
||||
__generateInitialAdditionalFunctions(globalKey: string) {
|
||||
__generateInitialAdditionalFunctions(globalKey: string): Array<AdditionalFunctionEntry> {
|
||||
let recordedAdditionalFunctions: Array<AdditionalFunctionEntry> = [];
|
||||
let realm = this.realm;
|
||||
let globalRecordedAdditionalFunctionsMap = this.moduleTracer.modules.logger.tryQuery(
|
||||
@ -187,7 +187,7 @@ export class Functions {
|
||||
return call.bind(this, thisArg, args);
|
||||
}
|
||||
|
||||
checkThatFunctionsAreIndependent(environmentRecordIdAfterGlobalCode: number) {
|
||||
checkThatFunctionsAreIndependent(environmentRecordIdAfterGlobalCode: number): void {
|
||||
let additionalFunctionsToProcess = this.__generateInitialAdditionalFunctions("__optimizedFunctions");
|
||||
// When we find declarations of nested optimized functions, we need to apply the parent
|
||||
// effects.
|
||||
@ -325,7 +325,7 @@ export class Functions {
|
||||
conflicts: Map<BabelNodeSourceLocation, CompilerDiagnostic>,
|
||||
pbs: PropertyBindings,
|
||||
call2: void => Value
|
||||
) {
|
||||
): void {
|
||||
let reportConflict = (location: BabelNodeSourceLocation) => {
|
||||
let error = new CompilerDiagnostic(
|
||||
`Property access conflicts with write in optimized function ${fname}`,
|
||||
|
@ -35,7 +35,7 @@ export class SerializerStatistics extends RealmStatistics {
|
||||
this.babelGenerate = new PerformanceTracker(getTime, getMemory);
|
||||
}
|
||||
|
||||
resetBeforePass() {
|
||||
resetBeforePass(): void {
|
||||
this.objects = 0;
|
||||
this.objectProperties = 0;
|
||||
this.functionClones = 0;
|
||||
@ -99,7 +99,7 @@ export class SerializerStatistics extends RealmStatistics {
|
||||
serializePass: PerformanceTracker;
|
||||
babelGenerate: PerformanceTracker;
|
||||
|
||||
log() {
|
||||
log(): void {
|
||||
super.log();
|
||||
console.log(`=== serialization statistics`);
|
||||
console.log(`${this.objects} objects with ${this.objectProperties} properties`);
|
||||
@ -123,7 +123,7 @@ export class SerializerStatistics extends RealmStatistics {
|
||||
console.log(`${this.generators} generators`);
|
||||
}
|
||||
|
||||
logSerializerPerformanceTrackers(title: string, note: void | string, format: PerformanceTracker => string) {
|
||||
logSerializerPerformanceTrackers(title: string, note: void | string, format: PerformanceTracker => string): void {
|
||||
console.log(`=== ${title}: ${format(this.total)} total`);
|
||||
if (note !== undefined) console.log(`NOTE: ${note}`);
|
||||
this.logPerformanceTrackers(format);
|
||||
|
@ -28,7 +28,7 @@ export class RealmStatistics {
|
||||
evaluatedNodes: number;
|
||||
|
||||
// legacy projection
|
||||
getRealmStatistics() {
|
||||
getRealmStatistics(): any {
|
||||
return {
|
||||
simplifications: this.simplifications,
|
||||
simplificationAttempts: this.simplificationAttempts,
|
||||
@ -41,7 +41,7 @@ export class RealmStatistics {
|
||||
fixupFilenames: PerformanceTracker;
|
||||
evaluation: PerformanceTracker;
|
||||
|
||||
projectPerformanceTrackers(suffix: string, projection: PerformanceTracker => number) {
|
||||
projectPerformanceTrackers(suffix: string, projection: PerformanceTracker => number): any {
|
||||
let res = {};
|
||||
for (let key of Object.keys(this)) {
|
||||
let value = (this: any)[key];
|
||||
@ -50,7 +50,7 @@ export class RealmStatistics {
|
||||
return res;
|
||||
}
|
||||
|
||||
log() {
|
||||
log(): void {
|
||||
console.log(`=== realm statistics`);
|
||||
console.log(`${this.evaluatedNodes} AST nodes evaluated.`);
|
||||
console.log(`${this.simplifications} abstract values simplified after ${this.simplificationAttempts} attempts.`);
|
||||
|
@ -641,7 +641,7 @@ export type EnvironmentType = {
|
||||
realm: Realm,
|
||||
G: ObjectValue | AbstractObjectValue,
|
||||
thisValue: ObjectValue | AbstractObjectValue
|
||||
): void,
|
||||
): LexicalEnvironment,
|
||||
|
||||
// ECMA262 8.1.2.3
|
||||
NewObjectEnvironment(realm: Realm, O: ObjectValue | AbstractObjectValue, E: LexicalEnvironment): LexicalEnvironment,
|
||||
|
@ -83,7 +83,7 @@ export class HeapInspector {
|
||||
freeze: { writable: false, configurable: false },
|
||||
};
|
||||
|
||||
getTargetIntegrityDescriptor(val: ObjectValue) {
|
||||
getTargetIntegrityDescriptor(val: ObjectValue): { writable: boolean, configurable: boolean } {
|
||||
return HeapInspector._integrityDescriptors[this.getTargetIntegrityCommand(val)];
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ export class HeapInspector {
|
||||
}
|
||||
|
||||
// Object properties which have the default value can be ignored by the serializer.
|
||||
canIgnoreProperty(val: ObjectValue, key: string) {
|
||||
canIgnoreProperty(val: ObjectValue, key: string): boolean {
|
||||
let set = this.ignoredProperties.get(val);
|
||||
if (!set) {
|
||||
this.ignoredProperties.set(val, (set = this._getIgnoredProperties(val)));
|
||||
@ -123,7 +123,7 @@ export class HeapInspector {
|
||||
return set.has(key);
|
||||
}
|
||||
|
||||
_getIgnoredProperties(val: ObjectValue) {
|
||||
_getIgnoredProperties(val: ObjectValue): Set<string> {
|
||||
let set: Set<string> = new Set();
|
||||
for (let [key, propertyBinding] of val.properties) {
|
||||
invariant(propertyBinding);
|
||||
@ -134,7 +134,7 @@ export class HeapInspector {
|
||||
return set;
|
||||
}
|
||||
|
||||
_canIgnoreProperty(val: ObjectValue, key: string, desc: Descriptor) {
|
||||
_canIgnoreProperty(val: ObjectValue, key: string, desc: Descriptor): boolean {
|
||||
let targetDescriptor = this.getTargetIntegrityDescriptor(val);
|
||||
|
||||
if (IsArray(this.realm, val)) {
|
||||
|
@ -192,7 +192,7 @@ export class TemporalBuildNodeEntry extends GeneratorEntry {
|
||||
}
|
||||
}
|
||||
|
||||
serialize(context: SerializationContext) {
|
||||
serialize(context: SerializationContext): void {
|
||||
let omit = this.isPure && this.declared && context.canOmit(this.declared);
|
||||
|
||||
if (!omit && this.declared && this.mutatesOnly !== undefined) {
|
||||
@ -229,7 +229,7 @@ export class TemporalBuildNodeEntry extends GeneratorEntry {
|
||||
}
|
||||
}
|
||||
|
||||
getDependencies() {
|
||||
getDependencies(): void | Array<Generator> {
|
||||
return this.dependencies;
|
||||
}
|
||||
}
|
||||
@ -282,7 +282,7 @@ class ModifiedPropertyEntry extends GeneratorEntry {
|
||||
propertyBinding: PropertyBinding;
|
||||
newDescriptor: void | Descriptor;
|
||||
|
||||
serialize(context: SerializationContext) {
|
||||
serialize(context: SerializationContext): void {
|
||||
let desc = this.propertyBinding.descriptor;
|
||||
invariant(desc === this.newDescriptor);
|
||||
context.emitPropertyModification(this.propertyBinding);
|
||||
@ -299,7 +299,7 @@ class ModifiedPropertyEntry extends GeneratorEntry {
|
||||
return true;
|
||||
}
|
||||
|
||||
getDependencies() {
|
||||
getDependencies(): void | Array<Generator> {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@ -321,7 +321,7 @@ class ModifiedBindingEntry extends GeneratorEntry {
|
||||
newValue: void | Value;
|
||||
residualFunctionBinding: void | ResidualFunctionBinding;
|
||||
|
||||
serialize(context: SerializationContext) {
|
||||
serialize(context: SerializationContext): void {
|
||||
let residualFunctionBinding = this.residualFunctionBinding;
|
||||
invariant(residualFunctionBinding !== undefined);
|
||||
invariant(residualFunctionBinding.referentialized);
|
||||
@ -359,7 +359,7 @@ class ModifiedBindingEntry extends GeneratorEntry {
|
||||
return true;
|
||||
}
|
||||
|
||||
getDependencies() {
|
||||
getDependencies(): void | Array<Generator> {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@ -383,12 +383,12 @@ class ReturnValueEntry extends GeneratorEntry {
|
||||
return true;
|
||||
}
|
||||
|
||||
serialize(context: SerializationContext) {
|
||||
serialize(context: SerializationContext): void {
|
||||
let result = context.serializeValue(this.returnValue);
|
||||
context.emit(t.returnStatement(result));
|
||||
}
|
||||
|
||||
getDependencies() {
|
||||
getDependencies(): void | Array<Generator> {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@ -422,7 +422,7 @@ class IfThenElseEntry extends GeneratorEntry {
|
||||
return true;
|
||||
}
|
||||
|
||||
serialize(context: SerializationContext) {
|
||||
serialize(context: SerializationContext): void {
|
||||
let condition = context.serializeValue(this.condition);
|
||||
let valuesToProcess = new Set();
|
||||
let consequentBody = context.serializeGenerator(this.consequentGenerator, valuesToProcess);
|
||||
@ -431,7 +431,7 @@ class IfThenElseEntry extends GeneratorEntry {
|
||||
context.processValues(valuesToProcess);
|
||||
}
|
||||
|
||||
getDependencies() {
|
||||
getDependencies(): void | Array<Generator> {
|
||||
return [this.consequentGenerator, this.alternateGenerator];
|
||||
}
|
||||
}
|
||||
@ -446,7 +446,7 @@ class BindingAssignmentEntry extends GeneratorEntry {
|
||||
binding: Binding;
|
||||
value: Value;
|
||||
|
||||
serialize(context: SerializationContext) {
|
||||
serialize(context: SerializationContext): void {
|
||||
context.emit(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression("=", context.serializeBinding(this.binding), context.serializeValue(this.value))
|
||||
@ -459,7 +459,7 @@ class BindingAssignmentEntry extends GeneratorEntry {
|
||||
return true;
|
||||
}
|
||||
|
||||
getDependencies() {
|
||||
getDependencies(): void | Array<Generator> {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@ -496,7 +496,12 @@ export class Generator {
|
||||
_name: string;
|
||||
pathConditions: Array<AbstractValue>;
|
||||
|
||||
static _generatorOfEffects(realm: Realm, name: string, environmentRecordIdAfterGlobalCode: number, effects: Effects) {
|
||||
static _generatorOfEffects(
|
||||
realm: Realm,
|
||||
name: string,
|
||||
environmentRecordIdAfterGlobalCode: number,
|
||||
effects: Effects
|
||||
): Generator {
|
||||
let { result, generator, modifiedBindings, modifiedProperties, createdObjects } = effects;
|
||||
|
||||
let output = new Generator(realm, name, generator.pathConditions, effects);
|
||||
@ -549,7 +554,7 @@ export class Generator {
|
||||
);
|
||||
}
|
||||
|
||||
emitPropertyModification(propertyBinding: PropertyBinding) {
|
||||
emitPropertyModification(propertyBinding: PropertyBinding): void {
|
||||
invariant(this.effectsToApply !== undefined);
|
||||
let desc = propertyBinding.descriptor;
|
||||
if (desc !== undefined) {
|
||||
@ -582,7 +587,7 @@ export class Generator {
|
||||
);
|
||||
}
|
||||
|
||||
emitBindingModification(modifiedBinding: Binding) {
|
||||
emitBindingModification(modifiedBinding: Binding): void {
|
||||
invariant(this.effectsToApply !== undefined);
|
||||
this._entries.push(
|
||||
new ModifiedBindingEntry(this.realm, {
|
||||
@ -593,11 +598,11 @@ export class Generator {
|
||||
);
|
||||
}
|
||||
|
||||
emitReturnValue(result: Value) {
|
||||
emitReturnValue(result: Value): void {
|
||||
this._entries.push(new ReturnValueEntry(this.realm, this, result));
|
||||
}
|
||||
|
||||
emitIfThenElse(result: PossiblyNormalCompletion | ForkedAbruptCompletion, realm: Realm) {
|
||||
emitIfThenElse(result: PossiblyNormalCompletion | ForkedAbruptCompletion, realm: Realm): void {
|
||||
this._entries.push(new IfThenElseEntry(this, result, realm));
|
||||
}
|
||||
|
||||
@ -605,16 +610,16 @@ export class Generator {
|
||||
return `${this._name}(#${this.id})`;
|
||||
}
|
||||
|
||||
empty() {
|
||||
empty(): boolean {
|
||||
return this._entries.length === 0;
|
||||
}
|
||||
|
||||
emitGlobalDeclaration(key: string, value: Value) {
|
||||
emitGlobalDeclaration(key: string, value: Value): void {
|
||||
this.preludeGenerator.declaredGlobals.add(key);
|
||||
if (!(value instanceof UndefinedValue)) this.emitGlobalAssignment(key, value);
|
||||
}
|
||||
|
||||
emitGlobalAssignment(key: string, value: Value) {
|
||||
emitGlobalAssignment(key: string, value: Value): void {
|
||||
this._addEntry({
|
||||
args: [value],
|
||||
buildNode: ([valueNode]) =>
|
||||
@ -624,7 +629,7 @@ export class Generator {
|
||||
});
|
||||
}
|
||||
|
||||
emitConcreteModel(key: string, value: Value) {
|
||||
emitConcreteModel(key: string, value: Value): void {
|
||||
this._addEntry({
|
||||
args: [concretize(this.realm, value)],
|
||||
buildNode: ([valueNode]) =>
|
||||
@ -634,7 +639,7 @@ export class Generator {
|
||||
});
|
||||
}
|
||||
|
||||
emitGlobalDelete(key: string) {
|
||||
emitGlobalDelete(key: string): void {
|
||||
this._addEntry({
|
||||
args: [],
|
||||
buildNode: ([]) =>
|
||||
@ -642,11 +647,11 @@ export class Generator {
|
||||
});
|
||||
}
|
||||
|
||||
emitBindingAssignment(binding: Binding, value: Value) {
|
||||
emitBindingAssignment(binding: Binding, value: Value): void {
|
||||
this._entries.push(new BindingAssignmentEntry(this.realm, binding, value));
|
||||
}
|
||||
|
||||
emitPropertyAssignment(object: ObjectValue, key: string, value: Value) {
|
||||
emitPropertyAssignment(object: ObjectValue, key: string, value: Value): void {
|
||||
if (object.refuseSerialization) return;
|
||||
this._addEntry({
|
||||
args: [object, value],
|
||||
@ -660,7 +665,7 @@ export class Generator {
|
||||
});
|
||||
}
|
||||
|
||||
emitDefineProperty(object: ObjectValue, key: string, desc: Descriptor, isDescChanged: boolean = true) {
|
||||
emitDefineProperty(object: ObjectValue, key: string, desc: Descriptor, isDescChanged: boolean = true): void {
|
||||
if (object.refuseSerialization) return;
|
||||
if (desc.enumerable && desc.configurable && desc.writable && desc.value && !isDescChanged) {
|
||||
let descValue = desc.value;
|
||||
@ -682,7 +687,7 @@ export class Generator {
|
||||
}
|
||||
}
|
||||
|
||||
emitPropertyDelete(object: ObjectValue, key: string) {
|
||||
emitPropertyDelete(object: ObjectValue, key: string): void {
|
||||
if (object.refuseSerialization) return;
|
||||
this._addEntry({
|
||||
args: [object],
|
||||
@ -691,14 +696,14 @@ export class Generator {
|
||||
});
|
||||
}
|
||||
|
||||
emitCall(createCallee: () => BabelNodeExpression, args: Array<Value>) {
|
||||
emitCall(createCallee: () => BabelNodeExpression, args: Array<Value>): void {
|
||||
this._addEntry({
|
||||
args,
|
||||
buildNode: values => t.expressionStatement(t.callExpression(createCallee(), [...values])),
|
||||
});
|
||||
}
|
||||
|
||||
emitConsoleLog(method: ConsoleMethodTypes, args: Array<string | ConcreteValue>) {
|
||||
emitConsoleLog(method: ConsoleMethodTypes, args: Array<string | ConcreteValue>): void {
|
||||
this.emitCall(
|
||||
() => t.memberExpression(t.identifier("console"), t.identifier(method)),
|
||||
args.map(v => (typeof v === "string" ? new StringValue(this.realm, v) : v))
|
||||
@ -706,7 +711,7 @@ export class Generator {
|
||||
}
|
||||
|
||||
// test must be a temporal value, which means that it must have a defined intrinsicName
|
||||
emitDoWhileStatement(test: AbstractValue, body: Generator) {
|
||||
emitDoWhileStatement(test: AbstractValue, body: Generator): void {
|
||||
this._addEntry({
|
||||
args: [],
|
||||
buildNode: function([], context, valuesToProcess) {
|
||||
@ -720,7 +725,7 @@ export class Generator {
|
||||
});
|
||||
}
|
||||
|
||||
emitConditionalThrow(value: Value) {
|
||||
emitConditionalThrow(value: Value): void {
|
||||
function createStatement(val: Value, context: SerializationContext) {
|
||||
if (!(val instanceof AbstractValue) || val.kind !== "conditional") {
|
||||
return t.throwStatement(context.serializeValue(val));
|
||||
@ -742,7 +747,7 @@ export class Generator {
|
||||
});
|
||||
}
|
||||
|
||||
_issueThrowCompilerDiagnostic(value: Value) {
|
||||
_issueThrowCompilerDiagnostic(value: Value): void {
|
||||
let message = "Program may terminate with exception";
|
||||
if (value instanceof ObjectValue) {
|
||||
let object = ((value: any): ObjectValue);
|
||||
@ -757,7 +762,7 @@ export class Generator {
|
||||
this.realm.handleError(diagnostic);
|
||||
}
|
||||
|
||||
emitThrow(value: Value) {
|
||||
emitThrow(value: Value): void {
|
||||
this._issueThrowCompilerDiagnostic(value);
|
||||
this.emitStatement([value], ([argument]) => t.throwStatement(argument));
|
||||
}
|
||||
@ -766,7 +771,7 @@ export class Generator {
|
||||
// for any AbstractValues
|
||||
// e.g: (obj.property !== undefined && typeof obj.property !== "object")
|
||||
// NB: if the type of the AbstractValue is top, skips the invariant
|
||||
emitFullInvariant(object: ObjectValue | AbstractObjectValue, key: string, value: Value) {
|
||||
emitFullInvariant(object: ObjectValue | AbstractObjectValue, key: string, value: Value): void {
|
||||
if (object.refuseSerialization) return;
|
||||
let accessedPropertyOf = objectNode => memberExpressionHelper(objectNode, key);
|
||||
let condition;
|
||||
@ -785,7 +790,7 @@ export class Generator {
|
||||
invariant(nestedValue instanceof AbstractValue);
|
||||
populateComparisonsLists(nestedValue);
|
||||
}
|
||||
} else if (absValue.getType().isTop || absValue.getType() === Value) {
|
||||
} else if (absValue.getType() === Value) {
|
||||
isTop = true;
|
||||
} else {
|
||||
typeComparisons.add(absValue.getType());
|
||||
@ -857,7 +862,7 @@ export class Generator {
|
||||
object: ObjectValue | AbstractObjectValue,
|
||||
key: string,
|
||||
state: "MISSING" | "PRESENT" | "DEFINED"
|
||||
) {
|
||||
): void {
|
||||
if (object.refuseSerialization) return;
|
||||
let accessedPropertyOf = (objectNode: BabelNodeExpression) => memberExpressionHelper(objectNode, key);
|
||||
let condition = ([objectNode: BabelNodeExpression]) => {
|
||||
@ -921,7 +926,7 @@ export class Generator {
|
||||
return this.deriveAbstract(types, values, args, (nodes: any) => t.callExpression(createCallee(), nodes), { kind });
|
||||
}
|
||||
|
||||
emitStatement(args: Array<Value>, buildNode_: (Array<BabelNodeExpression>) => BabelNodeStatement) {
|
||||
emitStatement(args: Array<Value>, buildNode_: (Array<BabelNodeExpression>) => BabelNodeStatement): void {
|
||||
this._addEntry({
|
||||
args,
|
||||
buildNode: buildNode_,
|
||||
@ -952,7 +957,7 @@ export class Generator {
|
||||
sourceObject: ObjectValue,
|
||||
targetObject: ObjectValue,
|
||||
boundName: BabelNodeIdentifier
|
||||
) {
|
||||
): void {
|
||||
this._addEntry({
|
||||
// duplicate args to ensure refcount > 1
|
||||
args: [o, targetObject, sourceObject, targetObject, sourceObject],
|
||||
@ -1089,7 +1094,7 @@ export class Generator {
|
||||
return res;
|
||||
}
|
||||
|
||||
visit(callbacks: VisitEntryCallbacks) {
|
||||
visit(callbacks: VisitEntryCallbacks): void {
|
||||
let visitFn = () => {
|
||||
for (let entry of this._entries) entry.visit(callbacks, this);
|
||||
return null;
|
||||
@ -1101,7 +1106,7 @@ export class Generator {
|
||||
}
|
||||
}
|
||||
|
||||
serialize(context: SerializationContext) {
|
||||
serialize(context: SerializationContext): void {
|
||||
let serializeFn = () => {
|
||||
context.initGenerator(this);
|
||||
for (let entry of this._entries) entry.serialize(context);
|
||||
@ -1187,7 +1192,7 @@ export class Generator {
|
||||
}
|
||||
}
|
||||
|
||||
function escapeInvalidIdentifierCharacters(s: string) {
|
||||
function escapeInvalidIdentifierCharacters(s: string): string {
|
||||
let res = "";
|
||||
for (let c of s)
|
||||
if ((c >= "0" && c <= "9") || (c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) res += c;
|
||||
@ -1276,7 +1281,7 @@ export class PreludeGenerator {
|
||||
.reduce((obj, prop) => t.memberExpression(obj, prop));
|
||||
}
|
||||
|
||||
globalReference(key: string, globalScope: boolean = false) {
|
||||
globalReference(key: string, globalScope: boolean = false): BabelNodeIdentifier | BabelNodeMemberExpression {
|
||||
if (globalScope && t.isValidIdentifier(key)) return t.identifier(key);
|
||||
return memberExpressionHelper(this.memoizeReference("global"), key);
|
||||
}
|
||||
|
@ -47,7 +47,13 @@ type HavocedFunctionInfo = {
|
||||
unboundWrites: Set<string>,
|
||||
};
|
||||
|
||||
function visitName(path: BabelTraversePath, state: HavocedFunctionInfo, name: string, read: boolean, write: boolean) {
|
||||
function visitName(
|
||||
path: BabelTraversePath,
|
||||
state: HavocedFunctionInfo,
|
||||
name: string,
|
||||
read: boolean,
|
||||
write: boolean
|
||||
): void {
|
||||
// Is the name bound to some local identifier? If so, we don't need to do anything
|
||||
if (path.scope.hasBinding(name, /*noGlobals*/ true)) return;
|
||||
|
||||
@ -56,13 +62,13 @@ function visitName(path: BabelTraversePath, state: HavocedFunctionInfo, name: st
|
||||
if (write) state.unboundWrites.add(name);
|
||||
}
|
||||
|
||||
function ignorePath(path: BabelTraversePath) {
|
||||
function ignorePath(path: BabelTraversePath): boolean {
|
||||
let parent = path.parent;
|
||||
return t.isLabeledStatement(parent) || t.isBreakStatement(parent) || t.isContinueStatement(parent);
|
||||
}
|
||||
|
||||
let HavocedClosureRefVisitor = {
|
||||
ReferencedIdentifier(path: BabelTraversePath, state: HavocedFunctionInfo) {
|
||||
ReferencedIdentifier(path: BabelTraversePath, state: HavocedFunctionInfo): void {
|
||||
if (ignorePath(path)) return;
|
||||
|
||||
let innerName = path.node.name;
|
||||
@ -72,7 +78,7 @@ let HavocedClosureRefVisitor = {
|
||||
visitName(path, state, innerName, true, false);
|
||||
},
|
||||
|
||||
"AssignmentExpression|UpdateExpression"(path: BabelTraversePath, state: HavocedFunctionInfo) {
|
||||
"AssignmentExpression|UpdateExpression"(path: BabelTraversePath, state: HavocedFunctionInfo): void {
|
||||
let doesRead = path.node.operator !== "=";
|
||||
for (let name in path.getBindingIdentifiers()) {
|
||||
visitName(path, state, name, doesRead, true);
|
||||
@ -137,7 +143,7 @@ class ObjectValueHavocingVisitor {
|
||||
return true;
|
||||
}
|
||||
|
||||
visitObjectProperty(binding: PropertyBinding) {
|
||||
visitObjectProperty(binding: PropertyBinding): void {
|
||||
let desc = binding.descriptor;
|
||||
if (desc === undefined) return; //deleted
|
||||
this.visitDescriptor(desc);
|
||||
@ -227,7 +233,7 @@ class ObjectValueHavocingVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
visitObjectPrototype(obj: ObjectValue) {
|
||||
visitObjectPrototype(obj: ObjectValue): void {
|
||||
let proto = obj.$Prototype;
|
||||
this.visitValue(proto);
|
||||
}
|
||||
@ -273,7 +279,7 @@ class ObjectValueHavocingVisitor {
|
||||
visitDeclarativeEnvironmentRecordBinding(
|
||||
record: DeclarativeEnvironmentRecord,
|
||||
remainingHavocedBindings: HavocedFunctionInfo
|
||||
) {
|
||||
): void {
|
||||
let bindings = record.bindings;
|
||||
for (let bindingName of Object.keys(bindings)) {
|
||||
let binding = bindings[bindingName];
|
||||
@ -514,7 +520,7 @@ class ObjectValueHavocingVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
function ensureFrozenValue(realm, value, loc) {
|
||||
function ensureFrozenValue(realm, value, loc): void {
|
||||
// TODO: This should really check if it is recursively immutability.
|
||||
if (value instanceof ObjectValue && !TestIntegrityLevel(realm, value, "frozen")) {
|
||||
let diag = new CompilerDiagnostic(
|
||||
@ -530,7 +536,7 @@ function ensureFrozenValue(realm, value, loc) {
|
||||
// Ensure that a value is immutable. If it is not, set all its properties to abstract values
|
||||
// and all reachable bindings to abstract values.
|
||||
export class HavocImplementation {
|
||||
value(realm: Realm, value: Value, loc: ?BabelNodeSourceLocation) {
|
||||
value(realm: Realm, value: Value, loc: ?BabelNodeSourceLocation): void {
|
||||
if (realm.instantRender.enabled) {
|
||||
// TODO: For InstantRender...
|
||||
// - For declarative bindings, we do want proper materialization/leaking/havocing
|
||||
|
@ -72,7 +72,7 @@ export class Logger {
|
||||
}
|
||||
}
|
||||
|
||||
logCompletion(res: Completion) {
|
||||
logCompletion(res: Completion): void {
|
||||
let realm = this.realm;
|
||||
let value = res.value;
|
||||
if (this.internalDebug) console.error(`=== ${res.constructor.name} ===`);
|
||||
@ -115,20 +115,20 @@ export class Logger {
|
||||
this._hasErrors = true;
|
||||
}
|
||||
|
||||
logError(value: Value, message: string) {
|
||||
logError(value: Value, message: string): void {
|
||||
this._log(value, message, "RecoverableError");
|
||||
this._hasErrors = true;
|
||||
}
|
||||
|
||||
logWarning(value: Value, message: string) {
|
||||
logWarning(value: Value, message: string): void {
|
||||
this._log(value, message, "Warning");
|
||||
}
|
||||
|
||||
logInformation(message: string) {
|
||||
logInformation(message: string): void {
|
||||
this._log(this.realm.intrinsics.undefined, message, "Information");
|
||||
}
|
||||
|
||||
_log(value: Value, message: string, severity: Severity) {
|
||||
_log(value: Value, message: string, severity: Severity): void {
|
||||
let loc = value.expressionLocation;
|
||||
if (value.intrinsicName) {
|
||||
message = `${message}\nintrinsic name: ${value.intrinsicName}`;
|
||||
@ -137,7 +137,7 @@ export class Logger {
|
||||
if (this.realm.handleError(diagnostic) === "Fail") throw new FatalError();
|
||||
}
|
||||
|
||||
hasErrors() {
|
||||
hasErrors(): boolean {
|
||||
return this._hasErrors;
|
||||
}
|
||||
}
|
||||
|
@ -83,11 +83,11 @@ export class ModuleTracer extends Tracer {
|
||||
return this.modules.getStatistics();
|
||||
}
|
||||
|
||||
log(message: string) {
|
||||
log(message: string): void {
|
||||
if (this.logModules) console.log(`[modules] ${this.requireStack.map(_ => " ").join("")}${message}`);
|
||||
}
|
||||
|
||||
beginEvaluateForEffects(state: any) {
|
||||
beginEvaluateForEffects(state: any): void {
|
||||
if (state !== this) {
|
||||
this.log(">evaluate for effects");
|
||||
this.evaluateForEffectsNesting++;
|
||||
@ -95,7 +95,7 @@ export class ModuleTracer extends Tracer {
|
||||
}
|
||||
}
|
||||
|
||||
endEvaluateForEffects(state: any, effects: void | Effects) {
|
||||
endEvaluateForEffects(state: any, effects: void | Effects): void {
|
||||
if (state !== this) {
|
||||
let popped = this.requireStack.pop();
|
||||
invariant(popped === undefined);
|
||||
@ -106,7 +106,7 @@ export class ModuleTracer extends Tracer {
|
||||
|
||||
// If we don't delay unsupported requires, we simply want to record here
|
||||
// when a module gets initialized, and then we return.
|
||||
_callRequireAndRecord(moduleIdValue: number | string, performCall: () => Value) {
|
||||
_callRequireAndRecord(moduleIdValue: number | string, performCall: () => Value): void | Value {
|
||||
if (this.requireStack.length === 0 || this.requireStack[this.requireStack.length - 1] !== moduleIdValue) {
|
||||
this.requireStack.push(moduleIdValue);
|
||||
try {
|
||||
@ -183,7 +183,7 @@ export class ModuleTracer extends Tracer {
|
||||
|
||||
// If a require fails, recover from it and delay the factory call until runtime
|
||||
// Also, only in this mode, consider "accelerating" require calls, see below.
|
||||
_callRequireAndDelayIfNeeded(moduleIdValue: number | string, performCall: () => Value) {
|
||||
_callRequireAndDelayIfNeeded(moduleIdValue: number | string, performCall: () => Value): void | Value {
|
||||
let realm = this.modules.realm;
|
||||
this.log(`>require(${moduleIdValue})`);
|
||||
let isTopLevelRequire = this.requireStack.length === 0;
|
||||
@ -577,7 +577,7 @@ export class Modules {
|
||||
};
|
||||
}
|
||||
|
||||
recordModuleInitialized(moduleId: number | string, value: Value) {
|
||||
recordModuleInitialized(moduleId: number | string, value: Value): void {
|
||||
this.realm.assignToGlobal(
|
||||
t.memberExpression(
|
||||
t.memberExpression(t.identifier("global"), t.identifier("__initializedModules")),
|
||||
@ -607,7 +607,7 @@ export class Modules {
|
||||
});
|
||||
}
|
||||
|
||||
initializeMoreModules() {
|
||||
initializeMoreModules(): void {
|
||||
// partially evaluate all factory methods by calling require
|
||||
let count = 0;
|
||||
for (let moduleId of this.moduleIds) {
|
||||
|
@ -79,7 +79,7 @@ export class PathImplementation {
|
||||
}
|
||||
}
|
||||
|
||||
pushAndRefine(condition: Value) {
|
||||
pushAndRefine(condition: Value): void {
|
||||
let realm = condition.$Realm;
|
||||
let savedPath = realm.pathConditions;
|
||||
realm.pathConditions = [];
|
||||
@ -88,7 +88,7 @@ export class PathImplementation {
|
||||
pushRefinedConditions(realm, savedPath);
|
||||
}
|
||||
|
||||
pushInverseAndRefine(condition: Value) {
|
||||
pushInverseAndRefine(condition: Value): void {
|
||||
let realm = condition.$Realm;
|
||||
let savedPath = realm.pathConditions;
|
||||
realm.pathConditions = [];
|
||||
@ -99,7 +99,7 @@ export class PathImplementation {
|
||||
}
|
||||
|
||||
// A path condition is an abstract value that must be true in this particular code path, so we want to assume as much
|
||||
function pushPathCondition(condition: Value) {
|
||||
function pushPathCondition(condition: Value): void {
|
||||
invariant(condition.mightNotBeFalse(), "pushing false"); // it is mistake to assume that false is true
|
||||
if (condition instanceof ConcreteValue) return;
|
||||
if (!condition.mightNotBeTrue()) return;
|
||||
@ -146,7 +146,7 @@ function pushPathCondition(condition: Value) {
|
||||
}
|
||||
|
||||
// An inverse path condition is an abstract value that must be false in this particular code path, so we want to assume as much
|
||||
function pushInversePathCondition(condition: Value) {
|
||||
function pushInversePathCondition(condition: Value): void {
|
||||
// it is mistake to assume that true is false.
|
||||
invariant(condition.mightNotBeTrue());
|
||||
if (condition instanceof ConcreteValue) return;
|
||||
@ -183,7 +183,7 @@ function pushInversePathCondition(condition: Value) {
|
||||
}
|
||||
}
|
||||
|
||||
function pushRefinedConditions(realm: Realm, unrefinedConditions: Array<AbstractValue>) {
|
||||
function pushRefinedConditions(realm: Realm, unrefinedConditions: Array<AbstractValue>): void {
|
||||
let refinedConditions = unrefinedConditions.map(c => realm.simplifyAndRefineAbstractCondition(c));
|
||||
if (refinedConditions.some(c => !c.mightNotBeFalse())) throw new InfeasiblePathError();
|
||||
let pc = realm.pathConditions;
|
||||
|
@ -128,7 +128,7 @@ export default class AbstractValue extends Value {
|
||||
return "[Abstract " + this.hashValue.toString() + "]";
|
||||
}
|
||||
|
||||
addSourceLocationsTo(locations: Array<BabelNodeSourceLocation>, seenValues?: Set<AbstractValue> = new Set()) {
|
||||
addSourceLocationsTo(locations: Array<BabelNodeSourceLocation>, seenValues?: Set<AbstractValue> = new Set()): void {
|
||||
if (seenValues.has(this)) return;
|
||||
seenValues.add(this);
|
||||
if (this._buildNode && !(this._buildNode instanceof Function)) {
|
||||
@ -139,7 +139,7 @@ export default class AbstractValue extends Value {
|
||||
}
|
||||
}
|
||||
|
||||
addSourceNamesTo(names: Array<string>, visited: Set<AbstractValue> = new Set()) {
|
||||
addSourceNamesTo(names: Array<string>, visited: Set<AbstractValue> = new Set()): void {
|
||||
if (visited.has(this)) return;
|
||||
visited.add(this);
|
||||
let realm = this.$Realm;
|
||||
@ -179,7 +179,7 @@ export default class AbstractValue extends Value {
|
||||
: ((buildNode: any): BabelNodeExpression);
|
||||
}
|
||||
|
||||
equals(x: Value) {
|
||||
equals(x: Value): boolean {
|
||||
if (x instanceof ConcreteValue) return false;
|
||||
let thisArgs = this.args;
|
||||
let n = thisArgs.length;
|
||||
@ -216,20 +216,20 @@ export default class AbstractValue extends Value {
|
||||
return this.hashValue;
|
||||
}
|
||||
|
||||
getType() {
|
||||
getType(): typeof Value {
|
||||
return this.types.getType();
|
||||
}
|
||||
|
||||
getIdentifier() {
|
||||
getIdentifier(): BabelNodeIdentifier {
|
||||
invariant(this.hasIdentifier());
|
||||
return ((this._buildNode: any): BabelNodeIdentifier);
|
||||
}
|
||||
|
||||
hasIdentifier() {
|
||||
return this._buildNode && this._buildNode.type === "Identifier";
|
||||
hasIdentifier(): boolean {
|
||||
return this._buildNode ? this._buildNode.type === "Identifier" : false;
|
||||
}
|
||||
|
||||
_checkAbstractValueImpliesCounter() {
|
||||
_checkAbstractValueImpliesCounter(): void {
|
||||
let realm = this.$Realm;
|
||||
let abstractValueImpliesMax = realm.abstractValueImpliesMax;
|
||||
// if abstractValueImpliesMax is 0, then the counter is disabled
|
||||
@ -897,7 +897,7 @@ export default class AbstractValue extends Value {
|
||||
name: string,
|
||||
location: ?BabelNodeSourceLocation,
|
||||
type: typeof Value = Value
|
||||
) {
|
||||
): AbstractValue {
|
||||
if (!realm.useAbstractInterpretation) {
|
||||
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "realm is not partial");
|
||||
}
|
||||
@ -947,7 +947,7 @@ export default class AbstractValue extends Value {
|
||||
return `${identity} ${location}`;
|
||||
}
|
||||
|
||||
static reportIntrospectionError(val: Value, propertyName: void | PropertyKeyValue) {
|
||||
static reportIntrospectionError(val: Value, propertyName: void | PropertyKeyValue): void {
|
||||
let message = "";
|
||||
if (!val.$Realm.suppressDiagnostics)
|
||||
message = `This operation is not yet supported on ${AbstractValue.describe(val, propertyName)}`;
|
||||
|
@ -56,7 +56,7 @@ export default class ArgumentsExotic extends ObjectValue {
|
||||
}
|
||||
|
||||
// ECMA262 9.4.4.2
|
||||
$DefineOwnProperty(P: PropertyKeyValue, Desc: Descriptor) {
|
||||
$DefineOwnProperty(P: PropertyKeyValue, Desc: Descriptor): boolean {
|
||||
// 1. Let args be the arguments object.
|
||||
let args = this;
|
||||
|
||||
|
@ -53,7 +53,7 @@ export class IntegralValue extends NumberValue {
|
||||
super(realm, value, intrinsicName);
|
||||
}
|
||||
|
||||
static createFromNumberValue(realm: Realm, value: number, intrinsicName?: string) {
|
||||
static createFromNumberValue(realm: Realm, value: number, intrinsicName?: string): IntegralValue | NumberValue {
|
||||
return Number.isInteger(value)
|
||||
? new IntegralValue(realm, value, intrinsicName)
|
||||
: new NumberValue(realm, value, intrinsicName);
|
||||
|
@ -126,7 +126,7 @@ export default class ObjectValue extends ConcreteValue {
|
||||
return ObjectValue.trackedPropertyNames;
|
||||
}
|
||||
|
||||
setupBindings(propertyNames: Array<string>) {
|
||||
setupBindings(propertyNames: Array<string>): void {
|
||||
for (let propName of propertyNames) {
|
||||
let propBindingName = ObjectValue.trackedPropertyBindingNames.get(propName);
|
||||
invariant(propBindingName !== undefined);
|
||||
@ -134,7 +134,7 @@ export default class ObjectValue extends ConcreteValue {
|
||||
}
|
||||
}
|
||||
|
||||
static setupTrackedPropertyAccessors(propertyNames: Array<string>) {
|
||||
static setupTrackedPropertyAccessors(propertyNames: Array<string>): void {
|
||||
for (let propName of propertyNames) {
|
||||
let propBindingName = ObjectValue.trackedPropertyBindingNames.get(propName);
|
||||
if (propBindingName === undefined)
|
||||
@ -483,7 +483,7 @@ export default class ObjectValue extends ConcreteValue {
|
||||
return fnValue;
|
||||
}
|
||||
|
||||
defineNativeProperty(name: SymbolValue | string, value?: Value | Array<Value>, desc?: Descriptor = {}) {
|
||||
defineNativeProperty(name: SymbolValue | string, value?: Value | Array<Value>, desc?: Descriptor = {}): void {
|
||||
invariant(!value || value instanceof Value);
|
||||
this.$DefineOwnProperty(name, {
|
||||
value,
|
||||
@ -494,7 +494,7 @@ export default class ObjectValue extends ConcreteValue {
|
||||
});
|
||||
}
|
||||
|
||||
defineNativeGetter(name: SymbolValue | string, callback: NativeFunctionCallback, desc?: Descriptor = {}) {
|
||||
defineNativeGetter(name: SymbolValue | string, callback: NativeFunctionCallback, desc?: Descriptor = {}): void {
|
||||
let intrinsicName, funcName;
|
||||
if (typeof name === "string") {
|
||||
funcName = `get ${name}`;
|
||||
@ -519,7 +519,7 @@ export default class ObjectValue extends ConcreteValue {
|
||||
});
|
||||
}
|
||||
|
||||
defineNativeConstant(name: SymbolValue | string, value?: Value | Array<Value>, desc?: Descriptor = {}) {
|
||||
defineNativeConstant(name: SymbolValue | string, value?: Value | Array<Value>, desc?: Descriptor = {}): void {
|
||||
invariant(!value || value instanceof Value);
|
||||
this.$DefineOwnProperty(name, {
|
||||
value,
|
||||
@ -588,7 +588,7 @@ export default class ObjectValue extends ConcreteValue {
|
||||
}
|
||||
}
|
||||
|
||||
copyKeys(keys: Array<PropertyKeyValue>, from: ObjectValue, to: ObjectValue) {
|
||||
copyKeys(keys: Array<PropertyKeyValue>, from: ObjectValue, to: ObjectValue): void {
|
||||
// c. Repeat for each element nextKey of keys in List order,
|
||||
for (let nextKey of keys) {
|
||||
// i. Let desc be ? from.[[GetOwnProperty]](nextKey).
|
||||
|
Loading…
Reference in New Issue
Block a user