Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions packages/pet-daemon/src/guest-evaluate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
let nextRequestId = 0;

const makeRequestId = () => {
nextRequestId += 1;
return `${Date.now()}-${nextRequestId}`;
};

export const makeGuestEvaluator = mailbox => {
if (!mailbox || typeof mailbox.send !== 'function' || typeof mailbox.receive !== 'function') {
throw new TypeError('mailbox must have send and receive functions');
}

const evaluate = async program => {
if (typeof program !== 'string') {
throw new TypeError('program must be a string');
}

const requestId = makeRequestId();
const message = {
type: 'evaluation-request',
requestId,
source: program,
location: {
source: 'guest',
line: 1,
column: 0,
},
};

await mailbox.send(message);

for (;;) {
const response = await mailbox.receive();
if (!response) {
throw new Error('No response from host');
}
if (response.type === 'evaluation-response' && response.requestId === requestId) {
if (response.allow === true || response.decision === 'allow' || response.ok === true) {
return response;
}
const reason = response.reason || response.error || 'Evaluation denied';
throw new Error(reason);
}
}
};

return evaluate;
};
45 changes: 45 additions & 0 deletions packages/pet-daemon/src/host-evaluate-handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { makePromiseKit } from '@endo/promise-kit';

export const makeHostEvaluateHandler = (mailbox, endo, presenter) => {
const { promise, resolve } = makePromiseKit();

const handler = async message => {
if (message.type !== 'evaluation-request') {
return;
}

const { code, requestID } = message;

const decision = await presenter.presentEvaluationRequest(code);

if (!decision.approved) {
await mailbox.send({
type: 'evaluation-response',
requestID,
approved: false,
reason: decision.reason,
});
return;
}

let result;
let error;
try {
result = await endo.evaluate(code);
} catch (err) {
error = String(err);
}

await mailbox.send({
type: 'evaluation-response',
requestID,
approved: true,
result,
error,
});
};

mailbox.addHandler(handler);

return promise;
};