From 4e0639c2dceef3feca273cf0dadfd4f045826f77 Mon Sep 17 00:00:00 2001 From: Mofei Zhang Date: Mon, 3 Oct 2022 14:37:23 -0400 Subject: [PATCH] Add makeReadOnly codegen into the compiler --- compiler/forget/src/BackEnd/JS.ts | 13 +++++++++++++ compiler/forget/src/BackEnd/JSGen.ts | 5 +++++ compiler/forget/src/CompilerFlags.ts | 6 ++++++ .../forget/src/__tests__/CompilerOptions-test.ts | 1 + 4 files changed, 25 insertions(+) diff --git a/compiler/forget/src/BackEnd/JS.ts b/compiler/forget/src/BackEnd/JS.ts index 33f22aa77b..4baebb3d10 100644 --- a/compiler/forget/src/BackEnd/JS.ts +++ b/compiler/forget/src/BackEnd/JS.ts @@ -188,6 +188,19 @@ export class Func { ]); } + // Generate calls to utility function that freezes immut objects + emitMakeReadOnly(val: IR.BindingVal) { + if (this.context.opts.flags.addFreeze === true) { + this.code.push( + t.expressionStatement( + t.callExpression(t.identifier("useMemoCache.makeReadOnly"), [ + val.binding.identifier, + ]) + ) + ); + } + } + /** * Generate code materializing reactions * @returns diff --git a/compiler/forget/src/BackEnd/JSGen.ts b/compiler/forget/src/BackEnd/JSGen.ts index b0f66c9a2e..1a97c4872c 100644 --- a/compiler/forget/src/BackEnd/JSGen.ts +++ b/compiler/forget/src/BackEnd/JSGen.ts @@ -85,6 +85,8 @@ export function runFunc( */ function genPrologue(): void { for (const param of irFunc.params) { + // params are immut + jsFunc.emitMakeReadOnly(param); if (IR.isReactiveVal(param)) { jsFunc.emitReactiveVal(param); } @@ -102,6 +104,9 @@ export function runFunc( jsFunc.emit(instr.ast.node); for (const decl of instr.ir.decls) { + if (decl.immutable) { + jsFunc.emitMakeReadOnly(decl); + } if (IR.isReactiveVal(decl)) { jsFunc.emitReactiveVal(decl); } diff --git a/compiler/forget/src/CompilerFlags.ts b/compiler/forget/src/CompilerFlags.ts index 91f3333754..e92b6ea789 100644 --- a/compiler/forget/src/CompilerFlags.ts +++ b/compiler/forget/src/CompilerFlags.ts @@ -81,6 +81,10 @@ export type CompilerFlags = { * can remove this flag. */ guardThrows: boolean; + /** + * Experimental runtime logging to collect data + */ + addFreeze: boolean; }; export function createCompilerFlags(): CompilerFlags { @@ -95,6 +99,7 @@ export function createCompilerFlags(): CompilerFlags { guardReads: false, guardHooks: false, guardThrows: false, + addFreeze: false, }; } @@ -115,6 +120,7 @@ export function parseCompilerFlags( case "guardReads": case "guardHooks": case "guardThrows": + case "addFreeze": if (typeof value !== "boolean") { throw `Expected boolean for flag '${key}': ${value}`; } diff --git a/compiler/forget/src/__tests__/CompilerOptions-test.ts b/compiler/forget/src/__tests__/CompilerOptions-test.ts index 74780cea17..9a2dc859ec 100644 --- a/compiler/forget/src/__tests__/CompilerOptions-test.ts +++ b/compiler/forget/src/__tests__/CompilerOptions-test.ts @@ -49,6 +49,7 @@ describe("CompilerOptions", () => { const fullInput = { outputKinds: [OutputKind.JS, OutputKind.LIR], flags: { + addFreeze: true, condCache: true, guardReads: true, guardHooks: true,