STUDIO HAZE · topaz
Topaz source
Open by house policy. Topaz is our own language.
Topaz 5.20 · 56 files
compiler/crates/topaz_self_frontend/topaz/emitter/module.tpz
Topaz · 23552 B · Original file
1
import emitter.rust_text { rustStr }2
import emitter.emit {3
Bind,4
FnInfo,5
ModInfo,6
Ctx,7
Code,8
pushBind,9
restoreScope,10
newCell,11
modBind,12
paramsOf,13
argumentGuard,14
defaultValues,15
restArgument,16
emitExpr,17
emitStatement,18
emitImplementation,19
into,20
has,21
}22
import emitter.exports { projectExports, hasExplicitMain }23
import emitter.ir { Table, buildTable, patternBindings, opAt, child, children, refusal, spanOf, declarationSpan, rustName }24
import emitter.repr { reprOf, slotRepr, rustType, isCopyRepr, boxed, bare }25
import stage1_types { Stage1Module, Stage1Operation, LoweringOutput }27
// The emitted-crate contract every Topaz program crate exposes (the same28
// items the reference crate's `emitted.rs` defines). This emitter names29
// nominal values by their defining-module identity in every language mode, so30
// the runtime context projects host-returned std.lispex values to the same31
// identities (the Rust emitter selects this context from 5.20 on).32
const CONTRACT = """33
pub fn run_with_host(host: Rc<dyn Host>) -> RunOutcome \{34
run_with_host_and_input(host, Vec::new(), String::new())35
\}37
pub fn run_with_host_and_input(host: Rc<dyn Host>, args: Vec<String>, stdin: String) -> RunOutcome \{38
let cx = RtCx::new_module_stable(host);39
let __topaz_args = Value::array(args.into_iter().map(Value::str).collect());40
let __topaz_stdin = Value::str(stdin);41
match block_on(entry(cx, __topaz_args, __topaz_stdin)) \{42
Ok(value) => RunOutcome::Completed(value),43
Err(error) => RunOutcome::Faulted(error),44
\}45
\}47
pub fn call_export_with_host(host: Rc<dyn Host>, name: &str, args: Vec<Value>) -> RunOutcome \{48
call_export_with_host_and_input(host, name, args, Vec::new(), String::new())49
\}51
pub fn call_export_with_host_until(52
host: Rc<dyn Host>,53
name: &str,54
args: Vec<Value>,55
deadline: std::time::Instant,56
) -> Result<RunOutcome, DeadlineExceeded> \{57
let outcome = block_on_until(deadline, call_export_with_host_future(host, name, args))?;58
Ok(match outcome \{59
Ok(value) => RunOutcome::Completed(value),60
Err(error) => RunOutcome::Faulted(error),61
\})62
\}64
pub fn call_export_with_host_future(65
host: Rc<dyn Host>,66
name: &str,67
args: Vec<Value>,68
) -> CallFuture \{69
let cx = RtCx::new_module_stable(host);70
let __span = Span::new(FileId(0), 0, 0);71
let name = name.to_string();72
Box::pin(async move \{73
__topaz_call_export(cx, &name, args, __span).await74
\})75
\}77
pub fn call_export_with_host_and_input(78
host: Rc<dyn Host>,79
name: &str,80
args: Vec<Value>,81
_program_args: Vec<String>,82
_stdin: String,83
) -> RunOutcome \{84
let cx = RtCx::new_module_stable(host);85
let __span = Span::new(FileId(0), 0, 0);86
match block_on(__topaz_call_export(cx, name, args, __span)) \{87
Ok(value) => RunOutcome::Completed(value),88
Err(error) => RunOutcome::Faulted(error),89
\}90
\}92
pub fn call_export_json_with_host(host: Rc<dyn Host>, name: &str, args_json: &str) -> String \{93
call_export_json_with_host_and_input(host, name, args_json, Vec::new(), String::new())94
\}96
pub fn call_export_json_with_host_and_input(97
host: Rc<dyn Host>,98
name: &str,99
args_json: &str,100
program_args: Vec<String>,101
stdin: String,102
) -> String \{103
let args = match canonical_abi_decode_args(args_json) \{104
Ok(args) => args,105
Err(error) => return canonical_abi_error(&error),106
\};107
match call_export_with_host_and_input(host, name, args, program_args, stdin) \{108
RunOutcome::Completed(value) => canonical_abi_completed(&value),109
RunOutcome::Faulted(error) => canonical_abi_faulted(&error),110
\}111
\}113
async fn __topaz_exports(cx: RtCx) -> Result<Value, RtError> \{114
let (_, __exports) = __topaz_initialize(cx).await?;115
Ok(__exports)116
\}118
async fn __topaz_call_export(cx: RtCx, name: &str, args: Vec<Value>, span: Span) -> Result<Value, RtError> \{119
let __exports = __topaz_exports(cx.clone()).await?;120
let __callee = member_value_required(&__exports, name, span)?;121
call_value(__callee, args, cx, span).await122
\}123
"""125
const CELL_HELPER = """126
fn __cell_get<T: Copy>(cell: &std::cell::Cell<Option<T>>, name: &str, span: Span) -> Result<T, RtError> \{127
cell.get().ok_or_else(|| fault(codes::GUARD_UNBOUND, format!("`\{name\}` is not bound"), span))128
\}129
"""131
const CONST_HELPER = """132
fn __cg<T>(result: Result<T, RtError>, span: Span) -> Result<T, RtError> \{133
result.map_err(|error| \{134
if error.is_fault() \{135
fault(codes::GUARD_TYPE, format!("constant expression error: \{\}", error.message), span)136
\} else \{137
error138
\}139
\})140
\}141
"""143
record Item {144
decl: Stage1Operation,145
exported: bool,146
}148
function itemsOf(table: Table, root: Stage1Operation) -> Result<Array<Item>, string> {149
let mut items: Array<Item> = []150
for id in root.operands {151
let item = opAt(table, id)?152
if item.kind == "export" {153
items.push(Item { decl: child(table, item, "item")?, exported: true })154
} else {155
items.push(Item { decl: item, exported: false })156
}157
}158
Ok(items)159
}161
record ImportRow {162
kind: string,163
source: string,164
bound: string,165
}167
function importRows(op: Stage1Operation) -> Result<Array<ImportRow>, string> {168
let mut rows: Array<ImportRow> = []169
for row in op.importBindings {170
let parts = row.split("|")171
if parts.length != 5 {172
return Err(refusal("import row {row}", op))173
}174
rows.push(ImportRow { kind: parts[0], source: parts[1], bound: parts[2] })175
}176
Ok(rows)177
}179
function fnKey(ctx: Ctx) -> int {180
ctx.fns.length181
}183
// Module-level names become cells or function entries before any body is184
// emitted, so a function may name a binding declared later in its module.185
function registerModule(ctx: Ctx, module: Stage1Module, root: Stage1Operation) -> Result<ModInfo, string> {186
let mut binds: Array<Bind> = []187
let mut exported: Array<string> = []188
for item in itemsOf(ctx.table, root)? {189
let decl = item.decl190
if decl.kind == "function" {191
let params = paramsOf(ctx, decl, decl.declaredTypeAtoms)?192
let ret = slotRepr(decl.declaredTypeAtoms, "result", 0)193
if ret == "none" {194
return Err(refusal("function result type", decl))195
}196
let number = fnKey(ctx)197
let info = FnInfo {198
id: decl.id,199
name: decl.bindingName,200
body: "__b{number}",201
adapter: "__v{number}",202
cell: newCell(ctx, "value"),203
paramNames: params.names,204
paramReprs: params.reprs,205
paramSpans: params.spans,206
defaultIds: params.defaultIds,207
variadic: params.variadic,208
retRepr: ret,209
}210
let mut fns = ctx.fns211
fns.insert(decl.id, info)212
binds.push(Bind { name: decl.bindingName, kind: "fn", rust: decl.id, repr: "value", mutable: false })213
if item.exported {214
exported.push(decl.bindingName)215
}216
} else if decl.kind == "let" {217
let pattern = child(ctx.table, decl, "pattern")?218
for binding in patternBindings(ctx.table, pattern)? {219
let declared = reprOf(binding.semanticTypeAtoms)220
let repr = if declared == "none" { "value" } else { declared }221
binds.push(Bind { name: binding.bindingName, kind: "global", rust: newCell(ctx, repr), repr: repr, mutable: binding.bindingMutable })222
if item.exported { exported.push(binding.bindingName) }223
}224
} else if decl.kind == "constant" {225
let declared = reprOf(decl.declaredTypeAtoms)226
let repr = if declared != "none" {227
declared228
} else {229
let value = child(ctx.table, decl, "value")?230
reprOf(value.semanticTypeAtoms)231
}232
if repr == "none" {233
return Err(refusal("binding type {decl.bindingName}", decl))234
}235
binds.push(Bind { name: decl.bindingName, kind: "global", rust: newCell(ctx, repr), repr: repr, mutable: false })236
if item.exported {237
exported.push(decl.bindingName)238
}239
} else if decl.kind == "import" {240
for row in importRows(decl)? {241
if row.kind == "namespace-import" {242
binds.push(Bind { name: row.bound, kind: "namespace", rust: decl.importModule, repr: "value", mutable: false })243
} else if row.kind == "selected-import" {244
let target = match ctx.mods.get(decl.importModule) {245
case Some(found) => found246
case None => return Err(refusal("import of {decl.importModule}", decl))247
}248
match modBind(target, row.source) {249
case Some(bind) => if bind.kind == "fn" {250
binds.push(Bind { ...bind, name: row.bound })251
} else if has(target.exports, row.source) {252
binds.push(Bind { name: row.bound, kind: "global", rust: newCell(ctx, "value"), repr: "value", mutable: false })253
}254
case None => ()255
}256
} else {257
return Err(refusal("import form {row.kind}", decl))258
}259
}260
}261
}262
let info = ModInfo { identity: module.identity, cell: newCell(ctx, "value"), binds: binds, exports: exported, generatedStd: module.generatedStd }263
let mut mods = ctx.mods264
mods.insert(module.identity, info)265
Ok(info)266
}268
function enterModule(ctx: Ctx, info: ModInfo) -> () {269
restoreScope(ctx, 0)270
for bind in info.binds {271
pushBind(ctx, bind)272
}273
()274
}276
function findBind(info: ModInfo, name: string, op: Stage1Operation) -> Result<Bind, string> {277
match modBind(info, name) {278
case Some(bind) => Ok(bind)279
case None => Err(refusal("module binding {name}", op))280
}281
}283
function fnOf(ctx: Ctx, key: string, op: Stage1Operation) -> Result<FnInfo, string> {284
match ctx.fns.get(key) {285
case Some(info) => Ok(info)286
case None => Err(refusal("ir function {key}", op))287
}288
}290
// The boxed value of a module binding, for export records.291
function exportValue(ctx: Ctx, bind: Bind, op: Stage1Operation) -> Result<string, string> {292
let name = rustStr(bind.name)293
if bind.kind == "fn" {294
let info = fnOf(ctx, bind.rust, op)?295
Ok("top_cell_value(&g.{info.cell}, {name})?")296
} else if bind.kind == "global" && isCopyRepr(bind.repr) {297
Ok(boxed("__cell_get(&g.{bind.rust}, {name}, Span::new(FileId(0), 0, 0))?", bind.repr))298
} else if bind.kind == "global" {299
Ok("top_cell_value(&g.{bind.rust}, {name})?")300
} else {301
Err(refusal("export of {bind.kind} binding {bind.name}", op))302
}303
}305
function exportRecord(ctx: Ctx, info: ModInfo, root: Stage1Operation) -> Result<string, string> {306
let mut fields: Array<string> = []307
for name in info.exports {308
let bind = findBind(info, name, root)?309
fields.push("({rustStr(name)}.to_string(), {exportValue(ctx, bind, root)?})")310
}311
Ok("Value::record([{fields.join(", ")}])")312
}314
// The typed body function and the boxed adapter of one module function.315
function emitFunction(ctx: Ctx, info: FnInfo, modInfo: ModInfo) -> Result<(), string> {316
let decl = opAt(ctx.table, info.id)?317
enterModule(ctx, modInfo)318
let fnCtx = Ctx { ...ctx, fnRet: info.retRepr, inConst: false, atModuleTop: false, loops: [], defers: [] }319
let defaults = defaultValues(ctx, info.defaultIds, info.variadic)?320
let mut params: Array<string> = []321
let mut entry: Array<string> = []322
let mut position = 0323
for name in info.paramNames {324
let rust = rustName(name)325
params.push(", {rust}: {rustType(info.paramReprs[position])}")326
let repr = if info.paramReprs[position].startsWith("vec:") { "value" } else { info.paramReprs[position] }327
if repr == "value" && info.paramReprs[position].startsWith("vec:") {328
entry.push("let {rust} = {boxed(rust, info.paramReprs[position])};")329
}330
pushBind(ctx, Bind { name: name, kind: "local", rust: rust, repr: repr, mutable: false })331
position += 1332
}333
let body = emitExpr(fnCtx, child(ctx.table, decl, "body")?)?334
let result = if body.repr == "never" {335
body.rs336
} else {337
"Ok({bare(into(body, info.retRepr, decl)?)})"338
}339
let mut items = ctx.items340
items.push(341
"async fn {info.body}(cx: RtCx, g: Rc<__G>{params.join("")}) -> Result<{rustType(info.retRepr)}, RtError> \{\n let _ = &cx;\n let _ = &g;\n {entry.join(" ")}\n {result}\n\}\n",342
)343
let mut prologue: Array<string> = []344
let mut passed: Array<string> = ["cx", "g"]345
if info.paramNames.length > 0 {346
prologue.push("let mut __args = args.into_iter();")347
} else {348
prologue.push("let _ = args;")349
}350
position = 0351
for name in info.paramNames {352
let value = if info.paramReprs[position].startsWith("vec:") {353
restArgument(info.paramReprs[position], info.paramSpans[position])354
} else { argumentGuard("__args.next().expect(\"arity checked at the call site\")", info.paramReprs[position], info.paramSpans[position]) }355
prologue.push("let __a{position} = {value};")356
passed.push("__a{position}")357
position += 1358
}359
let mut quoted = quotedAll(info.paramNames)360
if info.variadic { let _ = quoted.pop() }361
let returned = boxed("{info.body}({passed.join(", ")}).await?", info.retRepr)362
items.push(363
"fn {info.adapter}(g: &Rc<__G>) -> Value \{\n let __cap_g = g.clone();\n Value::Closure(Rc::new(EmittedClosure \{ call: move |cx: RtCx, args: Vec<Value>| -> CallFuture \{ let g = __cap_g.clone(); Box::pin(async move \{ {prologue.join(" ")} Ok({bare(returned)}) \}) \}, params: &[{quoted.join(", ")}], defaults: {defaults}, variadic: {info.variadic} \}))\n\}\n",364
)365
Ok(())366
}368
function quotedAll(names: Array<string>) -> Array<string> {369
let mut out: Array<string> = []370
for name in names {371
out.push(rustStr(name))372
}373
out374
}376
function importsOf(items: Array<Item>) -> Array<Item> {377
let mut out: Array<Item> = []378
for item in items {379
if item.decl.kind == "import" {380
out.push(item)381
}382
}383
out384
}386
record ModuleCode {387
lines: Array<string>,388
tail: string,389
}391
// A module's top-level code in execution order: hoisted constants, value392
// imports, then its items (functions bind positionally).393
function emitModuleInit(394
ctx: Ctx,395
module: Stage1Module,396
root: Stage1Operation,397
info: ModInfo,398
) -> Result<ModuleCode, string> {399
enterModule(ctx, info)400
let topCtx = Ctx { ...ctx, fnRet: "", inConst: false, atModuleTop: true }401
let constCtx = Ctx { ...topCtx, inConst: true }402
let items = itemsOf(ctx.table, root)?403
let mut lines: Array<string> = []404
for item in items {405
if item.decl.kind == "constant" {406
lines.push(emitStatement(constCtx, item.decl)?)407
}408
}409
for item in importsOf(items) {410
let target = match ctx.mods.get(item.decl.importModule) {411
case Some(found) => found412
case None => return Err(refusal("import of {item.decl.importModule}", item.decl))413
}414
for row in importRows(item.decl)? {415
if row.kind == "selected-import" {416
match modBind(info, row.bound) {417
case Some(bind) => if bind.kind == "global" {418
let read = "member_value_required(&top_cell_get(&g.{target.cell}, {rustStr(target.identity)}, {spanOf(item.decl)})?, {rustStr(row.source)}, {spanOf(item.decl)})?"419
lines.push("top_cell_set(&g.{bind.rust}, {read});")420
}421
case None => ()422
}423
}424
}425
}426
let mut tail = "Value::Unit"427
for item in items {428
if item.decl.kind == "implementation" { lines.push(emitImplementation(topCtx, item.decl)?) }429
}430
let mut position = 0431
for item in items {432
let decl = item.decl433
let last = position == items.length - 1434
if decl.kind == "function" {435
let declared = fnOf(ctx, decl.id, decl)?436
lines.push("top_cell_set(&g.{declared.cell}, {declared.adapter}(&g));")437
} else if has(["constant", "import", "type-alias", "record", "enum", "newtype", "protocol", "implementation"], decl.kind) {438
()439
} else if decl.kind == "expression/block" && module.entry && last {440
let expression = child(ctx.table, decl, "value")?441
// Module-level for remains a statement at the last item as well.442
if expression.kind == "expression/for" {443
lines.push(emitStatement(topCtx, decl)?)444
} else {445
let value = emitExpr(topCtx, expression)?446
tail = bare(into(value, "value", decl)?)447
}448
} else {449
lines.push(emitStatement(topCtx, decl)?)450
}451
position += 1452
}453
Ok(ModuleCode { lines: lines, tail: tail })454
}456
function chainTo(modules: Array<Stage1Module>, edges: Array<Array<string>>, entry: string, target: string) -> string {457
let mut queue: Array<string> = [entry]458
let mut previous: Map<string, string> = Map.new()459
let mut head = 0460
while head < queue.length {461
let current = queue[head]462
head += 1463
if current == target {464
let mut chain: Array<string> = [current]465
let mut at = current466
while previous.containsKey(at) {467
at = previous.get(at) ?? ""468
chain.push(at)469
}470
chain.reverse()471
return "import chain: " + chain.join(" -> ")472
}473
for edge in edges {474
if edge[0] == current && !previous.containsKey(edge[1]) && edge[1] != entry {475
previous.insert(edge[1], current)476
queue.push(edge[1])477
}478
}479
}480
"imported from `{entry}`"481
}483
function sortedModules(output: LoweringOutput) -> Array<Stage1Module> {484
let mut out: Array<Stage1Module> = []485
let mut ordinal = 0486
while out.length < output.modules.length {487
for module in output.modules {488
if module.initializationOrdinal == ordinal {489
out.push(module)490
}491
}492
ordinal += 1493
if ordinal > output.modules.length + 1 {494
return out495
}496
}497
out498
}500
export function emitProgram(output: LoweringOutput) -> Result<string, string> {501
let table = buildTable(output)502
let ctx = Ctx {503
table: table,504
scope: [],505
fns: Map.new(),506
mods: Map.new(),507
cellDecls: [],508
items: [],509
fnRet: "",510
inConst: false,511
atModuleTop: false,512
loops: [],513
defers: [],514
}515
let modules = sortedModules(output)516
if modules.length != output.modules.length {517
return Err("unsupported: module initialization order")518
}519
let mut roots: Array<Stage1Operation> = []520
let mut infos: Array<ModInfo> = []521
let mut entryIndex = -1522
let mut position = 0523
for module in modules {524
if module.extern {525
return Err("unsupported: extern module {module.identity}")526
}527
if module.operationIds.length == 0 {528
return Err("unsupported: empty module {module.identity}")529
}530
let root = opAt(table, module.operationIds[0])?531
roots.push(root)532
infos.push(registerModule(ctx, module, root)?)533
if module.entry {534
entryIndex = position535
}536
position += 1537
}538
if entryIndex < 0 {539
return Err("unsupported: no entry module")540
}541
let entryModule = modules[entryIndex]542
let entryRoot = roots[entryIndex]543
let entryInfo = infos[entryIndex]545
// Import edges in module source order, for the initialization-fault chain.546
let mut edges: Array<Array<string>> = []547
let mut ordinal = 0548
while ordinal < modules.length {549
let mut index = 0550
for module in modules {551
if module.sourceOrdinal == ordinal {552
for id in roots[index].operands {553
let item = opAt(table, id)?554
if item.kind == "import" {555
edges.push([module.identity, item.importModule])556
}557
}558
}559
index += 1560
}561
ordinal += 1562
}564
position = 0565
for module in modules {566
for bind in infos[position].binds {567
if bind.kind == "fn" {568
let declaration = opAt(table, bind.rust)?569
if declaration.module != module.identity {570
continue571
}572
emitFunction(ctx, fnOf(ctx, bind.rust, roots[position])?, infos[position])?573
}574
}575
position += 1576
}578
let mut body: Array<string> = []579
position = 0580
for module in modules {581
let code = emitModuleInit(ctx, module, roots[position], infos[position])?582
if module.entry {583
for line in code.lines {584
body.push(" {line}")585
}586
body.push(" let __topaz_init_value = {code.tail};")587
} else {588
let record = exportRecord(ctx, infos[position], roots[position])?589
let suffix = "(during initialization of module `{module.identity}`; {chainTo(modules, edges, entryModule.identity, module.identity)})"590
body.push(" match (async \{")591
for line in code.lines {592
body.push(" {line}")593
}594
body.push(" top_cell_set(&g.{infos[position].cell}, {record});")595
body.push(" Ok::<(), RtError>(())")596
body.push(" \}).await \{ Ok(()) => \{\}, Err(__e) => return Err(RtError \{ code: __e.code, message: format!(\"\{\} \{\}\", __e.message, {rustStr(suffix)}), span: __e.span \}), \}")597
}598
position += 1599
}601
let facts = projectExports(table, entryRoot)?602
let explicitMain = hasExplicitMain(facts)603
let mut entryValue = "__topaz_init_value"604
let mut mainSpan = "Span::new(FileId(0), 0, 0)"605
if explicitMain {606
let bind = findBind(entryInfo, "main", entryRoot)?607
let info = fnOf(ctx, bind.rust, entryRoot)?608
mainSpan = declarationSpan(opAt(table, info.id)?)609
entryValue = "top_cell_get(&g.{info.cell}, \"main\", {mainSpan})?"610
}611
let record = exportRecord(ctx, entryInfo, entryRoot)?612
let exportNames = quotedAll(entryInfo.exports).join(", ")614
let mut out: Array<string> = []615
out.push("// @generated by the Topaz self emitter; do not edit.\n")616
out.push("#![allow(non_snake_case)]\n")617
out.push("use std::rc::Rc;\nuse topaz_rt::*;\n\n")618
out.push("pub const TOPAZ_EXPLICIT_MAIN: bool = {explicitMain};\n\n")619
out.push("pub fn topaz_export_names() -> &'static [&'static str] \{\n &[{exportNames}]\n\}\n")620
out.push(CONTRACT)621
let bodyText = body.join("\n")622
let itemText = ctx.items.join("\n")623
let mut fields: Array<string> = []624
let mut inits: Array<string> = []625
if bodyText.contains("g.methods") || itemText.contains("g.methods") {626
fields.push(" methods: std::cell::RefCell<std::collections::HashMap<(String, String), Value>>,\n")627
inits.push("methods: Default::default()")628
}629
if bodyText.contains("g.protocols") || itemText.contains("g.protocols") {630
fields.push(" protocols: std::cell::RefCell<std::collections::HashMap<(String, String, String, String), Value>>,\n")631
inits.push("protocols: Default::default()")632
}633
for decl in ctx.cellDecls {634
let parts = decl.split("|")635
fields.push(" {parts[0]},\n")636
inits.push("{parts[0].split(":")[0]}: {parts[1]}")637
}638
out.push("\nstruct __G \{\n{fields.join("")}\}\n\n")639
if bodyText.contains("__cell_get(") || itemText.contains("__cell_get(") || record.contains("__cell_get(") {640
out.push(CELL_HELPER)641
}642
if bodyText.contains("__cg(") || itemText.contains("__cg(") {643
out.push(CONST_HELPER)644
}645
out.push("\n")646
out.push(itemText)647
if explicitMain {648
out.push("\nasync fn entry(cx: RtCx, __topaz_args: Value, __topaz_stdin: Value) -> Result<Value, RtError> \{\n let (__topaz_entry_value, _) = __topaz_initialize(cx.clone()).await?;\n call_value(__topaz_entry_value, vec![__topaz_args, __topaz_stdin], cx, {mainSpan}).await\n\}\n")649
} else {650
out.push("\nasync fn entry(cx: RtCx, __topaz_args: Value, __topaz_stdin: Value) -> Result<Value, RtError> \{\n let _ = (&__topaz_args, &__topaz_stdin);\n let (__topaz_entry_value, _) = __topaz_initialize(cx).await?;\n Ok(__topaz_entry_value)\n\}\n")651
}652
out.push("\nasync fn __topaz_initialize(cx: RtCx) -> Result<(Value, Value), RtError> \{\n let _ = &cx;\n")653
out.push(" let g = Rc::new(__G \{ {inits.join(", ")} \});\n let _ = &g;\n")654
out.push(bodyText)655
out.push("\n let __topaz_entry_value = {entryValue};\n Ok((__topaz_entry_value, {record}))\n\}\n")656
Ok(out.join(""))657
}SHA256 82146b611354801641b6d867c4de6f961f0771efdd5ab47152a8fc38bc1414f2