summaryrefslogtreecommitdiff
path: root/dev/vm.js
diff options
context:
space:
mode:
Diffstat (limited to 'dev/vm.js')
-rw-r--r--dev/vm.js204
1 files changed, 0 insertions, 204 deletions
diff --git a/dev/vm.js b/dev/vm.js
deleted file mode 100644
index c3266443..00000000
--- a/dev/vm.js
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2023 Yomitan Authors
- * Copyright (C) 2020-2022 Yomichan Authors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-const fs = require('fs');
-const vm = require('vm');
-const path = require('path');
-const assert = require('assert');
-const crypto = require('crypto');
-
-
-function getContextEnvironmentRecords(context, names) {
- // Enables export of values from the declarative environment record
- if (!Array.isArray(names) || names.length === 0) {
- return [];
- }
-
- let scriptSource = '(() => {\n "use strict";\n const results = [];';
- for (const name of names) {
- scriptSource += `\n try { results.push(${name}); } catch (e) { results.push(void 0); }`;
- }
- scriptSource += '\n return results;\n})();';
-
- const script = new vm.Script(scriptSource, {filename: 'getContextEnvironmentRecords'});
-
- const contextHasNames = Object.prototype.hasOwnProperty.call(context, 'names');
- const contextNames = context.names;
- context.names = names;
-
- const results = script.runInContext(context, {});
-
- if (contextHasNames) {
- context.names = contextNames;
- } else {
- delete context.names;
- }
-
- return Array.from(results);
-}
-
-function isDeepStrictEqual(val1, val2) {
- if (val1 === val2) { return true; }
-
- if (Array.isArray(val1)) {
- if (Array.isArray(val2)) {
- return isArrayDeepStrictEqual(val1, val2);
- }
- } else if (typeof val1 === 'object' && val1 !== null) {
- if (typeof val2 === 'object' && val2 !== null) {
- return isObjectDeepStrictEqual(val1, val2);
- }
- }
-
- return false;
-}
-
-function isArrayDeepStrictEqual(val1, val2) {
- const ii = val1.length;
- if (ii !== val2.length) { return false; }
-
- for (let i = 0; i < ii; ++i) {
- if (!isDeepStrictEqual(val1[i], val2[i])) {
- return false;
- }
- }
-
- return true;
-}
-
-function isObjectDeepStrictEqual(val1, val2) {
- const keys1 = Object.keys(val1);
- const keys2 = Object.keys(val2);
-
- if (keys1.length !== keys2.length) { return false; }
-
- const keySet = new Set(keys1);
- for (const key of keys2) {
- if (!keySet.delete(key)) { return false; }
- }
-
- for (const key of keys1) {
- if (!isDeepStrictEqual(val1[key], val2[key])) {
- return false;
- }
- }
-
- const tag1 = Object.prototype.toString.call(val1);
- const tag2 = Object.prototype.toString.call(val2);
- if (tag1 !== tag2) { return false; }
-
- return true;
-}
-
-function deepStrictEqual(actual, expected) {
- try {
- // This will fail on prototype === comparison on cross context objects
- assert.deepStrictEqual(actual, expected);
- } catch (e) {
- if (!isDeepStrictEqual(actual, expected)) {
- throw e;
- }
- }
-}
-
-
-function createURLClass() {
- const BaseURL = URL;
- const result = function URL(url) {
- const u = new BaseURL(url);
- this.hash = u.hash;
- this.host = u.host;
- this.hostname = u.hostname;
- this.href = u.href;
- this.origin = u.origin;
- this.password = u.password;
- this.pathname = u.pathname;
- this.port = u.port;
- this.protocol = u.protocol;
- this.search = u.search;
- this.searchParams = u.searchParams;
- this.username = u.username;
- };
- return result;
-}
-
-
-class VM {
- constructor(context={}) {
- context.URL = createURLClass();
- context.crypto = {
- getRandomValues: (array) => {
- const buffer = crypto.randomBytes(array.byteLength);
- buffer.copy(array);
- return array;
- }
- };
- this._context = vm.createContext(context);
- this._assert = {
- deepStrictEqual
- };
- }
-
- get context() {
- return this._context;
- }
-
- get assert() {
- return this._assert;
- }
-
- get(names) {
- if (typeof names === 'string') {
- return getContextEnvironmentRecords(this._context, [names])[0];
- } else if (Array.isArray(names)) {
- return getContextEnvironmentRecords(this._context, names);
- } else {
- throw new Error('Invalid argument');
- }
- }
-
- set(values) {
- if (typeof values === 'object' && values !== null) {
- Object.assign(this._context, values);
- } else {
- throw new Error('Invalid argument');
- }
- }
-
- execute(fileNames) {
- const single = !Array.isArray(fileNames);
- if (single) {
- fileNames = [fileNames];
- }
-
- const results = [];
- for (const fileName of fileNames) {
- const absoluteFileName = path.resolve(__dirname, '..', 'ext', fileName);
- const source = fs.readFileSync(absoluteFileName, {encoding: 'utf8'});
- const script = new vm.Script(source, {filename: absoluteFileName});
- results.push(script.runInContext(this._context, {}));
- }
-
- return single ? results[0] : results;
- }
-}
-
-
-module.exports = {
- VM
-};