From 3c1bb5608dc4a4dd666b6c365ed9f4082039353e Mon Sep 17 00:00:00 2001 From: CarrotzRule123 Date: Thu, 4 May 2023 23:04:09 +0800 Subject: [PATCH 1/4] feat: pointer --- .gitignore | 1 + types/pointer/pointer.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 .gitignore create mode 100644 types/pointer/pointer.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0dc7b4b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.vscode \ No newline at end of file diff --git a/types/pointer/pointer.ts b/types/pointer/pointer.ts new file mode 100644 index 0000000..b736229 --- /dev/null +++ b/types/pointer/pointer.ts @@ -0,0 +1,31 @@ +import { AlignedType } from "../types.ts"; +import { endianess } from "../../utils.ts"; + +export class Pointer implements AlignedType { + byteLength = 8; + byteAlign = 8; + type; + endian; + + constructor(type: AlignedType, endian = endianess) { + this.type = type; + this.endian = endian; + } + + read(dataView: DataView, byteOffset = 0): T { + const ptr = dataView.getBigUint64(byteOffset, this.endian); + const view = new Deno.UnsafePointerView(Deno.UnsafePointer.create(ptr)!); + const bufview = new DataView(view.getArrayBuffer(this.type.byteLength)); + return this.type.read(bufview); + } + + write(value: T, dataView: DataView, byteOffset = 0) { + const buffer = new ArrayBuffer(this.type.byteLength); + this.type.write(value, new DataView(buffer)) + const ptr = Deno.UnsafePointer.value(Deno.UnsafePointer.of(buffer)); + dataView.setBigUint64(byteOffset, BigInt(ptr), this.endian); + return dataView.buffer; + } +} + +export const pointer = (type: AlignedType) => new Pointer(type); \ No newline at end of file From 3d62c8d79618c9a2ebddbc37334759bd9a61f759 Mon Sep 17 00:00:00 2001 From: Jin Wei Tan <48111396+CarrotzRule123@users.noreply.github.com> Date: Fri, 5 May 2023 21:20:24 +0800 Subject: [PATCH 2/4] Update types/pointer/pointer.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Elias Sjögreen --- types/pointer/pointer.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/types/pointer/pointer.ts b/types/pointer/pointer.ts index b736229..7dca657 100644 --- a/types/pointer/pointer.ts +++ b/types/pointer/pointer.ts @@ -27,5 +27,3 @@ export class Pointer implements AlignedType { return dataView.buffer; } } - -export const pointer = (type: AlignedType) => new Pointer(type); \ No newline at end of file From 3cfc8c4f29c18f04306d134e732b2f88894c2688 Mon Sep 17 00:00:00 2001 From: CarrotzRule123 Date: Fri, 5 May 2023 23:21:30 +0800 Subject: [PATCH 3/4] support 32 bit platforms --- types/pointer/pointer.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/types/pointer/pointer.ts b/types/pointer/pointer.ts index 7dca657..3cff10a 100644 --- a/types/pointer/pointer.ts +++ b/types/pointer/pointer.ts @@ -2,18 +2,24 @@ import { AlignedType } from "../types.ts"; import { endianess } from "../../utils.ts"; export class Pointer implements AlignedType { - byteLength = 8; - byteAlign = 8; + byteLength; + byteAlign; type; endian; + bit64; - constructor(type: AlignedType, endian = endianess) { + constructor(type: AlignedType, endian = endianess, bit64 = true) { this.type = type; this.endian = endian; + this.bit64 = bit64; + this.byteLength = bit64 ? 8 : 4; + this.byteAlign = bit64 ? 8 : 4; } read(dataView: DataView, byteOffset = 0): T { - const ptr = dataView.getBigUint64(byteOffset, this.endian); + const ptr = this.bit64 + ? dataView.getBigUint64(byteOffset, this.endian) + : dataView.getUint32(byteOffset, this.endian); const view = new Deno.UnsafePointerView(Deno.UnsafePointer.create(ptr)!); const bufview = new DataView(view.getArrayBuffer(this.type.byteLength)); return this.type.read(bufview); @@ -21,9 +27,11 @@ export class Pointer implements AlignedType { write(value: T, dataView: DataView, byteOffset = 0) { const buffer = new ArrayBuffer(this.type.byteLength); - this.type.write(value, new DataView(buffer)) + this.type.write(value, new DataView(buffer)); const ptr = Deno.UnsafePointer.value(Deno.UnsafePointer.of(buffer)); - dataView.setBigUint64(byteOffset, BigInt(ptr), this.endian); + this.bit64 + ? dataView.setBigUint64(byteOffset, ptr as bigint, this.endian) + : dataView.setUint32(byteOffset, ptr as number, this.endian); return dataView.buffer; } } From 8ec3bf4253ac16cd01195755c8f4e7c549888c13 Mon Sep 17 00:00:00 2001 From: eliassjogreen Date: Fri, 5 May 2023 20:39:37 +0200 Subject: [PATCH 4/4] feat: split out into pointer value and view --- types/ffi/mod.ts | 3 +++ types/ffi/pointer.ts | 38 ++++++++++++++++++++++++++++++++++++++ types/ffi/pointer_value.ts | 32 ++++++++++++++++++++++++++++++++ types/ffi/pointer_view.ts | 28 ++++++++++++++++++++++++++++ types/pointer/pointer.ts | 37 ------------------------------------- 5 files changed, 101 insertions(+), 37 deletions(-) create mode 100644 types/ffi/mod.ts create mode 100644 types/ffi/pointer.ts create mode 100644 types/ffi/pointer_value.ts create mode 100644 types/ffi/pointer_view.ts delete mode 100644 types/pointer/pointer.ts diff --git a/types/ffi/mod.ts b/types/ffi/mod.ts new file mode 100644 index 0000000..2cb8ffd --- /dev/null +++ b/types/ffi/mod.ts @@ -0,0 +1,3 @@ +export * from "./pointer_value.ts"; +export * from "./pointer_view.ts"; +export * from "./pointer.ts"; diff --git a/types/ffi/pointer.ts b/types/ffi/pointer.ts new file mode 100644 index 0000000..ba73d20 --- /dev/null +++ b/types/ffi/pointer.ts @@ -0,0 +1,38 @@ +import type { AlignedType, SizedType } from "../types.ts"; +import { pointerView } from "./pointer_view.ts"; + +export class Pointer implements AlignedType { + byteLength: number; + byteAlign: number; + type: SizedType; + pointerType: AlignedType; + + constructor( + type: SizedType, + pointerType: AlignedType = pointerView, + ) { + this.byteAlign = pointerType.byteAlign; + this.byteLength = pointerType.byteLength; + this.type = type; + this.pointerType = pointerType; + } + + read(dataView: DataView, byteOffset = 0): T { + return this.type.read( + new DataView( + this.pointerType.read(dataView, byteOffset).getArrayBuffer( + this.type.byteLength, + ), + ), + ); + } + + write(value: T, dataView: DataView, byteOffset = 0) { + const buffer = new ArrayBuffer(this.type.byteLength); + this.type.write(value, new DataView(buffer)); + const pointerView = new Deno.UnsafePointerView( + Deno.UnsafePointer.of(buffer)!, + ); + this.pointerType.write(pointerView, dataView, byteOffset); + } +} diff --git a/types/ffi/pointer_value.ts b/types/ffi/pointer_value.ts new file mode 100644 index 0000000..d15c0fa --- /dev/null +++ b/types/ffi/pointer_value.ts @@ -0,0 +1,32 @@ +import type { AlignedType } from "../types.ts"; +import { u64 } from "../mod.ts"; + +export class PointerValue implements AlignedType { + byteLength: number; + byteAlign: number; + pointerType: AlignedType; + + constructor( + pointerType: AlignedType = u64, + ) { + this.byteAlign = pointerType.byteAlign; + this.byteLength = pointerType.byteLength; + this.pointerType = pointerType; + } + + read(dataView: DataView, byteOffset = 0): Deno.PointerValue { + return Deno.UnsafePointer.create( + this.pointerType.read(dataView, byteOffset), + ); + } + + write(value: Deno.PointerValue, dataView: DataView, byteOffset = 0) { + this.pointerType.write( + Deno.UnsafePointer.value(value), + dataView, + byteOffset, + ); + } +} + +export const pointerValue = new PointerValue(); diff --git a/types/ffi/pointer_view.ts b/types/ffi/pointer_view.ts new file mode 100644 index 0000000..e0bdfe3 --- /dev/null +++ b/types/ffi/pointer_view.ts @@ -0,0 +1,28 @@ +import type { AlignedType } from "../types.ts"; +import { pointerValue } from "./pointer_value.ts"; + +export class PointerView implements AlignedType { + byteLength: number; + byteAlign: number; + pointerType: AlignedType; + + constructor( + pointerType: AlignedType = pointerValue, + ) { + this.byteAlign = pointerType.byteAlign; + this.byteLength = pointerType.byteLength; + this.pointerType = pointerType; + } + + read(dataView: DataView, byteOffset = 0): Deno.UnsafePointerView { + return new Deno.UnsafePointerView( + this.pointerType.read(dataView, byteOffset)!, + ); + } + + write(value: Deno.UnsafePointerView, dataView: DataView, byteOffset = 0) { + this.pointerType.write(value.pointer, dataView, byteOffset); + } +} + +export const pointerView = new PointerView(); diff --git a/types/pointer/pointer.ts b/types/pointer/pointer.ts deleted file mode 100644 index 3cff10a..0000000 --- a/types/pointer/pointer.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { AlignedType } from "../types.ts"; -import { endianess } from "../../utils.ts"; - -export class Pointer implements AlignedType { - byteLength; - byteAlign; - type; - endian; - bit64; - - constructor(type: AlignedType, endian = endianess, bit64 = true) { - this.type = type; - this.endian = endian; - this.bit64 = bit64; - this.byteLength = bit64 ? 8 : 4; - this.byteAlign = bit64 ? 8 : 4; - } - - read(dataView: DataView, byteOffset = 0): T { - const ptr = this.bit64 - ? dataView.getBigUint64(byteOffset, this.endian) - : dataView.getUint32(byteOffset, this.endian); - const view = new Deno.UnsafePointerView(Deno.UnsafePointer.create(ptr)!); - const bufview = new DataView(view.getArrayBuffer(this.type.byteLength)); - return this.type.read(bufview); - } - - write(value: T, dataView: DataView, byteOffset = 0) { - const buffer = new ArrayBuffer(this.type.byteLength); - this.type.write(value, new DataView(buffer)); - const ptr = Deno.UnsafePointer.value(Deno.UnsafePointer.of(buffer)); - this.bit64 - ? dataView.setBigUint64(byteOffset, ptr as bigint, this.endian) - : dataView.setUint32(byteOffset, ptr as number, this.endian); - return dataView.buffer; - } -}