Bug 966575 part 02 - Migrate away from accessing TypeRepresentation directly r=sfink

This commit is contained in:
Nicholas D. Matsakis 2014-01-27 18:54:07 -05:00
parent 747b08c100
commit 89a94ef82e
8 changed files with 198 additions and 311 deletions

View File

@ -133,7 +133,7 @@ class Float32x4Defn {
} // namespace js
const JSFunctionSpec js::Float32x4Defn::TypeDescriptorMethods[] = {
JS_FN("toSource", TypeDescrToSource, 0, 0),
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
JS_SELF_HOSTED_FN("handle", "HandleCreate", 2, 0),
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),
@ -155,7 +155,7 @@ const JSFunctionSpec js::Float32x4Defn::TypedDatumMethods[] = {
};
const JSFunctionSpec js::Int32x4Defn::TypeDescriptorMethods[] = {
JS_FN("toSource", TypeDescrToSource, 0, 0),
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
JS_SELF_HOSTED_FN("handle", "HandleCreate", 2, 0),
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
JS_SELF_HOSTED_FN("equivalent", "TypeDescrEquivalent", 1, 0),

View File

@ -689,33 +689,6 @@ TypeRepresentation::obj_finalize(js::FreeOp *fop, JSObject *object)
///////////////////////////////////////////////////////////////////////////
// To string
bool
TypeRepresentation::appendString(JSContext *cx, StringBuffer &contents)
{
switch (kind()) {
case Scalar:
return asScalar()->appendStringScalar(cx, contents);
case Reference:
return asReference()->appendStringReference(cx, contents);
case X4:
return asX4()->appendStringX4(cx, contents);
case SizedArray:
return asSizedArray()->appendStringSizedArray(cx, contents);
case UnsizedArray:
return asUnsizedArray()->appendStringUnsizedArray(cx, contents);
case Struct:
return asStruct()->appendStringStruct(cx, contents);
}
MOZ_ASSUME_UNREACHABLE("Invalid kind");
return false;
}
/*static*/ const char *
ScalarTypeRepresentation::typeName(Type type)
{
@ -727,17 +700,6 @@ ScalarTypeRepresentation::typeName(Type type)
MOZ_ASSUME_UNREACHABLE("Invalid type");
}
bool
ScalarTypeRepresentation::appendStringScalar(JSContext *cx, StringBuffer &contents)
{
switch (type()) {
#define NUMERIC_TYPE_APPEND_STRING(constant_, type_, name_) \
case constant_: return contents.append(#name_);
JS_FOR_EACH_SCALAR_TYPE_REPR(NUMERIC_TYPE_APPEND_STRING)
}
MOZ_ASSUME_UNREACHABLE("Invalid type");
}
/*static*/ const char *
ReferenceTypeRepresentation::typeName(Type type)
{
@ -749,103 +711,6 @@ ReferenceTypeRepresentation::typeName(Type type)
MOZ_ASSUME_UNREACHABLE("Invalid type");
}
bool
ReferenceTypeRepresentation::appendStringReference(JSContext *cx, StringBuffer &contents)
{
switch (type()) {
#define NUMERIC_TYPE_APPEND_STRING(constant_, type_, name_) \
case constant_: return contents.append(#name_);
JS_FOR_EACH_REFERENCE_TYPE_REPR(NUMERIC_TYPE_APPEND_STRING)
}
MOZ_ASSUME_UNREACHABLE("Invalid type");
}
bool
X4TypeRepresentation::appendStringX4(JSContext *cx, StringBuffer &contents)
{
switch (type()) {
case TYPE_FLOAT32:
return contents.append("float32x4");
case TYPE_INT32:
return contents.append("int32x4");
}
MOZ_ASSUME_UNREACHABLE("Invalid type");
}
bool
SizedArrayTypeRepresentation::appendStringSizedArray(JSContext *cx, StringBuffer &contents)
{
SizedTypeRepresentation *elementType = element();
while (elementType->isSizedArray())
elementType = elementType->asSizedArray()->element();
if (!elementType->appendString(cx, contents))
return false;
contents.append(".array(");
SizedArrayTypeRepresentation *arrayType = this;
while (arrayType != nullptr) {
if (!NumberValueToStringBuffer(cx, NumberValue(length()), contents))
return false;
if (arrayType->element()->isSizedArray()) {
if (!contents.append(","))
return false;
arrayType = arrayType->element()->asSizedArray();
} else {
break;
}
}
if (!contents.append(")"))
return false;
return true;
}
bool
UnsizedArrayTypeRepresentation::appendStringUnsizedArray(JSContext *cx, StringBuffer &contents)
{
if (!element()->appendString(cx, contents))
return false;
if (!contents.append(".array()"))
return false;
return true;
}
bool
StructTypeRepresentation::appendStringStruct(JSContext *cx, StringBuffer &contents)
{
if (!contents.append("StructType({"))
return false;
for (size_t i = 0; i < fieldCount(); i++) {
const StructField &fld = field(i);
if (i > 0)
contents.append(", ");
RootedString idString(cx, fld.propertyName);
if (!idString)
return false;
if (!contents.append(idString))
return false;
if (!contents.append(": "))
return false;
if (!fld.typeRepr->appendString(cx, contents))
return false;
}
if (!contents.append("})"))
return false;
return true;
}
///////////////////////////////////////////////////////////////////////////
// Walking memory

View File

@ -160,10 +160,6 @@ class TypeRepresentation {
JSObject *ownerObject() const { return ownerObject_.get(); }
types::TypeObject *typeObject() const { return typeObject_.get(); }
// Appends a stringified form of this type representation onto
// buffer, for use in error messages and the like.
bool appendString(JSContext *cx, StringBuffer &buffer);
static bool isOwnerObject(JSObject &obj);
static TypeRepresentation *fromOwnerObject(JSObject &obj);
@ -261,9 +257,6 @@ class ScalarTypeRepresentation : public SizedTypeRepresentation {
static const int32_t TYPE_MAX = TYPE_UINT8_CLAMPED + 1;
private:
// so TypeRepresentation can call appendStringScalar() etc
friend class TypeRepresentation;
// in order to call constructor
friend class TypeRepresentationHelper;
@ -271,9 +264,6 @@ class ScalarTypeRepresentation : public SizedTypeRepresentation {
explicit ScalarTypeRepresentation(Type type);
// See TypeRepresentation::appendString()
bool appendStringScalar(JSContext *cx, StringBuffer &buffer);
public:
Type type() const {
return type_;
@ -316,16 +306,10 @@ class ReferenceTypeRepresentation : public SizedTypeRepresentation {
static const int32_t TYPE_MAX = TYPE_STRING + 1;
private:
// so TypeRepresentation can call appendStringScalar() etc
friend class TypeRepresentation;
Type type_;
explicit ReferenceTypeRepresentation(Type type);
// See TypeRepresentation::appendString()
bool appendStringReference(JSContext *cx, StringBuffer &buffer);
public:
Type type() const {
return type_;
@ -352,9 +336,6 @@ class X4TypeRepresentation : public SizedTypeRepresentation {
};
private:
// so TypeRepresentation can call appendStringScalar() etc
friend class TypeRepresentation;
// in order to call constructor
friend class TypeRepresentationHelper;
@ -362,9 +343,6 @@ class X4TypeRepresentation : public SizedTypeRepresentation {
explicit X4TypeRepresentation(Type type);
// See TypeRepresentation::appendString()
bool appendStringX4(JSContext *cx, StringBuffer &buffer);
public:
Type type() const {
return type_;
@ -380,7 +358,7 @@ class X4TypeRepresentation : public SizedTypeRepresentation {
class UnsizedArrayTypeRepresentation : public TypeRepresentation {
private:
// so TypeRepresentation can call appendStringArray() etc
// so TypeRepresentation can call tracing routines
friend class TypeRepresentation;
SizedTypeRepresentation *element_;
@ -390,9 +368,6 @@ class UnsizedArrayTypeRepresentation : public TypeRepresentation {
// See TypeRepresentation::traceFields()
void traceUnsizedArrayFields(JSTracer *trace);
// See TypeRepresentation::appendString()
bool appendStringUnsizedArray(JSContext *cx, StringBuffer &buffer);
public:
SizedTypeRepresentation *element() {
return element_;
@ -404,7 +379,7 @@ class UnsizedArrayTypeRepresentation : public TypeRepresentation {
class SizedArrayTypeRepresentation : public SizedTypeRepresentation {
private:
// so TypeRepresentation can call appendStringSizedArray() etc
// so TypeRepresentation can call traceSizedArrayFields()
friend class TypeRepresentation;
SizedTypeRepresentation *element_;
@ -416,9 +391,6 @@ class SizedArrayTypeRepresentation : public SizedTypeRepresentation {
// See TypeRepresentation::traceFields()
void traceSizedArrayFields(JSTracer *trace);
// See TypeRepresentation::appendString()
bool appendStringSizedArray(JSContext *cx, StringBuffer &buffer);
public:
SizedTypeRepresentation *element() {
return element_;
@ -447,7 +419,7 @@ struct StructField {
class StructTypeRepresentation : public SizedTypeRepresentation {
private:
// so TypeRepresentation can call appendStringStruct() etc
// so TypeRepresentation can call traceStructFields() etc
friend class TypeRepresentation;
size_t fieldCount_;
@ -469,9 +441,6 @@ class StructTypeRepresentation : public SizedTypeRepresentation {
// See TypeRepresentation::traceFields()
void traceStructFields(JSTracer *trace);
// See TypeRepresentation::appendString()
bool appendStringStruct(JSContext *cx, StringBuffer &buffer);
public:
size_t fieldCount() const {
return fieldCount_;

View File

@ -67,31 +67,6 @@ ToObjectIf(HandleValue value)
return &value.toObject().as<T>();
}
bool
js::TypeDescrToSource(JSContext *cx, unsigned int argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<TypeDescr*> thisObj(cx, ToObjectIf<TypeDescr>(args.thisv()));
if (!thisObj) {
JS_ReportErrorNumber(cx, js_GetErrorMessage,
nullptr, JSMSG_TYPEDOBJECT_HANDLE_BAD_ARGS,
"this", "type object");
return false;
}
StringBuffer contents(cx);
if (!thisObj->typeRepresentation()->appendString(cx, contents))
return false;
RootedString result(cx, contents.finishString());
if (!result)
return false;
args.rval().setString(result);
return true;
}
/*
* Overwrites the contents of `datum` at offset `offset` with `val`
* converted to the type `typeObj`. This is done by delegating to
@ -130,15 +105,14 @@ ConvertAndCopyTo(JSContext *cx,
return false;
InvokeArgs args(cx);
if (!args.init(5))
if (!args.init(4))
return false;
args.setCallee(ObjectValue(*func));
args[0].setObject(typeObj->typeRepresentationOwnerObj());
args[1].setObject(*typeObj);
args[2].setObject(*datum);
args[3].setInt32(offset);
args[4].set(val);
args[0].setObject(*typeObj);
args[1].setObject(*datum);
args[2].setInt32(offset);
args[3].set(val);
return Invoke(cx, args);
}
@ -167,14 +141,13 @@ Reify(JSContext *cx,
return false;
InvokeArgs args(cx);
if (!args.init(4))
if (!args.init(3))
return false;
args.setCallee(ObjectValue(*func));
args[0].setObject(*typeRepr->ownerObject());
args[1].setObject(*type);
args[2].setObject(*datum);
args[3].setInt32(offset);
args[0].setObject(*type);
args[1].setObject(*datum);
args[2].setInt32(offset);
if (!Invoke(cx, args))
return false;
@ -229,7 +202,7 @@ const Class js::ScalarTypeDescr::class_ = {
};
const JSFunctionSpec js::ScalarTypeDescr::typeObjectMethods[] = {
JS_FN("toSource", TypeDescrToSource, 0, 0),
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
{"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"},
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
@ -300,7 +273,7 @@ const Class js::ReferenceTypeDescr::class_ = {
};
const JSFunctionSpec js::ReferenceTypeDescr::typeObjectMethods[] = {
JS_FN("toSource", TypeDescrToSource, 0, 0),
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
{"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"},
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
@ -442,7 +415,7 @@ const JSFunctionSpec ArrayMetaTypeDescr::typeObjectMethods[] = {
{"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"},
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
JS_FN("dimension", UnsizedArrayTypeDescr::dimension, 1, 0),
JS_FN("toSource", TypeDescrToSource, 0, 0),
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
JS_SELF_HOSTED_FN("build", "TypedObjectArrayTypeBuild", 3, 0),
JS_SELF_HOSTED_FN("buildPar", "TypedObjectArrayTypeBuildPar", 3, 0),
@ -715,7 +688,7 @@ const JSPropertySpec StructMetaTypeDescr::typeObjectProperties[] = {
const JSFunctionSpec StructMetaTypeDescr::typeObjectMethods[] = {
{"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"},
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
JS_FN("toSource", TypeDescrToSource, 0, 0),
JS_SELF_HOSTED_FN("toSource", "DescrToSourceMethod", 0, 0),
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeDescrEquivalent"},
JS_FS_END
};
@ -1396,13 +1369,20 @@ ReportDatumTypeError(JSContext *cx,
const unsigned errorNumber,
HandleTypedDatum obj)
{
TypeRepresentation *typeRepr = obj->typeRepresentation();
StringBuffer contents(cx);
if (!typeRepr->appendString(cx, contents))
// Serialize type string using self-hosted function DescrToSource
RootedFunction func(
cx, SelfHostedFunction(cx, cx->names().DescrToSource));
if (!func)
return false;
InvokeArgs args(cx);
if (!args.init(1))
return false;
args.setCallee(ObjectValue(*func));
args[0].setObject(obj->typeDescr());
if (!Invoke(cx, args))
return false;
RootedString result(cx, contents.finishString());
RootedString result(cx, args.rval().toString());
if (!result)
return false;

View File

@ -139,8 +139,6 @@ static T ConvertScalar(double d)
}
}
bool TypeDescrToSource(JSContext *cx, unsigned int argc, Value *vp);
class TypeDescr : public JSObject
{
public:

View File

@ -3,10 +3,29 @@
///////////////////////////////////////////////////////////////////////////
// Getters and setters for various slots.
// Type repr slots
#define REPR_KIND(obj) \
TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEREPR_SLOT_KIND))
#define REPR_SIZE(obj) \
TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEREPR_SLOT_SIZE))
#define REPR_LENGTH(obj) \
TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEREPR_SLOT_LENGTH))
#define REPR_TYPE(obj) \
TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEREPR_SLOT_TYPE))
// Type object slots
#define TYPE_TYPE_REPR(obj) \
#define DESCR_TYPE_REPR(obj) \
UnsafeGetReservedSlot(obj, JS_TYPEOBJ_SLOT_TYPE_REPR)
#define DESCR_KIND(obj) \
REPR_KIND(DESCR_TYPE_REPR(obj))
#define DESCR_SIZE(obj) \
REPR_SIZE(DESCR_TYPE_REPR(obj))
#define DESCR_LENGTH(obj) \
REPR_LENGTH(DESCR_TYPE_REPR(obj))
#define DESCR_TYPE(obj) \
REPR_TYPE(DESCR_TYPE_REPR(obj))
// Typed object slots
@ -17,25 +36,97 @@
#define DATUM_LENGTH(obj) \
TO_INT32(UnsafeGetReservedSlot(obj, JS_DATUM_SLOT_LENGTH))
// Type repr slots
#define REPR_KIND(obj) \
TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEREPR_SLOT_KIND))
#define REPR_SIZE(obj) \
TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEREPR_SLOT_SIZE))
#define REPR_ALIGNMENT(obj) \
TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEREPR_SLOT_ALIGNMENT))
#define REPR_LENGTH(obj) \
TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEREPR_SLOT_LENGTH))
#define REPR_TYPE(obj) \
TO_INT32(UnsafeGetReservedSlot(obj, JS_TYPEREPR_SLOT_TYPE))
#define HAS_PROPERTY(obj, prop) \
callFunction(std_Object_hasOwnProperty, obj, prop)
function DATUM_TYPE_REPR(obj) {
// Eventually this will be a slot on typed objects
return TYPE_TYPE_REPR(DATUM_TYPE_DESCR(obj));
return DESCR_TYPE_REPR(DATUM_TYPE_DESCR(obj));
}
///////////////////////////////////////////////////////////////////////////
// DescrToSource
//
// Converts a type descriptor to a descriptive string
// toSource() for type descriptors.
//
// Warning: user exposed!
function DescrToSourceMethod() {
if (!IsObject(this) || !ObjectIsTypeDescr(this))
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Type", "toSource", "value");
return DescrToSource(this);
}
function DescrToSource(descr) {
assert(IsObject(descr) && ObjectIsTypeDescr(descr),
"DescrToSource: not type descr");
switch (DESCR_KIND(descr)) {
case JS_TYPEREPR_SCALAR_KIND:
switch (DESCR_TYPE(descr)) {
case JS_SCALARTYPEREPR_INT8: return "int8";
case JS_SCALARTYPEREPR_UINT8: return "uint8";
case JS_SCALARTYPEREPR_UINT8_CLAMPED: return "uint8Clamped";
case JS_SCALARTYPEREPR_INT16: return "int16";
case JS_SCALARTYPEREPR_UINT16: return "uint16";
case JS_SCALARTYPEREPR_INT32: return "int32";
case JS_SCALARTYPEREPR_UINT32: return "uint32";
case JS_SCALARTYPEREPR_FLOAT32: return "float32";
case JS_SCALARTYPEREPR_FLOAT64: return "float64";
}
assert(false, "Unhandled type: " + DESCR_TYPE(descr));
return undefined;
case JS_TYPEREPR_REFERENCE_KIND:
switch (DESCR_TYPE(descr)) {
case JS_REFERENCETYPEREPR_ANY: return "any";
case JS_REFERENCETYPEREPR_OBJECT: return "Object";
case JS_REFERENCETYPEREPR_STRING: return "string";
}
assert(false, "Unhandled type: " + DESCR_TYPE(descr));
return undefined;
case JS_TYPEREPR_X4_KIND:
switch (DESCR_TYPE(descr)) {
case JS_X4TYPEREPR_FLOAT32: return "float32x4";
case JS_X4TYPEREPR_INT32: return "int32x4";
}
assert(false, "Unhandled type: " + DESCR_TYPE(descr));
return undefined;
case JS_TYPEREPR_STRUCT_KIND:
var result = "new StructType({";
for (var i = 0; i < descr.fieldNames.length; i++) {
if (i != 0)
result += ", ";
var fieldName = descr.fieldNames[i];
var fieldDescr = descr.fieldTypes[fieldName];
result += fieldName;
result += ": ";
result += DescrToSource(fieldDescr);
}
result += "})";
return result;
case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
return "new ArrayType(" + DescrToSource(descr.elementType) + ")";
case JS_TYPEREPR_SIZED_ARRAY_KIND:
var result = ".array";
var sep = "(";
while (DESCR_KIND(descr) == JS_TYPEREPR_SIZED_ARRAY_KIND) {
result += sep + DESCR_LENGTH(descr);
descr = descr.elementType;
sep = ", ";
}
return DescrToSource(descr) + result + ")";
}
assert(false, "Unhandled kind: " + DESCR_KIND(descr));
return undefined;
}
///////////////////////////////////////////////////////////////////////////
@ -43,8 +134,7 @@ function DATUM_TYPE_REPR(obj) {
//
// TypedObjectPointers are internal structs used to represent a
// pointer into typed object memory. They pull together:
// - typeRepr: the internal type representation
// - descr: the user-visible type object
// - descr: the type descriptor
// - datum: the typed object that contains the allocated block of memory
// - offset: an offset into that typed object
//
@ -58,8 +148,7 @@ function DATUM_TYPE_REPR(obj) {
// they mutate the receiver in place, because it makes for prettier
// code.
function TypedObjectPointer(typeRepr, descr, datum, offset) {
this.typeRepr = typeRepr;
function TypedObjectPointer(descr, datum, offset) {
this.descr = descr;
this.datum = datum;
this.offset = offset;
@ -68,25 +157,20 @@ function TypedObjectPointer(typeRepr, descr, datum, offset) {
MakeConstructible(TypedObjectPointer, {});
TypedObjectPointer.fromTypedDatum = function(typed) {
return new TypedObjectPointer(DATUM_TYPE_REPR(typed),
DATUM_TYPE_DESCR(typed),
typed,
0);
return new TypedObjectPointer(DATUM_TYPE_DESCR(typed), typed, 0);
}
#ifdef DEBUG
TypedObjectPointer.prototype.toString = function() {
return "Ptr(" + this.descr.toSource() + " @ " + this.offset + ")";
return "Ptr(" + DescrToSource(this.descr) + " @ " + this.offset + ")";
};
#endif
TypedObjectPointer.prototype.copy = function() {
return new TypedObjectPointer(this.typeRepr, this.descr,
this.datum, this.offset);
return new TypedObjectPointer(this.descr, this.datum, this.offset);
};
TypedObjectPointer.prototype.reset = function(inPtr) {
this.typeRepr = inPtr.typeRepr;
this.descr = inPtr.descr;
this.datum = inPtr.datum;
this.offset = inPtr.offset;
@ -94,13 +178,13 @@ TypedObjectPointer.prototype.reset = function(inPtr) {
};
TypedObjectPointer.prototype.kind = function() {
return REPR_KIND(this.typeRepr);
return DESCR_KIND(this.descr);
}
TypedObjectPointer.prototype.length = function() {
switch (this.kind()) {
case JS_TYPEREPR_SIZED_ARRAY_KIND:
return REPR_LENGTH(this.typeRepr);
return DESCR_LENGTH(this.descr);
case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
return DATUM_LENGTH(this.datum);
@ -157,11 +241,9 @@ TypedObjectPointer.prototype.moveToElem = function(index) {
assert(index >= 0 && index < this.length(),
"moveToElem invoked with out-of-bounds index: " + index);
var elementTypeObj = this.descr.elementType;
var elementTypeRepr = TYPE_TYPE_REPR(elementTypeObj);
this.typeRepr = elementTypeRepr;
this.descr = elementTypeObj;
var elementSize = REPR_SIZE(elementTypeRepr);
var elementDescr = this.descr.elementType;
this.descr = elementDescr;
var elementSize = DESCR_SIZE(elementDescr);
// Note: we do not allow construction of arrays where the offset
// of an element cannot be represented by an int32.
@ -179,10 +261,9 @@ TypedObjectPointer.prototype.moveToField = function(propName) {
assert(HAS_PROPERTY(this.descr.fieldTypes, propName),
"moveToField invoked with undefined field");
var fieldTypeObj = this.descr.fieldTypes[propName];
var fieldDescr = this.descr.fieldTypes[propName];
var fieldOffset = TO_INT32(this.descr.fieldOffsets[propName]);
this.descr = fieldTypeObj;
this.typeRepr = TYPE_TYPE_REPR(fieldTypeObj);
this.descr = fieldDescr;
// Note: we do not allow construction of structs where the
// offset of a field cannot be represented by an int32.
@ -206,7 +287,7 @@ TypedObjectPointer.prototype.moveToField = function(propName) {
TypedObjectPointer.prototype.get = function() {
assert(ObjectIsAttached(this.datum), "get() called with unattached datum");
switch (REPR_KIND(this.typeRepr)) {
switch (this.kind()) {
case JS_TYPEREPR_SCALAR_KIND:
return this.getScalar();
@ -223,15 +304,15 @@ TypedObjectPointer.prototype.get = function() {
return NewDerivedTypedDatum(this.descr, this.datum, this.offset);
case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
assert(false, "Unhandled repr kind: " + REPR_KIND(this.typeRepr));
assert(false, "Unhandled repr kind: " + this.kind());
}
assert(false, "Unhandled kind: " + REPR_KIND(this.typeRepr));
assert(false, "Unhandled kind: " + this.kind());
return undefined;
}
TypedObjectPointer.prototype.getScalar = function() {
var type = REPR_TYPE(this.typeRepr);
var type = DESCR_TYPE(this.descr);
switch (type) {
case JS_SCALARTYPEREPR_INT8:
return Load_int8(this.datum, this.offset);
@ -264,7 +345,7 @@ TypedObjectPointer.prototype.getScalar = function() {
}
TypedObjectPointer.prototype.getReference = function() {
var type = REPR_TYPE(this.typeRepr);
var type = DESCR_TYPE(this.descr);
switch (type) {
case JS_REFERENCETYPEREPR_ANY:
return Load_Any(this.datum, this.offset);
@ -281,7 +362,7 @@ TypedObjectPointer.prototype.getReference = function() {
}
TypedObjectPointer.prototype.getX4 = function() {
var type = REPR_TYPE(this.typeRepr);
var type = DESCR_TYPE(this.descr);
switch (type) {
case JS_X4TYPEREPR_FLOAT32:
var x = Load_float32(this.datum, this.offset + 0);
@ -313,23 +394,22 @@ TypedObjectPointer.prototype.getX4 = function() {
TypedObjectPointer.prototype.set = function(fromValue) {
assert(ObjectIsAttached(this.datum), "set() called with unattached datum");
var typeRepr = this.typeRepr;
// Fast path: `fromValue` is a typed object with same type
// representation as the destination. In that case, we can just do a
// memcpy.
if (IsObject(fromValue) && ObjectIsTypedDatum(fromValue)) {
var typeRepr = DESCR_TYPE_REPR(this.descr);
if (!typeRepr.variable && DATUM_TYPE_REPR(fromValue) === typeRepr) {
if (!ObjectIsAttached(fromValue))
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED);
var size = REPR_SIZE(typeRepr);
var size = DESCR_SIZE(this.descr);
Memcpy(this.datum, this.offset, fromValue, 0, size);
return;
}
}
switch (REPR_KIND(typeRepr)) {
switch (this.kind()) {
case JS_TYPEREPR_SCALAR_KIND:
this.setScalar(fromValue);
return;
@ -355,7 +435,7 @@ TypedObjectPointer.prototype.set = function(fromValue) {
// Adapt each element.
if (length > 0) {
var tempPtr = this.copy().moveToElem(0);
var size = REPR_SIZE(tempPtr.typeRepr);
var size = DESCR_SIZE(tempPtr.descr);
for (var i = 0; i < length; i++) {
tempPtr.set(fromValue[i]);
tempPtr.offset += size;
@ -379,15 +459,15 @@ TypedObjectPointer.prototype.set = function(fromValue) {
ThrowError(JSMSG_CANT_CONVERT_TO,
typeof(fromValue),
this.typeRepr.toSource());
DescrToSource(this.descr));
}
// Sets `fromValue` to `this` assuming that `this` is a scalar type.
TypedObjectPointer.prototype.setScalar = function(fromValue) {
assert(REPR_KIND(this.typeRepr) == JS_TYPEREPR_SCALAR_KIND,
assert(this.kind() == JS_TYPEREPR_SCALAR_KIND,
"setScalar called with non-scalar");
var type = REPR_TYPE(this.typeRepr);
var type = DESCR_TYPE(this.descr);
switch (type) {
case JS_SCALARTYPEREPR_INT8:
return Store_int8(this.datum, this.offset,
@ -429,7 +509,7 @@ TypedObjectPointer.prototype.setScalar = function(fromValue) {
}
TypedObjectPointer.prototype.setReference = function(fromValue) {
var type = REPR_TYPE(this.typeRepr);
var type = DESCR_TYPE(this.descr);
switch (type) {
case JS_REFERENCETYPEREPR_ANY:
return Store_Any(this.datum, this.offset, fromValue);
@ -454,7 +534,7 @@ TypedObjectPointer.prototype.setX4 = function(fromValue) {
// to "adapt" fromValue, but there are no legal adaptions.
ThrowError(JSMSG_CANT_CONVERT_TO,
typeof(fromValue),
this.typeRepr.toSource());
DescrToSource(this.descr));
}
///////////////////////////////////////////////////////////////////////////
@ -463,15 +543,12 @@ TypedObjectPointer.prototype.setX4 = function(fromValue) {
// These helpers are invoked by C++ code or used as method bodies.
// Wrapper for use from C++ code.
function ConvertAndCopyTo(destTypeRepr,
destTypeObj,
function ConvertAndCopyTo(destDescr,
destDatum,
destOffset,
fromValue)
{
assert(IsObject(destTypeRepr) && ObjectIsTypeRepresentation(destTypeRepr),
"ConvertAndCopyTo: not type repr");
assert(IsObject(destTypeObj) && ObjectIsTypeDescr(destTypeObj),
assert(IsObject(destDescr) && ObjectIsTypeDescr(destDescr),
"ConvertAndCopyTo: not type obj");
assert(IsObject(destDatum) && ObjectIsTypedDatum(destDatum),
"ConvertAndCopyTo: not type datum");
@ -479,19 +556,15 @@ function ConvertAndCopyTo(destTypeRepr,
if (!ObjectIsAttached(destDatum))
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED);
var ptr = new TypedObjectPointer(destTypeRepr, destTypeObj,
destDatum, destOffset);
var ptr = new TypedObjectPointer(destDescr, destDatum, destOffset);
ptr.set(fromValue);
}
// Wrapper for use from C++ code.
function Reify(sourceTypeRepr,
sourceTypeObj,
function Reify(sourceDescr,
sourceDatum,
sourceOffset) {
assert(IsObject(sourceTypeRepr) && ObjectIsTypeRepresentation(sourceTypeRepr),
"Reify: not type repr");
assert(IsObject(sourceTypeObj) && ObjectIsTypeDescr(sourceTypeObj),
assert(IsObject(sourceDescr) && ObjectIsTypeDescr(sourceDescr),
"Reify: not type obj");
assert(IsObject(sourceDatum) && ObjectIsTypedDatum(sourceDatum),
"Reify: not type datum");
@ -499,15 +572,17 @@ function Reify(sourceTypeRepr,
if (!ObjectIsAttached(sourceDatum))
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED);
var ptr = new TypedObjectPointer(sourceTypeRepr, sourceTypeObj,
sourceDatum, sourceOffset);
var ptr = new TypedObjectPointer(sourceDescr, sourceDatum, sourceOffset);
return ptr.get();
}
function FillTypedArrayWithValue(destArray, fromValue) {
var typeRepr = DATUM_TYPE_REPR(destArray);
var length = REPR_LENGTH(typeRepr);
assert(IsObject(handle) && ObjectIsTypedDatum(destArray),
"FillTypedArrayWithValue: not typed handle");
var descr = DATUM_TYPE_DESCR(destArray);
var length = DESCR_LENGTH(descr);
if (length === 0)
return;
@ -517,19 +592,19 @@ function FillTypedArrayWithValue(destArray, fromValue) {
ptr.set(fromValue);
// Stamp out the remaining copies:
var elementSize = REPR_SIZE(ptr.typeRepr);
var elementSize = DESCR_SIZE(ptr.descr);
var totalSize = length * elementSize;
for (var offset = elementSize; offset < totalSize; offset += elementSize)
Memcpy(destArray, offset, destArray, 0, elementSize);
}
// Warning: user exposed!
function TypeDescrEquivalent(otherTypeObj) {
function TypeDescrEquivalent(otherDescr) {
if (!IsObject(this) || !ObjectIsTypeDescr(this))
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_BAD_ARGS, "this", "type object");
if (!IsObject(otherTypeObj) || !ObjectIsTypeDescr(otherTypeObj))
if (!IsObject(otherDescr) || !ObjectIsTypeDescr(otherDescr))
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_BAD_ARGS, "1", "type object");
return TYPE_TYPE_REPR(this) === TYPE_TYPE_REPR(otherTypeObj);
return DESCR_TYPE_REPR(this) === DESCR_TYPE_REPR(otherDescr);
}
// TypedArray.redimension(newArrayType)
@ -562,7 +637,7 @@ function TypedArrayRedimension(newArrayType) {
// Peel away the outermost array layers from the type of `this` to find
// the core element type. In the process, count the number of elements.
var oldArrayType = DATUM_TYPE_DESCR(this);
var oldArrayReprKind = REPR_KIND(TYPE_TYPE_REPR(oldArrayType));
var oldArrayReprKind = DESCR_KIND(oldArrayType);
var oldElementType = oldArrayType;
var oldElementCount = 1;
switch (oldArrayReprKind) {
@ -577,7 +652,7 @@ function TypedArrayRedimension(newArrayType) {
default:
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_BAD_ARGS, "this", "typed array");
}
while (REPR_KIND(TYPE_TYPE_REPR(oldElementType)) === JS_TYPEREPR_SIZED_ARRAY_KIND) {
while (DESCR_KIND(oldElementType) === JS_TYPEREPR_SIZED_ARRAY_KIND) {
oldElementCount *= oldElementType.length;
oldElementType = oldElementType.elementType;
}
@ -586,7 +661,7 @@ function TypedArrayRedimension(newArrayType) {
// process, count the number of elements.
var newElementType = newArrayType;
var newElementCount = 1;
while (REPR_KIND(TYPE_TYPE_REPR(newElementType)) == JS_TYPEREPR_SIZED_ARRAY_KIND) {
while (DESCR_KIND(newElementType) == JS_TYPEREPR_SIZED_ARRAY_KIND) {
newElementCount *= newElementType.length;
newElementType = newElementType.elementType;
}
@ -598,14 +673,13 @@ function TypedArrayRedimension(newArrayType) {
}
// Check that the element types are equivalent.
if (TYPE_TYPE_REPR(oldElementType) !== TYPE_TYPE_REPR(newElementType)) {
if (DESCR_TYPE_REPR(oldElementType) !== DESCR_TYPE_REPR(newElementType)) {
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_BAD_ARGS, 1,
"New element type is not equivalent to old element type");
}
// Together, this should imply that the sizes are unchanged.
assert(REPR_SIZE(TYPE_TYPE_REPR(oldArrayType)) ==
REPR_SIZE(TYPE_TYPE_REPR(newArrayType)),
assert(DESCR_SIZE(oldArrayType) == DESCR_SIZE(newArrayType),
"Byte sizes should be equal");
// Rewrap the data from `this` in a new type.
@ -626,7 +700,7 @@ function HandleCreate(obj, ...path) {
if (!IsObject(this) || !ObjectIsTypeDescr(this))
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "Type", "handle", "value");
switch (REPR_KIND(TYPE_TYPE_REPR(this))) {
switch (DESCR_KIND(this)) {
case JS_TYPEREPR_SCALAR_KIND:
case JS_TYPEREPR_REFERENCE_KIND:
case JS_TYPEREPR_X4_KIND:
@ -667,7 +741,7 @@ function HandleMoveInternal(handle, obj, path) {
ptr.moveTo(path[i]);
// Check that the new destination is equivalent to the handle type.
if (ptr.typeRepr !== DATUM_TYPE_REPR(handle))
if (DESCR_TYPE_REPR(ptr.descr) !== DATUM_TYPE_REPR(handle))
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_BAD_TYPE);
AttachHandle(handle, ptr.datum, ptr.offset)
@ -724,11 +798,11 @@ function X4ToSource() {
if (!IsObject(this) || !ObjectIsTypedDatum(this))
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "X4", "toSource", typeof this);
var repr = DATUM_TYPE_REPR(this);
if (REPR_KIND(repr) != JS_TYPEREPR_X4_KIND)
if (DESCR_KIND(this) != JS_TYPEREPR_X4_KIND)
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "X4", "toSource", typeof this);
var type = REPR_TYPE(repr);
var descr = DATUM_TYPE_DESCR(this);
var type = DESCR_TYPE(descr);
return X4ProtoString(type)+"("+this.x+", "+this.y+", "+this.z+", "+this.w+")";
}
@ -799,7 +873,7 @@ function TypedObjectArrayTypeBuild(a,b,c) {
if (!IsObject(this) || !ObjectIsTypeDescr(this))
ThrowError(JSMSG_TYPEDOBJECT_HANDLE_BAD_ARGS, "this", "type object");
var kind = REPR_KIND(TYPE_TYPE_REPR(this));
var kind = DESCR_KIND(this);
switch (kind) {
case JS_TYPEREPR_SIZED_ARRAY_KIND:
if (typeof a === "function") // XXX here and elsewhere: these type dispatches are fragile at best.
@ -979,7 +1053,7 @@ function GET_BIT(data, index) {
function TypeDescrIsArrayType(t) {
assert(IsObject(t) && ObjectIsTypeDescr(t), "TypeDescrIsArrayType called on non-type-object");
var kind = REPR_KIND(TYPE_TYPE_REPR(t));
var kind = DESCR_KIND(t);
switch (kind) {
case JS_TYPEREPR_SIZED_ARRAY_KIND:
case JS_TYPEREPR_UNSIZED_ARRAY_KIND:
@ -997,7 +1071,7 @@ function TypeDescrIsArrayType(t) {
function TypeDescrIsSizedArrayType(t) {
assert(IsObject(t) && ObjectIsTypeDescr(t), "TypeDescrIsSizedArrayType called on non-type-object");
var kind = REPR_KIND(TYPE_TYPE_REPR(t));
var kind = DESCR_KIND(t);
switch (kind) {
case JS_TYPEREPR_SIZED_ARRAY_KIND:
return true;
@ -1015,7 +1089,7 @@ function TypeDescrIsSizedArrayType(t) {
function TypeDescrIsSimpleType(t) {
assert(IsObject(t) && ObjectIsTypeDescr(t), "TypeDescrIsSimpleType called on non-type-object");
var kind = REPR_KIND(TYPE_TYPE_REPR(t));
var kind = DESCR_KIND(t);
switch (kind) {
case JS_TYPEREPR_SCALAR_KIND:
case JS_TYPEREPR_REFERENCE_KIND:
@ -1071,7 +1145,7 @@ function BuildTypedSeqImpl(arrayType, len, depth, func) {
HandleSet(handle, r); // *handle = r
}
// Increment indices.
offset += REPR_SIZE(TYPE_TYPE_REPR(grainType));
offset += DESCR_SIZE(grainType);
IncrementIterationSpace(indices, iterationSpace);
}
@ -1148,7 +1222,7 @@ function MapUntypedSeqImpl(inArray, outputType, maybeFunc) {
var result = outputType.variable ? new outputType(inArray.length) : new outputType();
var outHandle = callFunction(HandleCreate, outGrainType);
var outUnitSize = REPR_SIZE(TYPE_TYPE_REPR(outGrainType));
var outUnitSize = DESCR_SIZE(outGrainType);
// Core of map computation starts here (comparable to
// DoMapTypedSeqDepth1 and DoMapTypedSeqDepthN below).
@ -1208,8 +1282,8 @@ function MapTypedSeqImpl(inArray, depth, outputType, func) {
var inHandle = callFunction(HandleCreate, inGrainType);
var outHandle = callFunction(HandleCreate, outGrainType);
var inUnitSize = REPR_SIZE(TYPE_TYPE_REPR(inGrainType));
var outUnitSize = REPR_SIZE(TYPE_TYPE_REPR(outGrainType));
var inUnitSize = DESCR_SIZE(inGrainType);
var outUnitSize = DESCR_SIZE(outGrainType);
var inGrainTypeIsSimple = TypeDescrIsSimpleType(inGrainType);

View File

@ -20,7 +20,7 @@ function runTests() {
var S = new StructType({x: int32, y: uint8, z: float64});
assertEq(S.__proto__, StructType.prototype);
assertEq(S.prototype.__proto__, StructType.prototype.prototype);
assertEq(S.toSource(), "StructType({x: int32, y: uint8, z: float64})");
assertEq(S.toSource(), "new StructType({x: int32, y: uint8, z: float64})");
assertEq(S.variable, false);
assertEq(S.byteLength, 16);
assertEq(S.byteAlignment, 8);

View File

@ -46,6 +46,7 @@
macro(DateTimeFormatFormatGet, DateTimeFormatFormatGet, "Intl_DateTimeFormat_format_get") \
macro(decodeURI, decodeURI, "decodeURI") \
macro(decodeURIComponent, decodeURIComponent, "decodeURIComponent") \
macro(DescrToSource, DescrToSource, "DescrToSource") \
macro(default_, default_, "default") \
macro(defineProperty, defineProperty, "defineProperty") \
macro(defineGetter, defineGetter, "__defineGetter__") \