public static void NodejsFuncComplete(IntPtr context, int taskStatus, IntPtr result, int resultType)
    {
        CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::NodejsFuncComplete (CLR) - Starting");

        GCHandle gcHandle = GCHandle.FromIntPtr(context);
        NodejsFuncInvokeContext actualContext = (NodejsFuncInvokeContext)gcHandle.Target;

        gcHandle.Free();

        V8Type v8ResultType     = (V8Type)resultType;
        object marshalledResult = CoreCLREmbedding.MarshalV8ToCLR(result, v8ResultType);

        CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::NodejsFuncComplete (CLR) - Marshalled result data back to the CLR");

        if (taskStatus == (int)TaskStatus.Faulted)
        {
            actualContext.TaskCompletionSource.SetException((Exception)marshalledResult);
            CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::NodejsFuncComplete (CLR) - Set the exception received from Node.js: {0}", ((Exception)marshalledResult).Message);
        }

        else
        {
            actualContext.TaskCompletionSource.SetResult(marshalledResult);
            CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::NodejsFuncComplete (CLR) - Set result data");
        }

        CoreCLREmbedding.DebugMessage("NodejsFuncInvokeContext::NodejsFuncComplete (CLR) - Finished");
    }
Exemplo n.º 2
0
    // ReSharper disable once InconsistentNaming
    public static IntPtr MarshalCLRToV8(object clrObject, out V8Type v8Type)
    {
        if (clrObject == null)
        {
            v8Type = V8Type.Null;
            return IntPtr.Zero;
        }

        else if (clrObject is string)
        {
            v8Type = V8Type.String;
            return Marshal.StringToHGlobalAnsi((string) clrObject);
        }

        else if (clrObject is char)
        {
            v8Type = V8Type.String;
            return Marshal.StringToHGlobalAnsi(clrObject.ToString());
        }

        else if (clrObject is bool)
        {
            v8Type = V8Type.Boolean;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof (int));

            Marshal.WriteInt32(memoryLocation, ((bool) clrObject)
                ? 1
                : 0);
            return memoryLocation;
        }

        else if (clrObject is Guid)
        {
            v8Type = V8Type.String;
            return Marshal.StringToHGlobalAnsi(clrObject.ToString());
        }

        else if (clrObject is DateTime)
        {
            v8Type = V8Type.Date;
            DateTime dateTime = (DateTime) clrObject;

            if (dateTime.Kind == DateTimeKind.Local)
            {
                dateTime = dateTime.ToUniversalTime();
            }

            else if (dateTime.Kind == DateTimeKind.Unspecified)
            {
                dateTime = new DateTime(dateTime.Ticks, DateTimeKind.Utc);
            }

            long ticks = (dateTime.Ticks - MinDateTimeTicks)/10000;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof (double));

            WriteDouble(memoryLocation, ticks);
            return memoryLocation;
        }

        else if (clrObject is DateTimeOffset)
        {
            v8Type = V8Type.String;
            return Marshal.StringToHGlobalAnsi(clrObject.ToString());
        }

        else if (clrObject is Uri)
        {
            v8Type = V8Type.String;
            return Marshal.StringToHGlobalAnsi(clrObject.ToString());
        }

        else if (clrObject is short)
        {
            v8Type = V8Type.Int32;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof (int));

            Marshal.WriteInt32(memoryLocation, Convert.ToInt32(clrObject));
            return memoryLocation;
        }

        else if (clrObject is int)
        {
            v8Type = V8Type.Int32;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof (int));

            Marshal.WriteInt32(memoryLocation, (int) clrObject);
            return memoryLocation;
        }

        else if (clrObject is long)
        {
            v8Type = V8Type.Number;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof (double));

            WriteDouble(memoryLocation, Convert.ToDouble((long) clrObject));
            return memoryLocation;
        }

        else if (clrObject is double)
        {
            v8Type = V8Type.Number;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof (double));

            WriteDouble(memoryLocation, (double) clrObject);
            return memoryLocation;
        }

        else if (clrObject is float)
        {
            v8Type = V8Type.Number;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof (double));

            WriteDouble(memoryLocation, Convert.ToDouble((Single) clrObject));
            return memoryLocation;
        }

        else if (clrObject is decimal)
        {
            v8Type = V8Type.String;
            return Marshal.StringToHGlobalAnsi(clrObject.ToString());
        }

        else if (clrObject is Enum)
        {
            v8Type = V8Type.String;
            return Marshal.StringToHGlobalAnsi(clrObject.ToString());
        }

        else if (clrObject is byte[] || clrObject is IEnumerable<byte>)
        {
            v8Type = V8Type.Buffer;

            V8BufferData bufferData = new V8BufferData();
            byte[] buffer;

            if (clrObject is byte[])
            {
                buffer = (byte[]) clrObject;
            }

            else
            {
                buffer = ((IEnumerable<byte>) clrObject).ToArray();
            }

            bufferData.bufferLength = buffer.Length;
            bufferData.buffer = Marshal.AllocHGlobal(buffer.Length*sizeof (byte));

            Marshal.Copy(buffer, 0, bufferData.buffer, bufferData.bufferLength);

            IntPtr destinationPointer = Marshal.AllocHGlobal(V8BufferDataSize);
            Marshal.StructureToPtr(bufferData, destinationPointer, false);

            return destinationPointer;
        }

        else if (clrObject is IDictionary || clrObject is ExpandoObject)
        {
            v8Type = V8Type.Object;

            IEnumerable keys;
            int keyCount;
            Func<object, object> getValue;

            if (clrObject is ExpandoObject)
            {
                IDictionary<string, object> objectDictionary = (IDictionary<string, object>) clrObject;

                keys = objectDictionary.Keys;
                keyCount = objectDictionary.Keys.Count;
                getValue = index => objectDictionary[index.ToString()];
            }

            else
            {
                IDictionary objectDictionary = (IDictionary) clrObject;

                keys = objectDictionary.Keys;
                keyCount = objectDictionary.Keys.Count;
                getValue = index => objectDictionary[index];
            }

            V8ObjectData objectData = new V8ObjectData();
            int counter = 0;

            objectData.propertiesCount = keyCount;
            objectData.propertyNames = Marshal.AllocHGlobal(PointerSize*keyCount);
            objectData.propertyTypes = Marshal.AllocHGlobal(sizeof (int)*keyCount);
            objectData.propertyValues = Marshal.AllocHGlobal(PointerSize*keyCount);

            foreach (object key in keys)
            {
                Marshal.WriteIntPtr(objectData.propertyNames, counter*PointerSize, Marshal.StringToHGlobalAnsi(key.ToString()));
                V8Type propertyType;
                Marshal.WriteIntPtr(objectData.propertyValues, counter*PointerSize, MarshalCLRToV8(getValue(key), out propertyType));
                Marshal.WriteInt32(objectData.propertyTypes, counter*sizeof (int), (int) propertyType);

                counter++;
            }

            IntPtr destinationPointer = Marshal.AllocHGlobal(V8ObjectDataSize);
            Marshal.StructureToPtr(objectData, destinationPointer, false);

            return destinationPointer;
        }

        else if (clrObject is IEnumerable)
        {
            v8Type = V8Type.Array;

            V8ArrayData arrayData = new V8ArrayData();
            List<IntPtr> itemValues = new List<IntPtr>();
            List<int> itemTypes = new List<int>();

            foreach (object item in (IEnumerable) clrObject)
            {
                V8Type itemType;

                itemValues.Add(MarshalCLRToV8(item, out itemType));
                itemTypes.Add((int) itemType);
            }

            arrayData.arrayLength = itemValues.Count;
            arrayData.itemTypes = Marshal.AllocHGlobal(sizeof (int)*arrayData.arrayLength);
            arrayData.itemValues = Marshal.AllocHGlobal(PointerSize*arrayData.arrayLength);

            Marshal.Copy(itemTypes.ToArray(), 0, arrayData.itemTypes, arrayData.arrayLength);
            Marshal.Copy(itemValues.ToArray(), 0, arrayData.itemValues, arrayData.arrayLength);

            IntPtr destinationPointer = Marshal.AllocHGlobal(V8ArrayDataSize);
            Marshal.StructureToPtr(arrayData, destinationPointer, false);

            return destinationPointer;
        }

        else if (clrObject.GetType().GetTypeInfo().IsGenericType && clrObject.GetType().GetGenericTypeDefinition() == typeof (Func<,>))
        {
            Func<object, Task<object>> funcObject = clrObject as Func<object, Task<object>>;

            if (funcObject == null)
            {
                throw new Exception("Properties that return Func<> instances must return Func<object, Task<object>> instances");
            }

            v8Type = V8Type.Function;
            return GCHandle.ToIntPtr(GCHandle.Alloc(funcObject));
        }

        else
        {
            v8Type = clrObject is Exception
                ? V8Type.Exception
                : V8Type.Object;

            if (clrObject is Exception)
            {
                AggregateException aggregateException = clrObject as AggregateException;

                if (aggregateException?.InnerExceptions != null && aggregateException.InnerExceptions.Count > 0)
                {
                    clrObject = aggregateException.InnerExceptions[0];
                }

                else
                {
                    TargetInvocationException targetInvocationException = clrObject as TargetInvocationException;

                    if (targetInvocationException?.InnerException != null)
                    {
                        clrObject = targetInvocationException.InnerException;
                    }
                }
            }

            List<Tuple<string, Func<object, object>>> propertyAccessors = GetPropertyAccessors(clrObject.GetType());
            V8ObjectData objectData = new V8ObjectData();
            int counter = 0;

            objectData.propertiesCount = propertyAccessors.Count;
            objectData.propertyNames = Marshal.AllocHGlobal(PointerSize*propertyAccessors.Count);
            objectData.propertyTypes = Marshal.AllocHGlobal(sizeof (int)*propertyAccessors.Count);
            objectData.propertyValues = Marshal.AllocHGlobal(PointerSize*propertyAccessors.Count);

            foreach (Tuple<string, Func<object, object>> propertyAccessor in propertyAccessors)
            {
                Marshal.WriteIntPtr(objectData.propertyNames, counter*PointerSize, Marshal.StringToHGlobalAnsi(propertyAccessor.Item1));

                V8Type propertyType;

                Marshal.WriteIntPtr(objectData.propertyValues, counter*PointerSize, MarshalCLRToV8(propertyAccessor.Item2(clrObject), out propertyType));
                Marshal.WriteInt32(objectData.propertyTypes, counter*sizeof (int), (int) propertyType);
                counter++;
            }

            IntPtr destinationPointer = Marshal.AllocHGlobal(V8ObjectDataSize);
            Marshal.StructureToPtr(objectData, destinationPointer, false);

            return destinationPointer;
        }
    }
Exemplo n.º 3
0
    public static object MarshalV8ToCLR(IntPtr v8Object, V8Type objectType)
    {
        switch (objectType)
        {
            case V8Type.String:
                return Marshal.PtrToStringAnsi(v8Object);

            case V8Type.Object:
                return V8ObjectToExpando(Marshal.PtrToStructure<V8ObjectData>(v8Object));

            case V8Type.Boolean:
                return Marshal.ReadByte(v8Object) != 0;

            case V8Type.Number:
                return ReadDouble(v8Object);

            case V8Type.Date:
                double ticks = ReadDouble(v8Object);
                return new DateTime(Convert.ToInt64(ticks) * 10000 + MinDateTimeTicks, DateTimeKind.Utc);

            case V8Type.Null:
                return null;

            case V8Type.Int32:
                return Marshal.ReadInt32(v8Object);

            case V8Type.UInt32:
                return (uint)Marshal.ReadInt32(v8Object);

            case V8Type.Function:
                NodejsFunc nodejsFunc = new NodejsFunc(v8Object);
                return nodejsFunc.GetFunc();

            case V8Type.Array:
                V8ArrayData arrayData = Marshal.PtrToStructure<V8ArrayData>(v8Object);
                object[] array = new object[arrayData.arrayLength];

                for (int i = 0; i < arrayData.arrayLength; i++)
                {
                    int itemType = Marshal.ReadInt32(arrayData.itemTypes, i * sizeof(int));
                    IntPtr itemValuePointer = Marshal.ReadIntPtr(arrayData.itemValues, i * PointerSize);

                    array[i] = MarshalV8ToCLR(itemValuePointer, (V8Type)itemType);
                }

                return array;

            case V8Type.Buffer:
                V8BufferData bufferData = Marshal.PtrToStructure<V8BufferData>(v8Object);
                byte[] buffer = new byte[bufferData.bufferLength];

                Marshal.Copy(bufferData.buffer, buffer, 0, bufferData.bufferLength);

                return buffer;

            case V8Type.Exception:
                string message = Marshal.PtrToStringAnsi(v8Object);
                return new Exception(message);

            default:
                throw new Exception("Unsupported V8 object type: " + objectType + ".");
        }
    }
Exemplo n.º 4
0
    // ReSharper disable once InconsistentNaming
    public static IntPtr MarshalCLRToV8(object clrObject, out V8Type v8Type)
    {
        if (clrObject == null)
        {
            v8Type = V8Type.Null;
            return(IntPtr.Zero);
        }

        else if (clrObject is string)
        {
            v8Type = V8Type.String;
            return(Marshal.StringToHGlobalAnsi((string)clrObject));
        }

        else if (clrObject is char)
        {
            v8Type = V8Type.String;
            return(Marshal.StringToHGlobalAnsi(clrObject.ToString()));
        }

        else if (clrObject is bool)
        {
            v8Type = V8Type.Boolean;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof(int));

            Marshal.WriteInt32(memoryLocation, ((bool)clrObject)
                ? 1
                : 0);
            return(memoryLocation);
        }

        else if (clrObject is Guid)
        {
            v8Type = V8Type.String;
            return(Marshal.StringToHGlobalAnsi(clrObject.ToString()));
        }

        else if (clrObject is DateTime)
        {
            v8Type = V8Type.Date;
            DateTime dateTime = (DateTime)clrObject;

            if (dateTime.Kind == DateTimeKind.Local)
            {
                dateTime = dateTime.ToUniversalTime();
            }

            else if (dateTime.Kind == DateTimeKind.Unspecified)
            {
                dateTime = new DateTime(dateTime.Ticks, DateTimeKind.Utc);
            }

            long   ticks          = (dateTime.Ticks - MinDateTimeTicks) / 10000;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof(double));

            WriteDouble(memoryLocation, ticks);
            return(memoryLocation);
        }

        else if (clrObject is DateTimeOffset)
        {
            v8Type = V8Type.String;
            return(Marshal.StringToHGlobalAnsi(clrObject.ToString()));
        }

        else if (clrObject is Uri)
        {
            v8Type = V8Type.String;
            return(Marshal.StringToHGlobalAnsi(clrObject.ToString()));
        }

        else if (clrObject is short)
        {
            v8Type = V8Type.Int32;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof(int));

            Marshal.WriteInt32(memoryLocation, Convert.ToInt32(clrObject));
            return(memoryLocation);
        }

        else if (clrObject is int)
        {
            v8Type = V8Type.Int32;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof(int));

            Marshal.WriteInt32(memoryLocation, (int)clrObject);
            return(memoryLocation);
        }

        else if (clrObject is long)
        {
            v8Type = V8Type.Number;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof(double));

            WriteDouble(memoryLocation, Convert.ToDouble((long)clrObject));
            return(memoryLocation);
        }

        else if (clrObject is double)
        {
            v8Type = V8Type.Number;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof(double));

            WriteDouble(memoryLocation, (double)clrObject);
            return(memoryLocation);
        }

        else if (clrObject is float)
        {
            v8Type = V8Type.Number;
            IntPtr memoryLocation = Marshal.AllocHGlobal(sizeof(double));

            WriteDouble(memoryLocation, Convert.ToDouble((Single)clrObject));
            return(memoryLocation);
        }

        else if (clrObject is decimal)
        {
            v8Type = V8Type.String;
            return(Marshal.StringToHGlobalAnsi(clrObject.ToString()));
        }

        else if (clrObject is Enum)
        {
            v8Type = V8Type.String;
            return(Marshal.StringToHGlobalAnsi(clrObject.ToString()));
        }

        else if (clrObject is byte[] || clrObject is IEnumerable <byte> )
        {
            v8Type = V8Type.Buffer;

            V8BufferData bufferData = new V8BufferData();
            byte[]       buffer;

            if (clrObject is byte[])
            {
                buffer = (byte[])clrObject;
            }

            else
            {
                buffer = ((IEnumerable <byte>)clrObject).ToArray();
            }

            bufferData.bufferLength = buffer.Length;
            bufferData.buffer       = Marshal.AllocHGlobal(buffer.Length * sizeof(byte));

            Marshal.Copy(buffer, 0, bufferData.buffer, bufferData.bufferLength);

            IntPtr destinationPointer = Marshal.AllocHGlobal(V8BufferDataSize);
            Marshal.StructureToPtr(bufferData, destinationPointer, false);

            return(destinationPointer);
        }

        else if (clrObject is IDictionary || clrObject is ExpandoObject)
        {
            v8Type = V8Type.Object;

            IEnumerable           keys;
            int                   keyCount;
            Func <object, object> getValue;

            if (clrObject is ExpandoObject)
            {
                IDictionary <string, object> objectDictionary = (IDictionary <string, object>)clrObject;

                keys     = objectDictionary.Keys;
                keyCount = objectDictionary.Keys.Count;
                getValue = index => objectDictionary[index.ToString()];
            }

            else
            {
                IDictionary objectDictionary = (IDictionary)clrObject;

                keys     = objectDictionary.Keys;
                keyCount = objectDictionary.Keys.Count;
                getValue = index => objectDictionary[index];
            }

            V8ObjectData objectData = new V8ObjectData();
            int          counter    = 0;

            objectData.propertiesCount = keyCount;
            objectData.propertyNames   = Marshal.AllocHGlobal(PointerSize * keyCount);
            objectData.propertyTypes   = Marshal.AllocHGlobal(sizeof(int) * keyCount);
            objectData.propertyValues  = Marshal.AllocHGlobal(PointerSize * keyCount);

            foreach (object key in keys)
            {
                Marshal.WriteIntPtr(objectData.propertyNames, counter * PointerSize, Marshal.StringToHGlobalAnsi(key.ToString()));
                V8Type propertyType;
                Marshal.WriteIntPtr(objectData.propertyValues, counter * PointerSize, MarshalCLRToV8(getValue(key), out propertyType));
                Marshal.WriteInt32(objectData.propertyTypes, counter * sizeof(int), (int)propertyType);

                counter++;
            }

            IntPtr destinationPointer = Marshal.AllocHGlobal(V8ObjectDataSize);
            Marshal.StructureToPtr(objectData, destinationPointer, false);

            return(destinationPointer);
        }

        else if (clrObject is IEnumerable)
        {
            v8Type = V8Type.Array;

            V8ArrayData   arrayData  = new V8ArrayData();
            List <IntPtr> itemValues = new List <IntPtr>();
            List <int>    itemTypes  = new List <int>();

            foreach (object item in (IEnumerable)clrObject)
            {
                V8Type itemType;

                itemValues.Add(MarshalCLRToV8(item, out itemType));
                itemTypes.Add((int)itemType);
            }

            arrayData.arrayLength = itemValues.Count;
            arrayData.itemTypes   = Marshal.AllocHGlobal(sizeof(int) * arrayData.arrayLength);
            arrayData.itemValues  = Marshal.AllocHGlobal(PointerSize * arrayData.arrayLength);

            Marshal.Copy(itemTypes.ToArray(), 0, arrayData.itemTypes, arrayData.arrayLength);
            Marshal.Copy(itemValues.ToArray(), 0, arrayData.itemValues, arrayData.arrayLength);

            IntPtr destinationPointer = Marshal.AllocHGlobal(V8ArrayDataSize);
            Marshal.StructureToPtr(arrayData, destinationPointer, false);

            return(destinationPointer);
        }

        else if (clrObject.GetType().GetTypeInfo().IsGenericType&& clrObject.GetType().GetGenericTypeDefinition() == typeof(Func <,>))
        {
            Func <object, Task <object> > funcObject = clrObject as Func <object, Task <object> >;

            if (funcObject == null)
            {
                throw new Exception("Properties that return Func<> instances must return Func<object, Task<object>> instances");
            }

            v8Type = V8Type.Function;
            return(GCHandle.ToIntPtr(GCHandle.Alloc(funcObject)));
        }

        else
        {
            v8Type = clrObject is Exception
                ? V8Type.Exception
                : V8Type.Object;

            if (clrObject is Exception)
            {
                AggregateException aggregateException = clrObject as AggregateException;

                if (aggregateException?.InnerExceptions != null && aggregateException.InnerExceptions.Count > 0)
                {
                    clrObject = aggregateException.InnerExceptions[0];
                }

                else
                {
                    TargetInvocationException targetInvocationException = clrObject as TargetInvocationException;

                    if (targetInvocationException?.InnerException != null)
                    {
                        clrObject = targetInvocationException.InnerException;
                    }
                }
            }

            List <Tuple <string, Func <object, object> > > propertyAccessors = GetPropertyAccessors(clrObject.GetType());
            V8ObjectData objectData = new V8ObjectData();
            int          counter    = 0;

            objectData.propertiesCount = propertyAccessors.Count;
            objectData.propertyNames   = Marshal.AllocHGlobal(PointerSize * propertyAccessors.Count);
            objectData.propertyTypes   = Marshal.AllocHGlobal(sizeof(int) * propertyAccessors.Count);
            objectData.propertyValues  = Marshal.AllocHGlobal(PointerSize * propertyAccessors.Count);

            foreach (Tuple <string, Func <object, object> > propertyAccessor in propertyAccessors)
            {
                Marshal.WriteIntPtr(objectData.propertyNames, counter * PointerSize, Marshal.StringToHGlobalAnsi(propertyAccessor.Item1));

                V8Type propertyType;

                Marshal.WriteIntPtr(objectData.propertyValues, counter * PointerSize, MarshalCLRToV8(propertyAccessor.Item2(clrObject), out propertyType));
                Marshal.WriteInt32(objectData.propertyTypes, counter * sizeof(int), (int)propertyType);
                counter++;
            }

            IntPtr destinationPointer = Marshal.AllocHGlobal(V8ObjectDataSize);
            Marshal.StructureToPtr(objectData, destinationPointer, false);

            return(destinationPointer);
        }
    }
Exemplo n.º 5
0
    public static object MarshalV8ToCLR(IntPtr v8Object, V8Type objectType)
    {
        switch (objectType)
        {
        case V8Type.String:
            return(Marshal.PtrToStringAnsi(v8Object));

        case V8Type.Object:
            return(V8ObjectToExpando(Marshal.PtrToStructure <V8ObjectData>(v8Object)));

        case V8Type.Boolean:
            return(Marshal.ReadByte(v8Object) != 0);

        case V8Type.Number:
            return(ReadDouble(v8Object));

        case V8Type.Date:
            double ticks = ReadDouble(v8Object);
            return(new DateTime(Convert.ToInt64(ticks) * 10000 + MinDateTimeTicks, DateTimeKind.Utc));

        case V8Type.Null:
            return(null);

        case V8Type.Int32:
            return(Marshal.ReadInt32(v8Object));

        case V8Type.UInt32:
            return((uint)Marshal.ReadInt32(v8Object));

        case V8Type.Function:
            NodejsFunc nodejsFunc = new NodejsFunc(v8Object);
            return(nodejsFunc.GetFunc());

        case V8Type.Array:
            V8ArrayData arrayData = Marshal.PtrToStructure <V8ArrayData>(v8Object);
            object[]    array     = new object[arrayData.arrayLength];

            for (int i = 0; i < arrayData.arrayLength; i++)
            {
                int    itemType         = Marshal.ReadInt32(arrayData.itemTypes, i * sizeof(int));
                IntPtr itemValuePointer = Marshal.ReadIntPtr(arrayData.itemValues, i * PointerSize);

                array[i] = MarshalV8ToCLR(itemValuePointer, (V8Type)itemType);
            }

            return(array);

        case V8Type.Buffer:
            V8BufferData bufferData = Marshal.PtrToStructure <V8BufferData>(v8Object);
            byte[]       buffer     = new byte[bufferData.bufferLength];

            Marshal.Copy(bufferData.buffer, buffer, 0, bufferData.bufferLength);

            return(buffer);

        case V8Type.Exception:
            string message = Marshal.PtrToStringAnsi(v8Object);
            return(new Exception(message));

        default:
            throw new Exception("Unsupported V8 object type: " + objectType + ".");
        }
    }