This commit is contained in:
Dmitry Vasilev
2022-12-23 02:14:38 +08:00
parent 4dbc7c26e2
commit 5be750b424
6 changed files with 61 additions and 75 deletions

View File

@@ -13,6 +13,17 @@ const join = arr => arr.reduce(
[],
)
const is_error = n =>
!n.ok
||
(
n.value instanceof globalThis.run_window.Promise
&&
n.value.status != null
&&
!n.value.status.ok
)
export class CallTree {
constructor(ui, container) {
this.ui = ui
@@ -108,7 +119,7 @@ export class CallTree {
)
: el('span',
'call_header '
+ (n.ok ? '' : 'error')
+ (is_error(n) ? 'error' : '')
+ (n.fn.__location == null ? ' native' : '')
,
// TODO show `this` argument

View File

@@ -42,10 +42,10 @@ export const stringify_for_header = v => {
if(v.status == null) {
return `Promise<pending>`
} else {
if(status.ok) {
return `Promise<fulfilled: ${stringify_for_header(status.value)}>`
if(v.status.ok) {
return `Promise<fulfilled: ${stringify_for_header(v.status.value)}>`
} else {
return `Promise<fulfilled: ${stringify_for_header(status.error)}>`
return `Promise<rejected: ${stringify_for_header(v.status.error)}>`
}
}
} else if(isError(v)) {

View File

@@ -367,7 +367,7 @@ export const eval_modules = (
}
const set_promise_status = value => {
if(value instanceof Promise.Original) {
if(value instanceof Promise) {
// record stack for async calls, so expand calls works sync
set_record_call()
return value
@@ -988,7 +988,7 @@ const do_eval_frame_expr = (node, scope, callsleft) => {
ok = true
value = - expr.result.value
} else if(node.operator == 'await') {
if(expr.result.value instanceof globalThis.run_window.Promise.Original) {
if(expr.result.value instanceof globalThis.run_window.Promise) {
const status = expr.result.value.status
if(status == null) {
// Promise must be already resolved

View File

@@ -1,78 +1,37 @@
export const patch_promise = window => {
if(window.Promise.Original != null) {
if(window.Promise.__patched) {
// already patched
return
}
class PromiseRecordChildren extends Promise {
then(on_resolve, on_reject) {
let children = window.get_children()
if(children == null) {
children = []
window.set_children(children)
}
return super.then(
on_resolve == null
? null
: value => {
window.set_children(children)
return on_resolve(value)
},
const _then = Promise.prototype.then
on_reject == null
? null
: error => {
window.set_children(children)
return on_reject(error)
Promise.prototype.then = function then(on_resolve, on_reject) {
let children = window.get_children()
if(children == null) {
children = []
window.set_children(children)
}
const make_callback = cb => cb == null
? null
: value => {
const current = window.get_children()
window.set_children(children)
try {
return cb(value)
} finally {
window.set_children(current)
}
)
}
}
class PromiseWithStatus extends window.Promise {
constructor(fn) {
let status
let is_constructor_finished = false
const p = new PromiseRecordChildren(
(resolve, reject) => {
fn(
(value) => {
if(value instanceof window.Promise.Original) {
value
.then(v => {
p.status = {ok: true, value: v}
resolve(v)
})
.catch(e => {
p.status = {ok: false, error: e}
reject(e)
})
} else {
status = {ok: true, value}
if(is_constructor_finished) {
p.status = status
}
resolve(value)
}
},
(error) => {
status = {ok: false, error}
if(is_constructor_finished) {
p.status = status
}
reject(error)
},
)
}
)
is_constructor_finished = true
p.status = status
return p
}
return _then.call(
this,
make_callback(on_resolve),
make_callback(on_reject),
)
}
PromiseWithStatus.Original = window.Promise
window.Promise = PromiseWithStatus
window.Promise.__patched = true
}