MCPcopy Index your code
hub / github.com/nodejs/node / wrapWithSharedBuffer

Function wrapWithSharedBuffer

lib/internal/ffi-shared-buffer.js:201–283  ·  view source on GitHub ↗
(rawFn, signature)

Source from the content-addressed store, hash-verified

199// reads the return value back only after, so nested/reentrant calls into
200// the same function are safe.
201function wrapWithSharedBuffer(rawFn, signature) {
202 if (rawFn == null) return rawFn;
203 const buffer = rawFn[kSbSharedBuffer];
204 if (buffer === undefined) return rawFn;
205
206 // Callers without explicit signature info (the `functions` accessor
207 // patch below) rely on the `kSbArguments` / `kSbReturn` metadata attached
208 // by the native `CreateFunction`.
209 let argumentTypes, returnType;
210 if (signature === undefined) {
211 argumentTypes = rawFn[kSbArguments];
212 returnType = rawFn[kSbReturn];
213
214 // `CreateFunction` always attaches these for SB-eligible functions.
215 // Missing here means the native side and this wrapper are out of sync.
216 assert(argumentTypes !== undefined && returnType !== undefined,
217 'FFI: shared-buffer raw function is missing kSbArguments or kSbReturn');
218 } else {
219 argumentTypes = signature.arguments ?? [];
220 returnType = signature.return ?? 'void';
221 }
222
223 const slowInvoke = rawFn[kSbInvokeSlow];
224 const view = new DataView(buffer);
225 let retGetter = null;
226 if (returnType !== 'void') {
227 const retInfo = sbTypeInfo[returnType];
228 assert(retInfo !== undefined,
229 `FFI: shared-buffer type table missing entry for return type "${returnType}"`);
230 retGetter = retInfo.get;
231 }
232
233 const nargs = argumentTypes.length;
234 const argInfos = [];
235 const argOffsets = [];
236 let anyPointer = false;
237 for (let i = 0; i < nargs; i++) {
238 const info = sbTypeInfo[argumentTypes[i]];
239 assert(info !== undefined,
240 `FFI: shared-buffer type table missing entry for argument type "${argumentTypes[i]}"`);
241 // Push the `sbTypeInfo` entry directly (entries with the same `kind`
242 // share a shape, keeping `writeNumericArg`'s call sites
243 // low-polymorphism) and store offsets in a parallel array to avoid
244 // per-arg object cloning.
245 argInfos.push(info);
246 argOffsets.push(8 * (i + 1));
247 if (info.kind === 'pointer') anyPointer = true;
248 }
249
250 let wrapper;
251 if (anyPointer) {
252 // Pointer signatures need a per-arg runtime type check and fall back
253 // to the native slow-path invoker for non-BigInt pointer arguments,
254 // so arity specialization wouldn't buy much here.
255 assert(slowInvoke !== undefined,
256 'FFI: shared-buffer raw function with pointer arguments is missing kSbInvokeSlow');
257 wrapper = function(...args) {
258 if (args.length !== nargs) {

Callers 1

wrapFFIFunctionFunction · 0.85

Calls 7

writePointerArgFunction · 0.85
writeNumericArgFunction · 0.85
buildNumericWrapperFunction · 0.85
assertFunction · 0.70
throwFFIArgCountErrorFunction · 0.70
inheritMetadataFunction · 0.70
pushMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…