Permalink
Browse files

Initial commit, good enough for jslinux

  • Loading branch information...
0 parents commit baeaf4d154fd6785eaf4acc536c0c53b1a171f4b @tlrobinson committed May 20, 2011
Showing with 218 additions and 0 deletions.
  1. +59 −0 README.md
  2. +16 −0 package.json
  3. +123 −0 typed-array.cc
  4. +20 −0 wscript
@@ -0,0 +1,59 @@
+v8-typed-array
+==============
+
+Typed Array implementation for V8 and Node.js. Works well enough to run jslinux but otherwise has not been tested. Many missing APIs.
+
+* ArrayBuffer
+* Int8Array
+* Uint8Array
+* Int16Array
+* Uint16Array
+* Int32Array
+* Uint32Array
+* Float32Array
+
+Based Editor's Draft 28 April 2011: http://www.khronos.org/registry/typedarray/specs/latest/
+
+Build
+-----
+
+ node-waf configure build
+
+Or install using NPM (npm install typed-array)
+
+Credits
+-------
+
+Inspired by:
+
+* https://github.com/pufuwozu/node-webgl
+* http://v8.googlecode.com/svn/trunk/samples/shell.cc
+
+TODO
+----
+
+* Implement the rest of the API
+* Bridge to Node's Buffers?
+
+License
+-------
+
+Copyright (C) 2011 by Thomas Robinson (http://tlrobinson.net/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
@@ -0,0 +1,16 @@
+{
+ "name": "typed-array",
+ "description": "Typed Array implementation for V8 and Node.js",
+ "version": "0.0.2",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/tlrobinson/v8-typed-array.git"
+ },
+ "keywords": ["buffer", "typed array", "webgl"],
+ "author": "Tom Robinson <tlrobinson@gmail.com> (http://tlrobinson.net/)",
+ "main": "build/default/typed-array.node",
+ "scripts": { "install": "node-waf configure build" },
+ "engines": {
+ "node": "*"
+ }
+}
@@ -0,0 +1,123 @@
+#include <v8.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+using namespace v8;
+
+#define DEFINE_ARRAY_BUFFER_VIEW(name, type, element_size) \
+ Handle<Value> name(const Arguments& args) {\
+ return CreateArrayBufferView(args, type, element_size);\
+ }
+
+#define INIT_ARRAY_BUFFER_VIEW(name, type, element_size) {\
+ Local<FunctionTemplate> t = FunctionTemplate::New(name); \
+ t->InstanceTemplate()->SetInternalFieldCount(1); \
+ Local<Function> f = t->GetFunction();\
+ f->Set(String::New("BYTES_PER_ELEMENT"), Int32::New(element_size), ReadOnly);\
+ target->Set(String::New(#name), f);}
+
+void ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
+ free(data);
+ object.Dispose();
+}
+
+Persistent<FunctionTemplate> array_buffer_constructor_template;
+
+Handle<Value> ArrayBuffer(const Arguments& args) {
+ if (args.Length() != 1 || !args[0]->IsNumber()) {
+ printf("x=%d y=%d\n", args.Length(), args[0]->IsNumber());
+ return ThrowException(String::New("Invalid ArrayBuffer arguments."));
+ }
+
+ unsigned long length = args[0]->Uint32Value();
+ void* data = malloc(length);
+ memset(data, 0, length);
+
+ Persistent<Object> persistentHandle = Persistent<Object>::New(args.This());
+ persistentHandle.MakeWeak(data, ExternalArrayWeakCallback);
+
+ args.This()->SetPointerInInternalField(0, data);
+ args.This()->SetPointerInInternalField(1, (void*)length);
+ args.This()->Set(String::New("byteLength"), Int32::New(length), ReadOnly);
+
+ return args.This();
+}
+
+Handle<Value> CreateArrayBufferView(const Arguments& args, ExternalArrayType type, int element_size) {
+ Local<Object> arrayBuffer;
+ unsigned long elements = 0;
+ unsigned long byteOffset = 0;
+
+ if (args.Length() == 1) {
+ elements = args[0]->Uint32Value();
+ Local<Value> arg = Int32::New(elements * element_size);
+ arrayBuffer = array_buffer_constructor_template->GetFunction()->NewInstance(1, &arg);
+ } else if (args.Length() >= 1 && args[0]->IsObject()) {
+ arrayBuffer = args[0]->ToObject();
+ if (args.Length() > 1) {
+ byteOffset = args[1]->Uint32Value();
+ if (byteOffset != 0) {
+ return ThrowException(String::New("ArrayBufferView(_, unsigned long offset, _) not implemented."));
+ }
+ }
+ if (args.Length() > 2) {
+ elements = args[2]->Uint32Value();
+ }
+ } else {
+ return ThrowException(String::New("Invalid ArrayBufferView arguments."));
+ }
+
+ void* arrayBufferData = arrayBuffer->GetPointerFromInternalField(0);
+ unsigned long arrayBufferLength = (unsigned long)arrayBuffer->GetPointerFromInternalField(1);
+
+ // FIXME: is 0 a legitimate length?
+ if (elements == 0) {
+ if ((arrayBufferLength - byteOffset) % element_size != 0) {
+ return ThrowException(String::New("Length of the ArrayBuffer minus the byteOffset must be a multiple of the element size."));
+ }
+ elements = (arrayBufferLength - byteOffset) / element_size;
+ }
+
+ if (byteOffset + elements * element_size > arrayBufferLength) {
+ return ThrowException(String::New("Given byteOffset and length references an area beyond the end of the ArrayBuffer."));
+ }
+
+ args.This()->SetHiddenValue(String::New("_buffer"), arrayBuffer);
+ args.This()->SetIndexedPropertiesToExternalArrayData(((int8_t*)arrayBufferData) + byteOffset, type, elements);
+ args.This()->Set(String::New("length"), Int32::New(elements), ReadOnly);
+
+ return args.This();
+}
+
+DEFINE_ARRAY_BUFFER_VIEW(Int8Array, kExternalByteArray, sizeof(int8_t));
+DEFINE_ARRAY_BUFFER_VIEW(Uint8Array, kExternalUnsignedByteArray, sizeof(uint8_t));
+DEFINE_ARRAY_BUFFER_VIEW(Int16Array, kExternalShortArray, sizeof(int16_t));
+DEFINE_ARRAY_BUFFER_VIEW(Uint16Array, kExternalUnsignedShortArray, sizeof(uint16_t));
+DEFINE_ARRAY_BUFFER_VIEW(Int32Array, kExternalIntArray, sizeof(int32_t));
+DEFINE_ARRAY_BUFFER_VIEW(Uint32Array, kExternalUnsignedIntArray, sizeof(uint32_t));
+DEFINE_ARRAY_BUFFER_VIEW(Float32Array, kExternalFloatArray, sizeof(float));
+// DEFINE_ARRAY_BUFFER_VIEW(Float64Array, kExternalDoubleArray, sizeof(double));
+// DEFINE_ARRAY_BUFFER_VIEW(PixelArray, kExternalPixelArray, sizeof(uint8_t));
+
+extern "C" void
+init (Handle<Object> target) {
+ HandleScope scope;
+
+ {
+ array_buffer_constructor_template = Persistent<FunctionTemplate>::New(FunctionTemplate::New(ArrayBuffer));
+ array_buffer_constructor_template->InstanceTemplate()->SetInternalFieldCount(2);
+ Local<Function> f = array_buffer_constructor_template->GetFunction();
+ target->Set(String::New("ArrayBuffer"), f);
+ }
+
+ INIT_ARRAY_BUFFER_VIEW(Int8Array, kExternalByteArray, sizeof(int8_t));
+ INIT_ARRAY_BUFFER_VIEW(Uint8Array, kExternalUnsignedByteArray, sizeof(uint8_t));
+ INIT_ARRAY_BUFFER_VIEW(Int16Array, kExternalShortArray, sizeof(int16_t));
+ INIT_ARRAY_BUFFER_VIEW(Uint16Array, kExternalUnsignedShortArray, sizeof(uint16_t));
+ INIT_ARRAY_BUFFER_VIEW(Int32Array, kExternalIntArray, sizeof(int32_t));
+ INIT_ARRAY_BUFFER_VIEW(Uint32Array, kExternalUnsignedIntArray, sizeof(uint32_t));
+ INIT_ARRAY_BUFFER_VIEW(Float32Array, kExternalFloatArray, sizeof(float));
+ // INIT_ARRAY_BUFFER_VIEW(Float64Array, kExternalDoubleArray, sizeof(double));
+ // INIT_ARRAY_BUFFER_VIEW(PixelArray, kExternalPixelArray, sizeof(uint8_t));
+}
20 wscript
@@ -0,0 +1,20 @@
+from os import mkdir
+from os import symlink
+from os import remove
+from os.path import lexists
+
+srcdir = '.'
+blddir = 'build'
+VERSION = '0.0.2'
+
+def set_options(opt):
+ opt.tool_options('compiler_cxx')
+
+def configure(conf):
+ conf.check_tool('compiler_cxx')
+ conf.check_tool('node_addon')
+
+def build(bld):
+ obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
+ obj.target = 'typed-array'
+ obj.source = 'typed-array.cc'

0 comments on commit baeaf4d

Please sign in to comment.