-
Notifications
You must be signed in to change notification settings - Fork 206
/
slogger.js
138 lines (120 loc) · 4.03 KB
/
slogger.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import { assert } from '@agoric/assert';
const IDLE = 'idle';
const STARTUP = 'startup';
const DELIVERY = 'delivery';
export function makeDummySlogger(makeConsole) {
return harden({
addVat: () => 0,
vatConsole: () => makeConsole('disabled slogger'),
startup: () => () => 0, // returns nop finish() function
delivery: () => () => 0,
syscall: () => () => 0,
changeCList: () => () => 0,
terminateVat: () => () => 0,
});
}
export function makeSlogger(writeObj) {
const write = writeObj ? e => writeObj(harden(e)) : () => 0;
const vatSlogs = new Map(); // vatID -> vatSlog
function makeVatSlog(vatID) {
let state = IDLE; // or STARTUP or DELIVERY
let crankNum;
let deliveryNum = 0;
let syscallNum;
function assertOldState(exp, msg) {
assert(state === exp, `vat ${vatID} in ${state}, not ${exp}: ${msg}`);
}
function vatConsole(origConsole) {
const vc = {};
for (const level of ['debug', 'log', 'info', 'warn', 'error']) {
vc[level] = (...args) => {
origConsole[level](...args);
const when = { state, crankNum, vatID, deliveryNum };
write({ type: 'console', ...when, level, args });
};
}
return harden(vc);
}
function startup() {
// provide a context for console calls during startup
assertOldState(IDLE, 'did startup get called twice?');
state = STARTUP;
function finish() {
assertOldState(STARTUP, 'startup-finish called twice?');
state = IDLE;
}
return harden(finish);
}
// kd: kernelDelivery, vd: vatDelivery
function delivery(newCrankNum, kd, vd) {
assertOldState(IDLE, 'reentrant delivery?');
state = DELIVERY;
crankNum = newCrankNum;
const when = { crankNum, vatID, deliveryNum };
write({ type: 'deliver', ...when, kd, vd });
deliveryNum += 1;
syscallNum = 0;
// dr: deliveryResult
function finish(dr) {
assertOldState(DELIVERY, 'delivery-finish called twice?');
write({ type: 'deliver-result', ...when, dr });
state = IDLE;
}
return harden(finish);
}
// ksc: kernelSyscallObject, vsc: vatSyscallObject
function syscall(ksc, vsc) {
assertOldState(DELIVERY, 'syscall invoked outside of delivery');
const when = { crankNum, vatID, deliveryNum, syscallNum };
write({ type: 'syscall', ...when, ksc, vsc });
syscallNum += 1;
// ksr: kernelSyscallResult, vsr: vatSyscallResult
function finish(ksr, vsr) {
assertOldState(DELIVERY, 'syscall finished after delivery?');
write({ type: 'syscall-result', ...when, ksr, vsr });
}
return harden(finish);
}
// mode: 'import' | 'export' | 'drop'
function changeCList(crank, mode, kobj, vobj) {
write({ type: 'clist', crankNum: crank, mode, vatID, kobj, vobj });
}
function terminateVat(shouldReject, info) {
write({ type: 'terminate', vatID, shouldReject, info });
}
return harden({
vatConsole,
startup,
delivery,
syscall,
changeCList,
terminateVat,
});
}
function addVat(vatID, dynamic, description, name, vatSourceBundle) {
assert(!vatSlogs.has(vatID), `already have slog for ${vatID}`);
const vatSlog = makeVatSlog(vatID);
vatSlogs.set(vatID, vatSlog);
write({
type: 'create-vat',
vatID,
dynamic,
description,
name,
vatSourceBundle,
});
return vatSlog;
}
// function annotateVat(vatID, data) {
// write({ type: 'annotate-vat', vatID, data });
// }
return harden({
addVat,
vatConsole: (vatID, ...args) => vatSlogs.get(vatID).vatConsole(...args),
startup: (vatID, ...args) => vatSlogs.get(vatID).startup(...args),
delivery: (vatID, ...args) => vatSlogs.get(vatID).delivery(...args),
syscall: (vatID, ...args) => vatSlogs.get(vatID).syscall(...args),
changeCList: (vatID, ...args) => vatSlogs.get(vatID).changeCList(...args),
terminateVat: (vatID, ...args) => vatSlogs.get(vatID).terminateVat(...args),
});
}