From: Gabriel Ivăncescu gabrielopcode@gmail.com
--- dlls/jscript/arraybuf.c | 111 ++++++++++++++++++++++++++++++ dlls/jscript/jscript.h | 16 ++++- dlls/jscript/object.c | 8 +++ dlls/mshtml/tests/documentmode.js | 34 +++++++-- dlls/mshtml/tests/es5.js | 8 +++ 5 files changed, 172 insertions(+), 5 deletions(-)
diff --git a/dlls/jscript/arraybuf.c b/dlls/jscript/arraybuf.c index cb3eef271de..82df57243eb 100644 --- a/dlls/jscript/arraybuf.c +++ b/dlls/jscript/arraybuf.c @@ -684,6 +684,108 @@ static const builtin_info_t DataViewConstr_info = { .call = Function_value, };
+/* NOTE: Keep in sync with the JSCLASS ordering of typed arrays */ +#define ALL_TYPED_ARRAYS \ + X(Int8Array) \ + X(Int16Array) \ + X(Int32Array) \ + X(Uint8Array) \ + X(Uint16Array) \ + X(Uint32Array) \ + X(Float32Array) \ + X(Float64Array) + +enum { +#define X(name) name ##_desc_idx, +ALL_TYPED_ARRAYS +#undef X +}; + +static HRESULT TypedArray_get_buffer(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) +{ + FIXME("%p\n", jsthis); + return E_NOTIMPL; +} + +static HRESULT TypedArray_get_byteLength(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) +{ + FIXME("%p\n", jsthis); + return E_NOTIMPL; +} + +static HRESULT TypedArray_get_byteOffset(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) +{ + FIXME("%p\n", jsthis); + return E_NOTIMPL; +} + +static HRESULT TypedArray_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r) +{ + FIXME("%p\n", jsthis); + return E_NOTIMPL; +} + +#define X(name) \ +static HRESULT name##_set(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) \ +{ \ + FIXME("\n"); \ + return E_NOTIMPL; \ +} \ + \ +static HRESULT name##_subarray(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) \ +{ \ + FIXME("\n"); \ + return E_NOTIMPL; \ +} \ + \ +static const builtin_prop_t name##_props[] = { \ + {L"buffer", NULL, 0, TypedArray_get_buffer}, \ + {L"byteLength", NULL, 0, TypedArray_get_byteLength}, \ + {L"byteOffset", NULL, 0, TypedArray_get_byteOffset}, \ + {L"length", NULL, 0, TypedArray_get_length}, \ + {L"set", name##_set, PROPF_METHOD|2}, \ + {L"subarray", name##_subarray, PROPF_METHOD|2}, \ +}; \ + \ +static const builtin_info_t name##_info = \ +{ \ + .class = FIRST_TYPEDARRAY_JSCLASS + name ##_desc_idx, \ + .props_cnt = ARRAY_SIZE(name##_props), \ + .props = name##_props, \ +}; \ + \ +static HRESULT name ## Constr_value(script_ctx_t *ctx, jsval_t jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) \ +{ \ + FIXME("\n"); \ + return E_NOTIMPL; \ +} +ALL_TYPED_ARRAYS +#undef X + +static const builtin_info_t TypedArrayConstr_info = { + .class = JSCLASS_FUNCTION, + .call = Function_value, +}; + +static HRESULT init_typed_array_constructor(script_ctx_t *ctx, builtin_invoke_t func, const WCHAR *name, + const builtin_info_t *info, unsigned int type_idx) +{ + jsdisp_t *prototype; + HRESULT hres; + + hres = create_dispex(ctx, info, ctx->object_prototype, &prototype); + if(FAILED(hres)) + return hres; + + hres = create_builtin_constructor(ctx, func, name, &TypedArrayConstr_info, PROPF_CONSTR|1, prototype, &ctx->typedarr_constr[type_idx]); + jsdisp_release(prototype); + if(FAILED(hres)) + return hres; + + return jsdisp_define_data_property(ctx->global, name, PROPF_CONFIGURABLE | PROPF_WRITABLE, + jsval_obj(ctx->typedarr_constr[type_idx])); +} + HRESULT init_arraybuf_constructors(script_ctx_t *ctx) { static const struct { @@ -766,6 +868,15 @@ HRESULT init_arraybuf_constructors(script_ctx_t *ctx)
hres = jsdisp_define_data_property(ctx->global, L"DataView", PROPF_CONFIGURABLE | PROPF_WRITABLE, jsval_obj(ctx->dataview_constr)); + if(FAILED(hres)) + return hres; + +#define X(name) \ + hres = init_typed_array_constructor(ctx, name##Constr_value, L"" #name, &name##_info, name##_desc_idx); \ + if(FAILED(hres)) \ + return hres; + ALL_TYPED_ARRAYS +#undef X
return hres; } diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 5e6685547ab..5a8910565b3 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -100,12 +100,25 @@ typedef enum { JSCLASS_JSON, JSCLASS_ARRAYBUFFER, JSCLASS_DATAVIEW, + JSCLASS_INT8ARRAY, + JSCLASS_INT16ARRAY, + JSCLASS_INT32ARRAY, + JSCLASS_UINT8ARRAY, + JSCLASS_UINT16ARRAY, + JSCLASS_UINT32ARRAY, + JSCLASS_FLOAT32ARRAY, + JSCLASS_FLOAT64ARRAY, JSCLASS_MAP, JSCLASS_SET, JSCLASS_WEAKMAP, JSCLASS_HOST, + + FIRST_TYPEDARRAY_JSCLASS = JSCLASS_INT8ARRAY, + LAST_TYPEDARRAY_JSCLASS = JSCLASS_FLOAT64ARRAY, } jsclass_t;
+enum { NUM_TYPEDARRAY_TYPES = LAST_TYPEDARRAY_JSCLASS - FIRST_TYPEDARRAY_JSCLASS + 1 }; + jsdisp_t *iface_to_jsdisp(IDispatch*);
typedef HRESULT (*builtin_invoke_t)(script_ctx_t*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*); @@ -420,11 +433,12 @@ struct _script_ctx_t { jsdisp_t *vbarray_constr; jsdisp_t *arraybuf_constr; jsdisp_t *dataview_constr; + jsdisp_t *typedarr_constr[NUM_TYPEDARRAY_TYPES]; jsdisp_t *map_prototype; jsdisp_t *set_prototype; jsdisp_t *weakmap_prototype; }; - jsdisp_t *global_objects[25]; + jsdisp_t *global_objects[25 + NUM_TYPEDARRAY_TYPES]; }; }; C_ASSERT(RTL_SIZEOF_THROUGH_FIELD(script_ctx_t, weakmap_prototype) == RTL_SIZEOF_THROUGH_FIELD(script_ctx_t, global_objects)); diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index a1ba990695b..bda4d28ecef 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -53,6 +53,14 @@ HRESULT Object_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned a L"[object Object]", L"[object ArrayBuffer]", L"[object Object]", + L"[object Int8Array]", + L"[object Int16Array]", + L"[object Int32Array]", + L"[object Uint8Array]", + L"[object Uint16Array]", + L"[object Uint32Array]", + L"[object Float32Array]", + L"[object Float64Array]", L"[object Object]", L"[object Object]", L"[object Object]", diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index ace0bcad06e..be141928453 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -4556,6 +4556,32 @@ sync_test("constructors", function() { HTMLMetaElement.prototype.constructor = old; });
+sync_test("typed arrays", function() { + if (document.documentMode < 10) + return; + + function check(constr) { + ok(Object.getPrototypeOf(constr) === Function.prototype, "unexpected " + constr + " porototype " + Object.getPrototypeOf(constr)); + ok(Object.getPrototypeOf(constr.prototype) === Object.prototype, + "unexpected " + constr + " porototype's prototype " + Object.getPrototypeOf(constr.prototype)); + test_own_props(constr, constr, + ["BYTES_PER_ELEMENT", "arguments", "caller", "length", "prototype"], + ["BYTES_PER_ELEMENT", "arguments", "caller"]); + test_own_props(constr.prototype, constr + ".prototype", + ["BYTES_PER_ELEMENT", "buffer", "byteLength", "byteOffset", "constructor", "length", "set", "subarray"], + ["BYTES_PER_ELEMENT"]); + } + + check(Int8Array); + check(Int16Array); + check(Int32Array); + check(Uint8Array); + check(Uint16Array); + check(Uint32Array); + check(Float32Array); + check(Float64Array); +}); + async_test("window own props", function() { if(!Object.getOwnPropertyNames) { next_test(); @@ -4631,7 +4657,7 @@ async_test("window own props", function() { "CompositionEvent", "ControlRangeCollection", "Coordinates", ["Crypto",11], ["CryptoOperation",11], "CSSFontFaceRule", "CSSImportRule", ["CSSKeyframeRule",10], ["CSSKeyframesRule",10], "CSSMediaRule", "CSSNamespaceRule", "CSSPageRule", "CSSRuleList", "DataTransfer", "Debug", ["DeviceAcceleration",11], ["DeviceMotionEvent",11], ["DeviceOrientationEvent",11], ["DeviceRotationRate",11], ["DOMError",10], "DOMException", ["DOMSettableTokenList",10], ["DOMStringList",10], ["DOMStringMap",11], - "DragEvent", ["ErrorEvent",10], "EventException", ["EXT_texture_filter_anisotropic",11], ["File",10], ["FileList",10], ["FileReader",10], ["Float32Array",10], ["Float64Array",10], + "DragEvent", ["ErrorEvent",10], "EventException", ["EXT_texture_filter_anisotropic",11], ["File",10], ["FileList",10], ["FileReader",10], "FocusEvent", ["FormData",10], "Geolocation", "GetObject", ["HTMLAllCollection",11], "HTMLAppletElement", "HTMLAreasCollection", "HTMLAudioElement", "HTMLBaseElement", "HTMLBaseFontElement", "HTMLBGSoundElement", "HTMLBlockElement", "HTMLBRElement", "HTMLCanvasElement", ["HTMLDataListElement",10], "HTMLDDElement", "HTMLDirectoryElement", "HTMLDivElement", "HTMLDListElement", "HTMLDTElement", "HTMLFieldSetElement", "HTMLFontElement", "HTMLFrameSetElement", "HTMLHeadingElement", "HTMLHRElement", "HTMLIsIndexElement", @@ -4639,7 +4665,7 @@ async_test("window own props", function() { "HTMLOptGroupElement", "HTMLParagraphElement", "HTMLParamElement", "HTMLPhraseElement", "HTMLPreElement", ["HTMLProgressElement",10], "HTMLQuoteElement", "HTMLSourceElement", "HTMLSpanElement", "HTMLTableCaptionElement", "HTMLTableColElement", "HTMLTableHeaderCellElement", "HTMLTableSectionElement", ["HTMLTrackElement",10], "HTMLUListElement", "HTMLVideoElement", ["IDBCursor",10], ["IDBCursorWithValue",10], ["IDBDatabase",10], ["IDBFactory",10], ["IDBIndex",10], ["IDBKeyRange",10], ["IDBObjectStore",10], ["IDBOpenDBRequest",10], - ["IDBRequest",10], ["IDBTransaction",10], ["IDBVersionChangeEvent",10], "ImageData", ["Int16Array",10], ["Int32Array",10], ["Int8Array",10], ["Intl",11], ["Key",11], ["KeyOperation",11], + ["IDBRequest",10], ["IDBTransaction",10], ["IDBVersionChangeEvent",10], "ImageData", ["Intl",11], ["Key",11], ["KeyOperation",11], ["KeyPair",11], "Location", "MediaError", "MediaList", ["MediaSource",11], ["MessageChannel",10], ["MessagePort",10], ["MimeType",11], ["MimeTypeArray",9,10], "MouseWheelEvent", "MSBehaviorUrnsCollection", ["MSBlobBuilder",10], "MSCompatibleInfo", "MSCompatibleInfoCollection", ["MSCSSMatrix",10], ["MSGesture",10], ["MSGestureEvent",10], ["MSGraphicsTrust",11], ["MSInputMethodContext",11], ["MSManipulationEvent",10], ["MSMediaKeyError",11], ["MSMediaKeyMessageEvent",11], ["MSMediaKeyNeededEvent",11], ["MSMediaKeys",11], ["MSMediaKeySession",11], @@ -4662,8 +4688,8 @@ async_test("window own props", function() { "SVGPatternElement", "SVGPoint", "SVGPointList", "SVGPolygonElement", "SVGPolylineElement", "SVGPreserveAspectRatio", "SVGRadialGradientElement", "SVGRect", "SVGRectElement", "SVGScriptElement", "SVGStopElement", "SVGStringList", "SVGStyleElement", "SVGSwitchElement", "SVGSymbolElement", "SVGTextElement", "SVGTextPathElement", "SVGTitleElement", "SVGTransform", "SVGTransformList", "SVGUnitTypes", "SVGUseElement", "SVGViewElement", "SVGZoomAndPan", "SVGZoomEvent", "TextEvent", "TextMetrics", "TextRangeCollection", ["TextTrack",10], - ["TextTrackCue",10], ["TextTrackCueList",10], ["TextTrackList",10], "TimeRanges", ["TrackEvent",10], ["TransitionEvent",10], "TreeWalker", ["Uint16Array",10], ["Uint32Array",10], - ["Uint8Array",10], ["Uint8ClampedArray",11], ["URL",10], ["ValidityState",10], ["VideoPlaybackQuality",11], ["WebGLActiveInfo",11], ["WebGLBuffer",11], ["WebGLContextEvent",11], + ["TextTrackCue",10], ["TextTrackCueList",10], ["TextTrackList",10], "TimeRanges", ["TrackEvent",10], ["TransitionEvent",10], "TreeWalker", + ["Uint8ClampedArray",11], ["URL",10], ["ValidityState",10], ["VideoPlaybackQuality",11], ["WebGLActiveInfo",11], ["WebGLBuffer",11], ["WebGLContextEvent",11], ["WebGLFramebuffer",11], ["WebGLObject",11], ["WebGLProgram",11], ["WebGLRenderbuffer",11], ["WebGLRenderingContext",11], ["WebGLShader",11], ["WebGLShaderPrecisionFormat",11], ["WebGLTexture",11], ["WebGLUniformLocation",11], ["WEBGL_compressed_texture_s3tc",11], ["WEBGL_debug_renderer_info",11], ["WebSocket",10], "WheelEvent", ["Worker",10], ["XMLHttpRequestEventTarget",10], "XMLSerializer" diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 402be2f9d9a..ef2c80a2c07 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2186,7 +2186,12 @@ sync_test("globals override", function() { "Error", "escape", "EvalError", + "Float32Array", + "Float64Array", "Function", + "Int8Array", + "Int16Array", + "Int32Array", "isFinite", "isNaN", "JSON", @@ -2206,6 +2211,9 @@ sync_test("globals override", function() { "String", "SyntaxError", "TypeError", + "Uint8Array", + "Uint16Array", + "Uint32Array", "unescape", "URIError", "VBArray",