Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
333 changes: 333 additions & 0 deletions compiler/fault-tolerance-overview.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ export type LoggerEvent =
| CompileErrorEvent
| CompileDiagnosticEvent
| CompileSkipEvent
| CompileUnexpectedThrowEvent
| PipelineErrorEvent
| TimingEvent;

Expand Down Expand Up @@ -288,6 +289,11 @@ export type PipelineErrorEvent = {
fnLoc: t.SourceLocation | null;
data: string;
};
export type CompileUnexpectedThrowEvent = {
kind: 'CompileUnexpectedThrow';
fnLoc: t.SourceLocation | null;
data: string;
};
export type TimingEvent = {
kind: 'Timing';
measurement: PerformanceMeasure;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {NodePath} from '@babel/traverse';
import * as t from '@babel/types';
import prettyFormat from 'pretty-format';
import {CompilerOutputMode, Logger, ProgramContext} from '.';
import {CompilerError} from '../CompilerError';
import {Err, Ok, Result} from '../Utils/Result';
import {
HIRFunction,
ReactiveFunction,
Expand Down Expand Up @@ -118,7 +120,7 @@ function run(
logger: Logger | null,
filename: string | null,
code: string | null,
): CodegenFunction {
): Result<CodegenFunction, CompilerError> {
const contextIdentifiers = findContextIdentifiers(func);
const env = new Environment(
func.scope,
Expand Down Expand Up @@ -149,21 +151,21 @@ function runWithEnvironment(
t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
>,
env: Environment,
): CodegenFunction {
): Result<CodegenFunction, CompilerError> {
const log = (value: CompilerPipelineValue): void => {
env.logger?.debugLogIRs?.(value);
};
const hir = lower(func, env).unwrap();
const hir = lower(func, env);
log({kind: 'hir', name: 'HIR', value: hir});

pruneMaybeThrows(hir);
log({kind: 'hir', name: 'PruneMaybeThrows', value: hir});

validateContextVariableLValues(hir);
validateUseMemo(hir).unwrap();
validateUseMemo(hir);

if (env.enableDropManualMemoization) {
dropManualMemoization(hir).unwrap();
dropManualMemoization(hir);
log({kind: 'hir', name: 'DropManualMemoization', value: hir});
}

Expand Down Expand Up @@ -196,10 +198,10 @@ function runWithEnvironment(

if (env.enableValidations) {
if (env.config.validateHooksUsage) {
validateHooksUsage(hir).unwrap();
validateHooksUsage(hir);
}
if (env.config.validateNoCapitalizedCalls) {
validateNoCapitalizedCalls(hir).unwrap();
validateNoCapitalizedCalls(hir);
}
}

Expand All @@ -209,13 +211,8 @@ function runWithEnvironment(
analyseFunctions(hir);
log({kind: 'hir', name: 'AnalyseFunctions', value: hir});

const mutabilityAliasingErrors = inferMutationAliasingEffects(hir);
inferMutationAliasingEffects(hir);
log({kind: 'hir', name: 'InferMutationAliasingEffects', value: hir});
if (env.enableValidations) {
if (mutabilityAliasingErrors.isErr()) {
throw mutabilityAliasingErrors.unwrapErr();
}
}

if (env.outputMode === 'ssr') {
optimizeForSSR(hir);
Expand All @@ -228,28 +225,23 @@ function runWithEnvironment(
pruneMaybeThrows(hir);
log({kind: 'hir', name: 'PruneMaybeThrows', value: hir});

const mutabilityAliasingRangeErrors = inferMutationAliasingRanges(hir, {
inferMutationAliasingRanges(hir, {
isFunctionExpression: false,
});
log({kind: 'hir', name: 'InferMutationAliasingRanges', value: hir});
if (env.enableValidations) {
if (mutabilityAliasingRangeErrors.isErr()) {
throw mutabilityAliasingRangeErrors.unwrapErr();
}
validateLocalsNotReassignedAfterRender(hir);
}

if (env.enableValidations) {
if (env.config.assertValidMutableRanges) {
assertValidMutableRanges(hir);
}

if (env.config.validateRefAccessDuringRender) {
validateNoRefAccessInRender(hir).unwrap();
validateNoRefAccessInRender(hir);
}

if (env.config.validateNoSetStateInRender) {
validateNoSetStateInRender(hir).unwrap();
validateNoSetStateInRender(hir);
}

if (
Expand All @@ -270,10 +262,10 @@ function runWithEnvironment(
}

if (env.config.validateNoImpureFunctionsInRender) {
validateNoImpureFunctionsInRender(hir).unwrap();
validateNoImpureFunctionsInRender(hir);
}

validateNoFreezingKnownMutableFunctions(hir).unwrap();
validateNoFreezingKnownMutableFunctions(hir);
}

inferReactivePlaces(hir);
Expand All @@ -285,7 +277,7 @@ function runWithEnvironment(
env.config.validateExhaustiveEffectDependencies
) {
// NOTE: this relies on reactivity inference running first
validateExhaustiveDependencies(hir).unwrap();
validateExhaustiveDependencies(hir);
}
}

Expand Down Expand Up @@ -399,6 +391,7 @@ function runWithEnvironment(
});
assertTerminalSuccessorsExist(hir);
assertTerminalPredsExist(hir);

propagateScopeDependenciesHIR(hir);
log({
kind: 'hir',
Expand Down Expand Up @@ -511,20 +504,20 @@ function runWithEnvironment(
env.config.enablePreserveExistingMemoizationGuarantees ||
env.config.validatePreserveExistingMemoizationGuarantees
) {
validatePreservedManualMemoization(reactiveFunction).unwrap();
validatePreservedManualMemoization(reactiveFunction);
}

const ast = codegenFunction(reactiveFunction, {
uniqueIdentifiers,
fbtOperands,
}).unwrap();
});
log({kind: 'ast', name: 'Codegen', value: ast});
for (const outlined of ast.outlined) {
log({kind: 'ast', name: 'Codegen (outlined)', value: outlined.fn});
}

if (env.config.validateSourceLocations) {
validateSourceLocations(func, ast).unwrap();
validateSourceLocations(func, ast, env);
}

/**
Expand All @@ -536,7 +529,10 @@ function runWithEnvironment(
throw new Error('unexpected error');
}

return ast;
if (env.hasErrors()) {
return Err(env.aggregateErrors());
}
return Ok(ast);
}

export function compileFn(
Expand All @@ -550,7 +546,7 @@ export function compileFn(
logger: Logger | null,
filename: string | null,
code: string | null,
): CodegenFunction {
): Result<CodegenFunction, CompilerError> {
return run(
func,
config,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -704,20 +704,36 @@ function tryCompileFunction(
}

try {
return {
kind: 'compile',
compiledFn: compileFn(
fn,
programContext.opts.environment,
fnType,
outputMode,
programContext,
programContext.opts.logger,
programContext.filename,
programContext.code,
),
};
const result = compileFn(
fn,
programContext.opts.environment,
fnType,
outputMode,
programContext,
programContext.opts.logger,
programContext.filename,
programContext.code,
);
if (result.isOk()) {
return {kind: 'compile', compiledFn: result.unwrap()};
} else {
return {kind: 'error', error: result.unwrapErr()};
}
} catch (err) {
/**
* A pass incorrectly threw instead of recording the error.
* Log for detection in development.
*/
if (
err instanceof CompilerError &&
err.details.every(detail => detail.category !== ErrorCategory.Invariant)
) {
programContext.logEvent({
kind: 'CompileUnexpectedThrow',
fnLoc: fn.node.loc ?? null,
data: err.toString(),
});
}
return {kind: 'error', error: err};
}
}
Expand Down
Loading
Loading