Merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2013-12-20 11:44:27 +01:00
commit 3d1fee4183
106 changed files with 3246 additions and 494 deletions

View File

@ -1,6 +1,7 @@
[DEFAULT]
support-files =
file_bug944407.xml
file_bug950909.xml
[test_bug378518.xul]
[test_bug398135.xul]
@ -9,3 +10,4 @@ support-files =
[test_bug723676.xul]
[test_bug772966.xul]
[test_bug944407.xul]
[test_bug950909.xul]

View File

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div style="-moz-binding: url(chrome://mochitests/content/chrome/content/xbl/test/file_bug950909.xml#testBinding"></div>
</body>
</html>

View File

@ -0,0 +1,37 @@
<?xml version="1.0"?>
<bindings id="chromeTestBindings" xmlns="http://www.mozilla.org/xbl">
<binding id="testBinding">
<implementation implements="nsIObserver">
<constructor>
<![CDATA[
// This binding gets applied to a content object, and thus is actually
// running in a content XBL scope.
var win = XPCNativeWrapper.unwrap(window);
var SpecialPowers = win.SpecialPowers;
var ok = SpecialPowers.unwrap(SpecialPowers.wrap(window).parent.ok);
ok(win != window, "Should be running in an XBL scope with Xrays");
// Generate an XPCWrappedJS for the reflector. We need to do this
// explicitly with a testing helper, because we're converging on
// removing XPConnect from the web, which means that it won't be
// possible to generate an XPCWrappedJS from content (or XBL) code.
var scope = {};
var holder = SpecialPowers.Cu.generateXPCWrappedJS(this, scope);
// Now, QI |this|, which will generate an aggregated native.
this.QueryInterface(Components.interfaces.nsIObserver);
ok(true, "Didn't assert or crash");
SpecialPowers.wrap(window).parent.SimpleTest.finish();
]]>
</constructor>
<method name="observe">
<parameter name="aSubject"/>
<parameter name="aTopic"/>
<parameter name="aData"/>
<body><![CDATA[]]></body>
</method>
</implementation>
</binding>
</bindings>

View File

@ -14,6 +14,7 @@ support-files =
file_bug844783.xhtml
file_bug944407.html
file_bug944407.xml
file_bug950909.html
[test_bug310107.html]
[test_bug366770.html]

View File

@ -0,0 +1,36 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=950909
-->
<window title="Mozilla Bug 950909"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=950909"
target="_blank">Mozilla Bug 950909</a>
</body>
<!-- test code goes here -->
<script type="application/javascript">
<![CDATA[
/*
* Test for bug 950909. This has to be a chrome tests because content needs
* to apply a chrome binding (file_bug950909.xml), which will only be registered
* as a chrome:// URI during mochitest-chrome runs. And the binding has to be
* served from a chrome origin, because otherwise implements="nsIFoo" attributes
* are ignored. So this test needs 3 files, all told. Ugh.
*/
// Just wait. When the iframe loads, it'll apply the binding, which will
// trigger the constructor for the binding.
SimpleTest.waitForExplicitFinish();
]]>
</script>
<iframe src="http://example.com/tests/content/xbl/test/file_bug950909.html"/>
</window>

View File

@ -82,6 +82,18 @@ interface nsIMarkupDocumentViewer : nsISupports
*/
void changeMaxLineBoxWidth(in int32_t maxLineBoxWidth);
/**
* Instruct the refresh driver to discontinue painting until further
* notice.
*/
void pausePainting();
/**
* Instruct the refresh driver to resume painting after a previous call to
* pausePainting().
*/
void resumePainting();
/*
* Render the document as if being viewed on a device with the specified
* media type. This will cause a reflow.

View File

@ -1365,6 +1365,7 @@ void
nsGlobalWindow::DropOuterWindowDocs()
{
MOZ_ASSERT(IsOuterWindow());
MOZ_ASSERT_IF(mDoc, !mDoc->EventHandlingSuppressed());
mDoc = nullptr;
mSuspendedDoc = nullptr;
}
@ -1547,7 +1548,7 @@ nsGlobalWindow::FreeInnerObjects()
mDocumentURI = mDoc->GetDocumentURI();
mDocBaseURI = mDoc->GetDocBaseURI();
if (mDoc->EventHandlingSuppressed()) {
while (mDoc->EventHandlingSuppressed()) {
mDoc->UnsuppressEventHandlingAndFireEvents(false);
}
}

View File

@ -242,8 +242,7 @@ CallbackObjectHolderBase::ToXPCOMCallback(CallbackObject* aCallback,
JSAutoCompartment ac(cx, callback);
nsRefPtr<nsXPCWrappedJS> wrappedJS;
nsresult rv =
nsXPCWrappedJS::GetNewOrUsed(callback, aIID,
nullptr, getter_AddRefs(wrappedJS));
nsXPCWrappedJS::GetNewOrUsed(callback, aIID, getter_AddRefs(wrappedJS));
if (NS_FAILED(rv) || !wrappedJS) {
return nullptr;
}

View File

@ -3299,13 +3299,14 @@ for (uint32_t i = 0; i < length; ++i) {
holderType = CGTemplatedType("Maybe", holderType)
# If we're isOptional and not nullable the normal optional handling will
# handle lazy construction of our holder. If we're nullable we do it
# all by hand because we do not want our holder constructed if we're
# null.
# handle lazy construction of our holder. If we're nullable and not
# isMember we do it all by hand because we do not want our holder
# constructed if we're null. But if we're isMember we don't have a
# holder anyway, so we can do the normal Optional codepath.
declLoc = "${declName}"
constructDecl = None
if nullable:
if isOptional:
if isOptional and not isMember:
holderArgs = "${declName}.Value().SetValue()"
declType = CGTemplatedType("Optional", declType)
constructDecl = CGGeneric("${declName}.Construct();")
@ -3374,7 +3375,7 @@ for (uint32_t i = 0; i < length; ++i) {
declType=declType,
holderType=holderType,
holderArgs=holderArgs,
dealWithOptional=isOptional and not nullable)
dealWithOptional=isOptional and (not nullable or isMember))
if type.isGeckoInterface():
assert not isEnforceRange and not isClamp

View File

@ -791,6 +791,7 @@ dictionary Dict : ParentDict {
#ifdef DEBUG
(EventInit or long) eventInitOrLong;
(EventInit or long)? nullableEventInitOrLong;
(Node or long)? nullableNodeOrLong;
// CustomEventInit is useful to test because it needs rooting.
(CustomEventInit or long) eventInitOrLong2;
(CustomEventInit or long)? nullableEventInitOrLong2;

View File

@ -74,6 +74,7 @@ var ecmaGlobals =
"ReferenceError",
"RegExp",
"Set",
{name: "SIMD", nightly: true},
"StopIteration",
"String",
"SyntaxError",

View File

@ -568,7 +568,7 @@ struct JSClass {
// with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was
// previously allowed, but is now an ES5 violation and thus unsupported.
//
#define JSCLASS_GLOBAL_SLOT_COUNT (3 + JSProto_LIMIT * 3 + 27)
#define JSCLASS_GLOBAL_SLOT_COUNT (3 + JSProto_LIMIT * 3 + 29)
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
#define JSCLASS_GLOBAL_FLAGS \

952
js/src/builtin/SIMD.cpp Normal file
View File

@ -0,0 +1,952 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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/. */
/*
* JS SIMD pseudo-module.
* Specification matches polyfill:
* https://github.com/johnmccutchan/ecmascript_simd/blob/master/src/ecmascript_simd.js
* The objects float32x4 and int32x4 are installed on the SIMD pseudo-module.
*/
#include "builtin/SIMD.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "builtin/TypedObject.h"
#include "jsobjinlines.h"
using namespace js;
using mozilla::ArrayLength;
using mozilla::IsFinite;
using mozilla::IsNaN;
namespace js {
extern const JSFunctionSpec Float32x4Methods[];
extern const JSFunctionSpec Int32x4Methods[];
}
///////////////////////////////////////////////////////////////////////////
// X4
namespace js {
struct Float32x4 {
typedef float Elem;
static const int32_t lanes = 4;
static const X4TypeRepresentation::Type type =
X4TypeRepresentation::TYPE_FLOAT32;
static JSObject &GetTypeObject(GlobalObject &global) {
return global.float32x4TypeObject();
}
static Elem toType(Elem a) {
return a;
}
static void toType2(JSContext *cx, JS::Handle<JS::Value> v, Elem *out) {
*out = v.toNumber();
}
static void setReturn(CallArgs &args, float value) {
args.rval().setDouble(value);
}
};
struct Int32x4 {
typedef int32_t Elem;
static const int32_t lanes = 4;
static const X4TypeRepresentation::Type type =
X4TypeRepresentation::TYPE_INT32;
static JSObject &GetTypeObject(GlobalObject &global) {
return global.int32x4TypeObject();
}
static Elem toType(Elem a) {
return ToInt32(a);
}
static void toType2(JSContext *cx, JS::Handle<JS::Value> v, Elem *out) {
ToInt32(cx,v,out);
}
static void setReturn(CallArgs &args, int32_t value) {
args.rval().setInt32(value);
}
};
} // namespace js
#define LANE_ACCESSOR(Type32x4, lane) \
bool Type32x4##Lane##lane(JSContext *cx, unsigned argc, Value *vp) { \
static const char *laneNames[] = {"lane 0", "lane 1", "lane 2", "lane3"}; \
CallArgs args = CallArgsFromVp(argc, vp); \
if(!args.thisv().isObject() || !IsTypedDatum(args.thisv().toObject())) { \
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, \
X4Type::class_.name, laneNames[lane], \
InformalValueTypeName(args.thisv())); \
return false; \
} \
TypedDatum &datum = AsTypedDatum(args.thisv().toObject()); \
TypeRepresentation *typeRepr = datum.datumTypeRepresentation(); \
if (typeRepr->kind() != TypeRepresentation::X4 || typeRepr->asX4()->type() != Type32x4::type) { \
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, \
X4Type::class_.name, laneNames[lane], \
InformalValueTypeName(args.thisv())); \
return false; \
} \
Type32x4::Elem *data = reinterpret_cast<Type32x4::Elem *>(datum.typedMem()); \
Type32x4::setReturn(args, data[lane]); \
return true; \
}
LANE_ACCESSOR(Float32x4, 0);
LANE_ACCESSOR(Float32x4, 1);
LANE_ACCESSOR(Float32x4, 2);
LANE_ACCESSOR(Float32x4, 3);
LANE_ACCESSOR(Int32x4, 0);
LANE_ACCESSOR(Int32x4, 1);
LANE_ACCESSOR(Int32x4, 2);
LANE_ACCESSOR(Int32x4, 3);
#undef LANE_ACCESSOR
#define SIGN_MASK(Type32x4) \
bool Type32x4##SignMask(JSContext *cx, unsigned argc, Value *vp) { \
CallArgs args = CallArgsFromVp(argc, vp); \
if(!args.thisv().isObject() || !IsTypedDatum(args.thisv().toObject())) { \
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, \
X4Type::class_.name, "signMask", \
InformalValueTypeName(args.thisv())); \
return false; \
} \
TypedDatum &datum = AsTypedDatum(args.thisv().toObject()); \
TypeRepresentation *typeRepr = datum.datumTypeRepresentation(); \
if (typeRepr->kind() != TypeRepresentation::X4 || typeRepr->asX4()->type() != Type32x4::type) { \
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, \
X4Type::class_.name, "signMask", \
InformalValueTypeName(args.thisv())); \
return false; \
} \
Type32x4::Elem *data = reinterpret_cast<Type32x4::Elem *>(datum.typedMem()); \
int32_t mx = data[0] < 0.0 ? 1 : 0; \
int32_t my = data[1] < 0.0 ? 1 : 0; \
int32_t mz = data[2] < 0.0 ? 1 : 0; \
int32_t mw = data[3] < 0.0 ? 1 : 0; \
int32_t result = mx | my << 1 | mz << 2 | mw << 3; \
args.rval().setInt32(result); \
return true; \
}
SIGN_MASK(Float32x4);
SIGN_MASK(Int32x4);
#undef SIGN_MASK
const Class X4Type::class_ = {
"X4",
JSCLASS_HAS_RESERVED_SLOTS(JS_TYPEOBJ_X4_SLOTS),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
nullptr, /* finalize */
nullptr, /* checkAccess */
call, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr
};
// These classes just exist to group together various properties and so on.
namespace js {
class Int32x4Defn {
public:
static const X4TypeRepresentation::Type type = X4TypeRepresentation::TYPE_INT32;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSPropertySpec TypeObjectProperties[];
static const JSFunctionSpec TypeObjectMethods[];
};
class Float32x4Defn {
public:
static const X4TypeRepresentation::Type type = X4TypeRepresentation::TYPE_FLOAT32;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSPropertySpec TypeObjectProperties[];
static const JSFunctionSpec TypeObjectMethods[];
};
} // namespace js
const JSFunctionSpec js::Float32x4Defn::TypeDescriptorMethods[] = {
JS_FN("toSource", TypeObjectToSource, 0, 0),
JS_SELF_HOSTED_FN("handle", "HandleCreate", 2, 0),
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
JS_SELF_HOSTED_FN("equivalent", "TypeObjectEquivalent", 1, 0),
JS_FS_END
};
const JSPropertySpec js::Float32x4Defn::TypeObjectProperties[] = {
JS_PSG("x", Float32x4Lane0, JSPROP_PERMANENT),
JS_PSG("y", Float32x4Lane1, JSPROP_PERMANENT),
JS_PSG("z", Float32x4Lane2, JSPROP_PERMANENT),
JS_PSG("w", Float32x4Lane3, JSPROP_PERMANENT),
JS_PSG("signMask", Float32x4SignMask, JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec js::Float32x4Defn::TypeObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "X4ToSource", 0, 0),
JS_FS_END
};
const JSFunctionSpec js::Int32x4Defn::TypeDescriptorMethods[] = {
JS_FN("toSource", TypeObjectToSource, 0, 0),
JS_SELF_HOSTED_FN("handle", "HandleCreate", 2, 0),
JS_SELF_HOSTED_FN("array", "ArrayShorthand", 1, 0),
JS_SELF_HOSTED_FN("equivalent", "TypeObjectEquivalent", 1, 0),
JS_FS_END,
};
const JSPropertySpec js::Int32x4Defn::TypeObjectProperties[] = {
JS_PSG("x", Int32x4Lane0, JSPROP_PERMANENT),
JS_PSG("y", Int32x4Lane1, JSPROP_PERMANENT),
JS_PSG("z", Int32x4Lane2, JSPROP_PERMANENT),
JS_PSG("w", Int32x4Lane3, JSPROP_PERMANENT),
JS_PSG("signMask", Int32x4SignMask, JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec js::Int32x4Defn::TypeObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "X4ToSource", 0, 0),
JS_FS_END
};
template<typename T>
static JSObject *
CreateX4Class(JSContext *cx, Handle<GlobalObject*> global)
{
RootedObject funcProto(cx, global->getOrCreateFunctionPrototype(cx));
if (!funcProto)
return nullptr;
// Create type representation.
RootedObject typeReprObj(cx);
typeReprObj = X4TypeRepresentation::Create(cx, T::type);
if (!typeReprObj)
return nullptr;
// Create prototype property, which inherits from Object.prototype.
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
if (!objProto)
return nullptr;
RootedObject proto(cx);
proto = NewObjectWithGivenProto(cx, &JSObject::class_, objProto, global, SingletonObject);
if (!proto)
return nullptr;
// Create type constructor itself.
RootedObject x4(cx);
x4 = NewObjectWithClassProto(cx, &X4Type::class_, funcProto, global);
if (!x4 ||
!InitializeCommonTypeDescriptorProperties(cx, x4, typeReprObj) ||
!DefinePropertiesAndBrand(cx, proto, nullptr, nullptr))
{
return nullptr;
}
// Link type constructor to the type representation.
x4->initReservedSlot(JS_TYPEOBJ_SLOT_TYPE_REPR, ObjectValue(*typeReprObj));
// Link constructor to prototype and install properties.
if (!JS_DefineFunctions(cx, x4, T::TypeDescriptorMethods))
return nullptr;
if (!LinkConstructorAndPrototype(cx, x4, proto) ||
!DefinePropertiesAndBrand(cx, proto, T::TypeObjectProperties,
T::TypeObjectMethods))
{
return nullptr;
}
return x4;
}
bool
X4Type::call(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
const uint32_t LANES = 4;
if (args.length() < LANES) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
args.callee().getClass()->name, "3", "s");
return false;
}
double values[LANES];
for (uint32_t i = 0; i < LANES; i++) {
if (!ToNumber(cx, args[i], &values[i]))
return false;
}
RootedObject typeObj(cx, &args.callee());
Rooted<TypedObject*> result(cx, TypedObject::createZeroed(cx, typeObj, 0));
if (!result)
return false;
X4TypeRepresentation *typeRepr = typeRepresentation(*typeObj)->asX4();
switch (typeRepr->type()) {
#define STORE_LANES(_constant, _type, _name) \
case _constant: \
{ \
_type *mem = reinterpret_cast<_type*>(result->typedMem()); \
for (uint32_t i = 0; i < LANES; i++) { \
mem[i] = ConvertScalar<_type>(values[i]); \
} \
break; \
}
JS_FOR_EACH_X4_TYPE_REPR(STORE_LANES)
#undef STORE_LANES
}
args.rval().setObject(*result);
return true;
}
///////////////////////////////////////////////////////////////////////////
// SIMD class
const Class SIMDObject::class_ = {
"SIMD",
JSCLASS_HAS_CACHED_PROTO(JSProto_SIMD),
JS_PropertyStub, /* addProperty */
JS_DeletePropertyStub, /* delProperty */
JS_PropertyStub, /* getProperty */
JS_StrictPropertyStub, /* setProperty */
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
nullptr, /* finalize */
nullptr, /* checkAccess */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */
nullptr
};
JSObject *
SIMDObject::initClass(JSContext *cx, Handle<GlobalObject *> global)
{
// Create SIMD Object.
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
if(!objProto)
return nullptr;
RootedObject SIMD(cx, NewObjectWithGivenProto(cx, &SIMDObject::class_, objProto,
global, SingletonObject));
if (!SIMD)
return nullptr;
// float32x4
RootedObject float32x4Object(cx, CreateX4Class<Float32x4Defn>(cx, global));
if (!float32x4Object)
return nullptr;
// Define float32x4 functions and install as a property of the SIMD object.
global->setFloat32x4TypeObject(*float32x4Object);
RootedValue float32x4Value(cx, ObjectValue(*float32x4Object));
if (!JS_DefineFunctions(cx, float32x4Object, Float32x4Methods) ||
!JSObject::defineProperty(cx, SIMD, cx->names().float32x4,
float32x4Value, nullptr, nullptr,
JSPROP_READONLY | JSPROP_PERMANENT))
{
return nullptr;
}
// int32x4
RootedObject int32x4Object(cx, CreateX4Class<Int32x4Defn>(cx, global));
if (!int32x4Object)
return nullptr;
// Define int32x4 functions and install as a property of the SIMD object.
global->setInt32x4TypeObject(*int32x4Object);
RootedValue int32x4Value(cx, ObjectValue(*int32x4Object));
if (!JS_DefineFunctions(cx, int32x4Object, Int32x4Methods) ||
!JSObject::defineProperty(cx, SIMD, cx->names().int32x4,
int32x4Value, nullptr, nullptr,
JSPROP_READONLY | JSPROP_PERMANENT))
{
return nullptr;
}
RootedValue SIMDValue(cx, ObjectValue(*SIMD));
global->setConstructor(JSProto_SIMD, SIMDValue);
// Everything is set up, install SIMD on the global object.
if (!JSObject::defineProperty(cx, global, cx->names().SIMD, SIMDValue, nullptr, nullptr, 0)) {
return nullptr;
}
return SIMD;
}
JSObject *
js_InitSIMDClass(JSContext *cx, HandleObject obj)
{
JS_ASSERT(obj->is<GlobalObject>());
Rooted<GlobalObject *> global(cx, &obj->as<GlobalObject>());
return SIMDObject::initClass(cx, global);
}
template<typename V>
static bool
ObjectIsVector(JSObject &obj) {
if (!IsTypedDatum(obj))
return false;
TypeRepresentation *typeRepr = AsTypedDatum(obj).datumTypeRepresentation();
if (typeRepr->kind() != TypeRepresentation::X4)
return false;
return typeRepr->asX4()->type() == V::type;
}
template<typename V>
static JSObject *
Create(JSContext *cx, typename V::Elem *data)
{
RootedObject typeObj(cx, &V::GetTypeObject(*cx->global()));
JS_ASSERT(typeObj);
Rooted<TypedObject *> result(cx, TypedObject::createZeroed(cx, typeObj, 0));
if (!result)
return nullptr;
typename V::Elem *resultMem = reinterpret_cast<typename V::Elem *>(result->typedMem());
memcpy(resultMem, data, sizeof(typename V::Elem) * V::lanes);
return result;
}
namespace js {
template<typename T, typename V>
struct Abs {
static inline T apply(T x, T zero) {return V::toType(x < 0 ? -1 * x : x);}
};
template<typename T, typename V>
struct Neg {
static inline T apply(T x, T zero) {return V::toType(-1 * x);}
};
template<typename T, typename V>
struct Not {
static inline T apply(T x, T zero) {return V::toType(~x);}
};
template<typename T, typename V>
struct Rec {
static inline T apply(T x, T zero) {return V::toType(1 / x);}
};
template<typename T, typename V>
struct RecSqrt {
static inline T apply(T x, T zero) {return V::toType(1 / sqrt(x));}
};
template<typename T, typename V>
struct Sqrt {
static inline T apply(T x, T zero) {return V::toType(sqrt(x));}
};
template<typename T, typename V>
struct Add {
static inline T apply(T l, T r) {return V::toType(l + r);}
};
template<typename T, typename V>
struct Sub {
static inline T apply(T l, T r) {return V::toType(l - r);}
};
template<typename T, typename V>
struct Div {
static inline T apply(T l, T r) {return V::toType(l / r);}
};
template<typename T, typename V>
struct Mul {
static inline T apply(T l, T r) {return V::toType(l * r);}
};
template<typename T, typename V>
struct Minimum {
static inline T apply(T l, T r) {return V::toType(l < r ? l : r);}
};
template<typename T, typename V>
struct Maximum {
static inline T apply(T l, T r) {return V::toType(l > r ? l : r);}
};
template<typename T, typename V>
struct LessThan {
static inline T apply(T l, T r) {return V::toType(l < r ? 0xFFFFFFFF: 0x0);}
};
template<typename T, typename V>
struct LessThanOrEqual {
static inline T apply(T l, T r) {return V::toType(l <= r ? 0xFFFFFFFF: 0x0);}
};
template<typename T, typename V>
struct GreaterThan {
static inline T apply(T l, T r) {return V::toType(l > r ? 0xFFFFFFFF: 0x0);}
};
template<typename T, typename V>
struct GreaterThanOrEqual {
static inline T apply(T l, T r) {return V::toType(l >= r ? 0xFFFFFFFF: 0x0);}
};
template<typename T, typename V>
struct Equal {
static inline T apply(T l, T r) {return V::toType(l == r ? 0xFFFFFFFF: 0x0);}
};
template<typename T, typename V>
struct NotEqual {
static inline T apply(T l, T r) {return V::toType(l != r ? 0xFFFFFFFF: 0x0);}
};
template<typename T, typename V>
struct Xor {
static inline T apply(T l, T r) {return V::toType(l ^ r);}
};
template<typename T, typename V>
struct And {
static inline T apply(T l, T r) {return V::toType(l & r);}
};
template<typename T, typename V>
struct Or {
static inline T apply(T l, T r) {return V::toType(l | r);}
};
template<typename T, typename V>
struct Scale {
static inline T apply(int32_t lane, T scalar, T x) {return V::toType(scalar * x);}
};
template<typename T, typename V>
struct WithX {
static inline T apply(int32_t lane, T scalar, T x) {return V::toType(lane == 0 ? scalar : x);}
};
template<typename T, typename V>
struct WithY {
static inline T apply(int32_t lane, T scalar, T x) {return V::toType(lane == 1 ? scalar : x);}
};
template<typename T, typename V>
struct WithZ {
static inline T apply(int32_t lane, T scalar, T x) {return V::toType(lane == 2 ? scalar : x);}
};
template<typename T, typename V>
struct WithW {
static inline T apply(int32_t lane, T scalar, T x) {return V::toType(lane == 3 ? scalar : x);}
};
template<typename T, typename V>
struct WithFlagX {
static inline T apply(T l, T f, T x) { return V::toType(l == 0 ? (f ? 0xFFFFFFFF : 0x0) : x);}
};
template<typename T, typename V>
struct WithFlagY {
static inline T apply(T l, T f, T x) { return V::toType(l == 1 ? (f ? 0xFFFFFFFF : 0x0) : x);}
};
template<typename T, typename V>
struct WithFlagZ {
static inline T apply(T l, T f, T x) { return V::toType(l == 2 ? (f ? 0xFFFFFFFF : 0x0) : x);}
};
template<typename T, typename V>
struct WithFlagW {
static inline T apply(T l, T f, T x) { return V::toType(l == 3 ? (f ? 0xFFFFFFFF : 0x0) : x);}
};
template<typename T, typename V>
struct Shuffle {
static inline int32_t apply(int32_t l, int32_t mask) {return V::toType((mask >> l) & 0x3);}
};
}
template<typename V, typename Op, typename Vret>
static bool
Func(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (argc == 1) {
if((!args[0].isObject() || !ObjectIsVector<V>(args[0].toObject()))) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
typename V::Elem *val =
reinterpret_cast<typename V::Elem *>(AsTypedDatum(args[0].toObject()).typedMem());
typename Vret::Elem result[Vret::lanes];
for (int32_t i = 0; i < Vret::lanes; i++)
result[i] = Op::apply(val[i], 0);
RootedObject obj(cx, Create<Vret>(cx, result));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
} else if (argc == 2) {
if((!args[0].isObject() || !ObjectIsVector<V>(args[0].toObject())) ||
(!args[1].isObject() || !ObjectIsVector<V>(args[1].toObject())))
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
typename V::Elem *left =
reinterpret_cast<typename V::Elem *>(AsTypedDatum(args[0].toObject()).typedMem());
typename V::Elem *right =
reinterpret_cast<typename V::Elem *>(AsTypedDatum(args[1].toObject()).typedMem());
typename Vret::Elem result[Vret::lanes];
for (int32_t i = 0; i < Vret::lanes; i++)
result[i] = Op::apply(left[i], right[i]);
RootedObject obj(cx, Create<Vret>(cx, result));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
} else {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
}
template<typename V, typename OpWith, typename Vret>
static bool
FuncWith(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if ((argc != 2) ||
(!args[0].isObject() || !ObjectIsVector<V>(args[0].toObject())) ||
(!args[1].isNumber() && !args[1].isBoolean()))
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
typename V::Elem *val =
reinterpret_cast<typename V::Elem *>(AsTypedDatum(args[0].toObject()).typedMem());
typename Vret::Elem result[Vret::lanes];
for (int32_t i = 0; i < Vret::lanes; i++) {
if(args[1].isNumber()) {
typename Vret::Elem arg1;
Vret::toType2(cx, args[1], &arg1);
result[i] = OpWith::apply(i, arg1, val[i]);
} else if (args[1].isBoolean()) {
result[i] = OpWith::apply(i, args[1].toBoolean(), val[i]);
}
}
RootedObject obj(cx, Create<Vret>(cx, result));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
template<typename V, typename OpShuffle, typename Vret>
static bool
FuncShuffle(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if(argc == 2){
if ((!args[0].isObject() || !ObjectIsVector<V>(args[0].toObject())) ||
(!args[1].isNumber()))
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
typename V::Elem *val =
reinterpret_cast<typename V::Elem *>(AsTypedDatum(args[0].toObject()).typedMem());
typename Vret::Elem result[Vret::lanes];
for (int32_t i = 0; i < Vret::lanes; i++) {
typename Vret::Elem arg1;
Vret::toType2(cx, args[1], &arg1);
result[i] = val[OpShuffle::apply(i * 2, arg1)];
}
RootedObject obj(cx, Create<Vret>(cx, result));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
} else if (argc == 3){
if ((!args[0].isObject() || !ObjectIsVector<V>(args[0].toObject())) ||
(!args[1].isObject() || !ObjectIsVector<V>(args[1].toObject())) ||
(!args[2].isNumber()))
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
typename V::Elem *val1 =
reinterpret_cast<typename V::Elem *>(AsTypedDatum(args[0].toObject()).typedMem());
typename V::Elem *val2 =
reinterpret_cast<typename V::Elem *>(AsTypedDatum(args[1].toObject()).typedMem());
typename Vret::Elem result[Vret::lanes];
for (int32_t i = 0; i < Vret::lanes; i++) {
typename Vret::Elem arg2;
Vret::toType2(cx, args[2], &arg2);
if(i < Vret::lanes / 2) {
result[i] = val1[OpShuffle::apply(i * 2, arg2)];
} else {
result[i] = val2[OpShuffle::apply(i * 2, arg2)];
}
}
RootedObject obj(cx, Create<Vret>(cx, result));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
} else {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
}
template<typename V, typename Vret>
static bool
FuncConvert(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if ((argc != 1) ||
(!args[0].isObject() || !ObjectIsVector<V>(args[0].toObject())))
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
typename V::Elem *val =
reinterpret_cast<typename V::Elem *>(AsTypedDatum(args[0].toObject()).typedMem());
typename Vret::Elem result[Vret::lanes];
for (int32_t i = 0; i < Vret::lanes; i++)
result[i] = static_cast<typename Vret::Elem>(val[i]);
RootedObject obj(cx, Create<Vret>(cx, result));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
template<typename V, typename Vret>
static bool
FuncConvertBits(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if ((argc != 1) ||
(!args[0].isObject() || !ObjectIsVector<V>(args[0].toObject())))
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
typename Vret::Elem *val =
reinterpret_cast<typename Vret::Elem *>(AsTypedDatum(args[0].toObject()).typedMem());
RootedObject obj(cx, Create<Vret>(cx, val));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
template<typename Vret>
static bool
FuncZero(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (argc != 0) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
typename Vret::Elem result[Vret::lanes];
for (int32_t i = 0; i < Vret::lanes; i++)
result[i] = static_cast<typename Vret::Elem>(0);
RootedObject obj(cx, Create<Vret>(cx, result));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
template<typename Vret>
static bool
FuncSplat(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if ((argc != 1) || (!args[0].isNumber())) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
typename Vret::Elem result[Vret::lanes];
for (int32_t i = 0; i < Vret::lanes; i++) {
typename Vret::Elem arg0;
Vret::toType2(cx, args[0], &arg0);
result[i] = static_cast<typename Vret::Elem>(arg0);
}
RootedObject obj(cx, Create<Vret>(cx, result));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
static bool
Int32x4Bool(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if ((argc != 4) ||
(!args[0].isBoolean()) || !args[1].isBoolean() ||
(!args[2].isBoolean()) || !args[3].isBoolean())
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
int32_t result[Int32x4::lanes];
for (int32_t i = 0; i < Int32x4::lanes; i++)
result[i] = args[i].toBoolean() ? 0xFFFFFFFF : 0x0;
RootedObject obj(cx, Create<Int32x4>(cx, result));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
static bool
Float32x4Clamp(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if ((argc != 3) ||
(!args[0].isObject() || !ObjectIsVector<Float32x4>(args[0].toObject())) ||
(!args[1].isObject() || !ObjectIsVector<Float32x4>(args[1].toObject())) ||
(!args[2].isObject() || !ObjectIsVector<Float32x4>(args[2].toObject())))
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
float *val = reinterpret_cast<float *>(AsTypedDatum(args[0].toObject()).typedMem());
float *lowerLimit = reinterpret_cast<float *>(AsTypedDatum(args[1].toObject()).typedMem());
float *upperLimit = reinterpret_cast<float *>(AsTypedDatum(args[2].toObject()).typedMem());
float result[Float32x4::lanes];
result[0] = val[0] < lowerLimit[0] ? lowerLimit[0] : val[0];
result[1] = val[1] < lowerLimit[1] ? lowerLimit[1] : val[1];
result[2] = val[2] < lowerLimit[2] ? lowerLimit[2] : val[2];
result[3] = val[3] < lowerLimit[3] ? lowerLimit[3] : val[3];
result[0] = result[0] > upperLimit[0] ? upperLimit[0] : result[0];
result[1] = result[1] > upperLimit[1] ? upperLimit[1] : result[1];
result[2] = result[2] > upperLimit[2] ? upperLimit[2] : result[2];
result[3] = result[3] > upperLimit[3] ? upperLimit[3] : result[3];
RootedObject obj(cx, Create<Float32x4>(cx, result));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
static bool
Int32x4Select(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if ((argc != 3) ||
(!args[0].isObject() || !ObjectIsVector<Int32x4>(args[0].toObject())) ||
(!args[1].isObject() || !ObjectIsVector<Float32x4>(args[1].toObject())) ||
(!args[2].isObject() || !ObjectIsVector<Float32x4>(args[2].toObject())))
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_BAD_ARGS);
return false;
}
int32_t *val = reinterpret_cast<int32_t *>(AsTypedDatum(args[0].toObject()).typedMem());
int32_t *tv = reinterpret_cast<int32_t *>(AsTypedDatum(args[1].toObject()).typedMem());
int32_t *fv = reinterpret_cast<int32_t *>(AsTypedDatum(args[2].toObject()).typedMem());
int32_t tr[Int32x4::lanes];
for (int32_t i = 0; i < Int32x4::lanes; i++)
tr[i] = And<int32_t, Int32x4>::apply(val[i], tv[i]);
int32_t fr[Int32x4::lanes];
for (int32_t i = 0; i < Int32x4::lanes; i++)
fr[i] = And<int32_t, Int32x4>::apply(Not<int32_t, Int32x4>::apply(val[i], 0), fv[i]);
int32_t orInt[Int32x4::lanes];
for (int32_t i = 0; i < Int32x4::lanes; i++)
orInt[i] = Or<int32_t, Int32x4>::apply(tr[i], fr[i]);
float *result[Float32x4::lanes];
*result = reinterpret_cast<float *>(&orInt);
RootedObject obj(cx, Create<Float32x4>(cx, *result));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
const JSFunctionSpec js::Float32x4Methods[] = {
JS_FN("abs", (Func<Float32x4, Abs<float, Float32x4>, Float32x4>), 1, 0),
JS_FN("neg", (Func<Float32x4, Neg<float, Float32x4>, Float32x4>), 1, 0),
JS_FN("reciprocal", (Func<Float32x4, Rec<float, Float32x4>, Float32x4>), 1, 0),
JS_FN("reciprocalSqrt", (Func<Float32x4, RecSqrt<float, Float32x4>, Float32x4>), 1, 0),
JS_FN("sqrt", (Func<Float32x4, Sqrt<float, Float32x4>, Float32x4>), 1, 0),
JS_FN("add", (Func<Float32x4, Add<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("sub", (Func<Float32x4, Sub<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("div", (Func<Float32x4, Div<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("mul", (Func<Float32x4, Mul<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("max", (Func<Float32x4, Maximum<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("min", (Func<Float32x4, Minimum<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("lessThan", (Func<Float32x4, LessThan<float, Int32x4>, Int32x4>), 2, 0),
JS_FN("lessThanOrEqual", (Func<Float32x4, LessThanOrEqual<float, Int32x4>, Int32x4>), 2, 0),
JS_FN("greaterThan", (Func<Float32x4, GreaterThan<float, Int32x4>, Int32x4>), 2, 0),
JS_FN("greaterThanOrEqual", (Func<Float32x4, GreaterThanOrEqual<float, Int32x4>, Int32x4>), 2, 0),
JS_FN("equal", (Func<Float32x4, Equal<float, Int32x4>, Int32x4>), 2, 0),
JS_FN("notEqual", (Func<Float32x4, NotEqual<float, Int32x4>, Int32x4>), 2, 0),
JS_FN("withX", (FuncWith<Float32x4, WithX<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("withY", (FuncWith<Float32x4, WithY<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("withZ", (FuncWith<Float32x4, WithZ<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("withW", (FuncWith<Float32x4, WithW<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("shuffle", (FuncShuffle<Float32x4, Shuffle<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("shuffleMix", (FuncShuffle<Float32x4, Shuffle<float, Float32x4>, Float32x4>), 3, 0),
JS_FN("scale", (FuncWith<Float32x4, Scale<float, Float32x4>, Float32x4>), 2, 0),
JS_FN("clamp", Float32x4Clamp, 3, 0),
JS_FN("toInt32x4", (FuncConvert<Float32x4, Int32x4>), 1, 0),
JS_FN("bitsToInt32x4", (FuncConvertBits<Float32x4, Int32x4>), 1, 0),
JS_FN("zero", (FuncZero<Float32x4>), 0, 0),
JS_FN("splat", (FuncSplat<Float32x4>), 0, 0),
JS_FS_END
};
const JSFunctionSpec js::Int32x4Methods[] = {
JS_FN("not", (Func<Int32x4, Not<int32_t, Int32x4>, Int32x4>), 1, 0),
JS_FN("neg", (Func<Int32x4, Neg<int32_t, Int32x4>, Int32x4>), 1, 0),
JS_FN("add", (Func<Int32x4, Add<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("sub", (Func<Int32x4, Sub<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("mul", (Func<Int32x4, Mul<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("xor", (Func<Int32x4, Xor<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("and", (Func<Int32x4, And<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("or", (Func<Int32x4, Or<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("withX", (FuncWith<Int32x4, WithX<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("withY", (FuncWith<Int32x4, WithY<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("withZ", (FuncWith<Int32x4, WithZ<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("withW", (FuncWith<Int32x4, WithW<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("withFlagX", (FuncWith<Int32x4, WithFlagX<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("withFlagY", (FuncWith<Int32x4, WithFlagY<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("withFlagZ", (FuncWith<Int32x4, WithFlagZ<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("withFlagW", (FuncWith<Int32x4, WithFlagW<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("shuffle", (FuncShuffle<Int32x4, Shuffle<int32_t, Int32x4>, Int32x4>), 2, 0),
JS_FN("shuffleMix", (FuncShuffle<Int32x4, Shuffle<int32_t, Int32x4>, Int32x4>), 3, 0),
JS_FN("toFloat32x4", (FuncConvert<Int32x4, Float32x4>), 1, 0),
JS_FN("bitsToFloat32x4", (FuncConvertBits<Int32x4, Float32x4>), 1, 0),
JS_FN("zero", (FuncZero<Int32x4>), 0, 0),
JS_FN("splat", (FuncSplat<Int32x4>), 0, 0),
JS_FN("select", Int32x4Select, 3, 0),
JS_FN("bool", Int32x4Bool, 4, 0),
JS_FS_END
};

34
js/src/builtin/SIMD.h Normal file
View File

@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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_SIMD_h
#define builtin_SIMD_h
#include "jsapi.h"
#include "jsobj.h"
/*
* JS SIMD functions.
* Spec matching polyfill:
* https://github.com/johnmccutchan/ecmascript_simd/blob/master/src/ecmascript_simd.js
*/
namespace js {
class SIMDObject : public JSObject
{
public:
static const Class class_;
static JSObject* initClass(JSContext *cx, Handle<GlobalObject *> global);
static bool toString(JSContext *cx, unsigned int argc, jsval *vp);
};
} /* namespace js */
JSObject *
js_InitSIMDClass(JSContext *cx, js::HandleObject obj);
#endif /* builtin_SIMD_h */

View File

@ -367,15 +367,13 @@ TypeRepresentation::addToTableOrFree(JSContext *cx,
Rooted<GlobalObject*> global(cx, cx->global());
JSCompartment *comp = cx->compartment();
// First, try to create the typed object to associate with this
// First, try to create the TI type object to associate with this
// type representation. Since nothing is in the table yet, if this
// fails we can just return and pretend this whole endeavor was
// just a bad dream.
RootedObject proto(cx);
const Class *clasp;
if (!global->getTypedObjectModule().getSuitableClaspAndProto(cx, kind(),
&clasp, &proto))
{
if (!TypedObjectModuleObject::getSuitableClaspAndProto(cx, kind(), &clasp, &proto)) {
return nullptr;
}
RootedTypeObject typeObject(cx, comp->types.newTypeObject(cx, clasp, proto));

View File

@ -63,88 +63,72 @@ ToObjectIfObject(HandleValue value)
return &value.toObject();
}
static inline bool
IsTypedDatum(JSObject &obj)
{
return obj.is<TypedObject>() || obj.is<TypedHandle>();
}
static inline uint8_t *
TypedMem(JSObject &val)
TypedMem(const JSObject &val)
{
JS_ASSERT(IsTypedDatum(val));
return (uint8_t*) val.getPrivate();
}
static inline bool IsTypeObject(JSObject &type);
static inline bool IsTypeObject(const JSObject &type);
/*
* Given a user-visible type descriptor object, returns the
* owner object for the TypeRepresentation* that we use internally.
*/
static JSObject *
typeRepresentationOwnerObj(JSObject &typeObj)
JSObject *
js::typeRepresentationOwnerObj(const JSObject &typeObj)
{
JS_ASSERT(IsTypeObject(typeObj));
return &typeObj.getReservedSlot(JS_TYPEOBJ_SLOT_TYPE_REPR).toObject();
}
/*
* Given a user-visible type descriptor object, returns the
* TypeRepresentation* that we use internally.
*
* Note: this pointer is valid only so long as `typeObj` remains rooted.
*/
static TypeRepresentation *
typeRepresentation(JSObject &typeObj)
TypeRepresentation *
js::typeRepresentation(const JSObject &typeObj)
{
return TypeRepresentation::fromOwnerObject(*typeRepresentationOwnerObj(typeObj));
}
static inline bool
IsScalarTypeObject(JSObject &type)
IsScalarTypeObject(const JSObject &type)
{
return type.hasClass(&ScalarType::class_);
}
static inline bool
IsReferenceTypeObject(JSObject &type)
IsReferenceTypeObject(const JSObject &type)
{
return type.hasClass(&ReferenceType::class_);
}
static inline bool
IsSimpleTypeObject(JSObject &type)
IsSimpleTypeObject(const JSObject &type)
{
return IsScalarTypeObject(type) || IsReferenceTypeObject(type);
}
static inline bool
IsArrayTypeObject(JSObject &type)
IsArrayTypeObject(const JSObject &type)
{
return type.hasClass(&ArrayType::class_);
}
static inline bool
IsStructTypeObject(JSObject &type)
IsStructTypeObject(const JSObject &type)
{
return type.hasClass(&StructType::class_);
}
static inline bool
IsX4TypeObject(JSObject &type)
IsX4TypeObject(const JSObject &type)
{
return type.hasClass(&X4Type::class_);
}
static inline bool
IsComplexTypeObject(JSObject &type)
IsComplexTypeObject(const JSObject &type)
{
return IsArrayTypeObject(type) || IsStructTypeObject(type);
}
static inline bool
IsTypeObject(JSObject &type)
IsTypeObject(const JSObject &type)
{
return IsScalarTypeObject(type) ||
IsReferenceTypeObject(type) ||
@ -171,14 +155,14 @@ IsSizedTypeObject(JSObject &type)
}
static inline JSObject *
GetType(JSObject &datum)
GetType(const JSObject &datum)
{
JS_ASSERT(IsTypedDatum(datum));
return &datum.getReservedSlot(JS_DATUM_SLOT_TYPE_OBJ).toObject();
}
static bool
TypeObjectToSource(JSContext *cx, unsigned int argc, Value *vp)
bool
js::TypeObjectToSource(JSContext *cx, unsigned int argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
@ -404,20 +388,6 @@ const JSFunctionSpec js::ScalarType::typeObjectMethods[] = {
JS_FS_END
};
template <typename T>
static T ConvertScalar(double d)
{
if (TypeIsFloatingPoint<T>()) {
return T(d);
} else if (TypeIsUnsigned<T>()) {
uint32_t n = ToUint32(d);
return T(n);
} else {
int32_t n = ToInt32(d);
return T(n);
}
}
bool
ScalarType::call(JSContext *cx, unsigned argc, Value *vp)
{
@ -631,10 +601,10 @@ ArrayElementType(JSObject &array)
return &array.getReservedSlot(JS_TYPEOBJ_SLOT_ARRAY_ELEM_TYPE).toObject();
}
static bool
InitializeCommonTypeDescriptorProperties(JSContext *cx,
HandleObject obj,
HandleObject typeReprOwnerObj)
bool
js::InitializeCommonTypeDescriptorProperties(JSContext *cx,
HandleObject obj,
HandleObject typeReprOwnerObj)
{
TypeRepresentation *typeRepr =
TypeRepresentation::fromOwnerObject(*typeReprOwnerObj);
@ -1174,183 +1144,6 @@ DefineSimpleTypeObject(JSContext *cx,
return true;
}
///////////////////////////////////////////////////////////////////////////
// X4
const Class X4Type::class_ = {
"X4",
JSCLASS_HAS_RESERVED_SLOTS(JS_TYPEOBJ_X4_SLOTS),
JS_PropertyStub,
JS_DeletePropertyStub,
JS_PropertyStub,
JS_StrictPropertyStub,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
nullptr,
nullptr,
call,
nullptr,
nullptr,
nullptr
};
// These classes just exist to group together various properties and so on.
namespace js {
class Int32x4Defn {
public:
static const X4TypeRepresentation::Type type = X4TypeRepresentation::TYPE_INT32;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSPropertySpec TypedObjectProperties[];
static const JSFunctionSpec TypedObjectMethods[];
};
class Float32x4Defn {
public:
static const X4TypeRepresentation::Type type = X4TypeRepresentation::TYPE_FLOAT32;
static const JSFunctionSpec TypeDescriptorMethods[];
static const JSPropertySpec TypedObjectProperties[];
static const JSFunctionSpec TypedObjectMethods[];
};
} // namespace js
const JSFunctionSpec js::Int32x4Defn::TypeDescriptorMethods[] = {
JS_FN("toSource", TypeObjectToSource, 0, 0),
{"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"},
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeObjectEquivalent"},
JS_FS_END
};
const JSPropertySpec js::Int32x4Defn::TypedObjectProperties[] = {
JS_SELF_HOSTED_GET("x", "Int32x4Lane0", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("y", "Int32x4Lane1", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("z", "Int32x4Lane2", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("w", "Int32x4Lane3", JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec js::Int32x4Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "X4ToSource", 0, 0),
JS_FS_END
};
const JSFunctionSpec js::Float32x4Defn::TypeDescriptorMethods[] = {
JS_FN("toSource", TypeObjectToSource, 0, 0),
{"handle", {nullptr, nullptr}, 2, 0, "HandleCreate"},
{"array", {nullptr, nullptr}, 1, 0, "ArrayShorthand"},
{"equivalent", {nullptr, nullptr}, 1, 0, "TypeObjectEquivalent"},
JS_FS_END
};
const JSPropertySpec js::Float32x4Defn::TypedObjectProperties[] = {
JS_SELF_HOSTED_GET("x", "Float32x4Lane0", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("y", "Float32x4Lane1", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("z", "Float32x4Lane2", JSPROP_PERMANENT),
JS_SELF_HOSTED_GET("w", "Float32x4Lane3", JSPROP_PERMANENT),
JS_PS_END
};
const JSFunctionSpec js::Float32x4Defn::TypedObjectMethods[] = {
JS_SELF_HOSTED_FN("toSource", "X4ToSource", 0, 0),
JS_FS_END
};
template<typename T>
static JSObject *
CreateX4Class(JSContext *cx, Handle<GlobalObject*> global)
{
RootedObject funcProto(cx, global->getOrCreateFunctionPrototype(cx));
if (!funcProto)
return nullptr;
// Create type representation
RootedObject typeReprObj(cx);
typeReprObj = X4TypeRepresentation::Create(cx, T::type);
if (!typeReprObj)
return nullptr;
// Create prototype property, which inherits from Object.prototype
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
if (!objProto)
return nullptr;
RootedObject proto(cx);
proto = NewObjectWithGivenProto(cx, &JSObject::class_, objProto, global, SingletonObject);
if (!proto)
return nullptr;
// Create type constructor itself
RootedObject x4(cx);
x4 = NewObjectWithClassProto(cx, &X4Type::class_, funcProto, global);
if (!x4 ||
!InitializeCommonTypeDescriptorProperties(cx, x4, typeReprObj) ||
!DefinePropertiesAndBrand(cx, proto, nullptr, nullptr))
{
return nullptr;
}
// Link type constructor to the type representation
x4->initReservedSlot(JS_TYPEOBJ_SLOT_TYPE_REPR, ObjectValue(*typeReprObj));
// Link constructor to prototype and install properties
if (!JS_DefineFunctions(cx, x4, T::TypeDescriptorMethods))
return nullptr;
if (!LinkConstructorAndPrototype(cx, x4, proto) ||
!DefinePropertiesAndBrand(cx, proto, T::TypedObjectProperties,
T::TypedObjectMethods))
{
return nullptr;
}
return x4;
}
bool
X4Type::call(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
const uint32_t LANES = 4;
if (args.length() < LANES) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
args.callee().getClass()->name, "3", "s");
return false;
}
double values[LANES];
for (uint32_t i = 0; i < LANES; i++) {
if (!ToNumber(cx, args[i], &values[i]))
return false;
}
RootedObject typeObj(cx, &args.callee());
RootedObject result(cx, TypedObject::createZeroed(cx, typeObj, 0));
if (!result)
return false;
X4TypeRepresentation *typeRepr = typeRepresentation(*typeObj)->asX4();
switch (typeRepr->type()) {
#define STORE_LANES(_constant, _type, _name) \
case _constant: \
{ \
_type *mem = (_type*) TypedMem(*result); \
for (uint32_t i = 0; i < LANES; i++) { \
mem[i] = values[i]; \
} \
break; \
}
JS_FOR_EACH_X4_TYPE_REPR(STORE_LANES)
#undef STORE_LANES
}
args.rval().setObject(*result);
return true;
}
///////////////////////////////////////////////////////////////////////////
template<typename T>
@ -1417,6 +1210,12 @@ DefineMetaTypeObject(JSContext *cx,
return ctor;
}
/* The initialization strategy for TypedObjects is mildly unusual
* compared to other classes. Because all of the types are members
* of a single global, `TypedObject`, we basically make the
* initializer for the `TypedObject` class populate the
* `TypedObject` global (which is referred to as "module" herein).
*/
bool
GlobalObject::initTypedObjectModule(JSContext *cx, Handle<GlobalObject*> global)
{
@ -1432,34 +1231,6 @@ GlobalObject::initTypedObjectModule(JSContext *cx, Handle<GlobalObject*> global)
if (!JS_DefineFunctions(cx, module, TypedObjectMethods))
return false;
RootedValue moduleValue(cx, ObjectValue(*module));
global->setConstructor(JSProto_TypedObject, moduleValue);
return true;
}
JSObject *
js_InitTypedObjectModuleObject(JSContext *cx, HandleObject obj)
{
/*
* The initialization strategy for TypedObjects is mildly unusual
* compared to other classes. Because all of the types are members
* of a single global, `TypedObject`, we basically make the
* initialized for the `TypedObject` class populate the
* `TypedObject` global (which is referred to as "module" herein).
*/
JS_ASSERT(obj->is<GlobalObject>());
Rooted<GlobalObject *> global(cx, &obj->as<GlobalObject>());
RootedObject module(cx, global->getOrCreateTypedObjectModule(cx));
if (!module)
return nullptr;
// Define TypedObject global.
RootedValue moduleValue(cx, ObjectValue(*module));
// uint8, uint16, any, etc
#define BINARYDATA_SCALAR_DEFINE(constant_, type_, name_) \
@ -1476,38 +1247,6 @@ js_InitTypedObjectModuleObject(JSContext *cx, HandleObject obj)
JS_FOR_EACH_REFERENCE_TYPE_REPR(BINARYDATA_REFERENCE_DEFINE)
#undef BINARYDATA_REFERENCE_DEFINE
// float32x4
RootedObject float32x4Object(cx);
float32x4Object = CreateX4Class<Float32x4Defn>(cx, global);
if (!float32x4Object)
return nullptr;
RootedValue float32x4Value(cx, ObjectValue(*float32x4Object));
if (!JSObject::defineProperty(cx, module, cx->names().float32x4,
float32x4Value,
nullptr, nullptr,
JSPROP_READONLY | JSPROP_PERMANENT))
{
return nullptr;
}
// int32x4
RootedObject int32x4Object(cx);
int32x4Object = CreateX4Class<Int32x4Defn>(cx, global);
if (!int32x4Object)
return nullptr;
RootedValue int32x4Value(cx, ObjectValue(*int32x4Object));
if (!JSObject::defineProperty(cx, module, cx->names().int32x4,
int32x4Value,
nullptr, nullptr,
JSPROP_READONLY | JSPROP_PERMANENT))
{
return nullptr;
}
// ArrayType.
RootedObject arrayType(cx);
@ -1557,15 +1296,27 @@ js_InitTypedObjectModuleObject(JSContext *cx, HandleObject obj)
}
// Everything is setup, install module on the global object:
RootedValue moduleValue(cx, ObjectValue(*module));
global->setConstructor(JSProto_TypedObject, moduleValue);
if (!JSObject::defineProperty(cx, global, cx->names().TypedObject,
moduleValue,
nullptr, nullptr,
0))
{
return nullptr;
}
return module;
}
JSObject *
js_InitTypedObjectModuleObject(JSContext *cx, HandleObject obj)
{
JS_ASSERT(obj->is<GlobalObject>());
Rooted<GlobalObject *> global(cx, &obj->as<GlobalObject>());
return global->getOrCreateTypedObjectModule(cx);
}
JSObject *
js_InitTypedObjectDummy(JSContext *cx, HandleObject obj)
{
@ -1578,41 +1329,56 @@ js_InitTypedObjectDummy(JSContext *cx, HandleObject obj)
MOZ_ASSUME_UNREACHABLE("shouldn't be initializing TypedObject via the JSProtoKey initializer mechanism");
}
bool
/*
* Each type repr has an associated TI type object (these will
* eventually be used as the TI type objects for type objects, though
* they are not now). To create these TI type objects, we need to know
* the clasp/proto of the type object for a particular kind. This
* accessor function returns those. In the case of the predefined type
* objects, like scalars/references/x4s, this is invoked while
* creating the typed object module, and thus does not require that
* the typed object module is fully initialized. For array types and
* struct types, it is invoked when the user creates an instance of
* those types (and hence requires that the typed object module is
* already initialized).
*/
/*static*/ bool
TypedObjectModuleObject::getSuitableClaspAndProto(JSContext *cx,
TypeRepresentation::Kind kind,
const Class **clasp,
MutableHandleObject proto)
{
Rooted<GlobalObject *> global(cx, cx->global());
JS_ASSERT(global);
switch (kind) {
case TypeRepresentation::Scalar:
*clasp = &ScalarType::class_;
proto.set(global().getOrCreateFunctionPrototype(cx));
proto.set(global->getOrCreateFunctionPrototype(cx));
break;
case TypeRepresentation::Reference:
*clasp = &ReferenceType::class_;
proto.set(global().getOrCreateFunctionPrototype(cx));
proto.set(global->getOrCreateFunctionPrototype(cx));
break;
case TypeRepresentation::X4:
*clasp = &X4Type::class_;
proto.set(global().getOrCreateFunctionPrototype(cx));
proto.set(global->getOrCreateFunctionPrototype(cx));
break;
case TypeRepresentation::Struct:
*clasp = &StructType::class_;
proto.set(&getSlot(StructTypePrototype).toObject());
proto.set(&global->getTypedObjectModule().getSlot(StructTypePrototype).toObject());
break;
case TypeRepresentation::SizedArray:
*clasp = &ArrayType::class_;
proto.set(&getSlot(ArrayTypePrototype).toObject());
proto.set(&global->getTypedObjectModule().getSlot(ArrayTypePrototype).toObject());
break;
case TypeRepresentation::UnsizedArray:
*clasp = &ArrayType::class_;
proto.set(&getSlot(ArrayTypePrototype).toObject());
proto.set(&global->getTypedObjectModule().getSlot(ArrayTypePrototype).toObject());
break;
}
@ -2454,6 +2220,18 @@ TypedDatum::dataOffset()
return JSObject::getPrivateDataOffset(JS_DATUM_SLOTS);
}
TypeRepresentation *
TypedDatum::datumTypeRepresentation() const
{
return typeRepresentation(*GetType(*this));
}
uint8_t *
TypedDatum::typedMem() const
{
return TypedMem(*this);
}
/******************************************************************************
* Typed Objects
*/
@ -2854,10 +2632,31 @@ js::GetTypedObjectModule(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
JS_ASSERT(global);
args.rval().setObject(global->getTypedObjectModule());
return true;
}
bool
js::GetFloat32x4TypeObject(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
JS_ASSERT(global);
args.rval().setObject(global->float32x4TypeObject());
return true;
}
bool
js::GetInt32x4TypeObject(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<GlobalObject*> global(cx, cx->global());
JS_ASSERT(global);
args.rval().setObject(global->int32x4TypeObject());
return true;
}
#define JS_STORE_SCALAR_CLASS_IMPL(_constant, T, _name) \
bool \
js::StoreScalar##T::Func(ThreadSafeContext *, unsigned argc, Value *vp) \

View File

@ -111,12 +111,52 @@ class TypedObjectModuleObject : public JSObject {
static const Class class_;
bool getSuitableClaspAndProto(JSContext *cx,
TypeRepresentation::Kind kind,
const Class **clasp,
MutableHandleObject proto);
static bool getSuitableClaspAndProto(JSContext *cx,
TypeRepresentation::Kind kind,
const Class **clasp,
MutableHandleObject proto);
};
/*
* Helper method for converting a double into other scalar
* types in the same way that JavaScript would. In particular,
* simple C casting from double to int32_t gets things wrong
* for values like 0xF0000000.
*/
template <typename T>
static T ConvertScalar(double d)
{
if (TypeIsFloatingPoint<T>()) {
return T(d);
} else if (TypeIsUnsigned<T>()) {
uint32_t n = ToUint32(d);
return T(n);
} else {
int32_t n = ToInt32(d);
return T(n);
}
}
/*
* Given a user-visible type descriptor object, returns the
* owner object for the TypeRepresentation* that we use internally.
*/
JSObject *typeRepresentationOwnerObj(const JSObject &typeObj);
/*
* Given a user-visible type descriptor object, returns the
* TypeRepresentation* that we use internally.
*
* Note: this pointer is valid only so long as `typeObj` remains rooted.
*/
TypeRepresentation *typeRepresentation(const JSObject &typeObj);
bool TypeObjectToSource(JSContext *cx, unsigned int argc, Value *vp);
bool InitializeCommonTypeDescriptorProperties(JSContext *cx,
HandleObject obj,
HandleObject typeReprOwnerObj);
// Type for scalar type constructors like `uint8`. All such type
// constructors share a common js::Class and JSFunctionSpec. Scalar
// types are non-opaque (their storage is visible unless combined with
@ -154,6 +194,7 @@ class X4Type : public JSObject
static const Class class_;
static bool call(JSContext *cx, unsigned argc, Value *vp);
static bool is(const Value &v);
};
/*
@ -356,6 +397,9 @@ class TypedDatum : public JSObject
// Otherwise, use this to attach to memory referenced by another datum.
void attach(JSObject &datum, uint32_t offset);
TypeRepresentation *datumTypeRepresentation() const;
uint8_t *typedMem() const;
};
class TypedObject : public TypedDatum
@ -381,6 +425,21 @@ class TypedHandle : public TypedDatum
static const JSFunctionSpec handleStaticMethods[];
};
/*
* Because TypedDatum is a supertype of two concrete
* classes, we can't use JSObject.is() and JSObject.as(),
* so create two concrete casting operations.
*/
inline bool IsTypedDatum(const JSObject &obj) {
return obj.is<TypedObject>() || obj.is<TypedHandle>();
}
inline TypedDatum &AsTypedDatum(JSObject &obj) {
JS_ASSERT(IsTypedDatum(obj));
return *static_cast<TypedDatum *>(&obj);
}
/*
* Usage: NewTypedHandle(typeObj)
*
@ -485,6 +544,22 @@ extern const JSJitInfo MemcpyJitInfo;
*/
bool GetTypedObjectModule(JSContext *cx, unsigned argc, Value *vp);
/*
* Usage: GetFloat32x4TypeObject()
*
* Returns the float32x4 type object. SIMD pseudo-module must have
* been initialized for this to be safe.
*/
bool GetFloat32x4TypeObject(JSContext *cx, unsigned argc, Value *vp);
/*
* Usage: GetInt32x4TypeObject()
*
* Returns the int32x4 type object. SIMD pseudo-module must have
* been initialized for this to be safe.
*/
bool GetInt32x4TypeObject(JSContext *cx, unsigned argc, Value *vp);
/*
* Usage: Store_int8(targetDatum, targetOffset, value)
* ...
@ -573,5 +648,8 @@ JS_FOR_EACH_REFERENCE_TYPE_REPR(JS_LOAD_REFERENCE_CLASS_DEFN)
} // namespace js
JSObject *
js_InitTypedObjectModuleObject(JSContext *cx, JS::HandleObject obj);
#endif /* builtin_TypedObject_h */

View File

@ -282,21 +282,20 @@ TypedObjectPointer.prototype.getReference = function() {
TypedObjectPointer.prototype.getX4 = function() {
var type = REPR_TYPE(this.typeRepr);
var T = GetTypedObjectModule();
switch (type) {
case JS_X4TYPEREPR_FLOAT32:
var x = Load_float32(this.datum, this.offset + 0);
var y = Load_float32(this.datum, this.offset + 4);
var z = Load_float32(this.datum, this.offset + 8);
var w = Load_float32(this.datum, this.offset + 12);
return T.float32x4(x, y, z, w);
return GetFloat32x4TypeObject()(x, y, z, w);
case JS_X4TYPEREPR_INT32:
var x = Load_int32(this.datum, this.offset + 0);
var y = Load_int32(this.datum, this.offset + 4);
var z = Load_int32(this.datum, this.offset + 8);
var w = Load_int32(this.datum, this.offset + 12);
return T.int32x4(x, y, z, w);
return GetInt32x4TypeObject()(x, y, z, w);
}
assert(false, "Unhandled x4 type: " + type);
@ -721,42 +720,6 @@ function X4ProtoString(type) {
return undefined;
}
var X4LaneStrings = ["x", "y", "z", "w"];
// Generalized handler for the various properties for accessing a
// single lane of an X4 vector value. Note that this is the slow path;
// the fast path will be inlined into ion code.
function X4GetLane(datum, type, lane) {
if (!IsObject(datum) || !ObjectIsTypedDatum(datum))
ThrowError(JSMSG_INCOMPATIBLE_PROTO, X4ProtoString(type),
X4LaneStrings[lane], typeof this);
var repr = DATUM_TYPE_REPR(datum);
if (REPR_KIND(repr) != JS_TYPEREPR_X4_KIND || REPR_TYPE(repr) != type)
ThrowError(JSMSG_INCOMPATIBLE_PROTO, X4ProtoString(type),
X4LaneStrings[lane], typeof this);
switch (type) {
case JS_X4TYPEREPR_INT32:
return Load_int32(datum, lane * 4);
case JS_X4TYPEREPR_FLOAT32:
return Load_float32(datum, lane * 4);
}
assert(false, "Unhandled type constant");
return undefined;
}
function Float32x4Lane0() { return X4GetLane(this, JS_X4TYPEREPR_FLOAT32, 0); }
function Float32x4Lane1() { return X4GetLane(this, JS_X4TYPEREPR_FLOAT32, 1); }
function Float32x4Lane2() { return X4GetLane(this, JS_X4TYPEREPR_FLOAT32, 2); }
function Float32x4Lane3() { return X4GetLane(this, JS_X4TYPEREPR_FLOAT32, 3); }
function Int32x4Lane0() { return X4GetLane(this, JS_X4TYPEREPR_INT32, 0); }
function Int32x4Lane1() { return X4GetLane(this, JS_X4TYPEREPR_INT32, 1); }
function Int32x4Lane2() { return X4GetLane(this, JS_X4TYPEREPR_INT32, 2); }
function Int32x4Lane3() { return X4GetLane(this, JS_X4TYPEREPR_INT32, 3); }
function X4ToSource() {
if (!IsObject(this) || !ObjectIsTypedDatum(this))
ThrowError(JSMSG_INCOMPATIBLE_PROTO, "X4", "toSource", typeof this);

View File

@ -53,7 +53,10 @@
#include "builtin/Intl.h"
#include "builtin/MapObject.h"
#include "builtin/RegExp.h"
#ifdef ENABLE_BINARYDATA
#include "builtin/SIMD.h"
#include "builtin/TypedObject.h"
#endif
#include "frontend/BytecodeCompiler.h"
#include "frontend/FullParseHandler.h" // for JS_BufferIsCompileableUnit
#include "frontend/Parser.h" // for JS_BufferIsCompileableUnit
@ -1219,6 +1222,10 @@ static const JSStdName builtin_property_names[] = {
#if JS_HAS_UNEVAL
{js_InitStringClass, EAGER_ATOM(uneval), OCLASP(String)},
#endif
#ifdef ENABLE_BINARYDATA
{js_InitSIMDClass, EAGER_ATOM(SIMD), OCLASP(SIMD)},
{js_InitTypedObjectModuleObject, EAGER_ATOM(TypedObject), OCLASP(TypedObjectModule)},
#endif
{nullptr, 0, nullptr}
};

View File

@ -5561,12 +5561,19 @@ JS::GetGCNumber()
}
JS::AutoAssertNoGC::AutoAssertNoGC()
: runtime(nullptr)
: runtime(nullptr), gcNumber(0)
{
js::PerThreadData *data = js::TlsPerThreadData.get();
if (data) {
runtime = data->runtimeFromMainThread();
gcNumber = runtime->gcNumber;
/*
* GC's from off-thread will always assert, so off-thread is implicitly
* AutoAssertNoGC. We still need to allow AutoAssertNoGC to be used in
* code that works from both threads, however. We also use this to
* annotate the off thread run loops.
*/
runtime = data->runtimeIfOnOwnerThread();
if (runtime)
gcNumber = runtime->gcNumber;
}
}
@ -5579,7 +5586,5 @@ JS::AutoAssertNoGC::~AutoAssertNoGC()
{
if (runtime)
MOZ_ASSERT(gcNumber == runtime->gcNumber, "GC ran inside an AutoAssertNoGC scope.");
else
MOZ_ASSERT(!js::TlsPerThreadData.get(), "Runtime created within AutoAssertNoGC scope?");
}
#endif

View File

@ -94,6 +94,7 @@
IF_INTL(real,imaginary) (Intl, 36, js_InitIntlClass, CLASP(Intl)) \
IF_BDATA(real,imaginary)(TypedObject, 37, js_InitTypedObjectModuleObject, OCLASP(TypedObjectModule)) \
imaginary(GeneratorFunction, 38, js_InitIteratorClasses, dummy) \
IF_BDATA(real,imaginary)(SIMD, 39, js_InitSIMDClass, OCLASP(SIMD)) \
#define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro)

View File

@ -982,6 +982,7 @@ ScriptSource::getOffThreadCompressionChars(ExclusiveContext *cx)
void
WorkerThread::threadLoop()
{
JS::AutoAssertNoGC nogc;
WorkerThreadState &state = *runtime->workerThreadState;
AutoLockWorkerThreadState lock(state);

View File

@ -97,6 +97,7 @@ UNIFIED_SOURCES += [
'builtin/MapObject.cpp',
'builtin/Object.cpp',
'builtin/Profilers.cpp',
'builtin/SIMD.cpp',
'builtin/TestingFunctions.cpp',
'builtin/TypedObject.cpp',
'builtin/TypeRepresentation.cpp',

View File

@ -0,0 +1,24 @@
//) |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 abs';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(-1, 2, -3, 4);
var c = SIMD.float32x4.abs(a);
assertEq(c.x, 1);
assertEq(c.y, 2);
assertEq(c.z, 3);
assertEq(c.w, 4);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 add';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 2, 3, 4);
var b = float32x4(10, 20, 30, 40);
var c = SIMD.float32x4.add(a, b);
assertEq(c.x, 11);
assertEq(c.y, 22);
assertEq(c.z, 33);
assertEq(c.w, 44);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,5 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 alignment';
/*
@ -9,7 +11,6 @@ var summary = 'float32x4 alignment';
var StructType = TypedObject.StructType;
var uint8 = TypedObject.uint8;
var float32x4 = TypedObject.float32x4;
function test() {
print(BUGNUMBER + ": " + summary);
@ -24,7 +25,6 @@ function test() {
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 bitsToInt32x4';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 2, 3, 4);
var c = SIMD.float32x4.bitsToInt32x4(a);
assertEq(c.x, 1065353216);
assertEq(c.y, 1073741824);
assertEq(c.z, 1077936128);
assertEq(c.w, 1082130432);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 add';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 2, 3, 4);
var b = float32x4(10, 20, 30, 40);
var c = SIMD.float32x4.add(a, b);
assertEq(c.x, 11);
assertEq(c.y, 22);
assertEq(c.z, 33);
assertEq(c.w, 44);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 div';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 2, 3, 4);
var b = float32x4(10, 20, 30, 40);
var c = SIMD.float32x4.div(b,a);
assertEq(c.x, 10);
assertEq(c.y, 10);
assertEq(c.z, 10);
assertEq(c.w, 10);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 equal';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 20, 30, 40);
var b = float32x4(10, 20, 30, 4);
var c = SIMD.float32x4.equal(a, b);
assertEq(c.x, 0);
assertEq(c.y, -1);
assertEq(c.z, -1);
assertEq(c.w, 0);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,5 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 getters';
/*
@ -7,8 +9,6 @@ var summary = 'float32x4 getters';
* http://creativecommons.org/licenses/publicdomain/
*/
var float32x4 = TypedObject.float32x4;
function test() {
print(BUGNUMBER + ": " + summary);
@ -39,13 +39,12 @@ function test() {
g.call(v)
}, TypeError, "Getter applicable to structs");
assertThrowsInstanceOf(function() {
var t = new TypedObject.int32x4(1, 2, 3, 4);
var t = new int32x4(1, 2, 3, 4);
g.call(t)
}, TypeError, "Getter applicable to int32x4");
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 greaterThan';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 20, 3, 40);
var b = float32x4(10, 2, 30, 4);
var c = SIMD.float32x4.greaterThan(b,a);
assertEq(c.x, -1);
assertEq(c.y, 0);
assertEq(c.z, -1);
assertEq(c.w, 0);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 greaterThanOrEqual';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 20, 30, 40);
var b = float32x4(10, 20, 30, 4);
var c = SIMD.float32x4.greaterThanOrEqual(b,a);
assertEq(c.x, -1);
assertEq(c.y, -1);
assertEq(c.z, -1);
assertEq(c.w, 0);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,5 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 handles';
/*
@ -8,7 +10,7 @@ var summary = 'float32x4 handles';
*/
var ArrayType = TypedObject.ArrayType;
var float32x4 = TypedObject.float32x4;
var float32 = TypedObject.float32;
var Handle = TypedObject.Handle;
@ -43,7 +45,6 @@ function test() {
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 lessThan';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 20, 3, 40);
var b = float32x4(10, 2, 30, 4);
var c = SIMD.float32x4.lessThan(a, b);
assertEq(c.x, -1);
assertEq(c.y, 0);
assertEq(c.z, -1);
assertEq(c.w, 0);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 lessThanOrEqual';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 20, 30, 40);
var b = float32x4(10, 20, 30, 4);
var c = SIMD.float32x4.lessThanOrEqual(a, b);
assertEq(c.x, -1);
assertEq(c.y, -1);
assertEq(c.z, -1);
assertEq(c.w, 0);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 max';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 20, 30, 4);
var b = float32x4(10, 2, 3, 40);
var c = SIMD.float32x4.max(a, b);
assertEq(c.x, 10);
assertEq(c.y, 20);
assertEq(c.z, 30);
assertEq(c.w, 40);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 min';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 20, 3, 40);
var b = float32x4(10, 2, 30, 4);
var c = SIMD.float32x4.min(a, b);
assertEq(c.x, 1);
assertEq(c.y, 2);
assertEq(c.z, 3);
assertEq(c.w, 4);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 add';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 2, 3, 4);
var b = float32x4(10, 20, 30, 40);
var c = SIMD.float32x4.mul(a, b);
assertEq(c.x, 10);
assertEq(c.y, 40);
assertEq(c.z, 90);
assertEq(c.w, 160);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 neg';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 2, 3, 4);
var c = SIMD.float32x4.neg(a);
assertEq(c.x, -1);
assertEq(c.y, -2);
assertEq(c.z, -3);
assertEq(c.w, -4);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 notEqual';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 20, 30, 40);
var b = float32x4(10, 20, 30, 4);
var c = SIMD.float32x4.notEqual(a, b);
assertEq(c.x, -1);
assertEq(c.y, 0);
assertEq(c.z, 0);
assertEq(c.w, -1);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 reciprocal';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 0.5, 0.25, 0.125);
var c = SIMD.float32x4.reciprocal(a);
assertEq(c.x, 1);
assertEq(c.y, 2);
assertEq(c.z, 4);
assertEq(c.w, 8);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 reciprocalSqrt';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 1, 0.25, 0.25);
var c = SIMD.float32x4.reciprocalSqrt(a);
assertEq(c.x, 1);
assertEq(c.y, 1);
assertEq(c.z, 2);
assertEq(c.w, 2);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,5 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 reify';
/*
@ -8,7 +10,6 @@ var summary = 'float32x4 reify';
*/
var ArrayType = TypedObject.ArrayType;
var float32x4 = TypedObject.float32x4;
function test() {
print(BUGNUMBER + ": " + summary);
@ -30,7 +31,6 @@ function test() {
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 scale';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 2, 3, 4);
var c = SIMD.float32x4.scale(a, 2);
assertEq(c.x, 2);
assertEq(c.y, 4);
assertEq(c.z, 6);
assertEq(c.w, 8);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,5 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 setting';
/*
@ -8,7 +10,6 @@ var summary = 'float32x4 setting';
*/
var ArrayType = TypedObject.ArrayType;
var float32x4 = TypedObject.float32x4;
function test() {
print(BUGNUMBER + ": " + summary);
@ -39,7 +40,6 @@ function test() {
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 shuffle';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 2, 3, 4);
var c = SIMD.float32x4.shuffle(a, 0x1B);
assertEq(c.x, 4);
assertEq(c.y, 3);
assertEq(c.z, 2);
assertEq(c.w, 1);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 shuffleMix';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 2, 3, 4);
var b = float32x4(10, 20, 30, 40);
var c = SIMD.float32x4.shuffleMix(a,b, 0x1B);
assertEq(c.x, 4);
assertEq(c.y, 3);
assertEq(c.z, 20);
assertEq(c.w, 10);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 sqrt';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 4, 9, 16);
var c = SIMD.float32x4.sqrt(a);
assertEq(c.x, 1);
assertEq(c.y, 2);
assertEq(c.z, 3);
assertEq(c.w, 4);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 sub';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 2, 3, 4);
var b = float32x4(10, 20, 30, 40);
var c = SIMD.float32x4.sub(b,a);
assertEq(c.x, 9);
assertEq(c.y, 18);
assertEq(c.z, 27);
assertEq(c.w, 36);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 toInt32x4';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1.1, 2.2, 3.3, 4.6);
var c = SIMD.float32x4.toInt32x4(a);
assertEq(c.x, 1);
assertEq(c.y, 2);
assertEq(c.z, 3);
assertEq(c.w, 4);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,28 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'float32x4 with';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(1, 2, 3, 4);
var x = SIMD.float32x4.withX(a, 5);
var y = SIMD.float32x4.withY(a, 5);
var z = SIMD.float32x4.withZ(a, 5);
var w = SIMD.float32x4.withW(a, 5);
assertEq(x.x, 5);
assertEq(y.y, 5);
assertEq(z.z, 5);
assertEq(w.w, 5);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 add';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var b = int32x4(10, 20, 30, 40);
var c = SIMD.int32x4.add(a, b);
assertEq(c.x, 11);
assertEq(c.y, 22);
assertEq(c.z, 33);
assertEq(c.w, 44);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,5 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 alignment';
/*
@ -9,7 +11,6 @@ var summary = 'int32x4 alignment';
var StructType = TypedObject.StructType;
var uint8 = TypedObject.uint8;
var int32x4 = TypedObject.int32x4;
function test() {
print(BUGNUMBER + ": " + summary);
@ -24,7 +25,6 @@ function test() {
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 and';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var b = int32x4(10, 20, 30, 40);
var c = SIMD.int32x4.and(a, b);
assertEq(c.x, 0);
assertEq(c.y, 0);
assertEq(c.z, 2);
assertEq(c.w, 0);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 bitsToFloat32x4';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(100, 200, 300, 400);
var c = SIMD.int32x4.bitsToFloat32x4(a);
assertEq(c.x, 1.401298464324817e-43);
assertEq(c.y, 2.802596928649634e-43);
assertEq(c.z, 4.203895392974451e-43);
assertEq(c.w, 5.605193857299268e-43);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,5 +1,8 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var {StructType, int32} = TypedObject;
var summary = 'int32x4 getters';
/*
@ -7,8 +10,6 @@ var summary = 'int32x4 getters';
* http://creativecommons.org/licenses/publicdomain/
*/
var int32x4 = TypedObject.int32x4;
function test() {
print(BUGNUMBER + ": " + summary);
@ -31,21 +32,17 @@ function test() {
g.call(0xDEADBEEF)
}, TypeError, "Getter applicable to integers");
assertThrowsInstanceOf(function() {
var T = new TypedObject.StructType({x: TypedObject.int32,
y: TypedObject.int32,
z: TypedObject.int32,
w: TypedObject.int32});
var T = new StructType({x: int32, y: int32, z: int32, w: int32});
var v = new T({x: 11, y: 22, z: 33, w: 44});
g.call(v)
}, TypeError, "Getter applicable to structs");
assertThrowsInstanceOf(function() {
var t = new TypedObject.float32x4(1, 2, 3, 4);
var t = new float32x4(1, 2, 3, 4);
g.call(t)
}, TypeError, "Getter applicable to float32x4");
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -1,5 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 handles';
/*
@ -8,7 +10,6 @@ var summary = 'int32x4 handles';
*/
var ArrayType = TypedObject.ArrayType;
var int32x4 = TypedObject.int32x4;
var int32 = TypedObject.int32;
var Handle = TypedObject.Handle;
@ -43,7 +44,6 @@ function test() {
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 mul';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var b = int32x4(10, 20, 30, 40);
var c = SIMD.int32x4.mul(a, b);
assertEq(c.x, 10);
assertEq(c.y, 40);
assertEq(c.z, 90);
assertEq(c.w, 160);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 neg';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var c = SIMD.int32x4.neg(a);
assertEq(c.x, -1);
assertEq(c.y, -2);
assertEq(c.z, -3);
assertEq(c.w, -4);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 not';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var c = SIMD.int32x4.not(a);
assertEq(c.x, -2);
assertEq(c.y, -3);
assertEq(c.z, -4);
assertEq(c.w, -5);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 or';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var b = int32x4(10, 20, 30, 40);
var c = SIMD.int32x4.or(a, b);
assertEq(c.x, 11);
assertEq(c.y, 22);
assertEq(c.z, 31);
assertEq(c.w, 44);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,5 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 reify';
/*
@ -8,7 +10,6 @@ var summary = 'int32x4 reify';
*/
var ArrayType = TypedObject.ArrayType;
var int32x4 = TypedObject.int32x4;
function test() {
print(BUGNUMBER + ": " + summary);
@ -30,7 +31,6 @@ function test() {
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,27 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 select';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = float32x4(0.0,4.0,9.0,16.0)
var b = float32x4(1.0,2.0,3.0,4.0)
var sel_ttff = int32x4.bool(true, true, false, false);
var c = SIMD.int32x4.select(sel_ttff,a,b);
assertEq(c.x, 0);
assertEq(c.y, 4);
assertEq(c.z, 3);
assertEq(c.w, 4);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -1,5 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 938728;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 setting';
/*
@ -8,7 +10,6 @@ var summary = 'int32x4 setting';
*/
var ArrayType = TypedObject.ArrayType;
var int32x4 = TypedObject.int32x4;
function test() {
print(BUGNUMBER + ": " + summary);
@ -39,7 +40,6 @@ function test() {
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 shuffle';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var c = SIMD.int32x4.shuffle(a, 0x1B);
assertEq(c.x, 4);
assertEq(c.y, 3);
assertEq(c.z, 2);
assertEq(c.w, 1);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 shuffleMix';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var b = int32x4(10, 20, 30, 40);
var c = SIMD.int32x4.shuffleMix(a,b, 0x1B);
assertEq(c.x, 4);
assertEq(c.y, 3);
assertEq(c.z, 20);
assertEq(c.w, 10);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 sub';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var b = int32x4(10, 20, 30, 40);
var c = SIMD.int32x4.sub(b,a);
assertEq(c.x, 9);
assertEq(c.y, 18);
assertEq(c.z, 27);
assertEq(c.w, 36);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,25 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 toFloat32x4';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var c = SIMD.int32x4.toFloat32x4(a);
assertEq(c.x, 1);
assertEq(c.y, 2);
assertEq(c.z, 3);
assertEq(c.w, 4);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,28 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 with';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var x = SIMD.int32x4.withX(a, 5);
var y = SIMD.int32x4.withY(a, 5);
var z = SIMD.int32x4.withZ(a, 5);
var w = SIMD.int32x4.withW(a, 5);
assertEq(x.x, 5);
assertEq(y.y, 5);
assertEq(z.z, 5);
assertEq(w.w, 5);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,28 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 with';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var x = SIMD.int32x4.withFlagX(a, true);
var y = SIMD.int32x4.withFlagY(a, false);
var z = SIMD.int32x4.withFlagZ(a, false);
var w = SIMD.int32x4.withFlagW(a, true);
assertEq(x.x, -1);
assertEq(y.y, 0);
assertEq(z.z, 0);
assertEq(w.w, -1);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -0,0 +1,26 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 946042;
var float32x4 = SIMD.float32x4;
var int32x4 = SIMD.int32x4;
var summary = 'int32x4 xor';
function test() {
print(BUGNUMBER + ": " + summary);
// FIXME -- Bug 948379: Amend to check for correctness of border cases.
var a = int32x4(1, 2, 3, 4);
var b = int32x4(10, 20, 30, 40);
var c = SIMD.int32x4.xor(a, b);
assertEq(c.x, 11);
assertEq(c.y, 22);
assertEq(c.z, 29);
assertEq(c.w, 44);
if (typeof reportCompare === "function")
reportCompare(true, true);
}
test();

View File

@ -26,9 +26,6 @@ js_InitFunctionClass(JSContext *cx, js::HandleObject obj);
extern JSObject *
js_InitTypedArrayClasses(JSContext *cx, js::HandleObject obj);
extern JSObject *
js_InitTypedObjectModuleObject(JSContext *cx, js::HandleObject obj);
namespace js {
class Debugger;
@ -111,9 +108,11 @@ class GlobalObject : public JSObject
static const unsigned RUNTIME_CODEGEN_ENABLED = WARNED_WATCH_DEPRECATED + 1;
static const unsigned DEBUGGERS = RUNTIME_CODEGEN_ENABLED + 1;
static const unsigned INTRINSICS = DEBUGGERS + 1;
static const unsigned FLOAT32X4_TYPE_OBJECT = INTRINSICS + 1;
static const unsigned INT32X4_TYPE_OBJECT = FLOAT32X4_TYPE_OBJECT + 1;
/* Total reserved-slot count for global objects. */
static const unsigned RESERVED_SLOTS = INTRINSICS + 1;
static const unsigned RESERVED_SLOTS = INT32X4_TYPE_OBJECT + 1;
/*
* The slot count must be in the public API for JSCLASS_GLOBAL_FLAGS, and
@ -416,6 +415,26 @@ class GlobalObject : public JSObject
return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_TypedObject, initTypedObjectModule);
}
void setFloat32x4TypeObject(JSObject &obj) {
JS_ASSERT(getSlotRef(FLOAT32X4_TYPE_OBJECT).isUndefined());
setSlot(FLOAT32X4_TYPE_OBJECT, ObjectValue(obj));
}
JSObject &float32x4TypeObject() {
JS_ASSERT(getSlotRef(FLOAT32X4_TYPE_OBJECT).isObject());
return getSlotRef(FLOAT32X4_TYPE_OBJECT).toObject();
}
void setInt32x4TypeObject(JSObject &obj) {
JS_ASSERT(getSlotRef(INT32X4_TYPE_OBJECT).isUndefined());
setSlot(INT32X4_TYPE_OBJECT, ObjectValue(obj));
}
JSObject &int32x4TypeObject() {
JS_ASSERT(getSlotRef(INT32X4_TYPE_OBJECT).isObject());
return getSlotRef(INT32X4_TYPE_OBJECT).toObject();
}
TypedObjectModuleObject &getTypedObjectModule() const;
JSObject *getIteratorPrototype() {

View File

@ -657,6 +657,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
JSNativeThreadSafeWrapper<js::Memcpy>,
&js::MemcpyJitInfo, 5, 0),
JS_FN("GetTypedObjectModule", js::GetTypedObjectModule, 0, 0),
JS_FN("GetFloat32x4TypeObject", js::GetFloat32x4TypeObject, 0, 0),
JS_FN("GetInt32x4TypeObject", js::GetInt32x4TypeObject, 0, 0),
#define LOAD_AND_STORE_SCALAR_FN_DECLS(_constant, _type, _name) \
JS_FNINFO("Store_" #_name, \

View File

@ -120,7 +120,7 @@ interface ScheduledGCCallback : nsISupports
/**
* interface of Components.utils
*/
[scriptable, uuid(e14f588b-63aa-4091-be82-a459a52f8ca6)]
[scriptable, uuid(ae292d08-cfb0-4862-a2b6-4779e5ef7e72)]
interface nsIXPCComponents_Utils : nsISupports
{
@ -519,6 +519,17 @@ interface nsIXPCComponents_Utils : nsISupports
[implicit_jscontext]
jsval getIncumbentGlobal([optional] in jsval callback);
/**
* Forces the generation of an XPCWrappedJS for a given object. For internal
* and testing use only. This is only useful to set up wrapper map conditions
* for a testcase. The return value is not an XPCWrappedJS itself, but an
* opaque nsISupports holder that keeps the underlying XPCWrappedJS alive.
*
* if |scope| is passed, the XPCWrappedJS is generated in the scope of that object.
*/
[implicit_jscontext]
nsISupports generateXPCWrappedJS(in jsval obj, [optional] in jsval scope);
/**
* Retrieve the last time, in microseconds since epoch, that a given
* watchdog-related event occured.

View File

@ -1053,6 +1053,9 @@ xpc::CreateSandboxObject(JSContext *cx, MutableHandleValue vp, nsISupports *prin
compartmentOptions.setSameZoneAs(js::UncheckedUnwrap(options.sameZoneAs));
else
compartmentOptions.setZone(JS::SystemZone);
compartmentOptions.setInvisibleToDebugger(options.invisibleToDebugger);
RootedObject sandbox(cx, xpc::CreateGlobalObject(cx, &SandboxClass,
principal, compartmentOptions));
if (!sandbox)
@ -1486,6 +1489,7 @@ SandboxOptions::Parse()
ParseBoolean("wantExportHelpers", &wantExportHelpers) &&
ParseString("sandboxName", sandboxName) &&
ParseObject("sameZoneAs", &sameZoneAs) &&
ParseBoolean("invisibleToDebugger", &invisibleToDebugger) &&
ParseGlobalProperties() &&
ParseValue("metadata", &metadata);
}

View File

@ -3514,6 +3514,46 @@ nsXPCComponents_Utils::GetIncumbentGlobal(const Value &aCallback,
return NS_OK;
}
/*
* Below is a bunch of awkward junk to allow JS test code to trigger the
* creation of an XPCWrappedJS, such that it ends up in the map. We need to
* hand the caller some sort of reference to hold onto (to prevent the
* refcount from dropping to zero as soon as the function returns), but trying
* to return a bonafide XPCWrappedJS to script causes all sorts of trouble. So
* we create a benign holder class instead, which acts as an opaque reference
* that script can use to keep the XPCWrappedJS alive and in the map.
*/
class WrappedJSHolder : public nsISupports
{
NS_DECL_ISUPPORTS
WrappedJSHolder() {}
virtual ~WrappedJSHolder() {}
nsRefPtr<nsXPCWrappedJS> mWrappedJS;
};
NS_IMPL_ISUPPORTS0(WrappedJSHolder);
NS_IMETHODIMP
nsXPCComponents_Utils::GenerateXPCWrappedJS(const Value &aObj, const Value &aScope,
JSContext *aCx, nsISupports **aOut)
{
if (!aObj.isObject())
return NS_ERROR_INVALID_ARG;
RootedObject obj(aCx, &aObj.toObject());
RootedObject scope(aCx, aScope.isObject() ? js::UncheckedUnwrap(&aScope.toObject())
: CurrentGlobalOrNull(aCx));
JSAutoCompartment ac(aCx, scope);
if (!JS_WrapObject(aCx, &obj))
return NS_ERROR_FAILURE;
nsRefPtr<WrappedJSHolder> holder = new WrappedJSHolder();
nsresult rv = nsXPCWrappedJS::GetNewOrUsed(obj, NS_GET_IID(nsISupports),
getter_AddRefs(holder->mWrappedJS));
holder.forget(aOut);
return rv;
}
NS_IMETHODIMP
nsXPCComponents_Utils::GetWatchdogTimestamp(const nsAString& aCategory, PRTime *aOut)
{

View File

@ -1028,10 +1028,16 @@ XPCConvert::JSObject2NativeInterface(void** dest, HandleObject src,
// else...
nsXPCWrappedJS* wrapper;
nsresult rv = nsXPCWrappedJS::GetNewOrUsed(src, *iid, aOuter, &wrapper);
nsresult rv = nsXPCWrappedJS::GetNewOrUsed(src, *iid, &wrapper);
if (pErr)
*pErr = rv;
if (NS_SUCCEEDED(rv) && wrapper) {
// If the caller wanted to aggregate this JS object to a native,
// attach it to the wrapper. Note that we allow a maximum of one
// aggregated native for a given XPCWrappedJS.
if (aOuter)
wrapper->SetAggregatedNativeObject(aOuter);
// We need to go through the QueryInterface logic to make this return
// the right thing for the various 'special' interfaces; e.g.
// nsIPropertyBag. We must use AggregatedQueryInterface in cases where
@ -1184,8 +1190,7 @@ XPCConvert::JSValToXPCException(MutableHandleValue s,
// lets try to build a wrapper around the JSObject
nsXPCWrappedJS* jswrapper;
nsresult rv =
nsXPCWrappedJS::GetNewOrUsed(obj, NS_GET_IID(nsIException),
nullptr, &jswrapper);
nsXPCWrappedJS::GetNewOrUsed(obj, NS_GET_IID(nsIException), &jswrapper);
if (NS_FAILED(rv))
return rv;

View File

@ -43,7 +43,6 @@ nsresult xpcJSWeakReference::Init(JSContext* cx, const JS::Value& object)
nsRefPtr<nsXPCWrappedJS> wrapped;
nsresult rv = nsXPCWrappedJS::GetNewOrUsed(obj,
NS_GET_IID(nsISupports),
nullptr,
getter_AddRefs(wrapped));
if (!wrapped) {
NS_ERROR("can't get nsISupportsWeakReference wrapper for obj");

View File

@ -735,8 +735,7 @@ xpc_qsUnwrapArgImpl(JSContext *cx,
}
nsRefPtr<nsXPCWrappedJS> wrappedJS;
rv = nsXPCWrappedJS::GetNewOrUsed(src, iid, nullptr,
getter_AddRefs(wrappedJS));
rv = nsXPCWrappedJS::GetNewOrUsed(src, iid, getter_AddRefs(wrappedJS));
if (NS_FAILED(rv) || !wrappedJS) {
*ppArgRef = nullptr;
return rv;

View File

@ -320,7 +320,6 @@ nsXPCWrappedJS::GetJSObject()
nsresult
nsXPCWrappedJS::GetNewOrUsed(JS::HandleObject jsObj,
REFNSIID aIID,
nsISupports* aOuter,
nsXPCWrappedJS** wrapperResult)
{
// Do a release-mode assert against accessing nsXPCWrappedJS off-main-thread.
@ -364,8 +363,7 @@ nsXPCWrappedJS::GetNewOrUsed(JS::HandleObject jsObj,
// build the root wrapper
if (rootJSObj == jsObj) {
// the root will do double duty as the interface wrapper
wrapper = root = new nsXPCWrappedJS(cx, jsObj, clazz, nullptr,
aOuter);
wrapper = root = new nsXPCWrappedJS(cx, jsObj, clazz, nullptr);
if (!root)
goto return_wrapper;
@ -380,7 +378,7 @@ nsXPCWrappedJS::GetNewOrUsed(JS::HandleObject jsObj,
if (!rootClazz)
goto return_wrapper;
root = new nsXPCWrappedJS(cx, rootJSObj, rootClazz, nullptr, aOuter);
root = new nsXPCWrappedJS(cx, rootJSObj, rootClazz, nullptr);
NS_RELEASE(rootClazz);
if (!root)
@ -397,7 +395,7 @@ nsXPCWrappedJS::GetNewOrUsed(JS::HandleObject jsObj,
MOZ_ASSERT(clazz,"bad clazz");
if (!wrapper) {
wrapper = new nsXPCWrappedJS(cx, jsObj, clazz, root, aOuter);
wrapper = new nsXPCWrappedJS(cx, jsObj, clazz, root);
if (!wrapper)
goto return_wrapper;
}
@ -422,13 +420,12 @@ return_wrapper:
nsXPCWrappedJS::nsXPCWrappedJS(JSContext* cx,
JSObject* aJSObj,
nsXPCWrappedJSClass* aClass,
nsXPCWrappedJS* root,
nsISupports* aOuter)
nsXPCWrappedJS* root)
: mJSObj(aJSObj),
mClass(aClass),
mRoot(root ? root : MOZ_THIS_IN_INITIALIZER_LIST()),
mNext(nullptr),
mOuter(root ? nullptr : aOuter)
mOuter(nullptr)
{
InitStub(GetClass()->GetIID());
@ -439,7 +436,6 @@ nsXPCWrappedJS::nsXPCWrappedJS(JSContext* cx,
NS_ADDREF_THIS();
NS_ADDREF(aClass);
NS_IF_ADDREF(mOuter);
if (!IsRootWrapper())
NS_ADDREF(mRoot);

View File

@ -700,8 +700,7 @@ nsXPCWrappedJSClass::DelegatedQueryInterface(nsXPCWrappedJS* self,
// XPConvert::JSObject2NativeInterface() here to make sure we
// get a new (or used) nsXPCWrappedJS.
nsXPCWrappedJS* wrapper;
nsresult rv = nsXPCWrappedJS::GetNewOrUsed(jsobj, aIID, nullptr,
&wrapper);
nsresult rv = nsXPCWrappedJS::GetNewOrUsed(jsobj, aIID, &wrapper);
if (NS_SUCCEEDED(rv) && wrapper) {
// We need to go through the QueryInterface logic to make
// this return the right thing for the various 'special'

View File

@ -2474,7 +2474,6 @@ public:
static nsresult
GetNewOrUsed(JS::HandleObject aJSObj,
REFNSIID aIID,
nsISupports* aOuter,
nsXPCWrappedJS** wrapper);
nsISomeInterface* GetXPTCStub() { return mXPTCStub; }
@ -2509,6 +2508,15 @@ public:
bool IsAggregatedToNative() const {return mRoot->mOuter != nullptr;}
nsISupports* GetAggregatedNativeObject() const {return mRoot->mOuter;}
void SetAggregatedNativeObject(nsISupports *aNative) {
MOZ_ASSERT(aNative);
if (mRoot->mOuter) {
MOZ_ASSERT(mRoot->mOuter == aNative,
"Only one aggregated native can be set");
return;
}
NS_ADDREF(mRoot->mOuter = aNative);
}
void TraceJS(JSTracer* trc);
static void GetTraceName(JSTracer* trc, char *buf, size_t bufsize);
@ -2519,8 +2527,7 @@ protected:
nsXPCWrappedJS(JSContext* cx,
JSObject* aJSObj,
nsXPCWrappedJSClass* aClass,
nsXPCWrappedJS* root,
nsISupports* aOuter);
nsXPCWrappedJS* root);
bool CanSkip();
void Destroy();
@ -3425,6 +3432,7 @@ public:
, wantExportHelpers(false)
, proto(cx)
, sameZoneAs(cx)
, invisibleToDebugger(false)
, metadata(cx)
{ }
@ -3436,6 +3444,7 @@ public:
JS::RootedObject proto;
nsCString sandboxName;
JS::RootedObject sameZoneAs;
bool invisibleToDebugger;
GlobalProperties globalProperties;
JS::RootedValue metadata;

View File

@ -150,5 +150,26 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=533596
catch (e) {
ok(false, "sameZoneAs works");
}
Cu.import("resource://gre/modules/jsdebugger.jsm");
addDebuggerToGlobal(this);
try {
let dbg = new Debugger();
let sandbox = new Cu.Sandbox(this, { invisibleToDebugger: false });
dbg.addDebuggee(sandbox);
ok(true, "debugger added visible value");
} catch(e) {
ok(false, "debugger could not add visible value");
}
try {
let dbg = new Debugger();
let sandbox = new Cu.Sandbox(this, { invisibleToDebugger: true });
dbg.addDebuggee(sandbox);
ok(false, "debugger added invisible value");
} catch(e) {
ok(true, "debugger did not add invisible value");
}
]]></script>
</window>

View File

@ -2700,6 +2700,17 @@ struct LineBoxInfo
nscoord mMaxLineBoxWidth;
};
static void
ChangeChildPaintingEnabled(nsIMarkupDocumentViewer* aChild, void* aClosure)
{
bool* enablePainting = (bool*) aClosure;
if (*enablePainting) {
aChild->ResumePainting();
} else {
aChild->PausePainting();
}
}
static void
ChangeChildMaxLineBoxWidth(nsIMarkupDocumentViewer* aChild, void* aClosure)
{
@ -3126,7 +3137,36 @@ NS_IMETHODIMP nsDocumentViewer::AppendSubtree(nsTArray<nsCOMPtr<nsIMarkupDocumen
return NS_OK;
}
NS_IMETHODIMP nsDocumentViewer::ChangeMaxLineBoxWidth(int32_t aMaxLineBoxWidth)
NS_IMETHODIMP
nsDocumentViewer::PausePainting()
{
bool enablePaint = false;
CallChildren(ChangeChildPaintingEnabled, &enablePaint);
nsIPresShell* presShell = GetPresShell();
if (presShell) {
presShell->PausePainting();
}
return NS_OK;
}
NS_IMETHODIMP
nsDocumentViewer::ResumePainting()
{
bool enablePaint = true;
CallChildren(ChangeChildPaintingEnabled, &enablePaint);
nsIPresShell* presShell = GetPresShell();
if (presShell) {
presShell->ResumePainting();
}
return NS_OK;
}
NS_IMETHODIMP
nsDocumentViewer::ChangeMaxLineBoxWidth(int32_t aMaxLineBoxWidth)
{
// Change the max line box width for all children.
struct LineBoxInfo lbi = { aMaxLineBoxWidth };

View File

@ -129,10 +129,10 @@ typedef struct CapturingContentInfo {
} CapturingContentInfo;
// f5b542a9-eaf0-4560-a656-37a9d379864c
// 0e4f2b36-7ab8-43c5-b912-5c311566297c
#define NS_IPRESSHELL_IID \
{ 0xf5b542a9, 0xeaf0, 0x4560, \
{ 0x37, 0xa9, 0xd3, 0x79, 0x86, 0x4c } }
{ 0xde498c49, 0xf83f, 0x47bf, \
{0x8c, 0xc6, 0x8f, 0xf8, 0x74, 0x62, 0x22, 0x23 } }
// debug VerifyReflow flags
#define VERIFY_REFLOW_ON 0x01
@ -836,6 +836,20 @@ public:
*/
bool IsPaintingSuppressed() const { return mPaintingSuppressed; }
/**
* Pause painting by freezing the refresh driver of this and all parent
* presentations. This may not have the desired effect if this pres shell
* has its own refresh driver.
*/
virtual void PausePainting() = 0;
/**
* Resume painting by thawing the refresh driver of this and all parent
* presentations. This may not have the desired effect if this pres shell
* has its own refresh driver.
*/
virtual void ResumePainting() = 0;
/**
* Unsuppress painting.
*/
@ -1601,6 +1615,7 @@ protected:
bool mFontSizeInflationForceEnabled;
bool mFontSizeInflationDisabledInMasterProcess;
bool mFontSizeInflationEnabled;
bool mPaintingIsFrozen;
// Dirty bit indicating that mFontSizeInflationEnabled needs to be recomputed.
bool mFontSizeInflationEnabledIsDirty;

View File

@ -724,6 +724,8 @@ PresShell::PresShell()
"layout.reflow.synthMouseMove", true);
addedSynthMouseMove = true;
}
mPaintingIsFrozen = false;
}
NS_IMPL_ISUPPORTS7(PresShell, nsIPresShell, nsIDocumentObserver,
@ -744,6 +746,13 @@ PresShell::~PresShell()
mLastCallbackEventRequest == nullptr,
"post-reflow queues not empty. This means we're leaking");
// Verify that if painting was frozen, but we're being removed from the tree,
// that we now re-enable painting on our refresh driver, since it may need to
// be re-used by another presentation.
if (mPaintingIsFrozen) {
mPresContext->RefreshDriver()->Thaw();
}
#ifdef DEBUG
MOZ_ASSERT(mPresArenaAllocCount == 0,
"Some pres arena objects were not freed");
@ -9931,3 +9940,23 @@ nsIPresShell::SetMaxLineBoxWidth(nscoord aMaxLineBoxWidth)
FrameNeedsReflow(GetRootFrame(), eResize, NS_FRAME_HAS_DIRTY_CHILDREN);
}
}
void
PresShell::PausePainting()
{
if (GetPresContext()->RefreshDriver()->PresContext() != GetPresContext())
return;
mPaintingIsFrozen = true;
GetPresContext()->RefreshDriver()->Freeze();
}
void
PresShell::ResumePainting()
{
if (GetPresContext()->RefreshDriver()->PresContext() != GetPresContext())
return;
mPaintingIsFrozen = false;
GetPresContext()->RefreshDriver()->Thaw();
}

View File

@ -689,6 +689,9 @@ protected:
virtual void ThemeChanged() MOZ_OVERRIDE { mPresContext->ThemeChanged(); }
virtual void BackingScaleFactorChanged() MOZ_OVERRIDE { mPresContext->UIResolutionChanged(); }
virtual void PausePainting() MOZ_OVERRIDE;
virtual void ResumePainting() MOZ_OVERRIDE;
void UpdateImageVisibility();
nsRevocableEventPtr<nsRunnableMethod<PresShell> > mUpdateImageVisibilityEvent;

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.container {
width: 100px;
height: 20px;
border: 5px solid black;
}
.container > * {
height: 18px;
float: left;
}
.itemA {
width: 38px;
background: purple;
border: 1px solid indigo;
}
.itemB {
width: 58px;
background: teal;
border: 1px solid lightblue;
}
</style>
</head>
<body>
<div class="container">
<div class="itemA"></div>
<div class="itemB"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing a horizontal flex container with box-sizing:border-box</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.container {
display: flex;
width: 110px;
height: 30px;
border: 5px solid black;
-moz-box-sizing: border-box;
}
.itemA {
flex: 1 28px;
background: purple;
border: 1px solid indigo;
}
.itemB {
flex: 1 48px;
background: teal;
border: 1px solid lightblue;
}
</style>
</head>
<body>
<div class="container">
<div class="itemA"></div>
<div class="itemB"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.container {
width: 20px;
height: 100px;
border: 5px solid black;
}
.container > * {
width: 18px;
}
.itemA {
height: 38px;
background: purple;
border: 1px solid indigo;
}
.itemB {
height: 58px;
background: teal;
border: 1px solid lightblue;
}
</style>
</head>
<body>
<div class="container">
<div class="itemA"></div>
<div class="itemB"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing a horizontal flex container with box-sizing:border-box</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.container {
display: flex;
flex-direction: column;
width: 30px;
height: 110px;
border: 5px solid black;
-moz-box-sizing: border-box;
}
.itemA {
flex: 1 28px;
background: purple;
border: 1px solid indigo;
}
.itemB {
flex: 1 48px;
background: teal;
border: 1px solid lightblue;
}
</style>
</head>
<body>
<div class="container">
<div class="itemA"></div>
<div class="itemB"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,60 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.container {
width: 100px;
height: 30px;
border: 1px solid black;
float: left;
margin: 2px;
}
.container > * {
float: left; /* emulate the testcase's horizontal lineup of flex items */
}
.itemA {
width: 22px;
height: 22px;
background: purple;
border: 4px solid indigo;
}
.itemB {
width: 40px;
height: 20px;
background: teal;
border: 5px solid lightblue;
}
</style>
</head>
<body>
<!-- FIRST ROW -->
<!-- 1 inflexible item -->
<div class="container">
<div class="itemA"></div>
</div>
<!-- 1 flexible item -->
<div class="container">
<div class="itemA" style="width: 92px"></div>
</div>
<div style="clear: both"></div>
<!-- SECOND ROW -->
<!-- 2 inflexible items -->
<div class="container">
<div class="itemA"></div>
<div class="itemB"></div>
</div>
<!-- 2 flexible items -->
<div class="container">
<div class="itemA" style="width: 32px"></div>
<div class="itemB" style="width: 50px"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,60 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing a horizontal flex container with box-sizing:border-box on its flex items</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.container {
display: flex;
width: 100px;
height: 30px;
border: 1px solid black;
float: left;
margin: 2px;
}
.container > * {
-moz-box-sizing: border-box;
}
.itemA {
width: 30px;
background: purple;
border: 4px solid indigo;
}
.itemB {
width: 50px;
background: teal;
border: 5px solid lightblue;
}
</style>
</head>
<body>
<!-- FIRST ROW -->
<!-- 1 inflexible item -->
<div class="container">
<div class="itemA"></div>
</div>
<!-- 1 flexible item -->
<div class="container">
<div class="itemA" style="flex-grow: 1"></div>
</div>
<div style="clear: both"></div>
<!-- SECOND ROW -->
<!-- 2 inflexible items -->
<div class="container">
<div class="itemA"></div>
<div class="itemB"></div>
</div>
<!-- 2 flexible items -->
<div class="container">
<div class="itemA" style="flex-grow: 1"></div>
<div class="itemB" style="flex-grow: 1"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,60 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing a horizontal flex container with box-sizing:border-box on its flex items</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.container {
display: flex;
width: 100px;
height: 30px;
border: 1px solid black;
float: left;
margin: 2px;
}
.container > * {
-moz-box-sizing: border-box;
}
.itemA {
flex-basis: 30px;
background: purple;
border: 4px solid indigo;
}
.itemB {
flex-basis: 50px;
background: teal;
border: 5px solid lightblue;
}
</style>
</head>
<body>
<!-- FIRST ROW -->
<!-- 1 inflexible item -->
<div class="container">
<div class="itemA"></div>
</div>
<!-- 1 flexible item -->
<div class="container">
<div class="itemA" style="flex-grow: 1"></div>
</div>
<div style="clear: both"></div>
<!-- SECOND ROW -->
<!-- 2 inflexible items -->
<div class="container">
<div class="itemA"></div>
<div class="itemB"></div>
</div>
<!-- 2 flexible items -->
<div class="container">
<div class="itemA" style="flex-grow: 1"></div>
<div class="itemB" style="flex-grow: 1"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,57 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.container {
width: 30px;
height: 100px;
border: 1px solid black;
float: left;
margin: 2px;
}
.itemA {
width: 22px;
height: 22px;
background: purple;
border: 4px solid indigo;
}
.itemB {
width: 20px;
height: 40px;
background: teal;
border: 5px solid lightblue;
}
</style>
</head>
<body>
<!-- FIRST ROW -->
<!-- 1 inflexible item -->
<div class="container">
<div class="itemA"></div>
</div>
<!-- 1 flexible item -->
<div class="container">
<div class="itemA" style="height: 92px"></div>
</div>
<div style="clear: both"></div>
<!-- SECOND ROW -->
<!-- 2 inflexible items -->
<div class="container">
<div class="itemA"></div>
<div class="itemB"></div>
</div>
<!-- 2 flexible items -->
<div class="container">
<div class="itemA" style="height: 32px"></div>
<div class="itemB" style="height: 50px"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing a vertical flex container with box-sizing:border-box on its flex items</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.container {
display: flex;
flex-direction: column;
width: 30px;
height: 100px;
border: 1px solid black;
float: left;
margin: 2px;
}
.container > * {
-moz-box-sizing: border-box;
}
.itemA {
height: 30px;
background: purple;
border: 4px solid indigo;
}
.itemB {
height: 50px;
background: teal;
border: 5px solid lightblue;
}
</style>
</head>
<body>
<!-- FIRST ROW -->
<!-- 1 inflexible item -->
<div class="container">
<div class="itemA"></div>
</div>
<!-- 1 flexible item -->
<div class="container">
<div class="itemA" style="flex-grow: 1"></div>
</div>
<div style="clear: both"></div>
<!-- SECOND ROW -->
<!-- 2 inflexible items -->
<div class="container">
<div class="itemA"></div>
<div class="itemB"></div>
</div>
<!-- 2 flexible items -->
<div class="container">
<div class="itemA" style="flex-grow: 1"></div>
<div class="itemB" style="flex-grow: 1"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing a vertical flex container with box-sizing:border-box on its flex items</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
<style>
.container {
display: flex;
flex-direction: column;
width: 30px;
height: 100px;
border: 1px solid black;
float: left;
margin: 2px;
}
.container > * {
-moz-box-sizing: border-box;
}
.itemA {
flex-basis: 30px;
background: purple;
border: 4px solid indigo;
}
.itemB {
flex-basis: 50px;
background: teal;
border: 5px solid lightblue;
}
</style>
</head>
<body>
<!-- FIRST ROW -->
<!-- 1 inflexible item -->
<div class="container">
<div class="itemA"></div>
</div>
<!-- 1 flexible item -->
<div class="container">
<div class="itemA" style="flex-grow: 1"></div>
</div>
<div style="clear: both"></div>
<!-- SECOND ROW -->
<!-- 2 inflexible items -->
<div class="container">
<div class="itemA"></div>
<div class="itemB"></div>
</div>
<!-- 2 flexible items -->
<div class="container">
<div class="itemA" style="flex-grow: 1"></div>
<div class="itemB" style="flex-grow: 1"></div>
</div>
</body>
</html>

View File

@ -47,6 +47,14 @@ fuzzy-if(B2G,10,3) random-if(winWidget) == flexbox-align-self-baseline-horiz-3.x
# fail until bug 794660 is fixed:
== flexbox-basic-video-vert-2.xhtml flexbox-basic-video-vert-2-ref.xhtml
# Tests for box-sizing on flex containers and flex items.
== flexbox-box-sizing-on-container-horiz-1.html flexbox-box-sizing-on-container-horiz-1-ref.html
== flexbox-box-sizing-on-container-vert-1.html flexbox-box-sizing-on-container-vert-1-ref.html
== flexbox-box-sizing-on-items-horiz-1a.html flexbox-box-sizing-on-items-horiz-1-ref.html
== flexbox-box-sizing-on-items-horiz-1b.html flexbox-box-sizing-on-items-horiz-1-ref.html
== flexbox-box-sizing-on-items-vert-1a.html flexbox-box-sizing-on-items-vert-1-ref.html
== flexbox-box-sizing-on-items-vert-1b.html flexbox-box-sizing-on-items-vert-1-ref.html
# Tests for dynamic modifications of content inside/around a flex container
== flexbox-dyn-changeFrameWidth-1.xhtml flexbox-dyn-changeFrameWidth-1-ref.xhtml
== flexbox-dyn-changeFrameWidth-2.xhtml flexbox-dyn-changeFrameWidth-2-ref.xhtml

View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path id="path" transform="scale(2,1)" />
<text>
<textPath xlink:href="#path">F</textPath>
</text>
</svg>

After

Width:  |  Height:  |  Size: 213 B

Some files were not shown because too many files have changed in this diff Show More