• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const {
3  Error,
4  ObjectDefineProperties,
5  ObjectGetOwnPropertyDescriptors,
6  ObjectGetPrototypeOf,
7  ObjectSetPrototypeOf,
8  ObjectValues,
9  ReflectConstruct,
10  StringPrototypeSplit,
11} = primordials;
12const {
13  messaging_deserialize_symbol,
14  messaging_transfer_symbol,
15  messaging_clone_symbol,
16  messaging_transfer_list_symbol,
17} = internalBinding('symbols');
18const {
19  JSTransferable,
20  setDeserializerCreateObjectFunction,
21} = internalBinding('messaging');
22
23function setup() {
24  // Register the handler that will be used when deserializing JS-based objects
25  // from .postMessage() calls. The format of `deserializeInfo` is generally
26  // 'module:Constructor', e.g. 'internal/fs/promises:FileHandle'.
27  setDeserializerCreateObjectFunction((deserializeInfo) => {
28    const { 0: module, 1: ctor } = StringPrototypeSplit(deserializeInfo, ':');
29    const Ctor = require(module)[ctor];
30    if (typeof Ctor !== 'function' ||
31        typeof Ctor.prototype[messaging_deserialize_symbol] !== 'function') {
32      // Not one of the official errors because one should not be able to get
33      // here without messing with Node.js internals.
34      // eslint-disable-next-line no-restricted-syntax
35      throw new Error(`Unknown deserialize spec ${deserializeInfo}`);
36    }
37
38    return new Ctor();
39  });
40}
41
42function makeTransferable(obj) {
43  // If the object is already transferable, skip all this.
44  if (obj instanceof JSTransferable) return obj;
45  const inst = ReflectConstruct(JSTransferable, [], obj.constructor);
46  const properties = ObjectGetOwnPropertyDescriptors(obj);
47  const propertiesValues = ObjectValues(properties);
48  for (let i = 0; i < propertiesValues.length; i++) {
49    // We want to use null-prototype objects to not rely on globally mutable
50    // %Object.prototype%.
51    ObjectSetPrototypeOf(propertiesValues[i], null);
52  }
53  ObjectDefineProperties(inst, properties);
54  ObjectSetPrototypeOf(inst, ObjectGetPrototypeOf(obj));
55  return inst;
56}
57
58module.exports = {
59  makeTransferable,
60  setup,
61  JSTransferable,
62  kClone: messaging_clone_symbol,
63  kDeserialize: messaging_deserialize_symbol,
64  kTransfer: messaging_transfer_symbol,
65  kTransferList: messaging_transfer_list_symbol,
66};
67