diff --git a/lib/smalloc.js b/lib/smalloc.js index 9ebbaf402d17df..f181cb60cf2d7c 100644 --- a/lib/smalloc.js +++ b/lib/smalloc.js @@ -2,6 +2,8 @@ const smalloc = process.binding('smalloc'); const kMaxLength = smalloc.kMaxLength; +const kMinType = smalloc.kMinType; +const kMaxType = smalloc.kMaxType; const util = require('util'); exports.alloc = alloc; @@ -15,24 +17,8 @@ Object.defineProperty(exports, 'kMaxLength', { enumerable: true, value: kMaxLength, writable: false }); -// enumerated values for different external array types -var Types = {}; - -// Must match enum v8::ExternalArrayType. -Object.defineProperties(Types, { - 'Int8': { enumerable: true, value: 1, writable: false }, - 'Uint8': { enumerable: true, value: 2, writable: false }, - 'Int16': { enumerable: true, value: 3, writable: false }, - 'Uint16': { enumerable: true, value: 4, writable: false }, - 'Int32': { enumerable: true, value: 5, writable: false }, - 'Uint32': { enumerable: true, value: 6, writable: false }, - 'Float': { enumerable: true, value: 7, writable: false }, - 'Double': { enumerable: true, value: 8, writable: false }, - 'Uint8Clamped': { enumerable: true, value: 9, writable: false } -}); - Object.defineProperty(exports, 'Types', { - enumerable: true, value: Types, writable: false + enumerable: true, value: Object.freeze(smalloc.types), writable: false }); @@ -59,8 +45,7 @@ function alloc(n, obj, type) { if (smalloc.hasExternalData(obj)) throw new TypeError('object already has external array data'); - // 1 == v8::kExternalUint8Array, 9 == v8::kExternalUint8ClampedArray - if (type < 1 || type > 9) + if (type < kMinType || type > kMaxType) throw new TypeError('unknown external array type: ' + type); if (n > kMaxLength) throw new RangeError('Attempt to allocate array larger than maximum ' + diff --git a/src/smalloc.cc b/src/smalloc.cc index 834b93a7473dd1..319c3937605404 100644 --- a/src/smalloc.cc +++ b/src/smalloc.cc @@ -10,6 +10,20 @@ #include #define ALLOC_ID (0xA10C) +#define EXTERNAL_ARRAY_TYPES(V) \ + V(Int8, kExternalInt8Array) \ + V(Uint8, kExternalUint8Array) \ + V(Int16, kExternalInt16Array) \ + V(Uint16, kExternalUint16Array) \ + V(Int32, kExternalInt32Array) \ + V(Uint32, kExternalUint32Array) \ + V(Float, kExternalFloat32Array) \ + V(Double, kExternalFloat64Array) \ + V(Uint8Clamped, kExternalUint8ClampedArray) + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + namespace node { namespace smalloc { @@ -559,6 +573,7 @@ void Initialize(Handle exports, Handle unused, Handle context) { Environment* env = Environment::GetCurrent(context); + Isolate* isolate = env->isolate(); env->SetMethod(exports, "copyOnto", CopyOnto); env->SetMethod(exports, "sliceOnto", SliceOnto); @@ -573,6 +588,25 @@ void Initialize(Handle exports, exports->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kMaxLength"), Uint32::NewFromUnsigned(env->isolate(), kMaxLength)); + Local types = Object::New(isolate); + + uint32_t kMinType = ~0; + uint32_t kMaxType = 0; + #define V(name, value) \ + types->Set(FIXED_ONE_BYTE_STRING(env->isolate(), #name), \ + Uint32::NewFromUnsigned(env->isolate(), v8::value)); \ + kMinType = MIN(kMinType, v8::value); \ + kMaxType = MAX(kMinType, v8::value); + + EXTERNAL_ARRAY_TYPES(V) + #undef V + + exports->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "types"), types); + exports->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kMinType"), + Uint32::NewFromUnsigned(env->isolate(), kMinType)); + exports->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kMaxType"), + Uint32::NewFromUnsigned(env->isolate(), kMaxType)); + HeapProfiler* heap_profiler = env->isolate()->GetHeapProfiler(); heap_profiler->SetWrapperClassInfoProvider(ALLOC_ID, WrapperInfo); } diff --git a/test/parallel/test-smalloc.js b/test/parallel/test-smalloc.js index 61ffe3b84da88c..ef1aa60bad6838 100644 --- a/test/parallel/test-smalloc.js +++ b/test/parallel/test-smalloc.js @@ -309,3 +309,23 @@ assert.throws(function() { assert.throws(function() { smalloc.dispose({}); }); + + +// Types should be immutable +assert.deepStrictEqual(Object.getOwnPropertyDescriptor(smalloc, 'Types'), { + value: smalloc.Types, + writable: false, + enumerable: true, + configurable: false +}); + +var types = Object.keys(smalloc.Types); +var Types = smalloc.Types; + +for (var i = 0; i < types.length; i++) + assert.deepStrictEqual(Object.getOwnPropertyDescriptor(Types, types[i]), { + value: Types[types[i]], + writable: false, + enumerable: true, + configurable: false + });