Module: wine Branch: master Commit: aa2bd097d63b6dbc9376085507ab09404cc96314 URL: https://gitlab.winehq.org/wine/wine/-/commit/aa2bd097d63b6dbc9376085507ab094...
Author: Gabriel Ivăncescu gabrielopcode@gmail.com Date: Mon Feb 12 17:47:11 2024 +0200
jscript: Implement DataView getters.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
---
dlls/jscript/arraybuf.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++ dlls/mshtml/tests/es5.js | 65 +++++++++++++++++-- 2 files changed, 219 insertions(+), 5 deletions(-)
diff --git a/dlls/jscript/arraybuf.c b/dlls/jscript/arraybuf.c index 66d41509ff5..56bda2a73fd 100644 --- a/dlls/jscript/arraybuf.c +++ b/dlls/jscript/arraybuf.c @@ -236,6 +236,45 @@ static inline void copy_type_data(void *dst, const void *src, unsigned type_size out[i] = in[type_size - i - 1]; }
+static HRESULT get_data(script_ctx_t *ctx, jsval_t vthis, unsigned argc, jsval_t *argv, unsigned type_size, void *ret) +{ + BOOL little_endian = FALSE; + DataViewInstance *view; + HRESULT hres; + DWORD offset; + BYTE *data; + double n; + + if(!(view = dataview_this(vthis))) + return JS_E_NOT_DATAVIEW; + if(!argc || is_undefined(argv[0])) + return JS_E_DATAVIEW_NO_ARGUMENT; + + hres = to_integer(ctx, argv[0], &n); + if(FAILED(hres)) + return hres; + + if(n < 0.0 || n + type_size > view->size) + return JS_E_DATAVIEW_INVALID_ACCESS; + + offset = n; + data = &view->buffer->buf[view->offset + offset]; + + if(type_size == 1) { + *(BYTE*)ret = data[0]; + return S_OK; + } + + if(argc > 1) { + hres = to_boolean(argv[1], &little_endian); + if(FAILED(hres)) + return hres; + } + + copy_type_data(ret, data, type_size, little_endian); + return S_OK; +} + static HRESULT set_data(script_ctx_t *ctx, jsval_t vthis, unsigned argc, jsval_t *argv, unsigned type_size, const void *val) { BOOL little_endian = FALSE; @@ -275,6 +314,118 @@ static HRESULT set_data(script_ctx_t *ctx, jsval_t vthis, unsigned argc, jsval_t return S_OK; }
+static HRESULT DataView_getFloat32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + HRESULT hres; + float v; + + TRACE("\n"); + + hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v); + if(FAILED(hres)) + return hres; + if(r) *r = jsval_number(v); + return S_OK; +} + +static HRESULT DataView_getFloat64(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + HRESULT hres; + double v; + + TRACE("\n"); + + hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v); + if(FAILED(hres)) + return hres; + if(r) *r = jsval_number(v); + return S_OK; +} + +static HRESULT DataView_getInt8(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + HRESULT hres; + INT8 v; + + TRACE("\n"); + + hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v); + if(FAILED(hres)) + return hres; + if(r) *r = jsval_number(v); + return S_OK; +} + +static HRESULT DataView_getInt16(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + HRESULT hres; + INT16 v; + + TRACE("\n"); + + hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v); + if(FAILED(hres)) + return hres; + if(r) *r = jsval_number(v); + return S_OK; +} + +static HRESULT DataView_getInt32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + HRESULT hres; + INT32 v; + + TRACE("\n"); + + hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v); + if(FAILED(hres)) + return hres; + if(r) *r = jsval_number(v); + return S_OK; +} + +static HRESULT DataView_getUint8(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + HRESULT hres; + UINT8 v; + + TRACE("\n"); + + hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v); + if(FAILED(hres)) + return hres; + if(r) *r = jsval_number(v); + return S_OK; +} + +static HRESULT DataView_getUint16(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + HRESULT hres; + UINT16 v; + + TRACE("\n"); + + hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v); + if(FAILED(hres)) + return hres; + if(r) *r = jsval_number(v); + return S_OK; +} + +static HRESULT DataView_getUint32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + HRESULT hres; + UINT32 v; + + TRACE("\n"); + + hres = get_data(ctx, vthis, argc, argv, sizeof(v), &v); + if(FAILED(hres)) + return hres; + if(r) *r = jsval_number(v); + return S_OK; +} + static HRESULT DataView_setFloat32(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { HRESULT hres; @@ -382,6 +533,14 @@ static HRESULT DataView_setInt32(script_ctx_t *ctx, jsval_t vthis, WORD flags, u }
static const builtin_prop_t DataView_props[] = { + {L"getFloat32", DataView_getFloat32, PROPF_METHOD|1}, + {L"getFloat64", DataView_getFloat64, PROPF_METHOD|1}, + {L"getInt16", DataView_getInt16, PROPF_METHOD|1}, + {L"getInt32", DataView_getInt32, PROPF_METHOD|1}, + {L"getInt8", DataView_getInt8, PROPF_METHOD|1}, + {L"getUint16", DataView_getUint16, PROPF_METHOD|1}, + {L"getUint32", DataView_getUint32, PROPF_METHOD|1}, + {L"getUint8", DataView_getUint8, PROPF_METHOD|1}, {L"setFloat32", DataView_setFloat32, PROPF_METHOD|1}, {L"setFloat64", DataView_setFloat64, PROPF_METHOD|1}, {L"setInt16", DataView_setInt16, PROPF_METHOD|1}, diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 1801df9663c..a18fea6476a 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -1751,10 +1751,10 @@ sync_test("ArrayBuffers & Views", function() {
test_own_props("DataView.prototype", [ "buffer", "byteLength", "byteOffset", - "setInt8", "setUint8", - "setInt16", "setUint16", - "setInt32", "setUint32", - "setFloat32", "setFloat64" + "getInt8", "setInt8", "getUint8", "setUint8", + "getInt16", "setInt16", "getUint16", "setUint16", + "getInt32", "setInt32", "getUint32", "setUint32", + "getFloat32", "setFloat32", "getFloat64", "setFloat64" ]);
r = Object.prototype.toString.call(new DataView(buf)); @@ -1869,8 +1869,51 @@ sync_test("ArrayBuffers & Views", function() { ok(view.byteLength === 10, "DataView(buf).byteLength = " + view.byteLength); ok(view.byteOffset === 0, "DataView(buf).byteOffset = " + view.byteOffset);
+ for(i = 0; i < 10; i++) { + r = view.getInt8(i); + ok(r === 0, "view byte " + i + " = " + r); + } + for(i = 0; i < types.length; i++) { - var method = "set" + types[i][0], offs = 11 - types[i][1]; + var method = "get" + types[i][0], offs = 11 - types[i][1]; + r = DataView.prototype[method].length; + ok(r === 1, "DataView.prototype." + method + ".length = " + r); + try { + view[method](); + ok(false, "view." + method + "() did not throw exception"); + }catch(ex) { + var n = ex.number >>> 0; + ok(n === JS_E_DATAVIEW_NO_ARGUMENT, "view." + method + "() threw " + n); + } + try { + view[method](-1); + ok(false, "view." + method + "(-1) did not throw exception"); + }catch(ex) { + var n = ex.number >>> 0; + ok(n === JS_E_DATAVIEW_INVALID_ACCESS, "view." + method + "(-1) threw " + n); + } + try { + view[method](offs); + ok(false, "view." + method + "(" + offs + ") did not throw exception"); + }catch(ex) { + var n = ex.number >>> 0; + ok(n === JS_E_DATAVIEW_INVALID_ACCESS, "view." + method + "(" + offs + ") threw " + n); + } + try { + view[method].call(null, 0); + ok(false, "view." + method + "(0) with null context did not throw exception"); + }catch(ex) { + var n = ex.number >>> 0; + ok(n === JS_E_NOT_DATAVIEW, "view." + method + "(0) with null context threw " + n); + } + try { + view[method].call({}, 0); + ok(false, "view." + method + "(0) with an object context did not throw exception"); + }catch(ex) { + var n = ex.number >>> 0; + ok(n === JS_E_NOT_DATAVIEW, "view." + method + "(0) with an object context threw " + n); + } + method = "set" + types[i][0]; r = DataView.prototype[method].length; ok(r === 1, "DataView.prototype." + method + ".length = " + r); try { @@ -1919,14 +1962,26 @@ sync_test("ArrayBuffers & Views", function() {
r = view.setInt8(1, -257); ok(r === undefined, "view.setInt8(1, -1) returned " + r); + r = view.getUint16(0); + ok(r === 255, "view.getUint16(0) returned " + r); + r = view.getUint16(0, true); + ok(r === 65280, "view.getUint16(0, true) returned " + r); r = view.setUint32(2, "12345678", true); ok(r === undefined, "view.setUint32(2, '12345678', true) returned " + r); + r = view.getInt32(1); + ok(r === -11640388, "view.getInt32(1) returned " + r); r = view.setInt16(3, 65535, true); ok(r === undefined, "view.setInt16(3, 65535) returned " + r); + r = view.getUint16(3); + ok(r === 65535, "view.getUint16(3) returned " + r); r = view.setUint32(0, -2, true); ok(r === undefined, "view.setUint32(0, -2) returned " + r); + r = view.getInt32(0, true); + ok(r === -2, "view.getInt32(0) returned " + r); r = view.setFloat32(6, 1234.5, true); ok(r === undefined, "view.setFloat32(6, 1234.5) returned " + r); + r = view2.getFloat32(0, true); + ok(r === 1234.5, "view2.getFloat32(0) returned " + r);
/* setters differing only in signedness have identical behavior, but they're not the same methods */ ok(view.setInt8 !== view.setUint8, "setInt8 and setUint8 are the same method");