summaryrefslogtreecommitdiffstats
path: root/toolkit/modules/subprocess/subprocess_shared.js
blob: d59a14a35132ba21c5abff10cdb24c511670be51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";

/* exported ArrayBuffer_transfer, Library, SubprocessConstants */

// ctypes is either already available in the chrome worker scope, or defined
// in scope via loadSubScript.
/* global ctypes */

/**
 * Returns a new ArrayBuffer whose contents have been taken from the `buffer`'s
 * data and then is either truncated or zero-extended by `size`. If `size` is
 * undefined, the `byteLength` of the `buffer` is used. This operation leaves
 * `buffer` in a detached state.
 *
 * @param {ArrayBuffer} buffer
 * @param {integer} [size = buffer.byteLength]
 * @returns {ArrayBuffer}
 */
var ArrayBuffer_transfer = function (buffer, size = buffer.byteLength) {
  let u8out = new Uint8Array(size);
  let u8buffer = new Uint8Array(buffer, 0, Math.min(size, buffer.byteLength));
  u8out.set(u8buffer);
  return u8out.buffer;
};

var libraries = {};

var Library = class Library {
  constructor(name, names, definitions) {
    if (name in libraries) {
      return libraries[name];
    }

    for (let name of names) {
      try {
        if (!this.library) {
          this.library = ctypes.open(name);
        }
      } catch (e) {
        // Ignore errors until we've tried all the options.
      }
    }
    if (!this.library) {
      throw new Error("Could not load libc");
    }

    libraries[name] = this;

    for (let symbol of Object.keys(definitions)) {
      this.declare(symbol, ...definitions[symbol]);
    }
  }

  declare(name, ...args) {
    Object.defineProperty(this, name, {
      configurable: true,
      get() {
        Object.defineProperty(this, name, {
          configurable: true,
          value: this.library.declare(name, ...args),
        });

        return this[name];
      },
    });
  }
};

/**
 * Holds constants which apply to various Subprocess operations.
 *
 * @namespace
 * @lends Subprocess
 */
var SubprocessConstants = {
  /**
   * @property {integer} ERROR_END_OF_FILE
   *           The operation failed because the end of the file was reached.
   *           @constant
   */
  ERROR_END_OF_FILE: 0xff7a0001,
  /**
   * @property {integer} ERROR_INVALID_JSON
   *           The operation failed because an invalid JSON was encountered.
   *           @constant
   */
  ERROR_INVALID_JSON: 0xff7a0002,
  /**
   * @property {integer} ERROR_BAD_EXECUTABLE
   *           The operation failed because the given file did not exist, or
   *           could not be executed.
   *           @constant
   */
  ERROR_BAD_EXECUTABLE: 0xff7a0003,
  /**
   * @property {integer} ERROR_INVALID_OPTION
   *           The operation failed because an invalid option was provided.
   *           @constant
   */
  ERROR_INVALID_OPTION: 0xff7a0004,
};

Object.freeze(SubprocessConstants);