UNPKG

reign

Version:

A persistent, typed-objects implementation.

217 lines (172 loc) 7.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Realm = undefined; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _typeClass = require("./type-class"); var _primitiveType = require("./type-class/primitive-type"); var _stringType = require("./type-class/string-type"); var _referenceType = require("./type-class/reference-type"); var _structType = require("./type-class/struct-type"); var _objectType = require("./type-class/object-type"); var _arrayType = require("./type-class/array-type"); var _hashMapType = require("./type-class/hash-map-type"); var _hashSetType = require("./type-class/hash-set-type"); var _unionType = require("./type-class/union-type"); var _enumType = require("./type-class/enum-type"); var _stringPool = require("./string-pool"); var _builtins = require("./builtins"); var _backing = require("backing"); var _backing2 = _interopRequireDefault(_backing); var _typeRegistry = require("type-registry"); var _typeRegistry2 = _interopRequireDefault(_typeRegistry); var _symbols = require("./symbols"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; } var HEADER_ADDRESS = 336; // First usable block in the backing store. var VERSION_ADDRESS = HEADER_ADDRESS; var STRING_POOL_POINTER_ADDRESS = VERSION_ADDRESS + 8; var ROOT_MAP_POINTER_ADDRESS = STRING_POOL_POINTER_ADDRESS + 8; var HEADER_CHECKSUM_ADDRESS = ROOT_MAP_POINTER_ADDRESS + 8; var HEADER_SIZE = HEADER_CHECKSUM_ADDRESS + 8 - HEADER_ADDRESS; var FIRST_ADDRESS = HEADER_ADDRESS + HEADER_SIZE; var $RootHashMap = Symbol('%RootHashMap'); var Realm = exports.Realm = function () { function Realm(backing) { _classCallCheck(this, Realm); this.backing = backing; this.registry = backing.registry; this.T = this.registry.T; this.I = this.registry.I; this.TypeClass = (0, _typeClass.make)(this); this.PrimitiveType = (0, _primitiveType.make)(this); this.ReferenceType = (0, _referenceType.make)(this); this.StructType = (0, _structType.make)(this); this.ObjectType = (0, _objectType.make)(this); this.ArrayType = (0, _arrayType.make)(this); this.StringType = (0, _stringType.make)(this); this.HashMapType = (0, _hashMapType.make)(this); this.HashSetType = (0, _hashSetType.make)(this); this.UnionType = (0, _unionType.make)(this); this.EnumType = (0, _enumType.make)(this); this.isInitialized = false; } /** * Initialize the realm. */ _createClass(Realm, [{ key: "init", value: function init() { var _this2 = this; var _this = this; return _asyncToGenerator(regeneratorRuntime.mark(function _callee() { var rootAddress; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (!_this.isInitialized) { _context.next = 2; break; } throw new Error("Realm cannot be initialized twice."); case 2: if (_this.backing.isInitialized) { _context.next = 5; break; } _context.next = 5; return _this.backing.init(); case 5: verifyHeader(_this); _this.strings = (0, _stringPool.make)(_this, STRING_POOL_POINTER_ADDRESS); (0, _builtins.registerBuiltins)(_this); rootAddress = _this.backing.getFloat64(ROOT_MAP_POINTER_ADDRESS); if (rootAddress === 0) { // Issue 252 _this[$RootHashMap] = new _this.T.HashMap(); // Issue 252 _this.backing.setFloat64(ROOT_MAP_POINTER_ADDRESS, _this[$RootHashMap][_symbols.$Address]); } else { // Issue 252 _this[$RootHashMap] = new _this.T.HashMap(_this.backing, rootAddress); } _this.isInitialized = true; Object.freeze(_this); return _context.abrupt("return", _this); case 13: case "end": return _context.stop(); } } }, _callee, _this2); }))(); } /** * Return the type of the given value. */ }, { key: "typeOf", value: function typeOf(value) { // Issue 252 if (value == null || typeof value === 'function' || (typeof value === "undefined" ? "undefined" : _typeof(value)) === 'symbol') { return null; } else if (typeof value === 'number') { return this.T.Float64; } else if (typeof value === 'boolean') { return this.T.Boolean; } else if (typeof value === 'string') { return this.T.String; } else if (value[_symbols.$ValueType]) { return value[_symbols.$ValueType]; } else if (Array.isArray(value)) { return this.T.Array; } else { return this.T.Object; } } }, { key: "get", value: function get(key) { // Issue 252 return this[$RootHashMap].get(key); } }, { key: "has", value: function has(key) { // Issue 252 return this[$RootHashMap].has(key); } }, { key: "set", value: function set(key, value) { // Issue 252 this[$RootHashMap].set(key, value); return this; } }, { key: "delete", value: function _delete(key) { // Issue 252 return this[$RootHashMap].delete(key); } }]); return Realm; }(); function verifyHeader(realm) { var backing = realm.backing; if (backing.getUint32(HEADER_ADDRESS) !== HEADER_ADDRESS || backing.getUint32(HEADER_CHECKSUM_ADDRESS) !== HEADER_CHECKSUM_ADDRESS) { var address = backing.calloc(HEADER_SIZE); /* istanbul ignore if */ if (address !== HEADER_ADDRESS) { throw new TypeError("Allocator returned an invalid backing header address, got " + address + " expected " + HEADER_ADDRESS + "."); } backing.setUint32(HEADER_ADDRESS, HEADER_ADDRESS); backing.setUint32(HEADER_CHECKSUM_ADDRESS, HEADER_CHECKSUM_ADDRESS); backing.setFloat64(STRING_POOL_POINTER_ADDRESS, 0); backing.setFloat64(ROOT_MAP_POINTER_ADDRESS, 0); } }