mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 13:04:30 -08:00
WIP
This commit is contained in:
10
README.md
10
README.md
@@ -130,9 +130,17 @@ there is cached result.
|
||||
|
||||
Builtin IO functions are mocked to cache IO. Current list of builtin cached
|
||||
functions is:
|
||||
- `Date` constructor
|
||||
- `Date`
|
||||
- `Math.random()`
|
||||
- `fetch`
|
||||
- `Response` methods:
|
||||
- `arrayBuffer`
|
||||
- `blob`
|
||||
- `formData`
|
||||
- `json`
|
||||
- `text`
|
||||
- `setTimeout`
|
||||
- `clearTimeout`
|
||||
|
||||
If you want to make your own own function IO-caching, or import third party
|
||||
function and make it IO-caching, then you should use `IO` pragma.
|
||||
|
||||
@@ -768,6 +768,11 @@ const on_deferred_call = (state, call, calltree_changed_token, logs) => {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO test
|
||||
const clear_io_cache = state => {
|
||||
return run_code({...state, io_cache: null})
|
||||
}
|
||||
|
||||
const do_load_dir = (state, dir) => {
|
||||
const collect_files = dir => dir.kind == 'file'
|
||||
? [dir]
|
||||
@@ -848,5 +853,6 @@ export const COMMANDS = {
|
||||
external_imports_loaded,
|
||||
eval_modules_finished,
|
||||
on_deferred_call,
|
||||
clear_io_cache,
|
||||
calltree: calltree_commands,
|
||||
}
|
||||
|
||||
@@ -20,7 +20,11 @@ const io_patch = (cxt, path, use_context = false) => {
|
||||
|
||||
const original = obj[method]
|
||||
obj[method] = function(...args) {
|
||||
// TODO guard calls from prev run
|
||||
// TODO if called from previous version of code (calltree_changed_token is
|
||||
// different), then do not call IO function and throw error to finish
|
||||
// previous run ASAP
|
||||
|
||||
// TODO remove
|
||||
console.error('patched method', name, {
|
||||
io_cache_is_recording: cxt.io_cache_is_recording,
|
||||
io_cache_is_replay_aborted: cxt.io_cache_is_replay_aborted,
|
||||
@@ -28,14 +32,18 @@ const io_patch = (cxt, path, use_context = false) => {
|
||||
? cxt.io_cache.length
|
||||
: cxt.io_cache_index
|
||||
})
|
||||
// TODO guard that in find_call io methods are not called?
|
||||
// if(searched_location != null) {
|
||||
// throw new Error('illegal state')
|
||||
// }
|
||||
|
||||
// sanity check
|
||||
if(cxt.searched_location != null) {
|
||||
throw new Error('illegal state')
|
||||
}
|
||||
|
||||
if(cxt.io_cache_is_replay_aborted) {
|
||||
// Try to finish fast
|
||||
throw new Error('io replay aborted')
|
||||
} else if(cxt.io_cache_is_recording) {
|
||||
}
|
||||
|
||||
if(cxt.io_cache_is_recording) {
|
||||
let ok, value, error
|
||||
const has_new_target = new.target != null
|
||||
try {
|
||||
@@ -141,6 +149,11 @@ const io_patch = (cxt, path, use_context = false) => {
|
||||
cxt.io_cache_resolver_is_set = true
|
||||
|
||||
original_setTimeout(() => {
|
||||
if(cxt.io_cache_is_replay_aborted) {
|
||||
console.error('RESOLVER ABORTED')
|
||||
return
|
||||
}
|
||||
|
||||
// TODO guard from previous run
|
||||
console.error('resolver', {
|
||||
io_cache_is_replay_aborted: cxt.io_cache_is_replay_aborted,
|
||||
@@ -151,38 +164,32 @@ const io_patch = (cxt, path, use_context = false) => {
|
||||
|
||||
// TODO check if call from prev run
|
||||
|
||||
if(cxt.io_cache_is_replay_aborted) {
|
||||
console.error('RESOLVER ABORTED')
|
||||
return
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if(cxt.io_cache_index >= cxt.io_cache.length) {
|
||||
// TODO Do nothing or what?
|
||||
// Should not gonna happen
|
||||
throw new Error('illegal state')
|
||||
}
|
||||
|
||||
const next_event = cxt.io_cache[cxt.io_cache_index]
|
||||
if(next_event.type == 'call') {
|
||||
// TODO Call not happened, replay?
|
||||
cxt.io_cache_is_replay_aborted = true
|
||||
} else {
|
||||
const next_event = cxt.io_cache[cxt.io_cache_index]
|
||||
if(next_event.type == 'call') {
|
||||
// TODO Call not happened, replay?
|
||||
cxt.io_cache_is_replay_aborted = true
|
||||
} else {
|
||||
while(
|
||||
cxt.io_cache_index < cxt.io_cache.length
|
||||
&&
|
||||
cxt.io_cache[cxt.io_cache_index].type == 'resolution'
|
||||
) {
|
||||
const resolution = cxt.io_cache[cxt.io_cache_index]
|
||||
const resolver = cxt.io_cache_resolvers.get(resolution.index)
|
||||
while(
|
||||
cxt.io_cache_index < cxt.io_cache.length
|
||||
&&
|
||||
cxt.io_cache[cxt.io_cache_index].type == 'resolution'
|
||||
) {
|
||||
const resolution = cxt.io_cache[cxt.io_cache_index]
|
||||
const resolver = cxt.io_cache_resolvers.get(resolution.index)
|
||||
|
||||
cxt.io_cache_index++
|
||||
cxt.io_cache_index++
|
||||
|
||||
if(cxt.io_cache[resolution.index].name == 'setTimeout') {
|
||||
resolver()
|
||||
} else {
|
||||
resolver(cxt.io_cache[resolution.index].value)
|
||||
}
|
||||
console.log('RESOLVE', cxt.io_cache_index, resolution.index)
|
||||
if(cxt.io_cache[resolution.index].name == 'setTimeout') {
|
||||
resolver()
|
||||
} else {
|
||||
resolver(cxt.io_cache[resolution.index].value)
|
||||
}
|
||||
console.log('RESOLVE', cxt.io_cache_index, resolution.index)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,9 +199,6 @@ const io_patch = (cxt, path, use_context = false) => {
|
||||
cxt.io_cache_index++
|
||||
|
||||
if(call.ok) {
|
||||
// TODO resolve promises in the same order they were resolved on
|
||||
// initial execution
|
||||
|
||||
if(call.value instanceof cxt.window.Promise) {
|
||||
return new Promise(resolve => {
|
||||
cxt.io_cache_resolvers.set(cxt.io_cache_index - 1, resolve)
|
||||
|
||||
@@ -3127,8 +3127,6 @@ const y = x()`
|
||||
console.log(await delay(0))
|
||||
`
|
||||
|
||||
console.log('CODE2', code2.slice(75))
|
||||
|
||||
const next = await command_input_async(i, code2, 0)
|
||||
|
||||
// Assert cache was used
|
||||
|
||||
Reference in New Issue
Block a user