@ -35,11 +35,41 @@ using node::ThrowRangeError;
using node : : ThrowTypeError ;
using node : : ThrowError ;
template < unsigned int TBytes , v8 : : ExternalArrayType TEAType >
class TypedArray ;
typedef TypedArray < 1 , v8 : : kExternalByteArray > Int8Array ;
typedef TypedArray < 1 , v8 : : kExternalUnsignedByteArray > Uint8Array ;
typedef TypedArray < 1 , v8 : : kExternalPixelArray > Uint8ClampedArray ;
typedef TypedArray < 2 , v8 : : kExternalShortArray > Int16Array ;
typedef TypedArray < 2 , v8 : : kExternalUnsignedShortArray > Uint16Array ;
typedef TypedArray < 4 , v8 : : kExternalIntArray > Int32Array ;
typedef TypedArray < 4 , v8 : : kExternalUnsignedIntArray > Uint32Array ;
typedef TypedArray < 4 , v8 : : kExternalFloatArray > Float32Array ;
typedef TypedArray < 8 , v8 : : kExternalDoubleArray > Float64Array ;
struct BatchedMethods {
const char * name ;
v8 : : Handle < v8 : : Value > ( * func ) ( const v8 : : Arguments & args ) ;
} ;
void WeakCallback ( v8 : : Persistent < v8 : : Value > value , void * data ) {
v8 : : Object * obj = v8 : : Object : : Cast ( * value ) ;
void * ptr = obj - > GetIndexedPropertiesExternalArrayData ( ) ;
int element_size = v8_typed_array : : SizeOfArrayElementForType (
obj - > GetIndexedPropertiesExternalArrayDataType ( ) ) ;
int size =
obj - > GetIndexedPropertiesExternalArrayDataLength ( ) * element_size ;
v8 : : V8 : : AdjustAmountOfExternalAllocatedMemory ( - size ) ;
value . ClearWeak ( ) ;
value . Dispose ( ) ;
free ( ptr ) ;
}
class ArrayBuffer {
public :
static v8 : : Persistent < v8 : : FunctionTemplate > GetTemplate ( ) {
@ -69,23 +99,6 @@ class ArrayBuffer {
}
private :
static void WeakCallback ( v8 : : Persistent < v8 : : Value > value , void * data ) {
v8 : : Object * obj = v8 : : Object : : Cast ( * value ) ;
void * ptr = obj - > GetIndexedPropertiesExternalArrayData ( ) ;
int element_size = v8_typed_array : : SizeOfArrayElementForType (
obj - > GetIndexedPropertiesExternalArrayDataType ( ) ) ;
int size =
obj - > GetIndexedPropertiesExternalArrayDataLength ( ) * element_size ;
v8 : : V8 : : AdjustAmountOfExternalAllocatedMemory ( - size ) ;
value . ClearWeak ( ) ;
value . Dispose ( ) ;
free ( ptr ) ;
}
static v8 : : Handle < v8 : : Value > V8New ( const v8 : : Arguments & args ) {
if ( ! args . IsConstructCall ( ) )
return ThrowTypeError ( " Constructor cannot be called as a function. " ) ;
@ -125,7 +138,7 @@ class ArrayBuffer {
v8 : : Persistent < v8 : : Object > persistent =
v8 : : Persistent < v8 : : Object > : : New ( args . This ( ) ) ;
persistent . MakeWeak ( NULL , & ArrayBuffer : : WeakCallback ) ;
persistent . MakeWeak ( NULL , WeakCallback ) ;
return args . This ( ) ;
}
@ -251,12 +264,23 @@ class TypedArray {
unsigned int length = 0 ;
unsigned int byte_offset = 0 ;
// [m1k3] added support for Buffer constructor
if ( node : : Buffer : : HasInstance ( args [ 0 ] )
| | ArrayBuffer : : HasInstance ( args [ 0 ] ) ) { // ArrayBuffer constructor.
if ( node : : Buffer : : HasInstance ( args [ 0 ] ) | |
ArrayBuffer : : HasInstance ( args [ 0 ] ) ) {
buffer = v8 : : Local < v8 : : Object > : : Cast ( args [ 0 ] ) ;
size_t buflen =
buffer - > GetIndexedPropertiesExternalArrayDataLength ( ) ;
size_t buflen = buffer - > GetIndexedPropertiesExternalArrayDataLength ( ) ;
// Try to short-circuit as early as possible. Assume that in most
// `new TypedArray(other_array)` calls, the old and the new array
// have the same type.
bool make_copy = HasInstance ( buffer ) | |
Int8Array : : HasInstance ( buffer ) | |
Uint8Array : : HasInstance ( buffer ) | |
Int16Array : : HasInstance ( buffer ) | |
Uint16Array : : HasInstance ( buffer ) | |
Int32Array : : HasInstance ( buffer ) | |
Uint32Array : : HasInstance ( buffer ) | |
Float32Array : : HasInstance ( buffer ) | |
Float64Array : : HasInstance ( buffer ) ;
if ( ! args [ 1 ] - > IsUndefined ( ) & & args [ 1 ] - > Int32Value ( ) < 0 )
return ThrowRangeError ( " Byte offset out of range. " ) ;
@ -281,13 +305,31 @@ class TypedArray {
}
void * buf = buffer - > GetIndexedPropertiesExternalArrayData ( ) ;
char * begin = reinterpret_cast < char * > ( buf ) + byte_offset ;
if ( ! checkAlignment ( reinterpret_cast < uintptr_t > ( begin ) , TBytes ) )
return ThrowRangeError ( " Byte offset is not aligned. " ) ;
if ( make_copy ) {
void * dst = malloc ( length ) ;
args . This ( ) - > SetIndexedPropertiesToExternalArrayData (
begin , TEAType , length ) ;
if ( dst = = NULL )
return ThrowError ( " Out of memory. " ) ;
v8 : : V8 : : AdjustAmountOfExternalAllocatedMemory ( length ) ;
memcpy ( dst , static_cast < const char * > ( buf ) + byte_offset , length ) ;
v8 : : Persistent < v8 : : Object > persistent =
v8 : : Persistent < v8 : : Object > : : New ( args . This ( ) ) ;
persistent - > SetIndexedPropertiesToExternalArrayData ( dst ,
TEAType ,
length ) ;
persistent . MakeWeak ( NULL , WeakCallback ) ;
}
else {
char * begin = reinterpret_cast < char * > ( buf ) + byte_offset ;
if ( ! checkAlignment ( reinterpret_cast < uintptr_t > ( begin ) , TBytes ) )
return ThrowRangeError ( " Byte offset is not aligned. " ) ;
args . This ( ) - > SetIndexedPropertiesToExternalArrayData (
begin , TEAType , length ) ;
}
}
else if ( args [ 0 ] - > IsObject ( ) ) { // TypedArray / type[] constructor.
v8 : : Local < v8 : : Object > obj = v8 : : Local < v8 : : Object > : : Cast ( args [ 0 ] ) ;
@ -461,16 +503,6 @@ class TypedArray {
}
} ;
class Int8Array : public TypedArray < 1 , v8 : : kExternalByteArray > { } ;
class Uint8Array : public TypedArray < 1 , v8 : : kExternalUnsignedByteArray > { } ;
class Uint8ClampedArray : public TypedArray < 1 , v8 : : kExternalPixelArray > { } ;
class Int16Array : public TypedArray < 2 , v8 : : kExternalShortArray > { } ;
class Uint16Array : public TypedArray < 2 , v8 : : kExternalUnsignedShortArray > { } ;
class Int32Array : public TypedArray < 4 , v8 : : kExternalIntArray > { } ;
class Uint32Array : public TypedArray < 4 , v8 : : kExternalUnsignedIntArray > { } ;
class Float32Array : public TypedArray < 4 , v8 : : kExternalFloatArray > { } ;
class Float64Array : public TypedArray < 8 , v8 : : kExternalDoubleArray > { } ;
template < typename T >
v8 : : Handle < v8 : : Value > cTypeToValue ( T ) {
return v8 : : Undefined ( ) ;