Bug 999755 - Add neuter() variants to vary data pointer, r=Waldo

This commit is contained in:
Steve Fink 2014-04-24 14:40:57 -07:00
Родитель 15fc04d4b4
Коммит 8b797a29fd
11 изменённых файлов: 95 добавлений и 47 удалений

Просмотреть файл

@ -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;
}