@quenk/potoo 4.0.7 → 4.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/actor/address.js.map +1 -1
- package/lib/actor/api.d.ts +2 -2
- package/lib/actor/api.js.map +1 -1
- package/lib/actor/framework/index.js +2 -2
- package/lib/actor/framework/index.js.map +1 -1
- package/lib/actor/framework/process.d.ts +3 -2
- package/lib/actor/framework/process.js.map +1 -1
- package/lib/actor/framework/resident.d.ts +5 -3
- package/lib/actor/framework/resident.js +2 -0
- package/lib/actor/framework/resident.js.map +1 -1
- package/lib/actor/index.js.map +1 -1
- package/lib/actor/system/vm/allocator/index.js.map +1 -1
- package/lib/actor/system/vm/allocator/map.js +7 -4
- package/lib/actor/system/vm/allocator/map.js.map +1 -1
- package/lib/actor/system/vm/conf.js.map +1 -1
- package/lib/actor/system/vm/event/dispatcher.d.ts +31 -12
- package/lib/actor/system/vm/event/dispatcher.js +72 -20
- package/lib/actor/system/vm/event/dispatcher.js.map +1 -1
- package/lib/actor/system/vm/event/index.js.map +1 -1
- package/lib/actor/system/vm/frame.js.map +1 -1
- package/lib/actor/system/vm/group.js.map +1 -1
- package/lib/actor/system/vm/index.js +2 -2
- package/lib/actor/system/vm/index.js.map +1 -1
- package/lib/actor/system/vm/log/index.js.map +1 -1
- package/lib/actor/system/vm/log/writer.js.map +1 -1
- package/lib/actor/system/vm/object/foreign.js.map +1 -1
- package/lib/actor/system/vm/object/index.js.map +1 -1
- package/lib/actor/system/vm/object/list.js.map +1 -1
- package/lib/actor/system/vm/op/actor.js.map +1 -1
- package/lib/actor/system/vm/op/base.js.map +1 -1
- package/lib/actor/system/vm/op/index.js.map +1 -1
- package/lib/actor/system/vm/op/object.js.map +1 -1
- package/lib/actor/system/vm/registry.js.map +1 -1
- package/lib/actor/system/vm/runtime/error.js.map +1 -1
- package/lib/actor/system/vm/runtime.js.map +1 -1
- package/lib/actor/system/vm/scheduler.js.map +1 -1
- package/lib/actor/system/vm/script/index.js.map +1 -1
- package/lib/actor/system/vm/script/info.js.map +1 -1
- package/lib/actor/system/vm/strategy/error.js.map +1 -1
- package/lib/actor/system/vm/thread/factory.js.map +1 -1
- package/lib/actor/system/vm/thread/index.js.map +1 -1
- package/lib/actor/system/vm/thread/process.js.map +1 -1
- package/lib/actor/system/vm/thread/shared/index.js.map +1 -1
- package/lib/actor/system/vm/thread/shared/js.d.ts +2 -2
- package/lib/actor/system/vm/thread/shared/js.js +3 -3
- package/lib/actor/system/vm/thread/shared/js.js.map +1 -1
- package/lib/actor/system/vm/type.js.map +1 -1
- package/lib/actor/template.d.ts +20 -0
- package/lib/actor/template.js +17 -1
- package/lib/actor/template.js.map +1 -1
- package/package.json +11 -9
- package/lib/actor/address.ts +0 -90
- package/lib/actor/api.ts +0 -57
- package/lib/actor/framework/index.ts +0 -1
- package/lib/actor/framework/process.ts +0 -87
- package/lib/actor/framework/resident.ts +0 -90
- package/lib/actor/index.ts +0 -35
- package/lib/actor/system/vm/allocator/index.ts +0 -43
- package/lib/actor/system/vm/allocator/map.ts +0 -256
- package/lib/actor/system/vm/conf.ts +0 -33
- package/lib/actor/system/vm/event/dispatcher.ts +0 -85
- package/lib/actor/system/vm/event/index.ts +0 -143
- package/lib/actor/system/vm/frame.ts +0 -484
- package/lib/actor/system/vm/group.ts +0 -46
- package/lib/actor/system/vm/index.ts +0 -230
- package/lib/actor/system/vm/log/index.ts +0 -73
- package/lib/actor/system/vm/log/writer.ts +0 -96
- package/lib/actor/system/vm/object/foreign.ts +0 -10
- package/lib/actor/system/vm/object/index.ts +0 -4
- package/lib/actor/system/vm/object/list.ts +0 -8
- package/lib/actor/system/vm/op/actor.ts +0 -126
- package/lib/actor/system/vm/op/base.ts +0 -243
- package/lib/actor/system/vm/op/index.ts +0 -388
- package/lib/actor/system/vm/op/object.ts +0 -81
- package/lib/actor/system/vm/registry.ts +0 -223
- package/lib/actor/system/vm/runtime/error.ts +0 -248
- package/lib/actor/system/vm/runtime.ts +0 -31
- package/lib/actor/system/vm/scheduler.ts +0 -108
- package/lib/actor/system/vm/script/index.ts +0 -64
- package/lib/actor/system/vm/script/info.ts +0 -359
- package/lib/actor/system/vm/strategy/error.ts +0 -88
- package/lib/actor/system/vm/thread/factory.ts +0 -29
- package/lib/actor/system/vm/thread/index.ts +0 -29
- package/lib/actor/system/vm/thread/process.ts +0 -134
- package/lib/actor/system/vm/thread/shared/index.ts +0 -50
- package/lib/actor/system/vm/thread/shared/js.ts +0 -151
- package/lib/actor/system/vm/type.ts +0 -115
- package/lib/actor/template.ts +0 -170
- package/lib/tsconfig.json +0 -22
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import * as template from '../../template';
|
|
2
|
-
import * as errors from './runtime/error';
|
|
3
|
-
import * as events from './event';
|
|
4
|
-
|
|
5
|
-
import { Err } from '@quenk/noni/lib/control/error';
|
|
6
|
-
import { Future } from '@quenk/noni/lib/control/monad/future';
|
|
7
|
-
import { diff, empty } from '@quenk/noni/lib/data/array';
|
|
8
|
-
import { merge } from '@quenk/noni/lib/data/record';
|
|
9
|
-
|
|
10
|
-
import { Address, ADDRESS_SYSTEM, isChild, isGroup } from '../../address';
|
|
11
|
-
import { fromSpawnable } from '../../template';
|
|
12
|
-
import { Actor, Message } from '../../';
|
|
13
|
-
import { MapAllocator } from './allocator/map';
|
|
14
|
-
import { ErrorStrategy, SupervisorErrorStrategy } from './strategy/error';
|
|
15
|
-
import { Thread } from './thread';
|
|
16
|
-
import { GroupMap } from './group';
|
|
17
|
-
import { Scheduler } from './scheduler';
|
|
18
|
-
import { RegistrySet } from './registry';
|
|
19
|
-
import { Allocator } from './allocator';
|
|
20
|
-
import { Api } from '../../api';
|
|
21
|
-
import { LogWritable, LogWriter } from './log/writer';
|
|
22
|
-
import { EventDispatcher } from './event/dispatcher';
|
|
23
|
-
import { Conf, PartialConf } from './conf';
|
|
24
|
-
import { toLogLevelValue } from './log';
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* VM is the interface for a virtual machine.
|
|
28
|
-
*
|
|
29
|
-
* It provides methods for manipulating the state of the actors of the system.
|
|
30
|
-
* Some opcode handlers depend on this interface to do their work.
|
|
31
|
-
*/
|
|
32
|
-
export interface VM extends Actor, Thread, Api {
|
|
33
|
-
/**
|
|
34
|
-
* allocator used to manage thread resources for an actor.
|
|
35
|
-
*/
|
|
36
|
-
allocator: Allocator;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* scheduler used for co-ordinating actor thread execution.
|
|
40
|
-
*/
|
|
41
|
-
scheduler: Scheduler;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* errors strategy used to handle errors that occur within the system.
|
|
45
|
-
*/
|
|
46
|
-
errors: ErrorStrategy;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* log service for the VM.
|
|
50
|
-
*
|
|
51
|
-
* Used to access the internal logging API.
|
|
52
|
-
*/
|
|
53
|
-
log: LogWritable;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* events service for the VM.
|
|
57
|
-
*
|
|
58
|
-
* Used to publish VM events to interested listeners.
|
|
59
|
-
*/
|
|
60
|
-
events: EventDispatcher;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* registry used to store internal VM objects.
|
|
64
|
-
*/
|
|
65
|
-
registry: RegistrySet;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* groups holds the mapping of group names to actor addresses.
|
|
69
|
-
*/
|
|
70
|
-
groups: GroupMap;
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* sendMessage to the actor act the destination address.
|
|
74
|
-
*
|
|
75
|
-
* This is used by the threads to communicate.
|
|
76
|
-
*/
|
|
77
|
-
sendMessage(from: Thread, to: Address, msg: Message): void;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* sendKillSignal initiates the deallocation of the actor at the
|
|
81
|
-
* specified address.
|
|
82
|
-
*
|
|
83
|
-
* Actual deallocation only occurs if the source thread is allowed to.
|
|
84
|
-
*/
|
|
85
|
-
sendKillSignal(src: Thread, target: Address): Promise<void>;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* runTask allows an async function to be executed on behalf of a Thread.
|
|
89
|
-
*
|
|
90
|
-
* If the Promise rejects, the error is raised with the Thread.
|
|
91
|
-
*/
|
|
92
|
-
runTask(thread: Thread, task: () => Promise<void>): Promise<void>;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* PVM (Potoo Virtual Machine) is a JavaScript implemented virtual machine that
|
|
97
|
-
* functions as a message delivery system between target actors.
|
|
98
|
-
*
|
|
99
|
-
* Actors known to the VM are considered to be part of a system and may or may
|
|
100
|
-
* not reside on the same process/worker/thread depending on the underlying
|
|
101
|
-
* platform and individual actor implementations.
|
|
102
|
-
*/
|
|
103
|
-
export class PVM implements VM {
|
|
104
|
-
constructor(
|
|
105
|
-
public allocator: Allocator = new MapAllocator(() => this),
|
|
106
|
-
public scheduler: Scheduler = new Scheduler(),
|
|
107
|
-
public errors: ErrorStrategy = new SupervisorErrorStrategy(allocator),
|
|
108
|
-
public log: LogWritable = new LogWriter(console),
|
|
109
|
-
public events = new EventDispatcher(log),
|
|
110
|
-
public registry = new RegistrySet(),
|
|
111
|
-
public groups: GroupMap = new GroupMap(),
|
|
112
|
-
public address = ADDRESS_SYSTEM,
|
|
113
|
-
public self = ADDRESS_SYSTEM
|
|
114
|
-
) {}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* create a new PVM instance using the provided configuration.
|
|
118
|
-
*/
|
|
119
|
-
static create(conf: PartialConf = {}): PVM {
|
|
120
|
-
let config: Conf = {
|
|
121
|
-
log: merge({ level: 'info', sink: console }, conf.log ?? {})
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
let vm: PVM;
|
|
125
|
-
|
|
126
|
-
let allocator = new MapAllocator(() => vm);
|
|
127
|
-
let log = new LogWriter(
|
|
128
|
-
config.log.sink,
|
|
129
|
-
toLogLevelValue(config.log.level)
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
vm = new PVM(
|
|
133
|
-
allocator,
|
|
134
|
-
new Scheduler(),
|
|
135
|
-
new SupervisorErrorStrategy(allocator),
|
|
136
|
-
log,
|
|
137
|
-
new EventDispatcher(log),
|
|
138
|
-
new RegistrySet(),
|
|
139
|
-
new GroupMap()
|
|
140
|
-
);
|
|
141
|
-
return vm;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Actor
|
|
145
|
-
|
|
146
|
-
async start() {}
|
|
147
|
-
|
|
148
|
-
//TODO: events.OnRootMessage.dispatch();
|
|
149
|
-
async notify() {}
|
|
150
|
-
|
|
151
|
-
//TODO: stop all actors?
|
|
152
|
-
async stop() {}
|
|
153
|
-
|
|
154
|
-
// Api
|
|
155
|
-
|
|
156
|
-
get vm() {
|
|
157
|
-
return this;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
async spawn(tmpl: template.Spawnable): Promise<Address> {
|
|
161
|
-
return this.allocator.allocate(this, fromSpawnable(tmpl));
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
async tell(to: Address, msg: Message) {
|
|
165
|
-
this.sendMessage(this, to, msg);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
async raise(err: Err) {
|
|
169
|
-
await this.errors.raise(this, err);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
async kill(addr: Address) {
|
|
173
|
-
await this.sendKillSignal(this, addr);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async receive<T>() {
|
|
177
|
-
return <Promise<T>>Future.raise(new Error('Not implemented'));
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Platform
|
|
181
|
-
|
|
182
|
-
sendMessage(from: Thread, to: Address, msg: Message) {
|
|
183
|
-
let targets = isGroup(to) ? this.groups.getMembers(to) : [to];
|
|
184
|
-
|
|
185
|
-
let threads = this.allocator.getThreads(targets);
|
|
186
|
-
|
|
187
|
-
let missing = diff(
|
|
188
|
-
targets,
|
|
189
|
-
threads.map(t => t.address)
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
if (!empty(missing)) {
|
|
193
|
-
for (let address of missing)
|
|
194
|
-
this.events.dispatchMessageEvent(
|
|
195
|
-
events.EVENT_MESSAGE_BOUNCE,
|
|
196
|
-
from.address,
|
|
197
|
-
address,
|
|
198
|
-
msg
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
for (let thread of threads) {
|
|
203
|
-
this.events.dispatchMessageEvent(
|
|
204
|
-
events.EVENT_MESSGAE_SEND,
|
|
205
|
-
from.address,
|
|
206
|
-
to,
|
|
207
|
-
msg
|
|
208
|
-
);
|
|
209
|
-
thread.notify(msg).catch(err => thread.raise(err));
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
async sendKillSignal(src: Thread, target: Address): Promise<void> {
|
|
214
|
-
if (src.address !== target && !isChild(src.address, target)) {
|
|
215
|
-
return Future.raise(new errors.IllegalStopErr(src.address, target));
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
let mtargetThread = this.allocator.getThread(target);
|
|
219
|
-
|
|
220
|
-
if (mtargetThread.isNothing()) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
await this.allocator.deallocate(mtargetThread.get());
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
runTask(thread: Thread, task: () => Promise<void>): Promise<void> {
|
|
228
|
-
return Future.do(task).catch(err => thread.raise(err));
|
|
229
|
-
}
|
|
230
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { Type } from '@quenk/noni/lib/data/type';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* LogLevel is a string indicating the maximum level of messages that should
|
|
5
|
-
* be written to the log sink.
|
|
6
|
-
*/
|
|
7
|
-
export type LogLevel = 'trace' | 'debug' | 'info' | 'notice' | 'warn' | 'error';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* LogLevelValue is a numeric representation of a LogLevel.
|
|
11
|
-
*/
|
|
12
|
-
export enum LogLevelValue {
|
|
13
|
-
trace = 8,
|
|
14
|
-
debug = 7,
|
|
15
|
-
info = 6,
|
|
16
|
-
notice = 5,
|
|
17
|
-
warn = 4,
|
|
18
|
-
error = 3
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* LogSink is the interface expected of log message destinations.
|
|
23
|
-
*
|
|
24
|
-
* This is based on the JS console API and as a result `console` is a valid
|
|
25
|
-
* LogSink.
|
|
26
|
-
*/
|
|
27
|
-
export interface LogSink {
|
|
28
|
-
/**
|
|
29
|
-
* debug level.
|
|
30
|
-
*/
|
|
31
|
-
debug(...e: Type[]): void;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* info level.
|
|
35
|
-
*/
|
|
36
|
-
info(...e: Type[]): void;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* warn level.
|
|
40
|
-
*/
|
|
41
|
-
warn(...e: Type[]): void;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* error level.
|
|
45
|
-
*/
|
|
46
|
-
error(...e: Type[]): void;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* log level.
|
|
50
|
-
*/
|
|
51
|
-
log(...e: Type[]): void;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const logLevelValueEntries = Object.entries(LogLevelValue);
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* toLogLevel converts a LogLevelValue to a LogLevel string.
|
|
58
|
-
*
|
|
59
|
-
* If the value is not valid '<void>' is returned.
|
|
60
|
-
*/
|
|
61
|
-
export const toLogLevel = (level: LogLevelValue): LogLevel => {
|
|
62
|
-
let entry = logLevelValueEntries.find(([, v]) => v === level);
|
|
63
|
-
return <LogLevel>(entry ? entry[0] : '<void>');
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* toLogLevelValue converts a LogLevel to a LogLevelValue.
|
|
68
|
-
*
|
|
69
|
-
* I the LogLevel is not valid LogLevelValue.info is returned.
|
|
70
|
-
*/
|
|
71
|
-
export const toLogLevelValue = (level: LogLevel | string): LogLevelValue => {
|
|
72
|
-
return LogLevelValue[<LogLevel>level] ?? LogLevelValue.info;
|
|
73
|
-
};
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import * as events from '../event';
|
|
2
|
-
|
|
3
|
-
import { isString, Type } from '@quenk/noni/lib/data/type';
|
|
4
|
-
import { Record } from '@quenk/noni/lib/data/record';
|
|
5
|
-
import { interpolate } from '@quenk/noni/lib/data/string';
|
|
6
|
-
|
|
7
|
-
import { InternalEvent } from '../event';
|
|
8
|
-
import { LogLevelValue, LogSink } from '.';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* LogWritable is the interface used by the VM for logging.
|
|
12
|
-
*
|
|
13
|
-
* It provides convenience methods for writing various types of messages to the
|
|
14
|
-
* log sink.
|
|
15
|
-
*/
|
|
16
|
-
export interface LogWritable {
|
|
17
|
-
/**
|
|
18
|
-
* level is the current log level.
|
|
19
|
-
*/
|
|
20
|
-
level: LogLevelValue;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* sink is the destination logs will be written to.
|
|
24
|
-
*/
|
|
25
|
-
sink: LogSink;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* write a message to the log if the level is less than or equal to the
|
|
29
|
-
* current log level.
|
|
30
|
-
*/
|
|
31
|
-
write(level: LogLevelValue, ...args: Type[]): void;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* writeEvent writes an InternalEvent to the log.
|
|
35
|
-
*
|
|
36
|
-
* This uses internal logic to format a message for each event.
|
|
37
|
-
*/
|
|
38
|
-
writeEvent<E extends InternalEvent>(event: E): void;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* LogTemplate used to format event log messages.
|
|
43
|
-
*/
|
|
44
|
-
export type LogTemplates = Record<string>;
|
|
45
|
-
|
|
46
|
-
const defaultTemplates: LogTemplates = {
|
|
47
|
-
[events.EVENT_MESSAGE_BOUNCE]: 'Message from {from} to {to} bounced!',
|
|
48
|
-
|
|
49
|
-
[events.EVENT_MESSGAE_SEND]:
|
|
50
|
-
'Message from {from} to {to} delivered successfully!'
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* LogWriter provides an implementation of [[LogWritable]] for the VM.
|
|
55
|
-
*/
|
|
56
|
-
export class LogWriter implements LogWritable {
|
|
57
|
-
constructor(
|
|
58
|
-
public sink: LogSink,
|
|
59
|
-
public level: LogLevelValue = LogLevelValue.error,
|
|
60
|
-
public templates: LogTemplates = defaultTemplates
|
|
61
|
-
) {}
|
|
62
|
-
|
|
63
|
-
write(level: LogLevelValue, ...args: Type[]) {
|
|
64
|
-
if (level > this.level) return;
|
|
65
|
-
|
|
66
|
-
let { sink } = this;
|
|
67
|
-
|
|
68
|
-
switch (level) {
|
|
69
|
-
case LogLevelValue.debug:
|
|
70
|
-
case LogLevelValue.trace:
|
|
71
|
-
sink.debug(...args);
|
|
72
|
-
break;
|
|
73
|
-
|
|
74
|
-
case LogLevelValue.notice:
|
|
75
|
-
case LogLevelValue.warn:
|
|
76
|
-
sink.warn(...args);
|
|
77
|
-
break;
|
|
78
|
-
|
|
79
|
-
case LogLevelValue.error:
|
|
80
|
-
sink.error(...args);
|
|
81
|
-
break;
|
|
82
|
-
|
|
83
|
-
default:
|
|
84
|
-
sink.info(...args);
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
writeEvent(evt: InternalEvent) {
|
|
90
|
-
let message = this.templates[evt.type] || evt;
|
|
91
|
-
this.write(
|
|
92
|
-
evt.level,
|
|
93
|
-
isString(message) ? interpolate(message, evt) : message
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { Frame } from '../frame';
|
|
2
|
-
import { Template } from '../../../template';
|
|
3
|
-
import { Operand } from '.';
|
|
4
|
-
import { JSThread } from '../thread/shared/js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* alloc allocates resources for a new child actor.
|
|
8
|
-
*
|
|
9
|
-
* TOS must be an instance of PTTemplate or an error will be raised.
|
|
10
|
-
* The address of the new actor is pushed onto the stack.
|
|
11
|
-
*
|
|
12
|
-
* Stack:
|
|
13
|
-
* <template> -> <address>
|
|
14
|
-
*/
|
|
15
|
-
export const alloc = (thread: JSThread, frame: Frame, _: Operand) => {
|
|
16
|
-
let eTemp = frame.popObject();
|
|
17
|
-
|
|
18
|
-
if (eTemp.isLeft()) return thread.raise(eTemp.takeLeft());
|
|
19
|
-
|
|
20
|
-
let tmpl = eTemp.takeRight();
|
|
21
|
-
|
|
22
|
-
//TODO: if(!isTemplateLike(tmpl)) return thread.raise(new Error('alloc: Cannot allocate non-template!'));
|
|
23
|
-
|
|
24
|
-
//TODO: this is async
|
|
25
|
-
thread.spawn(<Template>tmpl);
|
|
26
|
-
|
|
27
|
-
/*
|
|
28
|
-
if (eresult.isLeft()) {
|
|
29
|
-
thread.raise(eresult.takeLeft());
|
|
30
|
-
} else {
|
|
31
|
-
frame.push(thread.vm.registry.addString(eresult.takeRight()));
|
|
32
|
-
}*/
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* self puts the address of the current actor on to the stack.
|
|
37
|
-
* TODO: make self an automatic variable
|
|
38
|
-
*/
|
|
39
|
-
export const self = (_: JSThread, f: Frame, __: Operand) => {
|
|
40
|
-
f.pushSelf();
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* send a message to another actor.
|
|
45
|
-
*
|
|
46
|
-
* Stack:
|
|
47
|
-
* <message>,<address> -> <uint8>
|
|
48
|
-
*/
|
|
49
|
-
export const send = (r: JSThread, f: Frame, _: Operand) => {
|
|
50
|
-
let eMsg = f.popValue();
|
|
51
|
-
|
|
52
|
-
if (eMsg.isLeft()) return r.raise(eMsg.takeLeft());
|
|
53
|
-
|
|
54
|
-
let eAddr = f.popString();
|
|
55
|
-
|
|
56
|
-
if (eAddr.isLeft()) return r.raise(eAddr.takeLeft());
|
|
57
|
-
|
|
58
|
-
r.vm.sendMessage(r, eAddr.takeRight(), eMsg.takeRight());
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* recv schedules a receiver function for the next available message.
|
|
63
|
-
*
|
|
64
|
-
* Currently only supports foreign functions.
|
|
65
|
-
* Will invoke the actor's notify() method if there are pending
|
|
66
|
-
* messages.
|
|
67
|
-
*
|
|
68
|
-
* Stack:
|
|
69
|
-
* <function> ->
|
|
70
|
-
*/
|
|
71
|
-
export const recv = (r: JSThread, f: Frame, _: Operand) => {
|
|
72
|
-
let einfo = f.popFunction();
|
|
73
|
-
|
|
74
|
-
if (einfo.isLeft()) return r.raise(einfo.takeLeft());
|
|
75
|
-
|
|
76
|
-
// r.watch(r.receive());
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* recvcount pushes the total count of pending receives to the top of the stack.
|
|
81
|
-
*
|
|
82
|
-
* Stack:
|
|
83
|
-
* -> <uint32>
|
|
84
|
-
*/
|
|
85
|
-
export const recvcount = (_r: JSThread, _f: Frame, _: Operand) => {
|
|
86
|
-
//f.push(r.context.receivers.length);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* mailcount pushes the number of messages in the actor's mailbox onto the top
|
|
91
|
-
* of the stack.
|
|
92
|
-
*
|
|
93
|
-
* Stack:
|
|
94
|
-
* -> <uint32>
|
|
95
|
-
*/
|
|
96
|
-
export const mailcount = (r: JSThread, f: Frame, _: Operand) => {
|
|
97
|
-
f.push(r.mailbox.length);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* maildq pushes the earliest message in the mailbox (if any).
|
|
102
|
-
*
|
|
103
|
-
* Stack:
|
|
104
|
-
*
|
|
105
|
-
* -> <message>?
|
|
106
|
-
*/
|
|
107
|
-
export const maildq = (_: JSThread, f: Frame, __: Operand) => {
|
|
108
|
-
f.pushMessage();
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* stop an actor in the system.
|
|
113
|
-
*
|
|
114
|
-
* The actor will be removed.
|
|
115
|
-
*
|
|
116
|
-
* Stack:
|
|
117
|
-
*
|
|
118
|
-
* <address> ->
|
|
119
|
-
*/
|
|
120
|
-
export const stop = (r: JSThread, f: Frame, _: Operand) => {
|
|
121
|
-
let eaddr = f.popString();
|
|
122
|
-
|
|
123
|
-
if (eaddr.isLeft()) return r.raise(eaddr.takeLeft());
|
|
124
|
-
|
|
125
|
-
// r.watch(r.kill(eaddr.takeRight()));
|
|
126
|
-
};
|