File
Blob: src/node/v8.ts
| 1 | // Copyright (c) 2017-2022 Cloudflare, Inc. |
| 2 | // Licensed under the Apache 2.0 license found in the LICENSE file or at: |
| 3 | // https://opensource.org/licenses/Apache-2.0 |
| 4 | // Copyright (c) 2014, StrongLoop Inc. |
| 5 | // |
| 6 | // Permission to use, copy, modify, and/or distribute this software for any |
| 7 | // purpose with or without fee is hereby granted, provided that the above |
| 8 | // copyright notice and this permission notice appear in all copies. |
| 9 | // |
| 10 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 11 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 12 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 13 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 14 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 15 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 16 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 17 | |
| 18 | 'use strict'; |
| 19 | |
| 20 | import { Buffer } from 'node-internal:internal_buffer'; |
| 21 | import { |
| 22 | validateObject, |
| 23 | validateFunction, |
| 24 | validateBoolean, |
| 25 | validateString, |
| 26 | validateUint32, |
| 27 | validateOneOf, |
| 28 | } from 'node-internal:validators'; |
| 29 | |
| 30 | import type { |
| 31 | HeapSnapshotOptions, |
| 32 | HeapInfo, |
| 33 | HeapSpaceStatistics, |
| 34 | HeapCodeStatistics, |
| 35 | Init, |
| 36 | Before, |
| 37 | After, |
| 38 | Settled, |
| 39 | HookCallbacks, |
| 40 | } from 'node:v8'; |
| 41 | import type { Readable } from 'node:stream'; |
| 42 | |
| 43 | import { |
| 44 | ERR_INVALID_ARG_VALUE, |
| 45 | ERR_METHOD_NOT_IMPLEMENTED, |
| 46 | } from 'node-internal:internal_errors'; |
| 47 | |
| 48 | export function cachedDataVersionTag(): number { |
| 49 | return 0; |
| 50 | } |
| 51 | |
| 52 | function getHeapSnapshotOptions(options: HeapSnapshotOptions = {}): void { |
| 53 | validateObject(options, 'options'); |
| 54 | const { exposeInternals = false, exposeNumericValues = false } = options; |
| 55 | validateBoolean(exposeInternals, 'options.exposeInternals'); |
| 56 | validateBoolean(exposeNumericValues, 'options.exposeNumericValues'); |
| 57 | } |
| 58 | |
| 59 | // Other than the Serializer/Deserializer classes, most of the API here is not |
| 60 | // something that we intend to implement. |
| 61 | |
| 62 | export function writeHeapSnapshot( |
| 63 | filename?: string, |
| 64 | options: HeapSnapshotOptions = {} |
| 65 | ): void { |
| 66 | if (filename !== undefined) { |
| 67 | validateString(filename, 'filename'); |
| 68 | } |
| 69 | getHeapSnapshotOptions(options); |
| 70 | throw new ERR_METHOD_NOT_IMPLEMENTED('writeHeapSnapshot'); |
| 71 | } |
| 72 | |
| 73 | export function getHeapSnapshot(options: HeapSnapshotOptions = {}): Readable { |
| 74 | getHeapSnapshotOptions(options); |
| 75 | throw new ERR_METHOD_NOT_IMPLEMENTED('getHeapSnapshot'); |
| 76 | } |
| 77 | |
| 78 | export function setFlagsFromString(flags: string): void { |
| 79 | validateString(flags, 'flags'); |
| 80 | throw new ERR_METHOD_NOT_IMPLEMENTED('setFlagsFromString'); |
| 81 | } |
| 82 | |
| 83 | export function isStringOneByteRepresentation(content: string): boolean { |
| 84 | // TODO(later): We can implement this later |
| 85 | validateString(content, 'content'); |
| 86 | throw new ERR_METHOD_NOT_IMPLEMENTED('isStringOneByteRepresentation'); |
| 87 | } |
| 88 | |
| 89 | export function getHeapStatistics(): HeapInfo { |
| 90 | return { |
| 91 | total_heap_size: 0, |
| 92 | total_heap_size_executable: 0, |
| 93 | total_physical_size: 0, |
| 94 | total_available_size: 0, |
| 95 | used_heap_size: 0, |
| 96 | heap_size_limit: 0, |
| 97 | malloced_memory: 0, |
| 98 | peak_malloced_memory: 0, |
| 99 | does_zap_garbage: 0, |
| 100 | number_of_native_contexts: 0, |
| 101 | number_of_detached_contexts: 0, |
| 102 | total_global_handles_size: 0, |
| 103 | used_global_handles_size: 0, |
| 104 | external_memory: 0, |
| 105 | total_allocated_bytes: 0, |
| 106 | }; |
| 107 | } |
| 108 | |
| 109 | export function getHeapSpaceStatistics(): HeapSpaceStatistics[] { |
| 110 | return []; |
| 111 | } |
| 112 | |
| 113 | export function getHeapCodeStatistics(): HeapCodeStatistics { |
| 114 | return { |
| 115 | code_and_metadata_size: 0, |
| 116 | bytecode_and_metadata_size: 0, |
| 117 | external_script_source_size: 0, |
| 118 | // @ts-expect-error TS2353 cpu_profiler_metadata_size is not in node/types yet |
| 119 | cpu_profiler_metadata_size: 0, |
| 120 | }; |
| 121 | } |
| 122 | |
| 123 | export function setHeapSnapshotNearHeapLimit(limit: number): void { |
| 124 | validateUint32(limit, 'limit', true); |
| 125 | throw new ERR_METHOD_NOT_IMPLEMENTED('setHeapSnapshotNearHeapLimit'); |
| 126 | } |
| 127 | |
| 128 | export function getCppHeapStatistics(type = 'detailed'): object { |
| 129 | validateOneOf(type, 'type', ['brief', 'detailed']); |
| 130 | return { |
| 131 | committed_size_bytes: 0, |
| 132 | resident_size_bytes: 0, |
| 133 | used_size_bytes: 0, |
| 134 | space_statistics: [], |
| 135 | type_names: [], |
| 136 | detail_level: type, |
| 137 | }; |
| 138 | } |
| 139 | |
| 140 | // TODO(later): Implement Serializer/Deserializer later |
| 141 | export class Serializer { |
| 142 | constructor() { |
| 143 | throw new ERR_METHOD_NOT_IMPLEMENTED('Serializer'); |
| 144 | } |
| 145 | |
| 146 | writeHeader(): void { |
| 147 | throw new ERR_METHOD_NOT_IMPLEMENTED('writeHeader'); |
| 148 | } |
| 149 | writeValue(_value: unknown): void { |
| 150 | throw new ERR_METHOD_NOT_IMPLEMENTED('writeValue'); |
| 151 | } |
| 152 | releaseBuffer(): void { |
| 153 | throw new ERR_METHOD_NOT_IMPLEMENTED('releaseBuffer'); |
| 154 | } |
| 155 | transferArrayBuffer(_id: number, _arrayBuffer: ArrayBuffer): void { |
| 156 | throw new ERR_METHOD_NOT_IMPLEMENTED('transferArrayBuffer'); |
| 157 | } |
| 158 | writeUint32(_value: number): void { |
| 159 | throw new ERR_METHOD_NOT_IMPLEMENTED('writeUint32'); |
| 160 | } |
| 161 | writeUint64(_hi: number, _lo: number): void { |
| 162 | throw new ERR_METHOD_NOT_IMPLEMENTED('writeUint64'); |
| 163 | } |
| 164 | writeDouble(_value: number): void { |
| 165 | throw new ERR_METHOD_NOT_IMPLEMENTED('writeDouble'); |
| 166 | } |
| 167 | writeRawBytes(_buffer: NodeJS.TypedArray | Buffer): void { |
| 168 | throw new ERR_METHOD_NOT_IMPLEMENTED('writeRawBytes'); |
| 169 | } |
| 170 | _getDataCloneError(_message: unknown): void { |
| 171 | throw new ERR_METHOD_NOT_IMPLEMENTED('_getDataCloneError'); |
| 172 | } |
| 173 | _getSharedArrayBufferId(_sharedArrayBuffer: SharedArrayBuffer): number { |
| 174 | throw new ERR_METHOD_NOT_IMPLEMENTED('_getSharedArrayBufferId'); |
| 175 | } |
| 176 | _setTreatArrayBufferViewsAsHostObjects(_flag: boolean): void { |
| 177 | throw new ERR_METHOD_NOT_IMPLEMENTED( |
| 178 | '_setTreatArrayBufferViewsAsHostObjects' |
| 179 | ); |
| 180 | } |
| 181 | |
| 182 | _writeHostObject(_abView: NodeJS.TypedArray | Buffer): void { |
| 183 | throw new ERR_METHOD_NOT_IMPLEMENTED('_writeHostObject'); |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | export class Deserializer { |
| 188 | constructor(_buffer: NodeJS.TypedArray | Buffer) { |
| 189 | throw new ERR_METHOD_NOT_IMPLEMENTED('Deserializer'); |
| 190 | } |
| 191 | readHeader(): boolean { |
| 192 | throw new ERR_METHOD_NOT_IMPLEMENTED('readHeader'); |
| 193 | } |
| 194 | |
| 195 | readValue(): unknown { |
| 196 | throw new ERR_METHOD_NOT_IMPLEMENTED('readValue'); |
| 197 | } |
| 198 | |
| 199 | transferArrayBuffer(_id: number, _arrayBuffer: ArrayBuffer): void { |
| 200 | throw new ERR_METHOD_NOT_IMPLEMENTED('transferArrayBuffer'); |
| 201 | } |
| 202 | |
| 203 | getWireFormatVersion(): number { |
| 204 | throw new ERR_METHOD_NOT_IMPLEMENTED('getWireFormatVersion'); |
| 205 | } |
| 206 | |
| 207 | readUint32(): number { |
| 208 | throw new ERR_METHOD_NOT_IMPLEMENTED('readUint32'); |
| 209 | } |
| 210 | |
| 211 | readUint64(): [number, number] { |
| 212 | throw new ERR_METHOD_NOT_IMPLEMENTED('readUint64'); |
| 213 | } |
| 214 | |
| 215 | readDouble(): number { |
| 216 | throw new ERR_METHOD_NOT_IMPLEMENTED('readDouble'); |
| 217 | } |
| 218 | readRawBytes(_length: number): Buffer { |
| 219 | throw new ERR_METHOD_NOT_IMPLEMENTED('readRawBytes'); |
| 220 | } |
| 221 | |
| 222 | _readHostObject(): object { |
| 223 | throw new ERR_METHOD_NOT_IMPLEMENTED('_readHostObject'); |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | export class DefaultSerializer extends Serializer { |
| 228 | constructor() { |
| 229 | super(); |
| 230 | throw new ERR_METHOD_NOT_IMPLEMENTED('DefaultSerializer'); |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | export class DefaultDeserializer extends Deserializer { |
| 235 | constructor(buffer: NodeJS.TypedArray | Buffer) { |
| 236 | super(buffer); |
| 237 | throw new ERR_METHOD_NOT_IMPLEMENTED('DefaultDeserializer'); |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | export function serialize(_value: unknown): Buffer { |
| 242 | // TODO(later): This is one that we can implement later. |
| 243 | throw new ERR_METHOD_NOT_IMPLEMENTED('serialize'); |
| 244 | } |
| 245 | |
| 246 | export function deserialize(_buffer: NodeJS.TypedArray | Buffer): unknown { |
| 247 | // TODO(;later): This is one that we can implement later. |
| 248 | throw new ERR_METHOD_NOT_IMPLEMENTED('deserialize'); |
| 249 | } |
| 250 | |
| 251 | export class GCProfiler { |
| 252 | start(): void { |
| 253 | throw new ERR_METHOD_NOT_IMPLEMENTED('GCProfiler.start'); |
| 254 | } |
| 255 | |
| 256 | stop(): void { |
| 257 | throw new ERR_METHOD_NOT_IMPLEMENTED('GCProfiler.stop'); |
| 258 | } |
| 259 | } |
| 260 | |
| 261 | export const promiseHooks = { |
| 262 | // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type |
| 263 | createHook(_: HookCallbacks): Function { |
| 264 | throw new ERR_METHOD_NOT_IMPLEMENTED('promiseHooks.createHook'); |
| 265 | }, |
| 266 | |
| 267 | // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type |
| 268 | onInit(_: Init): Function { |
| 269 | throw new ERR_METHOD_NOT_IMPLEMENTED('promiseHooks.onInit'); |
| 270 | }, |
| 271 | |
| 272 | // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type |
| 273 | onBefore(_: Before): Function { |
| 274 | throw new ERR_METHOD_NOT_IMPLEMENTED('promiseHooks.onBefore'); |
| 275 | }, |
| 276 | |
| 277 | // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type |
| 278 | onAfter(_: After): Function { |
| 279 | throw new ERR_METHOD_NOT_IMPLEMENTED('promiseHooks.onAfter'); |
| 280 | }, |
| 281 | |
| 282 | // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type |
| 283 | onSettled(_: Settled): Function { |
| 284 | throw new ERR_METHOD_NOT_IMPLEMENTED('promiseHooks.onSettled'); |
| 285 | }, |
| 286 | }; |
| 287 | |
| 288 | export function queryObjects( |
| 289 | // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type |
| 290 | ctor: Function, |
| 291 | options: { format?: 'count' | 'summary' } = {} |
| 292 | ): number | string[] { |
| 293 | validateFunction(ctor, 'constructor'); |
| 294 | validateObject(options, 'options'); |
| 295 | const format = options.format || 'count'; |
| 296 | // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition |
| 297 | if (format !== 'count' && format !== 'summary') { |
| 298 | throw new ERR_INVALID_ARG_VALUE('options.format', format); |
| 299 | } |
| 300 | throw new ERR_METHOD_NOT_IMPLEMENTED('queryObjects'); |
| 301 | } |
| 302 | |
| 303 | export function takeCoverage(): void { |
| 304 | throw new ERR_METHOD_NOT_IMPLEMENTED('takeCoverage'); |
| 305 | } |
| 306 | |
| 307 | export function stopCoverage(): void { |
| 308 | throw new ERR_METHOD_NOT_IMPLEMENTED('stopCoverage'); |
| 309 | } |
| 310 | |
| 311 | export const startupSnapshot = { |
| 312 | // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type |
| 313 | addSerializeCallback(_callback: Function, _data: unknown): void { |
| 314 | throw new ERR_METHOD_NOT_IMPLEMENTED( |
| 315 | 'startupSnapshot.addSerializeCallback' |
| 316 | ); |
| 317 | }, |
| 318 | |
| 319 | // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type |
| 320 | addDeserializeCallback(_callback: Function, _data: unknown): void { |
| 321 | throw new ERR_METHOD_NOT_IMPLEMENTED( |
| 322 | 'startupSnapshot.addDeserializeCallback' |
| 323 | ); |
| 324 | }, |
| 325 | |
| 326 | // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type |
| 327 | setDeserializeMainFunction(_callback: Function, _data: unknown): void { |
| 328 | throw new ERR_METHOD_NOT_IMPLEMENTED( |
| 329 | 'startupSnapshot.setDeserializeMainFunction' |
| 330 | ); |
| 331 | }, |
| 332 | isBuildingSnapshot(): boolean { |
| 333 | return false; |
| 334 | }, |
| 335 | }; |
| 336 | |
| 337 | export default { |
| 338 | cachedDataVersionTag, |
| 339 | getHeapSnapshot, |
| 340 | getHeapStatistics, |
| 341 | getHeapSpaceStatistics, |
| 342 | getHeapCodeStatistics, |
| 343 | getCppHeapStatistics, |
| 344 | setFlagsFromString, |
| 345 | Serializer, |
| 346 | Deserializer, |
| 347 | DefaultSerializer, |
| 348 | DefaultDeserializer, |
| 349 | deserialize, |
| 350 | takeCoverage, |
| 351 | stopCoverage, |
| 352 | serialize, |
| 353 | writeHeapSnapshot, |
| 354 | promiseHooks, |
| 355 | queryObjects, |
| 356 | startupSnapshot, |
| 357 | setHeapSnapshotNearHeapLimit, |
| 358 | GCProfiler, |
| 359 | isStringOneByteRepresentation, |
| 360 | }; |