зеркало из https://github.com/mozilla/gecko-dev.git
Bug 999755 - Add neuter() variants to vary data pointer, r=Waldo
This commit is contained in:
Родитель
15fc04d4b4
Коммит
8b797a29fd
|
@ -1463,8 +1463,13 @@ Neuter(JSContext *cx, unsigned argc, jsval *vp)
|
|||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (args.length() != 2) {
|
||||
JS_ReportError(cx, "wrong number of arguments to neuter()");
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedObject obj(cx);
|
||||
if (!JS_ValueToObject(cx, args.get(0), &obj))
|
||||
if (!JS_ValueToObject(cx, args[0], &obj))
|
||||
return false;
|
||||
|
||||
if (!obj) {
|
||||
|
@ -1472,7 +1477,23 @@ Neuter(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!JS_NeuterArrayBuffer(cx, obj))
|
||||
NeuterDataDisposition changeData;
|
||||
RootedString str(cx, JS::ToString(cx, args[1]));
|
||||
if (!str)
|
||||
return false;
|
||||
JSAutoByteString dataDisposition(cx, str);
|
||||
if (!dataDisposition)
|
||||
return false;
|
||||
if (strcmp(dataDisposition.ptr(), "same-data") == 0) {
|
||||
changeData = KeepData;
|
||||
} else if (strcmp(dataDisposition.ptr(), "change-data") == 0) {
|
||||
changeData = ChangeData;
|
||||
} else {
|
||||
JS_ReportError(cx, "unknown parameter 2 to neuter()");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JS_NeuterArrayBuffer(cx, obj, changeData))
|
||||
return false;
|
||||
|
||||
args.rval().setUndefined();
|
||||
|
@ -1748,8 +1769,11 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = {
|
|||
" Deserialize data generated by serialize."),
|
||||
|
||||
JS_FN_HELP("neuter", Neuter, 1, 0,
|
||||
"neuter(buffer)",
|
||||
" Neuter the given ArrayBuffer object as if it had been transferred to a WebWorker."),
|
||||
"neuter(buffer, \"change-data\"|\"same-data\")",
|
||||
" Neuter the given ArrayBuffer object as if it had been transferred to a\n"
|
||||
" WebWorker. \"change-data\" will update the internal data pointer.\n"
|
||||
" \"same-data\" will leave it set to its original value, to mimic eg\n"
|
||||
" asm.js ArrayBuffer neutering."),
|
||||
|
||||
JS_FN_HELP("workerThreadCount", WorkerThreadCount, 0, 0,
|
||||
"workerThreadCount()",
|
||||
|
|
|
@ -8,16 +8,17 @@ load(libdir + "asserts.js")
|
|||
|
||||
var {StructType, uint32, Object, Any, storage, objectType} = TypedObject;
|
||||
|
||||
function main() { // once a C programmer, always a C programmer.
|
||||
function main(variant) { // once a C programmer, always a C programmer.
|
||||
var Uints = uint32.array();
|
||||
var Unit = new StructType({}); // Empty struct type
|
||||
var buffer = new ArrayBuffer(0); // Empty buffer
|
||||
var p = new Unit(buffer); // OK
|
||||
neuter(buffer);
|
||||
neuter(buffer, variant);
|
||||
assertThrowsInstanceOf(() => new Unit(buffer), TypeError,
|
||||
"Able to instantiate atop neutered buffer");
|
||||
assertThrowsInstanceOf(() => new Uints(buffer, 0), TypeError,
|
||||
"Able to instantiate atop neutered buffer");
|
||||
}
|
||||
|
||||
main();
|
||||
main("same-data");
|
||||
main("change-data");
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
if (!this.hasOwnProperty("TypedObject"))
|
||||
quit();
|
||||
|
||||
x = ArrayBuffer();
|
||||
neuter(x);
|
||||
neuter(x, "same-data");
|
||||
Uint32Array(x);
|
||||
gc();
|
||||
|
||||
x = ArrayBuffer();
|
||||
neuter(x, "change-data");
|
||||
Uint32Array(x);
|
||||
gc();
|
||||
|
|
|
@ -8,13 +8,13 @@ function readFromS(s) {
|
|||
return s.f + s.g;
|
||||
}
|
||||
|
||||
function main() {
|
||||
function main(variant) {
|
||||
var s = new S({f: 22, g: 44});
|
||||
|
||||
for (var i = 0; i < 10; i++)
|
||||
assertEq(readFromS(s), 66);
|
||||
|
||||
neuter(storage(s).buffer);
|
||||
neuter(storage(s).buffer, variant);
|
||||
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var ok = false;
|
||||
|
@ -29,4 +29,5 @@ function main() {
|
|||
}
|
||||
}
|
||||
|
||||
main();
|
||||
main("same-data");
|
||||
main("change-data");
|
||||
|
|
|
@ -14,7 +14,7 @@ function readFrom(a) {
|
|||
return a[2].f + a[2].g;
|
||||
}
|
||||
|
||||
function main() {
|
||||
function main(variant) {
|
||||
var a = new A();
|
||||
a[2].f = 22;
|
||||
a[2].g = 44;
|
||||
|
@ -22,7 +22,7 @@ function main() {
|
|||
for (var i = 0; i < 10; i++)
|
||||
assertEq(readFrom(a), 66);
|
||||
|
||||
neuter(storage(a).buffer);
|
||||
neuter(storage(a).buffer, variant);
|
||||
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var ok = false;
|
||||
|
@ -37,4 +37,5 @@ function main() {
|
|||
}
|
||||
}
|
||||
|
||||
main();
|
||||
main("same-data");
|
||||
main("change-data");
|
||||
|
|
|
@ -12,7 +12,7 @@ function readFrom(a) {
|
|||
return a[2].f + a[2].g;
|
||||
}
|
||||
|
||||
function main() {
|
||||
function main(variant) {
|
||||
var a = new A(10);
|
||||
a[2].f = 22;
|
||||
a[2].g = 44;
|
||||
|
@ -20,7 +20,7 @@ function main() {
|
|||
for (var i = 0; i < 10; i++)
|
||||
assertEq(readFrom(a), 66);
|
||||
|
||||
neuter(storage(a).buffer);
|
||||
neuter(storage(a).buffer, variant);
|
||||
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var ok = false;
|
||||
|
@ -35,4 +35,5 @@ function main() {
|
|||
}
|
||||
}
|
||||
|
||||
main();
|
||||
main("same-data");
|
||||
main("change-data");
|
||||
|
|
|
@ -26,7 +26,7 @@ if (isAsmJSCompilationAvailable())
|
|||
set(4, 42);
|
||||
assertEq(get(4), 42);
|
||||
|
||||
neuter(buffer);
|
||||
neuter(buffer, "same-data");
|
||||
|
||||
// These operations may throw internal errors
|
||||
try {
|
||||
|
@ -56,7 +56,7 @@ var buffer = i32.buffer;
|
|||
var threw = false;
|
||||
function ffi() {
|
||||
try {
|
||||
neuter(buffer);
|
||||
neuter(buffer, "same-data");
|
||||
} catch (e) {
|
||||
assertEq(String(e).indexOf("InternalError"), 0);
|
||||
threw = true;
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
var ab = new ArrayBuffer(4);
|
||||
var i32 = new Int32Array(ab);
|
||||
i32[0] = 42;
|
||||
neuter(ab);
|
||||
assertEq(i32.length, 0);
|
||||
assertEq(ab.byteLength, 0);
|
||||
assertEq(i32[0], undefined);
|
||||
for (var variant of ["same-data", "change-data"]) {
|
||||
var ab = new ArrayBuffer(4);
|
||||
var i32 = new Int32Array(ab);
|
||||
i32[0] = 42;
|
||||
neuter(ab, variant);
|
||||
assertEq(i32.length, 0);
|
||||
assertEq(ab.byteLength, 0);
|
||||
assertEq(i32[0], undefined);
|
||||
|
||||
var ab = new ArrayBuffer(12);
|
||||
var i32 = new Int32Array(ab);
|
||||
i32[0] = 42;
|
||||
neuter(ab);
|
||||
assertEq(i32.length, 0);
|
||||
assertEq(ab.byteLength, 0);
|
||||
assertEq(i32[0], undefined);
|
||||
var ab = new ArrayBuffer(12);
|
||||
var i32 = new Int32Array(ab);
|
||||
i32[0] = 42;
|
||||
neuter(ab, variant);
|
||||
assertEq(i32.length, 0);
|
||||
assertEq(ab.byteLength, 0);
|
||||
assertEq(i32[0], undefined);
|
||||
|
||||
var ab = new ArrayBuffer(4096);
|
||||
var i32 = new Int32Array(ab);
|
||||
i32[0] = 42;
|
||||
neuter(ab);
|
||||
assertEq(i32.length, 0);
|
||||
assertEq(ab.byteLength, 0);
|
||||
assertEq(i32[0], undefined);
|
||||
var ab = new ArrayBuffer(4096);
|
||||
var i32 = new Int32Array(ab);
|
||||
i32[0] = 42;
|
||||
neuter(ab, variant);
|
||||
assertEq(i32.length, 0);
|
||||
assertEq(ab.byteLength, 0);
|
||||
assertEq(i32[0], undefined);
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ bool TestNeuterObject()
|
|||
{
|
||||
JS::RootedObject obj(cx, CreateNewObject(8, 12));
|
||||
CHECK(obj);
|
||||
JS_NeuterArrayBuffer(cx, obj);
|
||||
JS_NeuterArrayBuffer(cx, obj, ChangeData);
|
||||
CHECK(isNeutered(obj));
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1446,11 +1446,17 @@ JS_GetArrayBufferViewData(JSObject *obj);
|
|||
extern JS_FRIEND_API(JSObject *)
|
||||
JS_GetArrayBufferViewBuffer(JSContext *cx, JSObject *obj);
|
||||
|
||||
typedef enum {
|
||||
ChangeData,
|
||||
KeepData
|
||||
} NeuterDataDisposition;
|
||||
|
||||
/*
|
||||
* Set an ArrayBuffer's length to 0 and neuter all of its views.
|
||||
*/
|
||||
extern JS_FRIEND_API(bool)
|
||||
JS_NeuterArrayBuffer(JSContext *cx, JS::HandleObject obj);
|
||||
JS_NeuterArrayBuffer(JSContext *cx, JS::HandleObject obj,
|
||||
NeuterDataDisposition changeData);
|
||||
|
||||
/*
|
||||
* Check whether obj supports JS_GetDataView* APIs.
|
||||
|
|
|
@ -1024,7 +1024,8 @@ JS_GetStableArrayBufferData(JSContext *cx, HandleObject objArg)
|
|||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
JS_NeuterArrayBuffer(JSContext *cx, HandleObject obj)
|
||||
JS_NeuterArrayBuffer(JSContext *cx, HandleObject obj,
|
||||
NeuterDataDisposition changeData)
|
||||
{
|
||||
if (!obj->is<ArrayBufferObject>()) {
|
||||
JS_ReportError(cx, "ArrayBuffer object required");
|
||||
|
@ -1038,7 +1039,16 @@ JS_NeuterArrayBuffer(JSContext *cx, HandleObject obj)
|
|||
return false;
|
||||
}
|
||||
|
||||
ArrayBufferObject::neuter(cx, buffer, buffer->dataPointer());
|
||||
void *newData;
|
||||
if (changeData == ChangeData) {
|
||||
newData = AllocateArrayBufferContents(cx, buffer->byteLength());
|
||||
if (!newData)
|
||||
return false;
|
||||
} else {
|
||||
newData = buffer->dataPointer();
|
||||
}
|
||||
|
||||
ArrayBufferObject::neuter(cx, buffer, newData);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче