template<> void ScriptInterface::ToJSVal<Grid<u16> >(JSContext* cx, JS::MutableHandleValue ret, const Grid<u16>& val) { JSAutoRequest rq(cx); u32 length = (u32)(val.m_W * val.m_H); u32 nbytes = (u32)(length * sizeof(u16)); JS::RootedObject objArr(cx, JS_NewUint16Array(cx, length)); memcpy((void*)JS_GetUint16ArrayData(objArr), val.m_Data, nbytes); JS::RootedValue data(cx, JS::ObjectValue(*objArr)); JS::RootedValue w(cx); JS::RootedValue h(cx); ScriptInterface::ToJSVal(cx, &w, val.m_W); ScriptInterface::ToJSVal(cx, &h, val.m_H); JS::RootedObject obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr())); JS_SetProperty(cx, obj, "width", w); JS_SetProperty(cx, obj, "height", h); JS_SetProperty(cx, obj, "data", data); ret.setObject(*obj); }
JSBool JSB_jsval_typedarray_to_dataptr( JSContext *cx, jsval vp, GLsizei *count, void **data, JSArrayBufferViewType t) { JSObject *jsobj; JSBool ok = JS_ValueToObject( cx, vp, &jsobj ); JSB_PRECONDITION2( ok && jsobj, cx, JS_FALSE, "Error converting value to object"); // WebGL supports TypedArray and sequences for some of its APIs. So when converting a TypedArray, we should // also check for a possible non-Typed Array JS object, like a JS Array. if( JS_IsTypedArrayObject( jsobj ) ) { *count = JS_GetTypedArrayLength(jsobj); JSArrayBufferViewType type = JS_GetArrayBufferViewType(jsobj); JSB_PRECONDITION2(t==type, cx, JS_FALSE, "TypedArray type different than expected type"); switch (t) { case js::ArrayBufferView::TYPE_INT8: case js::ArrayBufferView::TYPE_UINT8: *data = JS_GetUint8ArrayData(jsobj); break; case js::ArrayBufferView::TYPE_INT16: case js::ArrayBufferView::TYPE_UINT16: *data = JS_GetUint16ArrayData(jsobj); break; case js::ArrayBufferView::TYPE_INT32: case js::ArrayBufferView::TYPE_UINT32: *data = JS_GetUint32ArrayData(jsobj); break; case js::ArrayBufferView::TYPE_FLOAT32: *data = JS_GetFloat32ArrayData(jsobj); break; default: JSB_PRECONDITION2(false, cx, JS_FALSE, "Unsupported typedarray type"); break; } } else if( JS_IsArrayObject(cx, jsobj)) { // Slow... avoid it. Use TypedArray instead, but the spec says that it can receive // Sequence<> as well. uint32_t length; JS_GetArrayLength(cx, jsobj, &length); for( uint32_t i=0; i<length; i++ ) { jsval valarg; JS_GetElement(cx, jsobj, i, &valarg); switch(t) { case js::ArrayBufferView::TYPE_INT32: case js::ArrayBufferView::TYPE_UINT32: { uint32_t e = JSVAL_TO_INT(valarg); ((uint32_t*)data)[i] = e; break; } case js::ArrayBufferView::TYPE_FLOAT32: { double e = JSVAL_TO_DOUBLE(valarg); ((GLfloat*)data)[i] = (GLfloat)e; break; } default: JSB_PRECONDITION2(false, cx, JS_FALSE, "Unsupported typedarray type"); break; } } } else JSB_PRECONDITION2(false, cx, JS_FALSE, "Object shall be a TypedArray or Sequence"); return JS_TRUE; }