1 The exports of statically linked modules belong to the main function of a 2 program and live as long as that function. A program that is loaded and run 3 once does not wait for the collector, also if its module exports a function. 4 Each later call of the function binds the module instances of the first 5 call, so module state carries over. A call that starts while another call of 6 the function is active shares these instances, and the imports that the 7 outer call resolves afterwards bind the correct exports. Functions imported 8 during a call stay valid after it. 9 10 -- Testcase -- 11 import * as fs from 'fs'; 12 13 let live = gc("count"); 14 15 for (let i = 0; i < 100; i++) 16 loadfile("files/counter.uc")(); 17 18 print("live values after 100 loads: ", gc("count") - live, "\n"); 19 20 let fn = loadfile("files/counter.uc"); 21 print("repeated call: ", fn(), " ", fn(), " ", fn(), "\n"); 22 23 gc(); 24 print("call after a collection: ", fn(), "\n"); 25 26 live = gc("count"); 27 28 for (let i = 0; i < 100; i++) 29 fn(); 30 31 print("live values after 100 calls: ", gc("count") - live, "\n"); 32 33 let inc = loadfile("files/keep.uc")(); 34 print("kept function: ", inc(), " ", inc(), "\n"); 35 36 global.depth = 0; 37 global.nested = loadfile("files/nested.uc"); 38 print("nested run: ", global.nested(), "\n"); 39 40 print("tail call: ", loadfile("files/tail.uc")(), "\n"); 41 42 let failing = loadfile("files/failing.uc"); 43 44 for (let i = 0; i < 2; i++) { 45 try { 46 failing(); 47 } 48 catch (e) { 49 print("failing run: ", e.message, "\n"); 50 } 51 } 52 53 let dynamic = import("dynamic"); 54 print("dynamic import: ", dynamic.inc(), " ", dynamic.inc(), " ", dynamic.name, "\n"); 55 56 // A file that the body of a dynamically loaded module loads is a program of 57 // its own, not a module. 58 let loader = import("loader"); 59 print("loaded in a module body: ", loader.fn(), " ", loader.fn(), " ", loader.fn(), "\n"); 60 61 system([ fs.readlink("/proc/self/exe"), "-c", "-o", "files/precompiled.uc", "files/counter.uc" ]); 62 fn = loadfile("files/precompiled.uc"); 63 print("precompiled: ", fn(), " ", fn(), "\n"); 64 -- End -- 65 66 -- File mod.uc -- 67 let n = 0; 68 69 export function inc() { return ++n; }; 70 export const name = "mod"; 71 -- End -- 72 73 -- File counter.uc -- 74 import { inc } from "./mod.uc"; 75 76 return inc(); 77 -- End -- 78 79 -- File keep.uc -- 80 import { inc } from "./mod.uc"; 81 82 return inc; 83 -- End -- 84 85 -- File nested.uc -- 86 import { inc } from "./mod.uc"; 87 88 let d = global.depth++; 89 let count = inc(); 90 let inner = (d < 2) ? global.nested() : "-"; 91 92 import * as other from "./other.uc"; 93 import { value } from "./other.uc"; 94 95 return `${d}:${count}:${inc()}:${value()}:${other.default} ${inner}`; 96 -- End -- 97 98 -- File other.uc -- 99 export function value() { return "value"; }; 100 export default "default"; 101 -- End -- 102 103 -- File tail.uc -- 104 import { inc } from "./mod.uc"; 105 106 inc(); 107 return inc(); 108 -- End -- 109 110 -- File failing.uc -- 111 import { inc } from "./mod.uc"; 112 113 die(`count ${inc()}`); 114 -- End -- 115 116 -- File loader.uc -- 117 export const fn = loadfile("files/counter.uc"); 118 -- End -- 119 120 -- File dynamic.uc -- 121 import { inc as mod_inc, name as mod_name } from "./mod.uc"; 122 123 export function inc() { return mod_inc(); }; 124 export const name = mod_name; 125 -- End -- 126 127 -- Args -- 128 -R -L files/ 129 -- End -- 130 131 -- Expect stdout -- 132 live values after 100 loads: 0 133 repeated call: 1 2 3 134 call after a collection: 4 135 live values after 100 calls: 0 136 kept function: 1 2 137 nested run: 0:1:6:value:default 1:2:5:value:default 2:3:4:value:default - 138 tail call: 2 139 failing run: count 1 140 failing run: count 2 141 dynamic import: 1 2 mod 142 loaded in a module body: 1 2 3 143 precompiled: 1 2 144 -- End --
This page was automatically generated by LXR 0.3.1. • OpenWrt