UNPKG

reign

Version:

A persistent, typed-objects implementation.

172 lines (136 loc) 5.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Realm = undefined; var _bluebird = require("bluebird"); 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 }; } const HEADER_ADDRESS = 336; // First usable block in the backing store. const VERSION_ADDRESS = HEADER_ADDRESS; const STRING_POOL_POINTER_ADDRESS = VERSION_ADDRESS + 8; const ROOT_MAP_POINTER_ADDRESS = STRING_POOL_POINTER_ADDRESS + 8; const HEADER_CHECKSUM_ADDRESS = ROOT_MAP_POINTER_ADDRESS + 8; const HEADER_SIZE = HEADER_CHECKSUM_ADDRESS + 8 - HEADER_ADDRESS; const FIRST_ADDRESS = HEADER_ADDRESS + HEADER_SIZE; const $RootHashMap = Symbol('%RootHashMap'); class Realm { constructor(backing) { 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. */ init() { var _this = this; return (0, _bluebird.coroutine)(function* () { if (_this.isInitialized) { throw new Error(`Realm cannot be initialized twice.`); } if (!_this.backing.isInitialized) { yield _this.backing.init(); } verifyHeader(_this); _this.strings = (0, _stringPool.make)(_this, STRING_POOL_POINTER_ADDRESS); (0, _builtins.registerBuiltins)(_this); let 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 _this; })(); } /** * Return the type of the given value. */ typeOf(value) { // Issue 252 if (value == null || typeof value === 'function' || 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; } } get(key) { // Issue 252 return this[$RootHashMap].get(key); } has(key) { // Issue 252 return this[$RootHashMap].has(key); } set(key, value) { // Issue 252 this[$RootHashMap].set(key, value); return this; } delete(key) { // Issue 252 return this[$RootHashMap].delete(key); } } exports.Realm = Realm; function verifyHeader(realm) { const backing = realm.backing; if (backing.getUint32(HEADER_ADDRESS) !== HEADER_ADDRESS || backing.getUint32(HEADER_CHECKSUM_ADDRESS) !== HEADER_CHECKSUM_ADDRESS) { const 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); } }