Skip to content

Commit 39a2c32

Browse files
authored
refactor: store promise in handleStore via reference (#157)
1 parent 99effe2 commit 39a2c32

File tree

7 files changed

+47
-67
lines changed

7 files changed

+47
-67
lines changed

packages/emnapi/src/promise.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@ export function napi_create_promise (env: napi_env, deferred: Pointer<napi_defer
1010
$CHECK_ARG!(envObject, deferred)
1111
$CHECK_ARG!(envObject, promise)
1212

13-
const p = new Promise<any>((resolve, reject) => {
14-
const deferredObject = emnapiCtx.createDeferred({ resolve, reject })
15-
deferredObjectId = deferredObject.id
16-
from64('deferred')
17-
makeSetValue('deferred', 0, 'deferredObjectId', '*')
18-
})
19-
from64('promise')
13+
const resolver = emnapiCtx.createResolver()
14+
deferredObjectId = emnapiCtx.createReference(undefined, resolver, 1, ReferenceOwnership.kUserland as any).id
15+
16+
from64('deferred')
17+
makeSetValue('deferred', 0, 'deferredObjectId', '*')
2018

21-
value = emnapiCtx.napiValueFromJsValue(p)
19+
value = emnapiCtx.napiValueFromJsValue(resolver.promise)
20+
from64('promise')
2221
makeSetValue('promise', 0, 'value', '*')
2322
return $GET_RETURN_STATUS!(envObject)
2423
})
@@ -29,8 +28,10 @@ export function napi_resolve_deferred (env: napi_env, deferred: napi_deferred, r
2928
return $PREAMBLE!(env, (envObject) => {
3029
$CHECK_ARG!(envObject, deferred)
3130
$CHECK_ARG!(envObject, resolution)
32-
const deferredObject = emnapiCtx.getDeferred(deferred)!
33-
deferredObject.resolve(emnapiCtx.jsValueFromNapiValue(resolution)!)
31+
const deferredRef = emnapiCtx.getRef(deferred)!
32+
const resolver = deferredRef.deref() as Resolver<any>
33+
resolver.resolve(emnapiCtx.jsValueFromNapiValue(resolution)!)
34+
deferredRef.dispose()
3435
return $GET_RETURN_STATUS!(envObject)
3536
})
3637
}
@@ -40,8 +41,10 @@ export function napi_reject_deferred (env: napi_env, deferred: napi_deferred, re
4041
return $PREAMBLE!(env, (envObject) => {
4142
$CHECK_ARG!(envObject, deferred)
4243
$CHECK_ARG!(envObject, resolution)
43-
const deferredObject = emnapiCtx.getDeferred(deferred)!
44-
deferredObject.reject(emnapiCtx.jsValueFromNapiValue(resolution)!)
44+
const deferredRef = emnapiCtx.getRef(deferred)!
45+
const resolver = deferredRef.deref() as Resolver<any>
46+
resolver.reject(emnapiCtx.jsValueFromNapiValue(resolution)!)
47+
deferredRef.dispose()
4548
return $GET_RETURN_STATUS!(envObject)
4649
})
4750
}

packages/emnapi/src/typings/emnapi.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ declare type NodeEnv = import('../../../runtime/dist/types/index').NodeEnv
33
// declare type Handle<S> = import('../../../runtime/dist/types/index').Handle<S>
44
declare type Context = import('../../../runtime/dist/types/index').Context
55
declare type Reference = import('../../../runtime/dist/types/index').Reference
6+
declare type Resolver<T> = import('../../../runtime/dist/types/index').Resolver<T>
67
declare type FunctionTemplate = import('../../../runtime/dist/types/index').FunctionTemplate
78

89
declare type NodeBinding = typeof import('../../../node/index')

packages/runtime/src/Context.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import {
99
NODE_API_DEFAULT_MODULE_API_VERSION,
1010
NODE_MODULE_VERSION,
1111
detectFeatures,
12-
Features
12+
Features,
13+
type Resolver
1314
} from './util'
1415
import { TryCatch } from './TryCatch'
1516
import { NotSupportWeakRefError, NotSupportBufferError } from './errors'
1617
import { Reference, ReferenceOwnership, ReferenceWithData, ReferenceWithFinalizer } from './Reference'
17-
import { type IDeferrdValue, Deferred } from './Deferred'
1818
import { ArrayStore } from './Store'
1919
import { TrackedFinalizer } from './TrackedFinalizer'
2020
import { External, isExternal, getExternalValue } from './External'
@@ -139,11 +139,10 @@ export class Context {
139139

140140
private envStore = new ArrayStore<Env>()
141141
private scopeStore = new ScopeStore()
142-
private deferredStore = new ArrayStore<Deferred>()
143142
private readonly refCounter?: NodejsWaitingRequestCounter
144143
private readonly cleanupQueue: CleanupQueue
145144

146-
public readonly features: Features = detectFeatures()
145+
public readonly features: Features
147146

148147
private handleStore: HandleStore
149148

@@ -258,8 +257,8 @@ export class Context {
258257
)
259258
}
260259

261-
public createDeferred<T = any> (value: IDeferrdValue<T>): Deferred<T> {
262-
return new Deferred(this.deferredStore, value)
260+
public createResolver<T> (): Resolver<T> {
261+
return this.features.withResolvers.call<PromiseConstructor, [], Resolver<T>>(Promise)
263262
}
264263

265264
public createEnv (
@@ -475,10 +474,6 @@ export class Context {
475474
return this.scopeStore.deref(info)!.callbackInfo
476475
}
477476

478-
public getDeferred<T = any> (deferred: napi_deferred): Deferred<T> | undefined {
479-
return this.deferredStore.deref(deferred)
480-
}
481-
482477
public napiValueFromJsValue (value: unknown): number | bigint {
483478
switch (value) {
484479
case undefined: return GlobalHandle.UNDEFINED

packages/runtime/src/Deferred.ts

Lines changed: 0 additions & 43 deletions
This file was deleted.

packages/runtime/src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
export { createContext, getDefaultContext, Context, type CleanupHookCallbackFunction, type ContextOptions } from './Context'
2-
export { Deferred, type IDeferrdValue } from './Deferred'
32
export { Disposable } from './Disaposable'
43
export { Env, NodeEnv, type IReferenceBinding } from './env'
54
export { EmnapiError, NotSupportWeakRefError, NotSupportBufferError } from './errors'
@@ -17,7 +16,7 @@ export { Reference, ReferenceWithData, ReferenceWithFinalizer, ReferenceOwnershi
1716
export { RefTracker } from './RefTracker'
1817
export { ScopeStore } from './ScopeStore'
1918
export * from './Store'
20-
export { type Features } from './util'
19+
export { type Features, type Resolver } from './util'
2120

2221
export {
2322
isReferenceType,

packages/runtime/src/util.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ export function detectFinalizer () {
88

99
export const supportFinalizer = /*#__PURE__*/ detectFinalizer()
1010

11+
export interface Resolver<T> {
12+
promise: Promise<T>
13+
resolve: (value: T | PromiseLike<T>) => void
14+
reject: (reason?: any) => void
15+
}
16+
1117
export interface Features {
1218
makeDynamicFunction: ((...args: any[]) => Function) | undefined
1319
getGlobalThis: () => typeof globalThis
@@ -19,6 +25,7 @@ export interface Features {
1925
MessageChannel: typeof MessageChannel | undefined
2026
Buffer: BufferCtor | undefined
2127
setImmediate: (callback: () => void) => any
28+
withResolvers: <T>(this: PromiseConstructor) => Resolver<T>
2229
}
2330

2431
export function detectFeatures (features?: Partial<Features>): Features {
@@ -90,10 +97,26 @@ export function detectFeatures (features?: Partial<Features>): Features {
9097
throw new Error('Unable to get globalThis')
9198
}
9299

100+
function defaultWithResolvers<T> (this: PromiseConstructor) {
101+
let ok: (value: T | PromiseLike<T>) => void
102+
let err: (reason?: any) => void
103+
const promise = new this<T>((resolve, reject) => {
104+
ok = resolve
105+
err = reject
106+
})
107+
return { promise, resolve: ok!, reject: err! }
108+
}
109+
93110
const getGlobalThis = features && 'getGlobalThis' in features
94111
? (features.getGlobalThis ?? defaultGetGlobalThis)
95112
: defaultGetGlobalThis
96113

114+
const withResolvers = (features && 'withResolvers' in features)
115+
? (features.withResolvers ?? defaultWithResolvers)
116+
: typeof Promise.withResolvers === 'function'
117+
? Promise.withResolvers
118+
: defaultWithResolvers
119+
97120
const getBuiltinModule: (id: string) => any = getGlobalThis?.().process?.getBuiltinModule ?? _require
98121

99122
const ret: Features = {
@@ -146,6 +169,7 @@ export function detectFeatures (features?: Partial<Features>): Features {
146169
})(),
147170
...features,
148171
getGlobalThis,
172+
withResolvers
149173
}
150174

151175
return ret

packages/runtime/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"lib": [
1313
"ES2021",
1414
"ESNext.Disposable",
15+
"ES2024.Promise",
1516
"DOM"
1617
]
1718
},

0 commit comments

Comments
 (0)