fix io patches

This commit is contained in:
Dmitry Vasilev
2023-02-07 20:09:43 +08:00
parent 356cb09f92
commit 9b9d2e305e

View File

@@ -1,10 +1,24 @@
import {set_record_call} from './runtime.js' import {set_record_call} from './runtime.js'
const io_patch = (cxt, obj, method, name, use_context = false) => { const get_object_to_patch = (cxt, path) => {
let obj = cxt.window
for(let i = 0; i < path.length - 1; i++) {
obj = obj[path[i]]
}
return obj
}
const io_patch = (cxt, path, use_context = false) => {
const obj = get_object_to_patch(cxt, path)
const method = path.at(-1)
if(obj == null || obj[method] == null) { if(obj == null || obj[method] == null) {
// Method is absent in current env, skip patching // Method is absent in current env, skip patching
return return
} }
const name = path.join('.')
console.log('patching', name, obj, method)
const original = obj[method] const original = obj[method]
obj[method] = function(...args) { obj[method] = function(...args) {
// TODO guard calls from prev run // TODO guard calls from prev run
@@ -124,7 +138,7 @@ const io_patch = (cxt, obj, method, name, use_context = false) => {
if(next_resolution != null && !cxt.io_cache_resolver_is_set) { if(next_resolution != null && !cxt.io_cache_resolver_is_set) {
console.error('set resolver') console.error('set resolver')
const original_setTimeout = globalThis.setTimeout.__original const original_setTimeout = cxt.window.setTimeout.__original
cxt.io_cache_resolver_is_set = true cxt.io_cache_resolver_is_set = true
original_setTimeout(() => { original_setTimeout(() => {
@@ -204,11 +218,15 @@ const io_patch = (cxt, obj, method, name, use_context = false) => {
obj[method].__original = original obj[method].__original = original
} }
const io_patch_remove = (obj, method) => { const io_patch_remove = (cxt, path) => {
const obj = get_object_to_patch(cxt, path)
const method = path.at(-1)
if(obj == null || obj[method] == null) { if(obj == null || obj[method] == null) {
// Method is absent in current env, skip patching // Method is absent in current env, skip patching
return return
} }
console.log('removing io patch', obj, method)
obj[method] = obj[method].__original obj[method] = obj[method].__original
} }
@@ -221,48 +239,45 @@ const Response_methods = [
] ]
export const apply_io_patches = cxt => { export const apply_io_patches = cxt => {
io_patch(cxt, Math, 'random', 'Math.random') io_patch(cxt, ['Math', 'random'])
io_patch(cxt, globalThis, 'setTimeout', 'setTimeout') io_patch(cxt, ['setTimeout'])
// TODO test // TODO test
io_patch(cxt, globalThis, 'clearTimeout', 'clearTimeout') io_patch(cxt, ['clearTimeout'])
// TODO test // TODO test
const Date = globalThis.Date const Date = cxt.window.Date
io_patch(cxt, globalThis, 'Date', 'Date') io_patch(cxt, ['Date'])
globalThis.Date.parse = Date.parse cxt.window.Date.parse = Date.parse
globalThis.Date.now = Date.now cxt.window.Date.now = Date.now
globalThis.Date.UTC = Date.UTC cxt.window.Date.UTC = Date.UTC
io_patch(cxt, globalThis.Date, 'now', 'Date.now') io_patch(cxt, ['Date', 'now'])
io_patch(cxt, globalThis, 'fetch', 'fetch') io_patch(cxt, ['fetch'])
// Check if Response is defined, for node.js // Check if Response is defined, for node.js
if(globalThis.Response != null) { if(cxt.window.Response != null) {
for(let key of Response_methods) { for(let key of Response_methods) {
io_patch(cxt, Response.prototype, key, 'Response.prototype.' + key, true) io_patch(cxt, ['Response', 'prototype', key], true)
} }
} }
} }
export const remove_io_patches = cxt => { export const remove_io_patches = cxt => {
// TODO when to apply io_patches and promise_patches? Only once, when we io_patch_remove(cxt, ['Math', 'random'])
// create window?
io_patch_remove(Math, 'random') io_patch_remove(cxt, ['setTimeout'])
io_patch_remove(globalThis, 'setTimeout')
// TODO test // TODO test
io_patch_remove(globalThis, 'clearTimeout') io_patch_remove(cxt, ['clearTimeout'])
io_patch_remove(globalThis, 'Date') io_patch_remove(cxt, ['Date'])
io_patch_remove(globalThis, 'fetch') io_patch_remove(cxt, ['fetch'])
// Check if Response is defined, for node.js // Check if Response is defined, for node.js
if(globalThis.Response != null) { if(cxt.window.Response != null) {
for(let key of Response_methods) { for(let key of Response_methods) {
io_patch_remove(Response.prototype, key) io_patch_remove(cxt, ['Response', 'prototype', key])
} }
} }
} }