Skip to content

Commit

Permalink
refactor: remove RefBase (#122)
Browse files Browse the repository at this point in the history
* refactor: remove RefBase (nodejs/node#53590)

* export ReferenceOwnership as runtime value
  • Loading branch information
toyobayashi authored Aug 27, 2024
1 parent 6ac98c3 commit 5ab92c7
Show file tree
Hide file tree
Showing 19 changed files with 307 additions and 199 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/emnapi/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { Context } from '@emnapi/runtime'
import type { Context, ReferenceOwnership } from '@emnapi/runtime'
import type { ThreadManager, ThreadManagerOptionsMain, MainThreadBaseOptions } from '@emnapi/wasi-threads'

/** @public */
export declare interface PointerInfo {
address: number
ownership: 0 | 1
ownership: ReferenceOwnership
runtimeAllocated: 0 | 1
}

Expand Down
2 changes: 1 addition & 1 deletion packages/emnapi/src/core/async-work.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export var napi_create_async_work = singleThreadAsyncWork
if (!aw) return envObject.setLastError(napi_status.napi_generic_failure)
new Uint8Array(wasmMemory.buffer).subarray(aw, aw + sizeofAW).fill(0)
const s = envObject.ensureHandleId(resourceObject)
const resourceRef = emnapiCtx.createReference(envObject, s, 1, Ownership.kUserland as any)
const resourceRef = emnapiCtx.createReference(envObject, s, 1, ReferenceOwnership.kUserland as any)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const resource_ = resourceRef.id
makeSetValue('aw', 0, 'resource_', '*')
Expand Down
26 changes: 13 additions & 13 deletions packages/emnapi/src/emnapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,46 +45,46 @@ export function emnapi_create_memory_view (
let viewDescriptor: MemoryViewDescriptor
switch (typedarray_type) {
case emnapi_memory_view_type.emnapi_int8_array:
viewDescriptor = { Ctor: Int8Array, address: external_data, length: byte_length, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: Int8Array, address: external_data, length: byte_length, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_uint8_array:
viewDescriptor = { Ctor: Uint8Array, address: external_data, length: byte_length, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: Uint8Array, address: external_data, length: byte_length, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_uint8_clamped_array:
viewDescriptor = { Ctor: Uint8ClampedArray, address: external_data, length: byte_length, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: Uint8ClampedArray, address: external_data, length: byte_length, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_int16_array:
viewDescriptor = { Ctor: Int16Array, address: external_data, length: byte_length >> 1, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: Int16Array, address: external_data, length: byte_length >> 1, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_uint16_array:
viewDescriptor = { Ctor: Uint16Array, address: external_data, length: byte_length >> 1, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: Uint16Array, address: external_data, length: byte_length >> 1, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_int32_array:
viewDescriptor = { Ctor: Int32Array, address: external_data, length: byte_length >> 2, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: Int32Array, address: external_data, length: byte_length >> 2, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_uint32_array:
viewDescriptor = { Ctor: Uint32Array, address: external_data, length: byte_length >> 2, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: Uint32Array, address: external_data, length: byte_length >> 2, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_float32_array:
viewDescriptor = { Ctor: Float32Array, address: external_data, length: byte_length >> 2, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: Float32Array, address: external_data, length: byte_length >> 2, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_float64_array:
viewDescriptor = { Ctor: Float64Array, address: external_data, length: byte_length >> 3, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: Float64Array, address: external_data, length: byte_length >> 3, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_bigint64_array:
viewDescriptor = { Ctor: BigInt64Array, address: external_data, length: byte_length >> 3, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: BigInt64Array, address: external_data, length: byte_length >> 3, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_biguint64_array:
viewDescriptor = { Ctor: BigUint64Array, address: external_data, length: byte_length >> 3, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: BigUint64Array, address: external_data, length: byte_length >> 3, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_data_view:
viewDescriptor = { Ctor: DataView, address: external_data, length: byte_length, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: DataView, address: external_data, length: byte_length, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
case emnapi_memory_view_type.emnapi_buffer: {
if (!emnapiCtx.feature.Buffer) {
throw emnapiCtx.createNotSupportBufferError('emnapi_create_memory_view', '')
}
viewDescriptor = { Ctor: emnapiCtx.feature.Buffer!, address: external_data, length: byte_length, ownership: Ownership.kUserland, runtimeAllocated: 0 }
viewDescriptor = { Ctor: emnapiCtx.feature.Buffer!, address: external_data, length: byte_length, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0 }
break
}
default: return envObject.setLastError(napi_status.napi_invalid_arg)
Expand Down
8 changes: 5 additions & 3 deletions packages/emnapi/src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,14 @@ export function emnapiWrap (env: napi_env, js_object: napi_value, native_object:
let reference: Reference
if (result) {
if (!finalize_cb) return envObject.setLastError(napi_status.napi_invalid_arg)
reference = emnapiCtx.createReference(envObject, handle.id, 0, Ownership.kUserland as any, finalize_cb, native_object, finalize_hint)
reference = emnapiCtx.createReferenceWithFinalizer(envObject, handle.id, 0, ReferenceOwnership.kUserland as any, finalize_cb, native_object, finalize_hint)
from64('result')
referenceId = reference.id
makeSetValue('result', 0, 'referenceId', '*')
} else if (finalize_cb) {
reference = emnapiCtx.createReferenceWithFinalizer(envObject, handle.id, 0, ReferenceOwnership.kRuntime as any, finalize_cb, native_object, finalize_hint)
} else {
reference = emnapiCtx.createReference(envObject, handle.id, 0, Ownership.kRuntime as any, finalize_cb, native_object, !finalize_cb ? finalize_cb : finalize_hint)
reference = emnapiCtx.createReferenceWithData(envObject, handle.id, 0, ReferenceOwnership.kRuntime as any, native_object)
}

envObject.getObjectBinding(handle.value).wrapped = reference.id
Expand Down Expand Up @@ -181,7 +183,7 @@ export function emnapiUnwrap (env: napi_env, js_object: napi_value, result: void
}
if (action === UnwrapAction.RemoveWrap) {
binding.wrapped = 0
if (ref.ownership() === Ownership.kUserland) {
if ((ref.ownership() as unknown as ReferenceOwnership) === ReferenceOwnership.kUserland) {
// When the wrap is been removed, the finalizer should be reset.
ref.resetFinalizer()
} else {
Expand Down
6 changes: 3 additions & 3 deletions packages/emnapi/src/life.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function napi_create_reference (
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ref = emnapiCtx.createReference(envObject, handle.id, initial_refcount >>> 0, Ownership.kUserland as any)
const ref = emnapiCtx.createReference(envObject, handle.id, initial_refcount >>> 0, ReferenceOwnership.kUserland as any)
from64('result')
makeSetValue('result', 0, 'ref.id', '*')
return envObject.clearLastError()
Expand Down Expand Up @@ -129,7 +129,7 @@ export function napi_reference_unref (
const envObject: Env = $CHECK_ENV_NOT_IN_GC!(env)
$CHECK_ARG!(envObject, ref)
const reference = emnapiCtx.refStore.get(ref)!
const refcount = reference.refCount()
const refcount = reference.refcount()

if (refcount === 0) {
return envObject.setLastError(napi_status.napi_generic_failure)
Expand All @@ -154,7 +154,7 @@ export function napi_get_reference_value (
$CHECK_ARG!(envObject, result)
const reference = emnapiCtx.refStore.get(ref)!
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const handleId = reference.get()
const handleId = reference.get(envObject)
from64('result')
makeSetValue('result', 0, 'handleId', '*')
return envObject.clearLastError()
Expand Down
12 changes: 6 additions & 6 deletions packages/emnapi/src/memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type ViewConstuctor =

export interface ArrayBufferPointer {
address: void_p
ownership: Ownership
ownership: ReferenceOwnership
runtimeAllocated: 0 | 1
}

Expand Down Expand Up @@ -75,7 +75,7 @@ export const emnapiExternalMemory: {
getArrayBufferPointer: function (arrayBuffer: ArrayBuffer, shouldCopy: boolean): ArrayBufferPointer {
const info: ArrayBufferPointer = {
address: 0,
ownership: Ownership.kRuntime,
ownership: ReferenceOwnership.kRuntime,
runtimeAllocated: 0
}
if (arrayBuffer === wasmMemory.buffer) {
Expand All @@ -89,7 +89,7 @@ export const emnapiExternalMemory: {
cachedInfo.address = 0
return cachedInfo
}
if (shouldCopy && cachedInfo.ownership === Ownership.kRuntime && cachedInfo.runtimeAllocated === 1) {
if (shouldCopy && cachedInfo.ownership === ReferenceOwnership.kRuntime && cachedInfo.runtimeAllocated === 1) {
new Uint8Array(wasmMemory.buffer).set(new Uint8Array(arrayBuffer), cachedInfo.address)
}
return cachedInfo
Expand All @@ -108,7 +108,7 @@ export const emnapiExternalMemory: {
new Uint8Array(wasmMemory.buffer).set(new Uint8Array(arrayBuffer), pointer)

info.address = pointer
info.ownership = emnapiExternalMemory.registry ? Ownership.kRuntime : Ownership.kUserland
info.ownership = emnapiExternalMemory.registry ? ReferenceOwnership.kRuntime : ReferenceOwnership.kUserland
info.runtimeAllocated = 1

emnapiExternalMemory.table.set(arrayBuffer, info)
Expand All @@ -123,7 +123,7 @@ export const emnapiExternalMemory: {
Ctor: view.constructor as any,
address: view.byteOffset,
length: view instanceof DataView ? view.byteLength : (view as any).length,
ownership: Ownership.kUserland,
ownership: ReferenceOwnership.kUserland,
runtimeAllocated: 0
})
}
Expand Down Expand Up @@ -156,7 +156,7 @@ export const emnapiExternalMemory: {
const { address, ownership, runtimeAllocated } = emnapiExternalMemory.wasmMemoryViewTable.get(view)!
return { address, ownership, runtimeAllocated, view }
}
return { address: view.byteOffset, ownership: Ownership.kUserland, runtimeAllocated: 0, view }
return { address: view.byteOffset, ownership: ReferenceOwnership.kUserland, runtimeAllocated: 0, view }
}

const { address, ownership, runtimeAllocated } = emnapiExternalMemory.getArrayBufferPointer(view.buffer, shouldCopy)
Expand Down
4 changes: 2 additions & 2 deletions packages/emnapi/src/threadsafe-function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ export function napi_create_threadsafe_function (
return envObject.setLastError(napi_status.napi_invalid_arg)
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
ref = emnapiCtx.createReference(envObject, func, 1, Ownership.kUserland as any).id
ref = emnapiCtx.createReference(envObject, func, 1, ReferenceOwnership.kUserland as any).id
}

let asyncResourceObject: any
Expand All @@ -709,7 +709,7 @@ export function napi_create_threadsafe_function (
const tsfn = _malloc(to64('sizeofTSFN'))
if (!tsfn) return envObject.setLastError(napi_status.napi_generic_failure)
new Uint8Array(wasmMemory.buffer).subarray(tsfn, tsfn + sizeofTSFN).fill(0)
const resourceRef = emnapiCtx.createReference(envObject, resource, 1, Ownership.kUserland as any)
const resourceRef = emnapiCtx.createReference(envObject, resource, 1, ReferenceOwnership.kUserland as any)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const resource_ = resourceRef.id
makeSetValue('tsfn', 0, 'resource_', '*')
Expand Down
15 changes: 12 additions & 3 deletions packages/emnapi/src/typings/enum.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
declare const enum UnwrapAction {
KeepWrap,
RemoveWrap
import type { ReferenceOwnership as RuntimeReferenceOwnership } from '@emnapi/runtime'

declare global {
export const enum UnwrapAction {
KeepWrap,
RemoveWrap
}

export const enum ReferenceOwnership {
kRuntime = RuntimeReferenceOwnership.kRuntime,
kUserland = RuntimeReferenceOwnership.kUserland
}
}
10 changes: 5 additions & 5 deletions packages/emnapi/src/value/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export function napi_create_external (env: napi_env, data: void_p, finalize_cb:
}
const externalHandle = emnapiCtx.getCurrentScope()!.addExternal(envObject, data)
if (finalize_cb) {
emnapiCtx.createReference(envObject, externalHandle.id, 0, Ownership.kRuntime as any, finalize_cb, data, finalize_hint)
emnapiCtx.createReferenceWithFinalizer(envObject, externalHandle.id, 0, ReferenceOwnership.kRuntime as any, finalize_cb, data, finalize_hint)
}
from64('result')
value = externalHandle.id
Expand Down Expand Up @@ -151,7 +151,7 @@ export function napi_create_external_arraybuffer (
u8arr.set(new Uint8Array(wasmMemory.buffer).subarray(external_data, external_data + byte_length))
emnapiExternalMemory.table.set(arrayBuffer, {
address: external_data,
ownership: Ownership.kUserland,
ownership: ReferenceOwnership.kUserland,
runtimeAllocated: 0
})
}
Expand Down Expand Up @@ -262,7 +262,7 @@ export function napi_create_typedarray (
Ctor: Type as any,
address: byte_offset,
length,
ownership: Ownership.kUserland,
ownership: ReferenceOwnership.kUserland,
runtimeAllocated: 0
})
}
Expand Down Expand Up @@ -343,7 +343,7 @@ export function napi_create_buffer (
Ctor: Buffer,
address: pointer,
length: size,
ownership: emnapiExternalMemory.registry ? Ownership.kRuntime : Ownership.kUserland,
ownership: emnapiExternalMemory.registry ? ReferenceOwnership.kRuntime : ReferenceOwnership.kUserland,
runtimeAllocated: 1
}
emnapiExternalMemory.wasmMemoryViewTable.set(buffer, viewDescriptor)
Expand Down Expand Up @@ -451,7 +451,7 @@ export function napi_create_dataview (
Ctor: DataView,
address: byte_offset,
length: byte_length,
ownership: Ownership.kUserland,
ownership: ReferenceOwnership.kUserland,
runtimeAllocated: 0
})
}
Expand Down
4 changes: 2 additions & 2 deletions packages/emnapi/src/wrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,11 @@ export function napi_add_finalizer (env: napi_env, js_object: napi_value, finali
}
const handle = handleResult.handle!

const ownership: Ownership = !result ? Ownership.kRuntime : Ownership.kUserland
const ownership: ReferenceOwnership = !result ? ReferenceOwnership.kRuntime : ReferenceOwnership.kUserland
from64('finalize_data')
from64('finalize_cb')
from64('finalize_hint')
const reference = emnapiCtx.createReference(envObject, handle.id, 0, ownership as any, finalize_cb, finalize_data, finalize_hint)
const reference = emnapiCtx.createReferenceWithFinalizer(envObject, handle.id, 0, ownership as any, finalize_cb, finalize_data, finalize_hint)
if (result) {
from64('result')
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down
36 changes: 33 additions & 3 deletions packages/runtime/src/Context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from './util'
import { CallbackInfoStack } from './CallbackInfo'
import { NotSupportWeakRefError, NotSupportBufferError } from './errors'
import { Reference } from './Reference'
import { Reference, ReferenceWithData, ReferenceWithFinalizer, type ReferenceOwnership } from './Reference'
import { type IDeferrdValue, Deferred } from './Deferred'
import { Store } from './Store'
import { TrackedFinalizer } from './TrackedFinalizer'
Expand Down Expand Up @@ -179,12 +179,42 @@ export class Context {
envObject: Env,
handle_id: napi_value,
initialRefcount: uint32_t,
ownership: 0 | 1,
ownership: ReferenceOwnership
): Reference {
return Reference.create(
envObject,
handle_id,
initialRefcount,
ownership
)
}

public createReferenceWithData (
envObject: Env,
handle_id: napi_value,
initialRefcount: uint32_t,
ownership: ReferenceOwnership,
data: void_p
): Reference {
return ReferenceWithData.create(
envObject,
handle_id,
initialRefcount,
ownership,
data
)
}

public createReferenceWithFinalizer (
envObject: Env,
handle_id: napi_value,
initialRefcount: uint32_t,
ownership: ReferenceOwnership,
finalize_callback: napi_finalize = 0,
finalize_data: void_p = 0,
finalize_hint: void_p = 0
): Reference {
return Reference.create(
return ReferenceWithFinalizer.create(
envObject,
handle_id,
initialRefcount,
Expand Down
33 changes: 29 additions & 4 deletions packages/runtime/src/Finalizer.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,49 @@
import type { Env } from './env'

export class Finalizer {
private _makeDynCall_vppp: (cb: Ptr) => (a: Ptr, b: Ptr, c: Ptr) => void

public constructor (
public envObject: Env,
protected _finalizeCallback: napi_finalize = 0,
protected _finalizeData: void_p = 0,
protected _finalizeHint: void_p = 0
) {}
private _finalizeCallback: napi_finalize = 0,
private _finalizeData: void_p = 0,
private _finalizeHint: void_p = 0
) {
this._makeDynCall_vppp = envObject.makeDynCall_vppp
}

public callback (): napi_finalize { return this._finalizeCallback }
public data (): void_p { return this._finalizeData }
public hint (): void_p { return this._finalizeHint }

public resetEnv (): void {
this.envObject = undefined!
}

public resetFinalizer (): void {
this._finalizeCallback = 0
this._finalizeData = 0
this._finalizeHint = 0
}

public callFinalizer (): void {
const finalize_callback = this._finalizeCallback
const finalize_data = this._finalizeData
const finalize_hint = this._finalizeHint
this.resetFinalizer()

if (!finalize_callback) return

const fini = Number(finalize_callback)
if (!this.envObject) {
this._makeDynCall_vppp(fini)(0, finalize_data, finalize_hint)
} else {
this.envObject.callFinalizer(fini, finalize_data, finalize_hint)
}
}

public dispose (): void {
this.envObject = undefined!
this._makeDynCall_vppp = undefined!
}
}
Loading

0 comments on commit 5ab92c7

Please sign in to comment.