mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 578700 - Binary Data: initialize architecture. r=nmatsakis
--HG-- extra : amend_source : 7775dc457c0c25283608e583472dc7cf04bffe8c
This commit is contained in:
parent
b023ffcb98
commit
88f8ec69ce
@ -72,6 +72,10 @@ ifdef NIGHTLY_BUILD
|
||||
DEFINES += -DENABLE_PARALLEL_JS
|
||||
endif
|
||||
|
||||
ifdef NIGHTLY_BUILD
|
||||
DEFINES += -DENABLE_BINARYDATA
|
||||
endif
|
||||
|
||||
# Ion
|
||||
ifdef ENABLE_ION
|
||||
VPATH += $(srcdir)/ion
|
||||
|
201
js/src/builtin/BinaryData.cpp
Normal file
201
js/src/builtin/BinaryData.cpp
Normal file
@ -0,0 +1,201 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "builtin/BinaryData.h"
|
||||
|
||||
#include "jscompartment.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
#include "jsatominlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "vm/GlobalObject.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
JSBool TypeThrowError(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return ReportIsNotFunction(cx, *vp);
|
||||
}
|
||||
|
||||
JSBool DataThrowError(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return ReportIsNotFunction(cx, *vp);
|
||||
}
|
||||
|
||||
// FIXME will actually require knowing function name
|
||||
JSBool createNumericBlock(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
JSBool createArrayType(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
JSBool createStructType(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
JSBool DataInstanceUpdate(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
JSBool
|
||||
ArrayTypeObject::repeat(JSContext *cx, unsigned int argc, jsval *vp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalObject::initDataObject(JSContext *cx, Handle<GlobalObject *> global)
|
||||
{
|
||||
RootedObject DataProto(cx);
|
||||
DataProto = NewObjectWithGivenProto(cx, &DataClass, global->getOrCreateObjectPrototype(cx), global, SingletonObject);
|
||||
if (!DataProto)
|
||||
return false;
|
||||
|
||||
RootedAtom DataName(cx, ClassName(JSProto_Data, cx));
|
||||
RootedFunction DataCtor(cx, global->createConstructor(cx, DataThrowError, DataName, 1, JSFunction::ExtendedFinalizeKind));
|
||||
if (!DataCtor)
|
||||
return false;
|
||||
|
||||
if (!JS_DefineFunction(cx, DataProto, "update", DataInstanceUpdate, 1, 0))
|
||||
return false;
|
||||
|
||||
if (!LinkConstructorAndPrototype(cx, DataCtor, DataProto))
|
||||
return false;
|
||||
|
||||
if (!DefineConstructorAndPrototype(cx, global, JSProto_Data, DataCtor, DataProto))
|
||||
return false;
|
||||
|
||||
global->setReservedSlot(JSProto_Data, ObjectValue(*DataCtor));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalObject::initTypeObject(JSContext *cx, Handle<GlobalObject *> global)
|
||||
{
|
||||
RootedObject TypeProto(cx, global->getOrCreateDataObject(cx));
|
||||
if (!TypeProto)
|
||||
return false;
|
||||
|
||||
RootedAtom TypeName(cx, ClassName(JSProto_Type, cx));
|
||||
RootedFunction TypeCtor(cx, global->createConstructor(cx, TypeThrowError, TypeName, 1, JSFunction::ExtendedFinalizeKind));
|
||||
if (!TypeCtor)
|
||||
return false;
|
||||
|
||||
if (!LinkConstructorAndPrototype(cx, TypeCtor, TypeProto))
|
||||
return false;
|
||||
|
||||
if (!DefineConstructorAndPrototype(cx, global, JSProto_Type, TypeCtor, TypeProto))
|
||||
return false;
|
||||
|
||||
global->setReservedSlot(JSProto_Type, ObjectValue(*TypeCtor));
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
SetupComplexHeirarchy(JSContext *cx, Handle<GlobalObject *> global, HandleObject complexObject)
|
||||
{
|
||||
// get the 'Type' constructor
|
||||
RootedObject TypeObject(cx, global->getOrCreateTypeObject(cx));
|
||||
if (!TypeObject)
|
||||
return NULL;
|
||||
|
||||
// Set complexObject.__proto__ = Type
|
||||
if (!JS_SetPrototype(cx, complexObject, TypeObject))
|
||||
return NULL;
|
||||
|
||||
RootedObject DataObject(cx, global->getOrCreateDataObject(cx));
|
||||
if (!DataObject)
|
||||
return NULL;
|
||||
|
||||
RootedValue DataProtoVal(cx);
|
||||
if (!JSObject::getProperty(cx, DataObject, DataObject, cx->names().classPrototype, &DataProtoVal))
|
||||
return NULL;
|
||||
|
||||
RootedObject DataProto(cx, DataProtoVal.toObjectOrNull());
|
||||
if (!DataProto)
|
||||
return NULL;
|
||||
|
||||
// Set complexObject.prototype.__proto__ = Data
|
||||
RootedObject prototypeObj(cx, JS_NewObject(cx, NULL, NULL, global));
|
||||
if (!LinkConstructorAndPrototype(cx, complexObject, prototypeObj))
|
||||
return NULL;
|
||||
|
||||
if (!JS_SetPrototype(cx, prototypeObj, DataObject))
|
||||
return NULL;
|
||||
|
||||
// Set complexObject.prototype.prototype.__proto__ = Data.prototype
|
||||
// TODO does this have to actually be a Class so we can set accessor properties etc?
|
||||
RootedObject prototypePrototypeObj(cx, JS_NewObject(cx, NULL, NULL, global));
|
||||
if (!LinkConstructorAndPrototype(cx, prototypeObj, prototypePrototypeObj))
|
||||
return NULL;
|
||||
|
||||
if (!JS_SetPrototype(cx, prototypePrototypeObj, DataProto))
|
||||
return NULL;
|
||||
|
||||
return complexObject;
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
InitComplexClasses(JSContext *cx, Handle<GlobalObject *> global)
|
||||
{
|
||||
// TODO FIXME use DefineConstructorAndPrototype and other
|
||||
// utilities
|
||||
RootedFunction ArrayTypeFun(cx, JS_DefineFunction(cx, global, "ArrayType", createArrayType, 1, 0));
|
||||
if (!ArrayTypeFun)
|
||||
return NULL;
|
||||
|
||||
if (!SetupComplexHeirarchy(cx, global, ArrayTypeFun))
|
||||
return NULL;
|
||||
|
||||
// ArrayType.prototype.repeat
|
||||
RootedValue ArrayTypePrototypeVal(cx);
|
||||
if (!JSObject::getProperty(cx, ArrayTypeFun, ArrayTypeFun, cx->names().classPrototype, &ArrayTypePrototypeVal))
|
||||
return NULL;
|
||||
|
||||
if (!JS_DefineFunction(cx, ArrayTypePrototypeVal.toObjectOrNull(), "repeat", ArrayTypeObject::repeat, 1, 0))
|
||||
return NULL;
|
||||
|
||||
RootedFunction StructTypeFun(cx, JS_DefineFunction(cx, global, "StructType", createStructType, 1, 0));
|
||||
if (!StructTypeFun)
|
||||
return NULL;
|
||||
|
||||
if (!SetupComplexHeirarchy(cx, global, StructTypeFun))
|
||||
return NULL;
|
||||
|
||||
return global;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitBinaryDataClasses(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
JS_ASSERT(obj->is<GlobalObject>());
|
||||
Rooted<GlobalObject *> global(cx, &obj->as<GlobalObject>());
|
||||
|
||||
typedef float_t float32_t;
|
||||
typedef double_t float64_t;
|
||||
#define BINARYDATA_NUMERIC_DEFINE(type_)\
|
||||
do {\
|
||||
JSFunction *numFun = JS_DefineFunction(cx, obj, #type_, createNumericBlock, 1, 0);\
|
||||
if (!numFun)\
|
||||
return NULL;\
|
||||
\
|
||||
if (!JS_DefineProperty(cx, numFun, "bytes", INT_TO_JSVAL(sizeof(type_##_t)), JS_PropertyStub, JS_StrictPropertyStub, 0))\
|
||||
return NULL;\
|
||||
} while(0);
|
||||
BINARYDATA_FOR_EACH_NUMERIC_TYPES(BINARYDATA_NUMERIC_DEFINE)
|
||||
#undef BINARYDATA_NUMERIC_DEFINE
|
||||
|
||||
if (!InitComplexClasses(cx, global))
|
||||
return NULL;
|
||||
return global;
|
||||
}
|
103
js/src/builtin/BinaryData.h
Normal file
103
js/src/builtin/BinaryData.h
Normal file
@ -0,0 +1,103 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef builtin_BinaryData_h
|
||||
#define builtin_BinaryData_h
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "gc/Heap.h"
|
||||
|
||||
namespace js {
|
||||
class Block : public gc::Cell
|
||||
{
|
||||
};
|
||||
|
||||
static Class DataClass = {
|
||||
"Data",
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Data),
|
||||
JS_PropertyStub,
|
||||
JS_DeletePropertyStub,
|
||||
JS_PropertyStub,
|
||||
JS_StrictPropertyStub,
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub
|
||||
};
|
||||
|
||||
static Class TypeClass = {
|
||||
"Type",
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Type),
|
||||
JS_PropertyStub,
|
||||
JS_DeletePropertyStub,
|
||||
JS_PropertyStub,
|
||||
JS_StrictPropertyStub,
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub
|
||||
};
|
||||
|
||||
|
||||
#define BINARYDATA_FOR_EACH_NUMERIC_TYPES(macro_)\
|
||||
macro_(uint8)\
|
||||
macro_(uint16)\
|
||||
macro_(uint32)\
|
||||
macro_(uint64)\
|
||||
macro_(int8)\
|
||||
macro_(int16)\
|
||||
macro_(int32)\
|
||||
macro_(int64)\
|
||||
macro_(float32)\
|
||||
macro_(float64)
|
||||
|
||||
#define BINARYDATA_NUMERIC_CLASSES(type_)\
|
||||
static Class type_##BlockClass = {\
|
||||
#type_,\
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_##type_),\
|
||||
JS_PropertyStub, /* addProperty */\
|
||||
JS_DeletePropertyStub, /* delProperty */\
|
||||
JS_PropertyStub, /* getProperty */\
|
||||
JS_StrictPropertyStub, /* setProperty */\
|
||||
JS_EnumerateStub,\
|
||||
JS_ResolveStub,\
|
||||
JS_ConvertStub\
|
||||
};
|
||||
|
||||
BINARYDATA_FOR_EACH_NUMERIC_TYPES(BINARYDATA_NUMERIC_CLASSES)
|
||||
|
||||
static Class ArrayTypeClass = {
|
||||
"ArrayType",
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_ArrayType),
|
||||
JS_PropertyStub,
|
||||
JS_DeletePropertyStub,
|
||||
JS_PropertyStub,
|
||||
JS_StrictPropertyStub,
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub
|
||||
};
|
||||
|
||||
static Class StructTypeClass = {
|
||||
"StructType",
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_StructType),
|
||||
JS_PropertyStub,
|
||||
JS_DeletePropertyStub,
|
||||
JS_PropertyStub,
|
||||
JS_StrictPropertyStub,
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub
|
||||
};
|
||||
|
||||
class ArrayTypeObject : public JSObject
|
||||
{
|
||||
public:
|
||||
static JSBool repeat(JSContext *cx, unsigned int argc, jsval *vp);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* builtin_BinaryData_h */
|
@ -177,6 +177,14 @@ GetBuildConfiguration(JSContext *cx, unsigned argc, jsval *vp)
|
||||
if (!JS_SetProperty(cx, info, "parallelJS", &value))
|
||||
return false;
|
||||
|
||||
#ifdef ENABLE_BINARYDATA
|
||||
value = BooleanValue(true);
|
||||
#else
|
||||
value = BooleanValue(false);
|
||||
#endif
|
||||
if (!JS_SetProperty(cx, info, "binary-data", &value))
|
||||
return false;
|
||||
|
||||
*vp = ObjectValue(*info);
|
||||
return true;
|
||||
}
|
||||
|
@ -53,6 +53,7 @@
|
||||
#if ENABLE_YARR_JIT
|
||||
#include "assembler/jit/ExecutableAllocator.h"
|
||||
#endif
|
||||
#include "builtin/BinaryData.h"
|
||||
#include "builtin/Eval.h"
|
||||
#include "builtin/Intl.h"
|
||||
#include "builtin/MapObject.h"
|
||||
@ -1849,6 +1850,9 @@ static const JSStdName standard_class_atoms[] = {
|
||||
{js_InitProxyClass, EAGER_CLASS_ATOM(Proxy), OCLASP(ObjectProxy)},
|
||||
#if ENABLE_INTL_API
|
||||
{js_InitIntlClass, EAGER_ATOM_AND_CLASP(Intl)},
|
||||
#endif
|
||||
#ifdef ENABLE_BINARYDATA
|
||||
{js_InitBinaryDataClasses, EAGER_ATOM_AND_CLASP(Type)},
|
||||
#endif
|
||||
{NULL, 0, NULL}
|
||||
};
|
||||
@ -1906,6 +1910,17 @@ static const JSStdName standard_class_names[] = {
|
||||
TYPED_ARRAY_CLASP(TYPE_UINT8_CLAMPED)},
|
||||
{js_InitTypedArrayClasses, EAGER_CLASS_ATOM(DataView), &DataViewObject::class_},
|
||||
|
||||
/* Binary Data */
|
||||
#ifdef ENABLE_BINARYDATA
|
||||
{js_InitBinaryDataClasses, EAGER_ATOM_AND_CLASP(Type)},
|
||||
{js_InitBinaryDataClasses, EAGER_ATOM_AND_CLASP(Data)},
|
||||
#define BINARYDATA_NUMERIC_NAMES(type_)\
|
||||
{js_InitBinaryDataClasses, EAGER_CLASS_ATOM(type_), CLASP(type_##Block)},
|
||||
BINARYDATA_FOR_EACH_NUMERIC_TYPES(BINARYDATA_NUMERIC_NAMES)
|
||||
#undef BINARYDATA_NUMERIC_NAMES
|
||||
{js_InitBinaryDataClasses, EAGER_ATOM_AND_CLASP(ArrayType)},
|
||||
{js_InitBinaryDataClasses, EAGER_ATOM_AND_CLASP(StructType)},
|
||||
#endif
|
||||
{NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -56,5 +56,19 @@
|
||||
macro(DataView, 35, js_InitTypedArrayClasses) \
|
||||
macro(ParallelArray, 36, js_InitParallelArrayClass) \
|
||||
macro(Intl, 37, js_InitIntlClass) \
|
||||
macro(Type, 38, js_InitBinaryDataClasses) \
|
||||
macro(Data, 39, js_InitBinaryDataClasses) \
|
||||
macro(uint8, 40, js_InitBinaryDataClasses) \
|
||||
macro(uint16, 41, js_InitBinaryDataClasses) \
|
||||
macro(uint32, 42, js_InitBinaryDataClasses) \
|
||||
macro(uint64, 43, js_InitBinaryDataClasses) \
|
||||
macro(int8, 44, js_InitBinaryDataClasses) \
|
||||
macro(int16, 45, js_InitBinaryDataClasses) \
|
||||
macro(int32, 46, js_InitBinaryDataClasses) \
|
||||
macro(int64, 47, js_InitBinaryDataClasses) \
|
||||
macro(float32, 48, js_InitBinaryDataClasses) \
|
||||
macro(float64, 49, js_InitBinaryDataClasses) \
|
||||
macro(ArrayType, 50, js_InitBinaryDataClasses) \
|
||||
macro(StructType, 51, js_InitBinaryDataClasses) \
|
||||
|
||||
#endif /* jsprototypes_h */
|
||||
|
@ -80,6 +80,7 @@ EXPORTS.js += [
|
||||
|
||||
CPP_SOURCES += [
|
||||
'ArgumentsObject.cpp',
|
||||
'BinaryData.cpp',
|
||||
'BytecodeCompiler.cpp',
|
||||
'BytecodeEmitter.cpp',
|
||||
'CharacterEncoding.cpp',
|
||||
|
66
js/src/tests/ecma_6/BinaryData/architecture.js
Normal file
66
js/src/tests/ecma_6/BinaryData/architecture.js
Normal file
@ -0,0 +1,66 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("Type"))
|
||||
var BUGNUMBER = 578700;
|
||||
var summary = 'Binary Data class diagram';
|
||||
|
||||
function assertNotEq(a, b) {
|
||||
var ok = false;
|
||||
try {
|
||||
assertEq(a, b);
|
||||
} catch(exc) {
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
throw new TypeError("Assertion failed: assertNotEq(" + a + " " + b + ")");
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
assertEq(Data.__proto__, Function.prototype);
|
||||
assertEq(Data.prototype.__proto__, Object.prototype);
|
||||
assertEq(Data.prototype.constructor, Data);
|
||||
assertEq(typeof Data.prototype.update === "function", true);
|
||||
|
||||
assertEq(Type.__proto__, Function.prototype);
|
||||
assertEq(Type.prototype, Data);
|
||||
|
||||
var sizes = [1, 2, 4, 8, 1, 2, 4, 8, 4, 8];
|
||||
[ uint8, uint16, uint32,
|
||||
uint64, int8, int16,
|
||||
int32, int64, float32, float64 ].forEach(function(numType, i) {
|
||||
assertEq(numType.__proto__, Function.prototype);
|
||||
assertEq(numType.bytes, sizes[i]);
|
||||
});
|
||||
|
||||
assertEq(ArrayType.__proto__, Type);
|
||||
assertEq(ArrayType.prototype.__proto__, Type.prototype);
|
||||
assertEq(typeof ArrayType.prototype.repeat === "function", true);
|
||||
|
||||
assertEq(ArrayType.prototype.prototype.__proto__, Data.prototype);
|
||||
|
||||
assertEq(StructType.__proto__, Type);
|
||||
assertEq(StructType.prototype.__proto__, Type.prototype);
|
||||
assertEq(StructType.prototype.prototype.__proto__, Data.prototype);
|
||||
|
||||
// Change global 'Type' and see if things stay sane.
|
||||
Type = function() {
|
||||
return 42;
|
||||
}
|
||||
|
||||
Data = function() {
|
||||
return 43;
|
||||
}
|
||||
|
||||
assertNotEq(ArrayType.prototype.__proto__, Type.prototype);
|
||||
assertNotEq(ArrayType.prototype.prototype.__proto__, Data.prototype);
|
||||
|
||||
assertNotEq(StructType.prototype.__proto__, Type.prototype);
|
||||
assertNotEq(StructType.prototype.prototype.__proto__, Data.prototype);
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
print("Tests complete");
|
||||
}
|
||||
|
||||
runTests();
|
0
js/src/tests/ecma_6/BinaryData/shell.js
Normal file
0
js/src/tests/ecma_6/BinaryData/shell.js
Normal file
@ -27,6 +27,9 @@ js_InitFunctionClass(JSContext *cx, js::HandleObject obj);
|
||||
extern JSObject *
|
||||
js_InitTypedArrayClasses(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
extern JSObject *
|
||||
js_InitBinaryDataClasses(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
namespace js {
|
||||
|
||||
class Debugger;
|
||||
@ -327,6 +330,14 @@ class GlobalObject : public JSObject
|
||||
return &getPrototype(JSProto_Iterator).toObject();
|
||||
}
|
||||
|
||||
JSObject *getOrCreateDataObject(JSContext *cx) {
|
||||
return getOrCreateObject(cx, JSProto_Data, initDataObject);
|
||||
}
|
||||
|
||||
JSObject *getOrCreateTypeObject(JSContext *cx) {
|
||||
return getOrCreateObject(cx, JSProto_Type, initTypeObject);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef bool (*ObjectInitOp)(JSContext *cx, Handle<GlobalObject*> global);
|
||||
|
||||
@ -429,6 +440,10 @@ class GlobalObject : public JSObject
|
||||
static bool initNumberFormatProto(JSContext *cx, Handle<GlobalObject*> global);
|
||||
static bool initDateTimeFormatProto(JSContext *cx, Handle<GlobalObject*> global);
|
||||
|
||||
// Implemented in builtin/BinaryData.cpp
|
||||
static bool initTypeObject(JSContext *cx, Handle<GlobalObject*> global);
|
||||
static bool initDataObject(JSContext *cx, Handle<GlobalObject*> global);
|
||||
|
||||
static bool initStandardClasses(JSContext *cx, Handle<GlobalObject*> global);
|
||||
|
||||
typedef js::Vector<js::Debugger *, 0, js::SystemAllocPolicy> DebuggerVector;
|
||||
|
Loading…
Reference in New Issue
Block a user