Version 0.6.9.0 .
svn merge -r 25219:25244 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@25249 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index 5d0b391..415102a 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -368,7 +368,7 @@
var typedefs = {};
var errors = {};
- mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
+ mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
if (includePrivate || !mirror.isPrivate) {
var superclass = (mirror.superclass != null) ?
mirror.superclass.qualifiedName : '';
@@ -377,7 +377,7 @@
var clazz = new Class(mirrorName, superclass, _getComment(mirror),
interfaces.toList(), _getVariables(mirror.variables, includePrivate),
_getMethods(mirror.methods, includePrivate),
- _getAnnotations(mirror), mirror.qualifiedName);
+ _getAnnotations(mirror), _getGenerics(mirror), mirror.qualifiedName);
_currentClass = mirror;
if (isError(mirror.qualifiedName)) {
@@ -417,6 +417,15 @@
}
/**
+ * Returns a map of [Generic] objects constructed from the class mirror.
+ */
+Map<String, Generic> _getGenerics(ClassMirror mirror) {
+ return new Map.fromIterable(mirror.typeVariables,
+ key: (e) => e.toString(),
+ value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName));
+}
+
+/**
* Writes text to a file in the 'docs' directory.
*/
void _writeToFile(String text, String filename) {
@@ -515,6 +524,9 @@
/// Methods in the class.
Map<String, Map<String, Method>> methods;
+ /// Generic infomation about the class.
+ Map<String, Generic> generics;
+
String name;
String superclass;
@@ -522,7 +534,7 @@
List<String> annotations;
Class(this.name, this.superclass, this.comment, this.interfaces,
- this.variables, this.methods, this.annotations,
+ this.variables, this.methods, this.annotations, this.generics,
String qualifiedName) : super(qualifiedName) {}
/// Generates a map describing the [Class] object.
@@ -535,6 +547,7 @@
classMap['variables'] = recurseMap(variables);
classMap['methods'] = recurseMap(methods);
classMap['annotations'] = new List.from(annotations);
+ classMap['generics'] = recurseMap(generics);
return classMap;
}
}
@@ -637,3 +650,20 @@
return parameterMap;
}
}
+
+/**
+ * A class containing properties of a Generic.
+ */
+class Generic {
+ String name;
+ String type;
+
+ Generic(this.name, this.type);
+
+ Map toMap() {
+ return {
+ 'name': name,
+ 'type': type
+ };
+ }
+}
\ No newline at end of file
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 3ced5d0..fc0522a 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -324,7 +324,7 @@
bool FileHandle::IsClosed() {
- return IsClosing();
+ return IsClosing() && !HasPendingRead() && !HasPendingWrite();
}
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index a3cc62b..c24ba4d 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -426,6 +426,8 @@
}
_NativeSocket accept() {
+ // Don't issue accept if we're closing.
+ if (isClosing || isClosed) return null;
var socket = new _NativeSocket.normal();
if (nativeAccept(socket) != true) return null;
socket.localPort = localPort;
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 450aa2d..e967378 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -733,6 +733,9 @@
var _owner;
DeclarationMirror get owner {
+ if (_owner == null) {
+ _owner = _LocalClassMirrorImpl._library(_reflectee);
+ }
if (_owner is! Mirror) {
_owner = _owner.resolve(mirrors);
}
diff --git a/runtime/lib/simd128.cc b/runtime/lib/simd128.cc
index 81894fe..542eee4 100644
--- a/runtime/lib/simd128.cc
+++ b/runtime/lib/simd128.cc
@@ -229,31 +229,16 @@
}
-DEFINE_NATIVE_ENTRY(Float32x4_getXXXX, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_shuffle, 2) {
GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
- float value = self.x();
- return Float32x4::New(value, value, value, value);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_getYYYY, 1) {
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
- float value = self.y();
- return Float32x4::New(value, value, value, value);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_getZZZZ, 1) {
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
- float value = self.z();
- return Float32x4::New(value, value, value, value);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_getWWWW, 1) {
- GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
- float value = self.w();
- return Float32x4::New(value, value, value, value);
+ GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(1));
+ int64_t m = mask.AsInt64Value();
+ float data[4] = { self.x(), self.y(), self.z(), self.w() };
+ float _x = data[m & 0x3];
+ float _y = data[(m >> 2) & 0x3];
+ float _z = data[(m >> 4) & 0x3];
+ float _w = data[(m >> 6) & 0x3];
+ return Float32x4::New(_x, _y, _z, _w);
}
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index f2fde0d..15a8deb 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -2006,10 +2006,263 @@
double get y native "Float32x4_getY";
double get z native "Float32x4_getZ";
double get w native "Float32x4_getW";
- Float32x4 get xxxx native "Float32x4_getXXXX";
- Float32x4 get yyyy native "Float32x4_getYYYY";
- Float32x4 get zzzz native "Float32x4_getZZZZ";
- Float32x4 get wwww native "Float32x4_getWWWW";
+ Float32x4 get xxxx => _shuffle(0x0);
+ Float32x4 get xxxy => _shuffle(0x40);
+ Float32x4 get xxxz => _shuffle(0x80);
+ Float32x4 get xxxw => _shuffle(0xC0);
+ Float32x4 get xxyx => _shuffle(0x10);
+ Float32x4 get xxyy => _shuffle(0x50);
+ Float32x4 get xxyz => _shuffle(0x90);
+ Float32x4 get xxyw => _shuffle(0xD0);
+ Float32x4 get xxzx => _shuffle(0x20);
+ Float32x4 get xxzy => _shuffle(0x60);
+ Float32x4 get xxzz => _shuffle(0xA0);
+ Float32x4 get xxzw => _shuffle(0xE0);
+ Float32x4 get xxwx => _shuffle(0x30);
+ Float32x4 get xxwy => _shuffle(0x70);
+ Float32x4 get xxwz => _shuffle(0xB0);
+ Float32x4 get xxww => _shuffle(0xF0);
+ Float32x4 get xyxx => _shuffle(0x4);
+ Float32x4 get xyxy => _shuffle(0x44);
+ Float32x4 get xyxz => _shuffle(0x84);
+ Float32x4 get xyxw => _shuffle(0xC4);
+ Float32x4 get xyyx => _shuffle(0x14);
+ Float32x4 get xyyy => _shuffle(0x54);
+ Float32x4 get xyyz => _shuffle(0x94);
+ Float32x4 get xyyw => _shuffle(0xD4);
+ Float32x4 get xyzx => _shuffle(0x24);
+ Float32x4 get xyzy => _shuffle(0x64);
+ Float32x4 get xyzz => _shuffle(0xA4);
+ Float32x4 get xyzw => _shuffle(0xE4);
+ Float32x4 get xywx => _shuffle(0x34);
+ Float32x4 get xywy => _shuffle(0x74);
+ Float32x4 get xywz => _shuffle(0xB4);
+ Float32x4 get xyww => _shuffle(0xF4);
+ Float32x4 get xzxx => _shuffle(0x8);
+ Float32x4 get xzxy => _shuffle(0x48);
+ Float32x4 get xzxz => _shuffle(0x88);
+ Float32x4 get xzxw => _shuffle(0xC8);
+ Float32x4 get xzyx => _shuffle(0x18);
+ Float32x4 get xzyy => _shuffle(0x58);
+ Float32x4 get xzyz => _shuffle(0x98);
+ Float32x4 get xzyw => _shuffle(0xD8);
+ Float32x4 get xzzx => _shuffle(0x28);
+ Float32x4 get xzzy => _shuffle(0x68);
+ Float32x4 get xzzz => _shuffle(0xA8);
+ Float32x4 get xzzw => _shuffle(0xE8);
+ Float32x4 get xzwx => _shuffle(0x38);
+ Float32x4 get xzwy => _shuffle(0x78);
+ Float32x4 get xzwz => _shuffle(0xB8);
+ Float32x4 get xzww => _shuffle(0xF8);
+ Float32x4 get xwxx => _shuffle(0xC);
+ Float32x4 get xwxy => _shuffle(0x4C);
+ Float32x4 get xwxz => _shuffle(0x8C);
+ Float32x4 get xwxw => _shuffle(0xCC);
+ Float32x4 get xwyx => _shuffle(0x1C);
+ Float32x4 get xwyy => _shuffle(0x5C);
+ Float32x4 get xwyz => _shuffle(0x9C);
+ Float32x4 get xwyw => _shuffle(0xDC);
+ Float32x4 get xwzx => _shuffle(0x2C);
+ Float32x4 get xwzy => _shuffle(0x6C);
+ Float32x4 get xwzz => _shuffle(0xAC);
+ Float32x4 get xwzw => _shuffle(0xEC);
+ Float32x4 get xwwx => _shuffle(0x3C);
+ Float32x4 get xwwy => _shuffle(0x7C);
+ Float32x4 get xwwz => _shuffle(0xBC);
+ Float32x4 get xwww => _shuffle(0xFC);
+ Float32x4 get yxxx => _shuffle(0x1);
+ Float32x4 get yxxy => _shuffle(0x41);
+ Float32x4 get yxxz => _shuffle(0x81);
+ Float32x4 get yxxw => _shuffle(0xC1);
+ Float32x4 get yxyx => _shuffle(0x11);
+ Float32x4 get yxyy => _shuffle(0x51);
+ Float32x4 get yxyz => _shuffle(0x91);
+ Float32x4 get yxyw => _shuffle(0xD1);
+ Float32x4 get yxzx => _shuffle(0x21);
+ Float32x4 get yxzy => _shuffle(0x61);
+ Float32x4 get yxzz => _shuffle(0xA1);
+ Float32x4 get yxzw => _shuffle(0xE1);
+ Float32x4 get yxwx => _shuffle(0x31);
+ Float32x4 get yxwy => _shuffle(0x71);
+ Float32x4 get yxwz => _shuffle(0xB1);
+ Float32x4 get yxww => _shuffle(0xF1);
+ Float32x4 get yyxx => _shuffle(0x5);
+ Float32x4 get yyxy => _shuffle(0x45);
+ Float32x4 get yyxz => _shuffle(0x85);
+ Float32x4 get yyxw => _shuffle(0xC5);
+ Float32x4 get yyyx => _shuffle(0x15);
+ Float32x4 get yyyy => _shuffle(0x55);
+ Float32x4 get yyyz => _shuffle(0x95);
+ Float32x4 get yyyw => _shuffle(0xD5);
+ Float32x4 get yyzx => _shuffle(0x25);
+ Float32x4 get yyzy => _shuffle(0x65);
+ Float32x4 get yyzz => _shuffle(0xA5);
+ Float32x4 get yyzw => _shuffle(0xE5);
+ Float32x4 get yywx => _shuffle(0x35);
+ Float32x4 get yywy => _shuffle(0x75);
+ Float32x4 get yywz => _shuffle(0xB5);
+ Float32x4 get yyww => _shuffle(0xF5);
+ Float32x4 get yzxx => _shuffle(0x9);
+ Float32x4 get yzxy => _shuffle(0x49);
+ Float32x4 get yzxz => _shuffle(0x89);
+ Float32x4 get yzxw => _shuffle(0xC9);
+ Float32x4 get yzyx => _shuffle(0x19);
+ Float32x4 get yzyy => _shuffle(0x59);
+ Float32x4 get yzyz => _shuffle(0x99);
+ Float32x4 get yzyw => _shuffle(0xD9);
+ Float32x4 get yzzx => _shuffle(0x29);
+ Float32x4 get yzzy => _shuffle(0x69);
+ Float32x4 get yzzz => _shuffle(0xA9);
+ Float32x4 get yzzw => _shuffle(0xE9);
+ Float32x4 get yzwx => _shuffle(0x39);
+ Float32x4 get yzwy => _shuffle(0x79);
+ Float32x4 get yzwz => _shuffle(0xB9);
+ Float32x4 get yzww => _shuffle(0xF9);
+ Float32x4 get ywxx => _shuffle(0xD);
+ Float32x4 get ywxy => _shuffle(0x4D);
+ Float32x4 get ywxz => _shuffle(0x8D);
+ Float32x4 get ywxw => _shuffle(0xCD);
+ Float32x4 get ywyx => _shuffle(0x1D);
+ Float32x4 get ywyy => _shuffle(0x5D);
+ Float32x4 get ywyz => _shuffle(0x9D);
+ Float32x4 get ywyw => _shuffle(0xDD);
+ Float32x4 get ywzx => _shuffle(0x2D);
+ Float32x4 get ywzy => _shuffle(0x6D);
+ Float32x4 get ywzz => _shuffle(0xAD);
+ Float32x4 get ywzw => _shuffle(0xED);
+ Float32x4 get ywwx => _shuffle(0x3D);
+ Float32x4 get ywwy => _shuffle(0x7D);
+ Float32x4 get ywwz => _shuffle(0xBD);
+ Float32x4 get ywww => _shuffle(0xFD);
+ Float32x4 get zxxx => _shuffle(0x2);
+ Float32x4 get zxxy => _shuffle(0x42);
+ Float32x4 get zxxz => _shuffle(0x82);
+ Float32x4 get zxxw => _shuffle(0xC2);
+ Float32x4 get zxyx => _shuffle(0x12);
+ Float32x4 get zxyy => _shuffle(0x52);
+ Float32x4 get zxyz => _shuffle(0x92);
+ Float32x4 get zxyw => _shuffle(0xD2);
+ Float32x4 get zxzx => _shuffle(0x22);
+ Float32x4 get zxzy => _shuffle(0x62);
+ Float32x4 get zxzz => _shuffle(0xA2);
+ Float32x4 get zxzw => _shuffle(0xE2);
+ Float32x4 get zxwx => _shuffle(0x32);
+ Float32x4 get zxwy => _shuffle(0x72);
+ Float32x4 get zxwz => _shuffle(0xB2);
+ Float32x4 get zxww => _shuffle(0xF2);
+ Float32x4 get zyxx => _shuffle(0x6);
+ Float32x4 get zyxy => _shuffle(0x46);
+ Float32x4 get zyxz => _shuffle(0x86);
+ Float32x4 get zyxw => _shuffle(0xC6);
+ Float32x4 get zyyx => _shuffle(0x16);
+ Float32x4 get zyyy => _shuffle(0x56);
+ Float32x4 get zyyz => _shuffle(0x96);
+ Float32x4 get zyyw => _shuffle(0xD6);
+ Float32x4 get zyzx => _shuffle(0x26);
+ Float32x4 get zyzy => _shuffle(0x66);
+ Float32x4 get zyzz => _shuffle(0xA6);
+ Float32x4 get zyzw => _shuffle(0xE6);
+ Float32x4 get zywx => _shuffle(0x36);
+ Float32x4 get zywy => _shuffle(0x76);
+ Float32x4 get zywz => _shuffle(0xB6);
+ Float32x4 get zyww => _shuffle(0xF6);
+ Float32x4 get zzxx => _shuffle(0xA);
+ Float32x4 get zzxy => _shuffle(0x4A);
+ Float32x4 get zzxz => _shuffle(0x8A);
+ Float32x4 get zzxw => _shuffle(0xCA);
+ Float32x4 get zzyx => _shuffle(0x1A);
+ Float32x4 get zzyy => _shuffle(0x5A);
+ Float32x4 get zzyz => _shuffle(0x9A);
+ Float32x4 get zzyw => _shuffle(0xDA);
+ Float32x4 get zzzx => _shuffle(0x2A);
+ Float32x4 get zzzy => _shuffle(0x6A);
+ Float32x4 get zzzz => _shuffle(0xAA);
+ Float32x4 get zzzw => _shuffle(0xEA);
+ Float32x4 get zzwx => _shuffle(0x3A);
+ Float32x4 get zzwy => _shuffle(0x7A);
+ Float32x4 get zzwz => _shuffle(0xBA);
+ Float32x4 get zzww => _shuffle(0xFA);
+ Float32x4 get zwxx => _shuffle(0xE);
+ Float32x4 get zwxy => _shuffle(0x4E);
+ Float32x4 get zwxz => _shuffle(0x8E);
+ Float32x4 get zwxw => _shuffle(0xCE);
+ Float32x4 get zwyx => _shuffle(0x1E);
+ Float32x4 get zwyy => _shuffle(0x5E);
+ Float32x4 get zwyz => _shuffle(0x9E);
+ Float32x4 get zwyw => _shuffle(0xDE);
+ Float32x4 get zwzx => _shuffle(0x2E);
+ Float32x4 get zwzy => _shuffle(0x6E);
+ Float32x4 get zwzz => _shuffle(0xAE);
+ Float32x4 get zwzw => _shuffle(0xEE);
+ Float32x4 get zwwx => _shuffle(0x3E);
+ Float32x4 get zwwy => _shuffle(0x7E);
+ Float32x4 get zwwz => _shuffle(0xBE);
+ Float32x4 get zwww => _shuffle(0xFE);
+ Float32x4 get wxxx => _shuffle(0x3);
+ Float32x4 get wxxy => _shuffle(0x43);
+ Float32x4 get wxxz => _shuffle(0x83);
+ Float32x4 get wxxw => _shuffle(0xC3);
+ Float32x4 get wxyx => _shuffle(0x13);
+ Float32x4 get wxyy => _shuffle(0x53);
+ Float32x4 get wxyz => _shuffle(0x93);
+ Float32x4 get wxyw => _shuffle(0xD3);
+ Float32x4 get wxzx => _shuffle(0x23);
+ Float32x4 get wxzy => _shuffle(0x63);
+ Float32x4 get wxzz => _shuffle(0xA3);
+ Float32x4 get wxzw => _shuffle(0xE3);
+ Float32x4 get wxwx => _shuffle(0x33);
+ Float32x4 get wxwy => _shuffle(0x73);
+ Float32x4 get wxwz => _shuffle(0xB3);
+ Float32x4 get wxww => _shuffle(0xF3);
+ Float32x4 get wyxx => _shuffle(0x7);
+ Float32x4 get wyxy => _shuffle(0x47);
+ Float32x4 get wyxz => _shuffle(0x87);
+ Float32x4 get wyxw => _shuffle(0xC7);
+ Float32x4 get wyyx => _shuffle(0x17);
+ Float32x4 get wyyy => _shuffle(0x57);
+ Float32x4 get wyyz => _shuffle(0x97);
+ Float32x4 get wyyw => _shuffle(0xD7);
+ Float32x4 get wyzx => _shuffle(0x27);
+ Float32x4 get wyzy => _shuffle(0x67);
+ Float32x4 get wyzz => _shuffle(0xA7);
+ Float32x4 get wyzw => _shuffle(0xE7);
+ Float32x4 get wywx => _shuffle(0x37);
+ Float32x4 get wywy => _shuffle(0x77);
+ Float32x4 get wywz => _shuffle(0xB7);
+ Float32x4 get wyww => _shuffle(0xF7);
+ Float32x4 get wzxx => _shuffle(0xB);
+ Float32x4 get wzxy => _shuffle(0x4B);
+ Float32x4 get wzxz => _shuffle(0x8B);
+ Float32x4 get wzxw => _shuffle(0xCB);
+ Float32x4 get wzyx => _shuffle(0x1B);
+ Float32x4 get wzyy => _shuffle(0x5B);
+ Float32x4 get wzyz => _shuffle(0x9B);
+ Float32x4 get wzyw => _shuffle(0xDB);
+ Float32x4 get wzzx => _shuffle(0x2B);
+ Float32x4 get wzzy => _shuffle(0x6B);
+ Float32x4 get wzzz => _shuffle(0xAB);
+ Float32x4 get wzzw => _shuffle(0xEB);
+ Float32x4 get wzwx => _shuffle(0x3B);
+ Float32x4 get wzwy => _shuffle(0x7B);
+ Float32x4 get wzwz => _shuffle(0xBB);
+ Float32x4 get wzww => _shuffle(0xFB);
+ Float32x4 get wwxx => _shuffle(0xF);
+ Float32x4 get wwxy => _shuffle(0x4F);
+ Float32x4 get wwxz => _shuffle(0x8F);
+ Float32x4 get wwxw => _shuffle(0xCF);
+ Float32x4 get wwyx => _shuffle(0x1F);
+ Float32x4 get wwyy => _shuffle(0x5F);
+ Float32x4 get wwyz => _shuffle(0x9F);
+ Float32x4 get wwyw => _shuffle(0xDF);
+ Float32x4 get wwzx => _shuffle(0x2F);
+ Float32x4 get wwzy => _shuffle(0x6F);
+ Float32x4 get wwzz => _shuffle(0xAF);
+ Float32x4 get wwzw => _shuffle(0xEF);
+ Float32x4 get wwwx => _shuffle(0x3F);
+ Float32x4 get wwwy => _shuffle(0x7F);
+ Float32x4 get wwwz => _shuffle(0xBF);
+ Float32x4 get wwww => _shuffle(0xFF);
+ Float32x4 _shuffle(int mask) native "Float32x4_shuffle";
Float32x4 withX(double x) native "Float32x4_setX";
Float32x4 withY(double y) native "Float32x4_setY";
Float32x4 withZ(double z) native "Float32x4_setZ";
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 5bf8ad1..ef83acb 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -195,10 +195,7 @@
V(Float32x4_getY, 1) \
V(Float32x4_getZ, 1) \
V(Float32x4_getW, 1) \
- V(Float32x4_getXXXX, 1) \
- V(Float32x4_getYYYY, 1) \
- V(Float32x4_getZZZZ, 1) \
- V(Float32x4_getWWWW, 1) \
+ V(Float32x4_shuffle, 2) \
V(Float32x4_setX, 2) \
V(Float32x4_setY, 2) \
V(Float32x4_setZ, 2) \
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 7294784..f439def 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1024,6 +1024,42 @@
}
+// Handles a static call in unoptimized code that has two argument types not
+// seen before. Compile the target if necessary and update the ICData.
+// Arg0: argument 0.
+// Arg1: argument 1.
+// Arg2: IC data object.
+DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) {
+ ASSERT(arguments.ArgCount() ==
+ kStaticCallMissHandlerTwoArgsRuntimeEntry.argument_count());
+ const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0));
+ const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1));
+ const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2));
+ // IC data for static call is prepopulated with the statically known target.
+ ASSERT(ic_data.NumberOfChecks() > 0);
+ const Function& target = Function::Handle(ic_data.GetTargetAt(0));
+ if (!target.HasCode()) {
+ const Error& error = Error::Handle(Compiler::CompileFunction(target));
+ if (!error.IsNull()) {
+ Exceptions::PropagateError(error);
+ }
+ }
+ ASSERT(!target.IsNull() && target.HasCode());
+ GrowableArray<intptr_t> cids(2);
+ cids.Add(arg0.GetClassId());
+ cids.Add(arg1.GetClassId());
+ ic_data.AddCheck(cids, target);
+ if (FLAG_trace_ic) {
+ DartFrameIterator iterator;
+ StackFrame* caller_frame = iterator.NextFrame();
+ ASSERT(caller_frame != NULL);
+ OS::PrintErr("StaticCallMissHandler at %#"Px" target %s (%"Pd", %"Pd")\n",
+ caller_frame->pc(), target.ToCString(), cids[0], cids[1]);
+ }
+ arguments.SetReturn(target);
+}
+
+
// Handle a miss of a megamorphic cache.
// Arg0: Receiver.
// Arg1: ICData object.
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index 2461594..6ec0c13 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -35,6 +35,7 @@
DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg);
DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs);
DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs);
+DECLARE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs);
DECLARE_RUNTIME_ENTRY(InstanceFunctionLookup);
DECLARE_RUNTIME_ENTRY(Instanceof);
DECLARE_RUNTIME_ENTRY(InstantiateType);
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index d68c938..9cccd56 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -91,7 +91,7 @@
#if defined(DEBUG)
ICData& test_ic_data = ICData::Handle();
test_ic_data ^= ic_data();
- ASSERT(test_ic_data.num_args_tested() == 0);
+ ASSERT(test_ic_data.num_args_tested() >= 0);
#endif // DEBUG
}
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index ec9e56f..ae307d57 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -82,7 +82,7 @@
#if defined(DEBUG)
ICData& test_ic_data = ICData::Handle();
test_ic_data ^= ic_data();
- ASSERT(test_ic_data.num_args_tested() == 0);
+ ASSERT(test_ic_data.num_args_tested() >= 0);
#endif // DEBUG
}
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 1a65c51..9b6d509 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -190,6 +190,7 @@
const Register PP = R10; // Caches object pool pointer in generated code.
const Register SPREG = SP; // Stack pointer register.
const Register FPREG = FP; // Frame pointer register.
+const Register ICREG = R5; // IC data register.
// Exception object is passed in this register to the catch handlers when an
// exception is thrown.
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index c679e12..acc1898 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -65,6 +65,7 @@
const Register PP = kNoRegister; // No object pool pointer.
const Register SPREG = ESP; // Stack pointer register.
const Register FPREG = EBP; // Frame pointer register.
+const Register ICREG = ECX; // IC data register.
// Exception object is passed in this register to the catch handlers when an
// exception is thrown.
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index bb16ccd..006280b 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -174,6 +174,7 @@
const Register PP = S7; // Caches object pool pointer in generated code.
const Register SPREG = SP; // Stack pointer register.
const Register FPREG = FP; // Frame pointer register.
+const Register ICREG = S5; // IC data register.
// The code that generates a comparison can be far away from the code that
// generates the branch that uses the result of that comparison. In this case,
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 8cc827c..3fa9526 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -89,6 +89,7 @@
const Register PP = kNoRegister; // No object pool pointer.
const Register SPREG = RSP; // Stack pointer register.
const Register FPREG = RBP; // Frame pointer register.
+const Register ICREG = RBX; // IC data register.
// Exception object is passed in this register to the catch handlers when an
// exception is thrown.
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 554ae8a..449c928 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -630,6 +630,48 @@
}
+void FlowGraphCompiler::EmitUnoptimizedStaticCall(
+ const Function& target_function,
+ const Array& arguments_descriptor,
+ intptr_t argument_count,
+ intptr_t deopt_id,
+ intptr_t token_pos,
+ LocationSummary* locs) {
+ // TODO(srdjan): Improve performance of function recognition.
+ MethodRecognizer::Kind recognized_kind =
+ MethodRecognizer::RecognizeKind(target_function);
+ int num_args_checked = 0;
+ if ((recognized_kind == MethodRecognizer::kMathMin) ||
+ (recognized_kind == MethodRecognizer::kMathMax)) {
+ num_args_checked = 2;
+ }
+ const ICData& ic_data = ICData::ZoneHandle(
+ ICData::New(parsed_function().function(), // Caller function.
+ String::Handle(target_function.name()),
+ arguments_descriptor,
+ deopt_id,
+ num_args_checked)); // No arguments checked.
+ ic_data.AddTarget(target_function);
+ uword label_address = 0;
+ if (ic_data.num_args_tested() == 0) {
+ label_address = StubCode::ZeroArgsUnoptimizedStaticCallEntryPoint();
+ } else if (ic_data.num_args_tested() == 2) {
+ label_address = StubCode::TwoArgsUnoptimizedStaticCallEntryPoint();
+ } else {
+ UNIMPLEMENTED();
+ }
+ ExternalLabel target_label("StaticCallICStub", label_address);
+ assembler()->LoadObject(ICREG, ic_data);
+ GenerateDartCall(deopt_id,
+ token_pos,
+ &target_label,
+ PcDescriptors::kUnoptStaticCall,
+ locs);
+ assembler()->Drop(argument_count);
+}
+
+
+
void FlowGraphCompiler::GenerateNumberTypeCheck(Register kClassIdReg,
const AbstractType& type,
Label* is_instance_lbl,
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 01b166f..0aeec79 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -1406,30 +1406,6 @@
}
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(
- const Function& target_function,
- const Array& arguments_descriptor,
- intptr_t argument_count,
- intptr_t deopt_id,
- intptr_t token_pos,
- LocationSummary* locs) {
- const ICData& ic_data = ICData::ZoneHandle(
- ICData::New(parsed_function().function(), // Caller function.
- String::Handle(target_function.name()),
- arguments_descriptor,
- deopt_id,
- 0)); // No arguments checked.
- ic_data.AddTarget(target_function);
- __ LoadObject(R5, ic_data);
- GenerateDartCall(deopt_id,
- token_pos,
- &StubCode::UnoptimizedStaticCallLabel(),
- PcDescriptors::kUnoptStaticCall,
- locs);
- __ Drop(argument_count);
-}
-
-
void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
const Object& obj,
bool needs_number_check,
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 6683c36..6db56ad 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -1409,30 +1409,6 @@
}
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(
- const Function& target_function,
- const Array& arguments_descriptor,
- intptr_t argument_count,
- intptr_t deopt_id,
- intptr_t token_pos,
- LocationSummary* locs) {
- const ICData& ic_data = ICData::ZoneHandle(
- ICData::New(parsed_function().function(), // Caller function.
- String::Handle(target_function.name()),
- arguments_descriptor,
- deopt_id,
- 0)); // No arguments checked.
- ic_data.AddTarget(target_function);
- __ LoadObject(ECX, ic_data);
- GenerateDartCall(deopt_id,
- token_pos,
- &StubCode::UnoptimizedStaticCallLabel(),
- PcDescriptors::kUnoptStaticCall,
- locs);
- __ Drop(argument_count);
-}
-
-
void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
const Object& obj,
bool needs_number_check,
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 2a5f44f..adbd850 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -1462,30 +1462,6 @@
}
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(
- const Function& target_function,
- const Array& arguments_descriptor,
- intptr_t argument_count,
- intptr_t deopt_id,
- intptr_t token_pos,
- LocationSummary* locs) {
- const ICData& ic_data = ICData::ZoneHandle(
- ICData::New(parsed_function().function(), // Caller function.
- String::Handle(target_function.name()),
- arguments_descriptor,
- deopt_id,
- 0)); // No arguments checked.
- ic_data.AddTarget(target_function);
- __ LoadObject(S5, ic_data);
- GenerateDartCall(deopt_id,
- token_pos,
- &StubCode::UnoptimizedStaticCallLabel(),
- PcDescriptors::kUnoptStaticCall,
- locs);
- __ Drop(argument_count);
-}
-
-
void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
const Object& obj,
bool needs_number_check,
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 22e25a9..c165e50 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -1404,30 +1404,6 @@
}
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(
- const Function& target_function,
- const Array& arguments_descriptor,
- intptr_t argument_count,
- intptr_t deopt_id,
- intptr_t token_pos,
- LocationSummary* locs) {
- const ICData& ic_data = ICData::ZoneHandle(
- ICData::New(parsed_function().function(), // Caller function.
- String::Handle(target_function.name()),
- arguments_descriptor,
- deopt_id,
- 0)); // No arguments checked.
- ic_data.AddTarget(target_function);
- __ LoadObject(RBX, ic_data);
- GenerateDartCall(deopt_id,
- token_pos,
- &StubCode::UnoptimizedStaticCallLabel(),
- PcDescriptors::kUnoptStaticCall,
- locs);
- __ Drop(argument_count);
-}
-
-
void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
const Object& obj,
bool needs_number_check,
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index e3a1f82..566290b 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -1468,9 +1468,23 @@
call->deopt_id(),
call->env(),
call);
+ intptr_t mask = 0;
+ if (getter == MethodRecognizer::kFloat32x4Shuffle) {
+ ASSERT(call->ArgumentCount() == 2);
+ // Extract shuffle mask.
+ Definition* mask_definition = call->ArgumentAt(1);
+ ASSERT(mask_definition->IsConstant());
+ ConstantInstr* constant_instruction = mask_definition->AsConstant();
+ const Object& constant_mask = constant_instruction->value();
+ ASSERT(constant_mask.IsSmi());
+ mask = Smi::Cast(constant_mask).Value();
+ ASSERT(mask >= 0);
+ ASSERT(mask <= 255);
+ }
Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr(
getter,
new Value(call->ArgumentAt(0)),
+ mask,
call->deopt_id());
ReplaceCall(call, instr);
return true;
@@ -1561,10 +1575,6 @@
}
InlineStringIsEmptyGetter(call);
return true;
- case MethodRecognizer::kFloat32x4ShuffleXXXX:
- case MethodRecognizer::kFloat32x4ShuffleYYYY:
- case MethodRecognizer::kFloat32x4ShuffleZZZZ:
- case MethodRecognizer::kFloat32x4ShuffleWWWW:
case MethodRecognizer::kFloat32x4ShuffleX:
case MethodRecognizer::kFloat32x4ShuffleY:
case MethodRecognizer::kFloat32x4ShuffleZ:
@@ -2035,6 +2045,9 @@
ReplaceCall(call, cast);
return true;
}
+ case MethodRecognizer::kFloat32x4Shuffle: {
+ return InlineFloat32x4Getter(call, recognized_kind);
+ }
default:
return false;
}
@@ -2485,7 +2498,7 @@
MethodRecognizer::RecognizeKind(call->function());
if (recognized_kind == MethodRecognizer::kMathSqrt) {
MathSqrtInstr* sqrt =
- new MathSqrtInstr(new Value(call->ArgumentAt(0)), call);
+ new MathSqrtInstr(new Value(call->ArgumentAt(0)), call->deopt_id());
ReplaceCall(call, sqrt);
} else if (recognized_kind == MethodRecognizer::kFloat32x4Zero) {
Float32x4ZeroInstr* zero = new Float32x4ZeroInstr(call->deopt_id());
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index bc01952..47e0967 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -36,6 +36,7 @@
// (class-name, function-name, recognized enum, fingerprint).
// See intrinsifier for fingerprint computation.
#define RECOGNIZED_LIST(V) \
+ V(::, identical, ObjectIdentical, 1018911876) \
V(Object, Object., ObjectConstructor, 2030609793) \
V(Object, get:_cid, ObjectCid, 732498573) \
V(_ObjectArray, get:length, ObjectArrayLength, 405297088) \
@@ -77,13 +78,12 @@
V(_Double, pow, DoublePow, 102305574) \
V(_Double, _modulo, DoubleMod, 663439671) \
V(::, sqrt, MathSqrt, 1662640002) \
+ V(::, min, MathMin, 269896129) \
+ V(::, max, MathMax, 1286442186) \
V(Float32x4, Float32x4., Float32x4Constructor, 1492157358) \
V(Float32x4, Float32x4.zero, Float32x4Zero, 444339161) \
V(Float32x4, Float32x4.splat, Float32x4Splat, 1843231403) \
- V(_Float32x4, get:xxxx, Float32x4ShuffleXXXX, 42621627) \
- V(_Float32x4, get:yyyy, Float32x4ShuffleYYYY, 42621627) \
- V(_Float32x4, get:zzzz, Float32x4ShuffleZZZZ, 42621627) \
- V(_Float32x4, get:wwww, Float32x4ShuffleWWWW, 42621627) \
+ V(_Float32x4, _shuffle, Float32x4Shuffle, 1618450134) \
V(_Float32x4, get:x, Float32x4ShuffleX, 211144022) \
V(_Float32x4, get:y, Float32x4ShuffleY, 211144022) \
V(_Float32x4, get:z, Float32x4ShuffleZ, 211144022) \
@@ -4593,9 +4593,9 @@
class MathSqrtInstr : public TemplateDefinition<1> {
public:
- MathSqrtInstr(Value* value, StaticCallInstr* instance_call) {
+ MathSqrtInstr(Value* value, intptr_t deopt_id) {
SetInputAt(0, value);
- deopt_id_ = instance_call->deopt_id();
+ deopt_id_ = deopt_id;
}
Value* value() const { return inputs_[0]; }
@@ -4748,8 +4748,9 @@
class Float32x4ShuffleInstr : public TemplateDefinition<1> {
public:
Float32x4ShuffleInstr(MethodRecognizer::Kind op_kind, Value* value,
+ intptr_t mask,
intptr_t deopt_id)
- : op_kind_(op_kind) {
+ : op_kind_(op_kind), mask_(mask) {
SetInputAt(0, value);
deopt_id_ = deopt_id;
}
@@ -4758,6 +4759,8 @@
MethodRecognizer::Kind op_kind() const { return op_kind_; }
+ intptr_t mask() const { return mask_; }
+
virtual void PrintOperandsTo(BufferFormatter* f) const;
virtual bool CanDeoptimize() const { return false; }
@@ -4790,13 +4793,15 @@
virtual EffectSet Effects() const { return EffectSet::None(); }
virtual EffectSet Dependencies() const { return EffectSet::None(); }
virtual bool AttributesEqual(Instruction* other) const {
- return op_kind() == other->AsFloat32x4Shuffle()->op_kind();
+ return op_kind() == other->AsFloat32x4Shuffle()->op_kind() &&
+ mask() == other->AsFloat32x4Shuffle()->mask();
}
virtual bool MayThrow() const { return false; }
private:
const MethodRecognizer::Kind op_kind_;
+ const intptr_t mask_;
DISALLOW_COPY_AND_ASSIGN(Float32x4ShuffleInstr);
};
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 8d95969..f6790b7 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -2965,18 +2965,6 @@
// For these cases the vdup instruction requires fewer
// instructions. For arbitrary shuffles, vtbl will be needed.
switch (op_kind()) {
- case MethodRecognizer::kFloat32x4ShuffleXXXX:
- __ vdup(kWord, result, dvalue0, 0);
- break;
- case MethodRecognizer::kFloat32x4ShuffleYYYY:
- __ vdup(kWord, result, dvalue0, 1);
- break;
- case MethodRecognizer::kFloat32x4ShuffleZZZZ:
- __ vdup(kWord, result, dvalue1, 0);
- break;
- case MethodRecognizer::kFloat32x4ShuffleWWWW:
- __ vdup(kWord, result, dvalue1, 1);
- break;
case MethodRecognizer::kFloat32x4ShuffleX:
__ vdup(kWord, result, dvalue0, 0);
__ vcvtds(dresult0, sresult0);
@@ -2993,6 +2981,20 @@
__ vdup(kWord, result, dvalue1, 1);
__ vcvtds(dresult0, sresult0);
break;
+ case MethodRecognizer::kFloat32x4Shuffle:
+ if (mask_ == 0x00) {
+ __ vdup(kWord, result, dvalue0, 0);
+ } else if (mask_ == 0x55) {
+ __ vdup(kWord, result, dvalue0, 1);
+ } else if (mask_ == 0xAA) {
+ __ vdup(kWord, result, dvalue1, 0);
+ } else if (mask_ == 0xFF) {
+ __ vdup(kWord, result, dvalue1, 1);
+ } else {
+ // TODO(zra): Implement other shuffles.
+ UNIMPLEMENTED();
+ }
+ break;
default: UNREACHABLE();
}
}
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 0f4e24b..00a833e 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -3006,18 +3006,6 @@
ASSERT(locs()->out().fpu_reg() == value);
switch (op_kind()) {
- case MethodRecognizer::kFloat32x4ShuffleXXXX:
- __ shufps(value, value, Immediate(0x00));
- break;
- case MethodRecognizer::kFloat32x4ShuffleYYYY:
- __ shufps(value, value, Immediate(0x55));
- break;
- case MethodRecognizer::kFloat32x4ShuffleZZZZ:
- __ shufps(value, value, Immediate(0xAA));
- break;
- case MethodRecognizer::kFloat32x4ShuffleWWWW:
- __ shufps(value, value, Immediate(0xFF));
- break;
case MethodRecognizer::kFloat32x4ShuffleX:
__ shufps(value, value, Immediate(0x00));
__ cvtss2sd(value, value);
@@ -3034,7 +3022,9 @@
__ shufps(value, value, Immediate(0xFF));
__ cvtss2sd(value, value);
break;
-
+ case MethodRecognizer::kFloat32x4Shuffle:
+ __ shufps(value, value, Immediate(mask_));
+ break;
default: UNREACHABLE();
}
}
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index a320b95..d0b0245 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -3047,18 +3047,6 @@
ASSERT(locs()->out().fpu_reg() == value);
switch (op_kind()) {
- case MethodRecognizer::kFloat32x4ShuffleXXXX:
- __ shufps(value, value, Immediate(0x00));
- break;
- case MethodRecognizer::kFloat32x4ShuffleYYYY:
- __ shufps(value, value, Immediate(0x55));
- break;
- case MethodRecognizer::kFloat32x4ShuffleZZZZ:
- __ shufps(value, value, Immediate(0xAA));
- break;
- case MethodRecognizer::kFloat32x4ShuffleWWWW:
- __ shufps(value, value, Immediate(0xFF));
- break;
case MethodRecognizer::kFloat32x4ShuffleX:
__ shufps(value, value, Immediate(0x00));
__ cvtss2sd(value, value);
@@ -3075,6 +3063,9 @@
__ shufps(value, value, Immediate(0xFF));
__ cvtss2sd(value, value);
break;
+ case MethodRecognizer::kFloat32x4Shuffle:
+ __ shufps(value, value, Immediate(mask_));
+ break;
default: UNREACHABLE();
}
}
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index a16190e..bc4c338 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -8779,12 +8779,14 @@
const char* ICData::ToCString() const {
- const char* kFormat = "ICData target:'%s' num-checks: %"Pd"";
+ const char* kFormat = "ICData target:'%s' num-args: %"Pd" num-checks: %"Pd"";
const String& name = String::Handle(target_name());
- const intptr_t num = NumberOfChecks();
- intptr_t len = OS::SNPrint(NULL, 0, kFormat, name.ToCString(), num) + 1;
+ const intptr_t num_args = num_args_tested();
+ const intptr_t num_checks = NumberOfChecks();
+ intptr_t len = OS::SNPrint(NULL, 0, kFormat, name.ToCString(),
+ num_args, num_checks) + 1;
char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
- OS::SNPrint(chars, len, kFormat, name.ToCString(), num);
+ OS::SNPrint(chars, len, kFormat, name.ToCString(), num_args, num_checks);
return chars;
}
@@ -8876,7 +8878,16 @@
// Used for unoptimized static calls when no class-ids are checked.
void ICData::AddTarget(const Function& target) const {
- ASSERT(num_args_tested() == 0);
+ if (num_args_tested() > 0) {
+ // Create a fake cid entry, so that we can store the target.
+ GrowableArray<intptr_t> class_ids(num_args_tested());
+ for (intptr_t i = 0; i < num_args_tested(); i++) {
+ class_ids.Add(kObjectCid);
+ }
+ AddCheck(class_ids, target);
+ return;
+ }
+ ASSERT(num_args_tested() >= 0);
// Can add only once.
const intptr_t old_num = NumberOfChecks();
ASSERT(old_num == 0);
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 60c57bc..5538c8d 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -2798,7 +2798,14 @@
*(qual_ident->ident),
NULL)) {
LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle();
- lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident));
+ if (current_class().mixin() == Type::null()) {
+ lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident));
+ } else {
+ // TODO(hausner): Should we resolve the prefix via the library scope
+ // rather than via the class?
+ Class& cls = Class::Handle(parsed_function()->function().origin());
+ lib_prefix = cls.LookupLibraryPrefix(*(qual_ident->ident));
+ }
if (!lib_prefix.IsNull()) {
// We have a library prefix qualified identifier, unless the prefix is
// shadowed by a type parameter in scope.
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index 185ca37..9d7a08e 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -62,7 +62,8 @@
V(ThreeArgsOptimizedCheckInlineCache) \
V(ClosureCallInlineCache) \
V(MegamorphicCall) \
- V(UnoptimizedStaticCall) \
+ V(ZeroArgsUnoptimizedStaticCall) \
+ V(TwoArgsUnoptimizedStaticCall) \
V(OptimizeFunction) \
V(BreakpointDynamic) \
V(EqualityWithNullArg) \
@@ -193,8 +194,10 @@
const Class& cls);
static void GenerateAllocationStubForClosure(Assembler* assembler,
const Function& func);
- static void GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
- intptr_t num_args);
+ static void GenerateNArgsCheckInlineCacheStub(
+ Assembler* assembler,
+ intptr_t num_args,
+ const RuntimeEntry& handle_ic_miss);
static void GenerateUsageCounterIncrement(Assembler* assembler,
Register temp_reg);
static void GenerateOptimizedUsageCounterIncrement(Assembler* assembler);
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index c7c1787..db932ba 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1362,8 +1362,10 @@
// - Check if 'num_args' (including receiver) match any IC data group.
// - Match found -> jump to target.
// - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
- intptr_t num_args) {
+void StubCode::GenerateNArgsCheckInlineCacheStub(
+ Assembler* assembler,
+ intptr_t num_args,
+ const RuntimeEntry& handle_ic_miss) {
ASSERT(num_args > 0);
#if defined(DEBUG)
{ Label ok;
@@ -1470,16 +1472,7 @@
}
// Pass IC data object.
__ Push(R5);
-
- if (num_args == 1) {
- __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
- } else if (num_args == 2) {
- __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry);
- } else if (num_args == 3) {
- __ CallRuntime(kInlineCacheMissHandlerThreeArgsRuntimeEntry);
- } else {
- UNIMPLEMENTED();
- }
+ __ CallRuntime(handle_ic_miss);
// Remove the call arguments pushed earlier, including the IC data object.
__ Drop(num_args + 1);
// Pop returned code object into R0 (null if not found).
@@ -1540,57 +1533,65 @@
// - 1 target function.
void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, R6);
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, R6);
- GenerateNArgsCheckInlineCacheStub(assembler, 2);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
}
void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, R6);
- GenerateNArgsCheckInlineCacheStub(assembler, 3);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
}
void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 2);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
}
void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 3);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
}
void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
// Intermediary stub between a static call and its target. ICData contains
// the target function and the call count.
// R5: ICData
-void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, R6);
#if defined(DEBUG)
{ Label ok;
@@ -1664,6 +1665,13 @@
}
+void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
+ GenerateUsageCounterIncrement(assembler, R6);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
+}
+
+
void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
__ Unimplemented("BreakpointRuntime stub");
}
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index ef24ad8..926816e 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1417,8 +1417,10 @@
// - Check if 'num_args' (including receiver) match any IC data group.
// - Match found -> jump to target.
// - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
- intptr_t num_args) {
+void StubCode::GenerateNArgsCheckInlineCacheStub(
+ Assembler* assembler,
+ intptr_t num_args,
+ const RuntimeEntry& handle_ic_miss) {
ASSERT(num_args > 0);
#if defined(DEBUG)
{ Label ok;
@@ -1446,6 +1448,7 @@
__ LeaveFrame();
__ Bind(¬_stepping);
+ // ECX: IC data object (preserved).
// Load arguments descriptor into EDX.
__ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
// Loop that checks if there is an IC data match.
@@ -1519,15 +1522,7 @@
__ pushl(EBX);
}
__ pushl(ECX); // Pass IC data object.
- if (num_args == 1) {
- __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
- } else if (num_args == 2) {
- __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry);
- } else if (num_args == 3) {
- __ CallRuntime(kInlineCacheMissHandlerThreeArgsRuntimeEntry);
- } else {
- UNIMPLEMENTED();
- }
+ __ CallRuntime(handle_ic_miss);
// Remove the call arguments pushed earlier, including the IC data object.
for (intptr_t i = 0; i < num_args + 1; i++) {
__ popl(EAX);
@@ -1590,19 +1585,22 @@
// - 1 target function.
void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, EBX);
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, EBX);
- GenerateNArgsCheckInlineCacheStub(assembler, 2);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
}
void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, EBX);
- GenerateNArgsCheckInlineCacheStub(assembler, 3);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
}
@@ -1620,44 +1618,50 @@
void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 2);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
}
void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 3);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
}
// Do not count as no type feedback is collected.
void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
// Megamorphic call is currently implemented as IC call but through a stub
// that does not check/count function invocations.
void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
// Intermediary stub between a static call and its target. ICData contains
// the target function and the call count.
// ECX: ICData
-void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, EBX);
+
#if defined(DEBUG)
{ Label ok;
- // Check that the IC data array has NumberOfArgumentsChecked() == 0.
+ // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
// 'num_args_tested' is stored as an untagged int.
__ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
__ cmpl(EBX, Immediate(0));
@@ -1666,7 +1670,6 @@
__ Bind(&ok);
}
#endif // DEBUG
-
// Check single stepping.
Label not_stepping;
__ movl(EAX, FieldAddress(CTX, Context::isolate_offset()));
@@ -1725,6 +1728,13 @@
}
+void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
+ GenerateUsageCounterIncrement(assembler, EBX);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
+}
+
+
// EDX, EXC: May contain arguments to runtime stub.
void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
__ EnterStubFrame();
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 0881c59..5644aa4 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -1542,8 +1542,10 @@
// - Check if 'num_args' (including receiver) match any IC data group.
// - Match found -> jump to target.
// - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
- intptr_t num_args) {
+void StubCode::GenerateNArgsCheckInlineCacheStub(
+ Assembler* assembler,
+ intptr_t num_args,
+ const RuntimeEntry& handle_ic_miss) {
__ TraceSimMsg("NArgsCheckInlineCacheStub");
ASSERT(num_args > 0);
#if defined(DEBUG)
@@ -1668,16 +1670,7 @@
}
// Pass IC data object.
__ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize));
-
- if (num_args == 1) {
- __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
- } else if (num_args == 2) {
- __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry);
- } else if (num_args == 3) {
- __ CallRuntime(kInlineCacheMissHandlerThreeArgsRuntimeEntry);
- } else {
- UNIMPLEMENTED();
- }
+ __ CallRuntime(handle_ic_miss);
__ TraceSimMsg("NArgsCheckInlineCacheStub return");
// Pop returned code object into T3 (null if not found).
// Restore arguments descriptor array and IC data array.
@@ -1749,57 +1742,65 @@
// - 1 target function.
void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, T0);
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, T0);
- GenerateNArgsCheckInlineCacheStub(assembler, 2);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
}
void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, T0);
- GenerateNArgsCheckInlineCacheStub(assembler, 3);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
}
void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 2);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
}
void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 3);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
}
void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
// Intermediary stub between a static call and its target. ICData contains
// the target function and the call count.
// S5: ICData
-void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, T0);
__ TraceSimMsg("UnoptimizedStaticCallStub");
#if defined(DEBUG)
@@ -1882,6 +1883,13 @@
}
+void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
+ GenerateUsageCounterIncrement(assembler, T0);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
+}
+
+
void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
__ Unimplemented("BreakpointRuntime stub");
}
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index e222c70..e74e83f 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1401,8 +1401,10 @@
// - Check if 'num_args' (including receiver) match any IC data group.
// - Match found -> jump to target.
// - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
- intptr_t num_args) {
+void StubCode::GenerateNArgsCheckInlineCacheStub(
+ Assembler* assembler,
+ intptr_t num_args,
+ const RuntimeEntry& handle_ic_miss) {
ASSERT(num_args > 0);
#if defined(DEBUG)
{ Label ok;
@@ -1500,15 +1502,7 @@
__ pushq(RCX);
}
__ pushq(RBX); // Pass IC data object.
- if (num_args == 1) {
- __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
- } else if (num_args == 2) {
- __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry);
- } else if (num_args == 3) {
- __ CallRuntime(kInlineCacheMissHandlerThreeArgsRuntimeEntry);
- } else {
- UNIMPLEMENTED();
- }
+ __ CallRuntime(handle_ic_miss);
// Remove the call arguments pushed earlier, including the IC data object.
for (intptr_t i = 0; i < num_args + 1; i++) {
__ popq(RAX);
@@ -1570,19 +1564,22 @@
// - 1 target function.
void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, RCX);
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, RCX);
- GenerateNArgsCheckInlineCacheStub(assembler, 2);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
}
void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, RCX);
- GenerateNArgsCheckInlineCacheStub(assembler, 3);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
}
// Use inline cache data array to invoke the target or continue in inline
@@ -1599,41 +1596,46 @@
void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 2);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
}
void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
Assembler* assembler) {
GenerateOptimizedUsageCounterIncrement(assembler);
- GenerateNArgsCheckInlineCacheStub(assembler, 3);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
}
// Do not count as no type feedback is collected.
void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
// Megamorphic call is currently implemented as IC call but through a stub
// that does not check/count function invocations.
void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
- GenerateNArgsCheckInlineCacheStub(assembler, 1);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
}
// Intermediary stub between a static call and its target. ICData contains
// the target function and the call count.
// RBX: ICData
-void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
GenerateUsageCounterIncrement(assembler, RCX);
#if defined(DEBUG)
{ Label ok;
@@ -1706,6 +1708,13 @@
}
+void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
+ GenerateUsageCounterIncrement(assembler, RCX);
+ GenerateNArgsCheckInlineCacheStub(
+ assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
+}
+
+
// RBX, R10: May contain arguments to runtime stub.
// TOS(0): return address (Dart code).
void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
diff --git a/sdk/lib/_internal/pub/lib/src/source/hosted.dart b/sdk/lib/_internal/pub/lib/src/source/hosted.dart
index aec150c..a4b7160 100644
--- a/sdk/lib/_internal/pub/lib/src/source/hosted.dart
+++ b/sdk/lib/_internal/pub/lib/src/source/hosted.dart
@@ -167,7 +167,7 @@
if (error is io.SocketException) {
fail('Got socket error trying to find package "$package" at $url.\n'
- '${error.osError}');
+ '$error');
}
// Otherwise re-throw the original exception.
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 2870931..13696d9 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -3519,12 +3519,17 @@
}
/** Gets the value of "box-sizing" */
- String get boxSizing =>
- getPropertyValue('box-sizing');
+ String get boxSizing => Device.isFirefox ?
+ getPropertyValue('${Device.cssPrefix}box-sizing') :
+ getPropertyValue('box-sizing');
/** Sets the value of "box-sizing" */
void set boxSizing(String value) {
- setProperty('box-sizing', value, '');
+ if (Device.isFirefox) {
+ setProperty('${Device.cssPrefix}box-sizing', value, '');
+ } else {
+ setProperty('box-sizing', value, '');
+ }
}
/** Gets the value of "caption-side" */
@@ -7919,7 +7924,8 @@
/**
* An immutable list containing HTML elements. This list contains some
- * additional methods for ease of CSS manipulation on a group of elements.
+ * additional methods when compared to regular lists for ease of CSS
+ * manipulation on a group of elements.
*/
abstract class ElementList<T extends Element> extends ListBase<T> {
/**
@@ -7936,6 +7942,63 @@
/** Replace the classes with `value` for every element in this list. */
set classes(Iterable<String> value);
+
+ /**
+ * Access dimensions and position of the Elements in this list.
+ *
+ * Setting the height or width properties will set the height or width
+ * property for all elements in the list. This returns a rectangle with the
+ * dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Getting the height or width returns the height or width of the
+ * first Element in this list.
+ *
+ * Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not.
+ */
+ @Experimental()
+ CssRect get contentEdge;
+
+ /**
+ * Access dimensions and position of the first Element's content + padding box
+ * in this list.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's `innerHeight` value for an element. This
+ * is also a rectangle equalling the dimensions of clientHeight and
+ * clientWidth.
+ */
+ @Experimental()
+ CssRect get paddingEdge;
+
+ /**
+ * Access dimensions and position of the first Element's content + padding +
+ * border box in this list.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's `outerHeight` value for an element.
+ */
+ @Experimental()
+ CssRect get borderEdge;
+
+ /**
+ * Access dimensions and position of the first Element's content + padding +
+ * border + margin box in this list.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's `outerHeight` value for an element.
+ */
+ @Experimental()
+ CssRect get marginEdge;
}
// TODO(jacobr): this is an inefficient implementation but it is hard to see
@@ -7944,8 +8007,12 @@
// contains Node objects that are not Elements.
class _FrozenElementList<T extends Element> extends ListBase<T> implements ElementList {
final List<Node> _nodeList;
+ // The subset of _nodeList that are Elements.
+ List<Element> _elementList;
- _FrozenElementList._wrap(this._nodeList);
+ _FrozenElementList._wrap(this._nodeList) {
+ _elementList = _nodeList.where((e) => e is Element).toList();
+ }
int get length => _nodeList.length;
@@ -7969,12 +8036,19 @@
Element get single => _nodeList.single;
- CssClassSet get classes => new _MultiElementCssClassSet(
- _nodeList.where((e) => e is Element));
+ CssClassSet get classes => new _MultiElementCssClassSet(_elementList);
void set classes(Iterable<String> value) {
- _nodeList.where((e) => e is Element).forEach((e) => e.classes = value);
+ _elementList.forEach((e) => e.classes = value);
}
+
+ CssRect get contentEdge => new _ContentCssListRect(_elementList);
+
+ CssRect get paddingEdge => _elementList.first.paddingEdge;
+
+ CssRect get borderEdge => _elementList.first.borderEdge;
+
+ CssRect get marginEdge => _elementList.first.marginEdge;
}
/**
@@ -8676,6 +8750,79 @@
TemplateElement.decorate(this);
}
+ /**
+ * Access this element's content position.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not.
+ *
+ * _Important_ _note_: use of this method _will_ perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get contentEdge => new _ContentCssRect(this);
+
+ /**
+ * Access the dimensions and position of this element's content + padding box.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's
+ * [innerHeight](http://api.jquery.com/innerHeight/) value for an element.
+ * This is also a rectangle equalling the dimensions of clientHeight and
+ * clientWidth.
+ *
+ * _Important_ _note_: use of this method _will_ perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get paddingEdge => new _PaddingCssRect(this);
+
+ /**
+ * Access the dimensions and position of this element's content + padding +
+ * border box.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's
+ * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+ *
+ * _Important_ _note_: use of this method _will_ perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get borderEdge => new _BorderCssRect(this);
+
+ /**
+ * Access the dimensions and position of this element's content + padding +
+ * border + margin box.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's
+ * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+ *
+ * _Important_ _note_: use of this method will perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get marginEdge => new _MarginCssRect(this);
// To suppress missing implicit constructor warnings.
factory Element._() { throw new UnsupportedError("Not supported"); }
@@ -12186,7 +12333,7 @@
* The data received as a reponse from the request.
*
* The data could be in the
- * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a
+ * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
* [String]). `null` indicates request failure.
*/
@DomName('XMLHttpRequest.response')
@@ -26703,6 +26850,348 @@
_element.className = s.join(' ');
}
}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+/**
+ * A rectangle representing all the content of the element in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssRect extends CssRect {
+
+ _ContentCssRect(element) : super(element);
+
+ num get height => _element.offsetHeight +
+ _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);
+
+ num get width => _element.offsetWidth +
+ _addOrSubtractToBoxModel(_WIDTH, _CONTENT);
+
+ /**
+ * Set the height to `newHeight`.
+ *
+ * newHeight can be either a [num] representing the height in pixels or a
+ * [Dimension] object. Values of newHeight that are less than zero are
+ * converted to effectively setting the height to 0. This is equivalent to the
+ * `height` function in jQuery and the calculated `height` CSS value,
+ * converted to a num in pixels.
+ */
+ void set height(newHeight) {
+ if (newHeight is Dimension) {
+ if (newHeight.value < 0) newHeight = new Dimension.px(0);
+ _element.style.height = newHeight.toString();
+ } else {
+ if (newHeight < 0) newHeight = 0;
+ _element.style.height = '${newHeight}px';
+ }
+ }
+
+ /**
+ * Set the current computed width in pixels of this element.
+ *
+ * newWidth can be either a [num] representing the width in pixels or a
+ * [Dimension] object. This is equivalent to the `width` function in jQuery
+ * and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels.
+ */
+ void set width(newWidth) {
+ if (newWidth is Dimension) {
+ if (newWidth.value < 0) newWidth = new Dimension.px(0);
+ _element.style.width = newWidth.toString();
+ } else {
+ if (newWidth < 0) newWidth = 0;
+ _element.style.width = '${newWidth}px';
+ }
+ }
+
+ num get left => _element.getBoundingClientRect().left -
+ _addOrSubtractToBoxModel(['left'], _CONTENT);
+ num get top => _element.getBoundingClientRect().top -
+ _addOrSubtractToBoxModel(['top'], _CONTENT);
+}
+
+/**
+ * A list of element content rectangles in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssListRect extends _ContentCssRect {
+ List<Element> _elementList;
+
+ _ContentCssListRect(elementList) : super(elementList.first) {
+ _elementList = elementList;
+ }
+
+ /**
+ * Set the height to `newHeight`.
+ *
+ * Values of newHeight that are less than zero are converted to effectively
+ * setting the height to 0. This is equivalent to the `height`
+ * function in jQuery and the calculated `height` CSS value, converted to a
+ * num in pixels.
+ */
+ void set height(newHeight) {
+ _elementList.forEach((e) => e.contentEdge.height = newHeight);
+ }
+
+ /**
+ * Set the current computed width in pixels of this element.
+ *
+ * This is equivalent to the `width` function in jQuery and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels.
+ */
+ void set width(newWidth) {
+ _elementList.forEach((e) => e.contentEdge.width = newWidth);
+ }
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _PaddingCssRect extends CssRect {
+ _PaddingCssRect(element) : super(element);
+ num get height => _element.offsetHeight +
+ _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
+ num get width => _element.offsetWidth +
+ _addOrSubtractToBoxModel(_WIDTH, _PADDING);
+
+ num get left => _element.getBoundingClientRect().left -
+ _addOrSubtractToBoxModel(['left'], _PADDING);
+ num get top => _element.getBoundingClientRect().top -
+ _addOrSubtractToBoxModel(['top'], _PADDING);
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _BorderCssRect extends CssRect {
+ _BorderCssRect(element) : super(element);
+ num get height => _element.offsetHeight;
+ num get width => _element.offsetWidth;
+
+ num get left => _element.getBoundingClientRect().left;
+ num get top => _element.getBoundingClientRect().top;
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border + margin in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _MarginCssRect extends CssRect {
+ _MarginCssRect(element) : super(element);
+ num get height => _element.offsetHeight +
+ _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
+ num get width =>
+ _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);
+
+ num get left => _element.getBoundingClientRect().left -
+ _addOrSubtractToBoxModel(['left'], _MARGIN);
+ num get top => _element.getBoundingClientRect().top -
+ _addOrSubtractToBoxModel(['top'], _MARGIN);
+}
+
+/**
+ * A class for representing CSS dimensions.
+ *
+ * In contrast to the more general purpose [Rect] class, this class's values are
+ * mutable, so one can change the height of an element programmatically.
+ *
+ * _Important_ _note_: use of these methods will perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of these properties _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+abstract class CssRect extends RectBase implements Rect {
+ Element _element;
+
+ CssRect(this._element);
+
+ num get left;
+
+ num get top;
+
+ /**
+ * The height of this rectangle.
+ *
+ * This is equivalent to the `height` function in jQuery and the calculated
+ * `height` CSS value, converted to a dimensionless num in pixels. Unlike
+ * [getBoundingClientRect], `height` will return the same numerical width if
+ * the element is hidden or not.
+ */
+ num get height;
+
+ /**
+ * The width of this rectangle.
+ *
+ * This is equivalent to the `width` function in jQuery and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels. Unlike
+ * [getBoundingClientRect], `width` will return the same numerical width if
+ * the element is hidden or not.
+ */
+ num get width;
+
+ /**
+ * Set the height to `newHeight`.
+ *
+ * newHeight can be either a [num] representing the height in pixels or a
+ * [Dimension] object. Values of newHeight that are less than zero are
+ * converted to effectively setting the height to 0. This is equivalent to the
+ * `height` function in jQuery and the calculated `height` CSS value,
+ * converted to a num in pixels.
+ *
+ * Note that only the content height can actually be set via this method.
+ */
+ void set height(newHeight) {
+ throw new UnsupportedError("Can only set height for content rect.");
+ }
+
+ /**
+ * Set the current computed width in pixels of this element.
+ *
+ * newWidth can be either a [num] representing the width in pixels or a
+ * [Dimension] object. This is equivalent to the `width` function in jQuery
+ * and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels.
+ *
+ * Note that only the content width can be set via this method.
+ */
+ void set width(newWidth) {
+ throw new UnsupportedError("Can only set width for content rect.");
+ }
+
+ /**
+ * Return a value that is used to modify the initial height or width
+ * measurement of an element. Depending on the value (ideally an enum) passed
+ * to augmentingMeasurement, we may need to add or subtract margin, padding,
+ * or border values, depending on the measurement we're trying to obtain.
+ */
+ num _addOrSubtractToBoxModel(List<String> dimensions,
+ String augmentingMeasurement) {
+ // getComputedStyle always returns pixel values (hence, computed), so we're
+ // always dealing with pixels in this method.
+ var styles = _element.getComputedStyle();
+
+ var val = 0;
+
+ for (String measurement in dimensions) {
+ // The border-box and default box model both exclude margin in the regular
+ // height/width calculation, so add it if we want it for this measurement.
+ if (augmentingMeasurement == _MARGIN) {
+ val += new Dimension.css(styles.getPropertyValue(
+ '$augmentingMeasurement-$measurement')).value;
+ }
+
+ // The border-box includes padding and border, so remove it if we want
+ // just the content itself.
+ if (augmentingMeasurement == _CONTENT) {
+ val -= new Dimension.css(
+ styles.getPropertyValue('${_PADDING}-$measurement')).value;
+ }
+
+ // At this point, we don't wan't to augment with border or margin,
+ // so remove border.
+ if (augmentingMeasurement != _MARGIN) {
+ val -= new Dimension.css(styles.getPropertyValue(
+ 'border-${measurement}-width')).value;
+ }
+ }
+ return val;
+ }
+}
+
+final _HEIGHT = ['top', 'bottom'];
+final _WIDTH = ['right', 'left'];
+final _CONTENT = 'content';
+final _PADDING = 'padding';
+final _MARGIN = 'margin';
+
+/**
+ * Class representing a
+ * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
+ * in CSS.
+ */
+@Experimental()
+class Dimension {
+ num _value;
+ String _unit;
+
+ /** Set this CSS Dimension to a percentage `value`. */
+ Dimension.percent(this._value) : _unit = '%';
+
+ /** Set this CSS Dimension to a pixel `value`. */
+ Dimension.px(this._value) : _unit = 'px';
+
+ /** Set this CSS Dimension to a pica `value`. */
+ Dimension.pc(this._value) : _unit = 'pc';
+
+ /** Set this CSS Dimension to a point `value`. */
+ Dimension.pt(this._value) : _unit = 'pt';
+
+ /** Set this CSS Dimension to an inch `value`. */
+ Dimension.inch(this._value) : _unit = 'in';
+
+ /** Set this CSS Dimension to a centimeter `value`. */
+ Dimension.cm(this._value) : _unit = 'cm';
+
+ /** Set this CSS Dimension to a millimeter `value`. */
+ Dimension.mm(this._value) : _unit = 'mm';
+
+ /**
+ * Set this CSS Dimension to the specified number of ems.
+ *
+ * 1em is equal to the current font size. (So 2ems is equal to double the font
+ * size). This is useful for producing website layouts that scale nicely with
+ * the user's desired font size.
+ */
+ Dimension.em(this._value) : _unit = 'em';
+
+ /**
+ * Set this CSS Dimension to the specified number of x-heights.
+ *
+ * One ex is equal to the the x-height of a font's baseline to its mean line,
+ * generally the height of the letter "x" in the font, which is usually about
+ * half the font-size.
+ */
+ Dimension.ex(this._value) : _unit = 'ex';
+
+ /**
+ * Construct a Dimension object from the valid, simple CSS string `cssValue`
+ * that represents a distance measurement.
+ *
+ * This constructor is intended as a convenience method for working with
+ * simplistic CSS length measurements. Non-numeric values such as `auto` or
+ * `inherit` or invalid CSS will cause this constructor to throw a
+ * FormatError.
+ */
+ Dimension.css(String cssValue) {
+ if (cssValue == '') cssValue = '0px';
+ if (cssValue.endsWith('%')) {
+ _unit = '%';
+ } else {
+ _unit = cssValue.substring(cssValue.length - 2);
+ }
+ if (cssValue.contains('.')) {
+ _value = double.parse(cssValue.substring(0,
+ cssValue.length - _unit.length));
+ } else {
+ _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
+ }
+ }
+
+ /** Print out the CSS String representation of this value. */
+ String toString() {
+ return '${_value}${_unit}';
+ }
+
+ /** Return a unitless, numerical value of this CSS value. */
+ num get value => this._value;
+}
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -28220,44 +28709,24 @@
/**
- * A class for representing two-dimensional rectangles.
+ * A base class for representing two-dimensional rectangles. This will hopefully
+ * be moved merged with the dart:math Rect.
*/
-class Rect {
- final num left;
- final num top;
- final num width;
- final num height;
+// TODO(efortuna): Merge with Math rect after finalizing with Florian.
+abstract class RectBase {
+ // Not used, but keeps the VM from complaining about Rect having a const
+ // constructor and this one not.
+ const RectBase();
- const Rect(this.left, this.top, this.width, this.height);
-
- factory Rect.fromPoints(Point a, Point b) {
- var left;
- var width;
- if (a.x < b.x) {
- left = a.x;
- width = b.x - left;
- } else {
- left = b.x;
- width = a.x - left;
- }
- var top;
- var height;
- if (a.y < b.y) {
- top = a.y;
- height = b.y - top;
- } else {
- top = b.y;
- height = a.y - top;
- }
-
- return new Rect(left, top, width, height);
- }
+ num get left;
+ num get top;
+ num get width;
+ num get height;
num get right => left + width;
num get bottom => top + height;
// NOTE! All code below should be common with Rect.
- // TODO: implement with mixins when available.
String toString() {
return '($left, $top, $width, $height)';
@@ -28351,6 +28820,46 @@
Point get bottomRight => new Point(this.left + this.width,
this.top + this.height);
}
+
+
+
+/**
+ * A class for representing two-dimensional rectangles.
+ *
+ * This class is distinctive from RectBase in that it enforces that its
+ * properties are immutable.
+ */
+class Rect extends RectBase {
+ final num left;
+ final num top;
+ final num width;
+ final num height;
+
+ const Rect(this.left, this.top, this.width, this.height): super();
+
+ factory Rect.fromPoints(Point a, Point b) {
+ var left;
+ var width;
+ if (a.x < b.x) {
+ left = a.x;
+ width = b.x - left;
+ } else {
+ left = b.x;
+ width = a.x - left;
+ }
+ var top;
+ var height;
+ if (a.y < b.y) {
+ top = a.y;
+ height = b.y - top;
+ } else {
+ top = b.y;
+ height = a.y - top;
+ }
+
+ return new Rect(left, top, width, height);
+ }
+}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 4a510d0..04268cd 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -3995,12 +3995,17 @@
}
/** Gets the value of "box-sizing" */
- String get boxSizing =>
- getPropertyValue('box-sizing');
+ String get boxSizing => Device.isFirefox ?
+ getPropertyValue('${Device.cssPrefix}box-sizing') :
+ getPropertyValue('box-sizing');
/** Sets the value of "box-sizing" */
void set boxSizing(String value) {
- setProperty('box-sizing', value, '');
+ if (Device.isFirefox) {
+ setProperty('${Device.cssPrefix}box-sizing', value, '');
+ } else {
+ setProperty('box-sizing', value, '');
+ }
}
/** Gets the value of "caption-side" */
@@ -8382,7 +8387,8 @@
/**
* An immutable list containing HTML elements. This list contains some
- * additional methods for ease of CSS manipulation on a group of elements.
+ * additional methods when compared to regular lists for ease of CSS
+ * manipulation on a group of elements.
*/
abstract class ElementList<T extends Element> extends ListBase<T> {
/**
@@ -8399,6 +8405,63 @@
/** Replace the classes with `value` for every element in this list. */
set classes(Iterable<String> value);
+
+ /**
+ * Access dimensions and position of the Elements in this list.
+ *
+ * Setting the height or width properties will set the height or width
+ * property for all elements in the list. This returns a rectangle with the
+ * dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Getting the height or width returns the height or width of the
+ * first Element in this list.
+ *
+ * Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not.
+ */
+ @Experimental()
+ CssRect get contentEdge;
+
+ /**
+ * Access dimensions and position of the first Element's content + padding box
+ * in this list.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's `innerHeight` value for an element. This
+ * is also a rectangle equalling the dimensions of clientHeight and
+ * clientWidth.
+ */
+ @Experimental()
+ CssRect get paddingEdge;
+
+ /**
+ * Access dimensions and position of the first Element's content + padding +
+ * border box in this list.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's `outerHeight` value for an element.
+ */
+ @Experimental()
+ CssRect get borderEdge;
+
+ /**
+ * Access dimensions and position of the first Element's content + padding +
+ * border + margin box in this list.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's `outerHeight` value for an element.
+ */
+ @Experimental()
+ CssRect get marginEdge;
}
// TODO(jacobr): this is an inefficient implementation but it is hard to see
@@ -8407,8 +8470,12 @@
// contains Node objects that are not Elements.
class _FrozenElementList<T extends Element> extends ListBase<T> implements ElementList {
final List<Node> _nodeList;
+ // The subset of _nodeList that are Elements.
+ List<Element> _elementList;
- _FrozenElementList._wrap(this._nodeList);
+ _FrozenElementList._wrap(this._nodeList) {
+ _elementList = _nodeList.where((e) => e is Element).toList();
+ }
int get length => _nodeList.length;
@@ -8432,12 +8499,19 @@
Element get single => _nodeList.single;
- CssClassSet get classes => new _MultiElementCssClassSet(
- _nodeList.where((e) => e is Element));
+ CssClassSet get classes => new _MultiElementCssClassSet(_elementList);
void set classes(Iterable<String> value) {
- _nodeList.where((e) => e is Element).forEach((e) => e.classes = value);
+ _elementList.forEach((e) => e.classes = value);
}
+
+ CssRect get contentEdge => new _ContentCssListRect(_elementList);
+
+ CssRect get paddingEdge => _elementList.first.paddingEdge;
+
+ CssRect get borderEdge => _elementList.first.borderEdge;
+
+ CssRect get marginEdge => _elementList.first.marginEdge;
}
/**
@@ -8990,6 +9064,79 @@
TemplateElement.decorate(this);
}
+ /**
+ * Access this element's content position.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not.
+ *
+ * _Important_ _note_: use of this method _will_ perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get contentEdge => new _ContentCssRect(this);
+
+ /**
+ * Access the dimensions and position of this element's content + padding box.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's
+ * [innerHeight](http://api.jquery.com/innerHeight/) value for an element.
+ * This is also a rectangle equalling the dimensions of clientHeight and
+ * clientWidth.
+ *
+ * _Important_ _note_: use of this method _will_ perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get paddingEdge => new _PaddingCssRect(this);
+
+ /**
+ * Access the dimensions and position of this element's content + padding +
+ * border box.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's
+ * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+ *
+ * _Important_ _note_: use of this method _will_ perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get borderEdge => new _BorderCssRect(this);
+
+ /**
+ * Access the dimensions and position of this element's content + padding +
+ * border + margin box.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's
+ * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+ *
+ * _Important_ _note_: use of this method will perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get marginEdge => new _MarginCssRect(this);
// To suppress missing implicit constructor warnings.
factory Element._() { throw new UnsupportedError("Not supported"); }
@@ -12590,7 +12737,7 @@
* The data received as a reponse from the request.
*
* The data could be in the
- * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a
+ * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
* [String]). `null` indicates request failure.
*/
@DomName('XMLHttpRequest.response')
@@ -28313,6 +28460,348 @@
_element.className = s.join(' ');
}
}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+/**
+ * A rectangle representing all the content of the element in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssRect extends CssRect {
+
+ _ContentCssRect(element) : super(element);
+
+ num get height => _element.offsetHeight +
+ _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);
+
+ num get width => _element.offsetWidth +
+ _addOrSubtractToBoxModel(_WIDTH, _CONTENT);
+
+ /**
+ * Set the height to `newHeight`.
+ *
+ * newHeight can be either a [num] representing the height in pixels or a
+ * [Dimension] object. Values of newHeight that are less than zero are
+ * converted to effectively setting the height to 0. This is equivalent to the
+ * `height` function in jQuery and the calculated `height` CSS value,
+ * converted to a num in pixels.
+ */
+ void set height(newHeight) {
+ if (newHeight is Dimension) {
+ if (newHeight.value < 0) newHeight = new Dimension.px(0);
+ _element.style.height = newHeight.toString();
+ } else {
+ if (newHeight < 0) newHeight = 0;
+ _element.style.height = '${newHeight}px';
+ }
+ }
+
+ /**
+ * Set the current computed width in pixels of this element.
+ *
+ * newWidth can be either a [num] representing the width in pixels or a
+ * [Dimension] object. This is equivalent to the `width` function in jQuery
+ * and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels.
+ */
+ void set width(newWidth) {
+ if (newWidth is Dimension) {
+ if (newWidth.value < 0) newWidth = new Dimension.px(0);
+ _element.style.width = newWidth.toString();
+ } else {
+ if (newWidth < 0) newWidth = 0;
+ _element.style.width = '${newWidth}px';
+ }
+ }
+
+ num get left => _element.getBoundingClientRect().left -
+ _addOrSubtractToBoxModel(['left'], _CONTENT);
+ num get top => _element.getBoundingClientRect().top -
+ _addOrSubtractToBoxModel(['top'], _CONTENT);
+}
+
+/**
+ * A list of element content rectangles in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssListRect extends _ContentCssRect {
+ List<Element> _elementList;
+
+ _ContentCssListRect(elementList) : super(elementList.first) {
+ _elementList = elementList;
+ }
+
+ /**
+ * Set the height to `newHeight`.
+ *
+ * Values of newHeight that are less than zero are converted to effectively
+ * setting the height to 0. This is equivalent to the `height`
+ * function in jQuery and the calculated `height` CSS value, converted to a
+ * num in pixels.
+ */
+ void set height(newHeight) {
+ _elementList.forEach((e) => e.contentEdge.height = newHeight);
+ }
+
+ /**
+ * Set the current computed width in pixels of this element.
+ *
+ * This is equivalent to the `width` function in jQuery and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels.
+ */
+ void set width(newWidth) {
+ _elementList.forEach((e) => e.contentEdge.width = newWidth);
+ }
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _PaddingCssRect extends CssRect {
+ _PaddingCssRect(element) : super(element);
+ num get height => _element.offsetHeight +
+ _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
+ num get width => _element.offsetWidth +
+ _addOrSubtractToBoxModel(_WIDTH, _PADDING);
+
+ num get left => _element.getBoundingClientRect().left -
+ _addOrSubtractToBoxModel(['left'], _PADDING);
+ num get top => _element.getBoundingClientRect().top -
+ _addOrSubtractToBoxModel(['top'], _PADDING);
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _BorderCssRect extends CssRect {
+ _BorderCssRect(element) : super(element);
+ num get height => _element.offsetHeight;
+ num get width => _element.offsetWidth;
+
+ num get left => _element.getBoundingClientRect().left;
+ num get top => _element.getBoundingClientRect().top;
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border + margin in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _MarginCssRect extends CssRect {
+ _MarginCssRect(element) : super(element);
+ num get height => _element.offsetHeight +
+ _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
+ num get width =>
+ _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);
+
+ num get left => _element.getBoundingClientRect().left -
+ _addOrSubtractToBoxModel(['left'], _MARGIN);
+ num get top => _element.getBoundingClientRect().top -
+ _addOrSubtractToBoxModel(['top'], _MARGIN);
+}
+
+/**
+ * A class for representing CSS dimensions.
+ *
+ * In contrast to the more general purpose [Rect] class, this class's values are
+ * mutable, so one can change the height of an element programmatically.
+ *
+ * _Important_ _note_: use of these methods will perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of these properties _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+abstract class CssRect extends RectBase implements Rect {
+ Element _element;
+
+ CssRect(this._element);
+
+ num get left;
+
+ num get top;
+
+ /**
+ * The height of this rectangle.
+ *
+ * This is equivalent to the `height` function in jQuery and the calculated
+ * `height` CSS value, converted to a dimensionless num in pixels. Unlike
+ * [getBoundingClientRect], `height` will return the same numerical width if
+ * the element is hidden or not.
+ */
+ num get height;
+
+ /**
+ * The width of this rectangle.
+ *
+ * This is equivalent to the `width` function in jQuery and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels. Unlike
+ * [getBoundingClientRect], `width` will return the same numerical width if
+ * the element is hidden or not.
+ */
+ num get width;
+
+ /**
+ * Set the height to `newHeight`.
+ *
+ * newHeight can be either a [num] representing the height in pixels or a
+ * [Dimension] object. Values of newHeight that are less than zero are
+ * converted to effectively setting the height to 0. This is equivalent to the
+ * `height` function in jQuery and the calculated `height` CSS value,
+ * converted to a num in pixels.
+ *
+ * Note that only the content height can actually be set via this method.
+ */
+ void set height(newHeight) {
+ throw new UnsupportedError("Can only set height for content rect.");
+ }
+
+ /**
+ * Set the current computed width in pixels of this element.
+ *
+ * newWidth can be either a [num] representing the width in pixels or a
+ * [Dimension] object. This is equivalent to the `width` function in jQuery
+ * and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels.
+ *
+ * Note that only the content width can be set via this method.
+ */
+ void set width(newWidth) {
+ throw new UnsupportedError("Can only set width for content rect.");
+ }
+
+ /**
+ * Return a value that is used to modify the initial height or width
+ * measurement of an element. Depending on the value (ideally an enum) passed
+ * to augmentingMeasurement, we may need to add or subtract margin, padding,
+ * or border values, depending on the measurement we're trying to obtain.
+ */
+ num _addOrSubtractToBoxModel(List<String> dimensions,
+ String augmentingMeasurement) {
+ // getComputedStyle always returns pixel values (hence, computed), so we're
+ // always dealing with pixels in this method.
+ var styles = _element.getComputedStyle();
+
+ var val = 0;
+
+ for (String measurement in dimensions) {
+ // The border-box and default box model both exclude margin in the regular
+ // height/width calculation, so add it if we want it for this measurement.
+ if (augmentingMeasurement == _MARGIN) {
+ val += new Dimension.css(styles.getPropertyValue(
+ '$augmentingMeasurement-$measurement')).value;
+ }
+
+ // The border-box includes padding and border, so remove it if we want
+ // just the content itself.
+ if (augmentingMeasurement == _CONTENT) {
+ val -= new Dimension.css(
+ styles.getPropertyValue('${_PADDING}-$measurement')).value;
+ }
+
+ // At this point, we don't wan't to augment with border or margin,
+ // so remove border.
+ if (augmentingMeasurement != _MARGIN) {
+ val -= new Dimension.css(styles.getPropertyValue(
+ 'border-${measurement}-width')).value;
+ }
+ }
+ return val;
+ }
+}
+
+final _HEIGHT = ['top', 'bottom'];
+final _WIDTH = ['right', 'left'];
+final _CONTENT = 'content';
+final _PADDING = 'padding';
+final _MARGIN = 'margin';
+
+/**
+ * Class representing a
+ * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
+ * in CSS.
+ */
+@Experimental()
+class Dimension {
+ num _value;
+ String _unit;
+
+ /** Set this CSS Dimension to a percentage `value`. */
+ Dimension.percent(this._value) : _unit = '%';
+
+ /** Set this CSS Dimension to a pixel `value`. */
+ Dimension.px(this._value) : _unit = 'px';
+
+ /** Set this CSS Dimension to a pica `value`. */
+ Dimension.pc(this._value) : _unit = 'pc';
+
+ /** Set this CSS Dimension to a point `value`. */
+ Dimension.pt(this._value) : _unit = 'pt';
+
+ /** Set this CSS Dimension to an inch `value`. */
+ Dimension.inch(this._value) : _unit = 'in';
+
+ /** Set this CSS Dimension to a centimeter `value`. */
+ Dimension.cm(this._value) : _unit = 'cm';
+
+ /** Set this CSS Dimension to a millimeter `value`. */
+ Dimension.mm(this._value) : _unit = 'mm';
+
+ /**
+ * Set this CSS Dimension to the specified number of ems.
+ *
+ * 1em is equal to the current font size. (So 2ems is equal to double the font
+ * size). This is useful for producing website layouts that scale nicely with
+ * the user's desired font size.
+ */
+ Dimension.em(this._value) : _unit = 'em';
+
+ /**
+ * Set this CSS Dimension to the specified number of x-heights.
+ *
+ * One ex is equal to the the x-height of a font's baseline to its mean line,
+ * generally the height of the letter "x" in the font, which is usually about
+ * half the font-size.
+ */
+ Dimension.ex(this._value) : _unit = 'ex';
+
+ /**
+ * Construct a Dimension object from the valid, simple CSS string `cssValue`
+ * that represents a distance measurement.
+ *
+ * This constructor is intended as a convenience method for working with
+ * simplistic CSS length measurements. Non-numeric values such as `auto` or
+ * `inherit` or invalid CSS will cause this constructor to throw a
+ * FormatError.
+ */
+ Dimension.css(String cssValue) {
+ if (cssValue == '') cssValue = '0px';
+ if (cssValue.endsWith('%')) {
+ _unit = '%';
+ } else {
+ _unit = cssValue.substring(cssValue.length - 2);
+ }
+ if (cssValue.contains('.')) {
+ _value = double.parse(cssValue.substring(0,
+ cssValue.length - _unit.length));
+ } else {
+ _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
+ }
+ }
+
+ /** Print out the CSS String representation of this value. */
+ String toString() {
+ return '${_value}${_unit}';
+ }
+
+ /** Return a unitless, numerical value of this CSS value. */
+ num get value => this._value;
+}
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -29830,44 +30319,24 @@
/**
- * A class for representing two-dimensional rectangles.
+ * A base class for representing two-dimensional rectangles. This will hopefully
+ * be moved merged with the dart:math Rect.
*/
-class Rect {
- final num left;
- final num top;
- final num width;
- final num height;
+// TODO(efortuna): Merge with Math rect after finalizing with Florian.
+abstract class RectBase {
+ // Not used, but keeps the VM from complaining about Rect having a const
+ // constructor and this one not.
+ const RectBase();
- const Rect(this.left, this.top, this.width, this.height);
-
- factory Rect.fromPoints(Point a, Point b) {
- var left;
- var width;
- if (a.x < b.x) {
- left = a.x;
- width = b.x - left;
- } else {
- left = b.x;
- width = a.x - left;
- }
- var top;
- var height;
- if (a.y < b.y) {
- top = a.y;
- height = b.y - top;
- } else {
- top = b.y;
- height = a.y - top;
- }
-
- return new Rect(left, top, width, height);
- }
+ num get left;
+ num get top;
+ num get width;
+ num get height;
num get right => left + width;
num get bottom => top + height;
// NOTE! All code below should be common with Rect.
- // TODO: implement with mixins when available.
String toString() {
return '($left, $top, $width, $height)';
@@ -29961,6 +30430,46 @@
Point get bottomRight => new Point(this.left + this.width,
this.top + this.height);
}
+
+
+
+/**
+ * A class for representing two-dimensional rectangles.
+ *
+ * This class is distinctive from RectBase in that it enforces that its
+ * properties are immutable.
+ */
+class Rect extends RectBase {
+ final num left;
+ final num top;
+ final num width;
+ final num height;
+
+ const Rect(this.left, this.top, this.width, this.height): super();
+
+ factory Rect.fromPoints(Point a, Point b) {
+ var left;
+ var width;
+ if (a.x < b.x) {
+ left = a.x;
+ width = b.x - left;
+ } else {
+ left = b.x;
+ width = a.x - left;
+ }
+ var top;
+ var height;
+ if (a.y < b.y) {
+ top = a.y;
+ height = b.y - top;
+ } else {
+ top = b.y;
+ height = a.y - top;
+ }
+
+ return new Rect(left, top, width, height);
+ }
+}
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index 043a61e..756b34a 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -870,15 +870,518 @@
/// Extracted w value.
double get w;
- /// Returns a new [Float32x4] with [this]' x value in all four lanes.
+ /// Returns a new [Float32x4] with lane values reordered.
Float32x4 get xxxx;
- /// Returns a new [Float32x4] with [this]' y value in all four lanes.
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxwz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xxww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xywx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xywy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xywz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xyww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzwz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xzww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwwz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get xwww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxwz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yxww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyyx;
+ /// Returns a new [Float32x4] with lane values reordered.
Float32x4 get yyyy;
- /// Returns a new [Float32x4] with [this]' z value in all four lanes.
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yywx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yywy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yywz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yyww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzwz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get yzww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywwz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get ywww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxwz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zxww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zywx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zywy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zywz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zyww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzzy;
+ /// Returns a new [Float32x4] with lane values reordered.
Float32x4 get zzzz;
- /// Returns a new [Float32x4] with [this]' w value in all four lanes.
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzwz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zzww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwwz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get zwww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxwz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wxww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wywx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wywy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wywz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wyww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzwz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wzww;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwxx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwxy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwxz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwxw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwyx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwyy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwyz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwyw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwzx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwzy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwzz;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwzw;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwwx;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwwy;
+ /// Returns a new [Float32x4] with lane values reordered.
+ Float32x4 get wwwz;
+ /// Returns a new [Float32x4] with lane values reordered.
Float32x4 get wwww;
- // TODO(johnmccutchan): Add all 256 possible combinations.
/// Returns a new [Float32x4] copied from [this] with a new x value.
Float32x4 withX(double x);
diff --git a/tests/async_helper.dart b/tests/async_helper.dart
index 34d471e..c1b8273 100644
--- a/tests/async_helper.dart
+++ b/tests/async_helper.dart
@@ -18,8 +18,14 @@
library async_helper;
+// TODO(kustermann): This is problematic because we rely on a working
+// 'dart:isolate' (i.e. it is in particular problematic with dart2js).
+// It would be nice if we could use a different mechanism for different
+// runtimes.
+import 'dart:isolate';
bool _initialized = false;
+ReceivePort _port = null;
int _asyncLevel = 0;
Exception _buildException(String msg) {
@@ -34,6 +40,7 @@
if (!_initialized) {
print('unittest-suite-wait-for-done');
_initialized = true;
+ _port = new ReceivePort();
}
_asyncLevel++;
}
@@ -49,6 +56,8 @@
}
_asyncLevel--;
if (_asyncLevel == 0) {
+ _port.close();
+ _port = null;
print('unittest-suite-done');
}
}
diff --git a/tests/html/element_dimensions_test.dart b/tests/html/element_dimensions_test.dart
new file mode 100644
index 0000000..413d302
--- /dev/null
+++ b/tests/html/element_dimensions_test.dart
@@ -0,0 +1,263 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+library element_dimensions_test;
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'dart:html';
+
+main() {
+ useHtmlConfiguration();
+
+ var isElement = predicate((x) => x is Element, 'is an Element');
+ var isCanvasElement =
+ predicate((x) => x is CanvasElement, 'is a CanvasElement');
+ var isDivElement = predicate((x) => x is DivElement, 'is a isDivElement');
+
+ var div = new DivElement();
+ div.id = 'test';
+ document.body.nodes.add(div);
+
+ void initDiv() {
+ var style = div.style;
+ style..padding = '4px'
+ ..border = '0px solid #fff'
+ ..margin = '6px'
+ ..height = '10px'
+ ..width = '11px'
+ ..boxSizing = 'content-box'
+ ..overflow = 'visible';
+ }
+
+ div.nodes.addAll([
+ new DivElement(),
+ new CanvasElement(),
+ new DivElement(),
+ new Text('Hello'),
+ new DivElement(),
+ new Text('World'),
+ new CanvasElement()]);
+
+ group('dimensions', () {
+ setUp(initDiv);
+
+ test('contentEdge.height', () {
+ var all1 = queryAll('#test');
+
+ expect(all1.contentEdge.height, 10);
+ expect(all1[0].getComputedStyle().getPropertyValue('height'), '10px');
+
+ all1.contentEdge.height = new Dimension.px(600);
+ all1.contentEdge.height = 600;
+ expect(all1.contentEdge.height, 600);
+ expect(all1[0].getComputedStyle().getPropertyValue('height'), '600px');
+ all1[0].style.visibility = 'hidden';
+ expect(all1.contentEdge.height, 600);
+ all1[0].style.visibility = 'visible';
+
+ // If user passes in a negative number, set height to 0.
+ all1.contentEdge.height = new Dimension.px(-1);
+ expect(all1.contentEdge.height, 0);
+
+ // Adding padding or border shouldn't affect the height for
+ // non-box-sizing.
+ div.style.padding = '20pc';
+ expect(all1.contentEdge.height, 0);
+ div.style.border = '2px solid #fff';
+ expect(all1.contentEdge.height, 0);
+ });
+
+ test('contentEdge.height with border-box', () {
+ var all1 = queryAll('#test');
+ div.style.boxSizing = 'border-box';
+ expect(all1.contentEdge.height, 2);
+ div.style.padding = '20pc';
+ expect(all1.contentEdge.height, 0);
+ div.style.border = '2px solid #fff';
+ expect(all1.contentEdge.height, 0);
+ });
+
+ test('contentEdge.width', () {
+ var all1 = queryAll('#test');
+ expect(all1.contentEdge.width, 11);
+ expect(all1[0].getComputedStyle().getPropertyValue('width'), '11px');
+
+ all1.contentEdge.width = new Dimension.px(600);
+ expect(all1.contentEdge.width, 600);
+ expect(all1[0].getComputedStyle().getPropertyValue('width'), '600px');
+ all1[0].style.visibility = 'hidden';
+ expect(all1.contentEdge.width, 600);
+ all1[0].style.visibility = 'visible';
+
+ // If user passes in a negative number, set width to 0.
+ all1.contentEdge.width = new Dimension.px(-1);
+ expect(all1.contentEdge.width, 0);
+
+ // Adding padding or border shouldn't affect the width.
+ div.style.padding = '20pc';
+ expect(all1.contentEdge.width, 0);
+ div.style.border = '2px solid #fff';
+ expect(all1.contentEdge.width, 0);
+ });
+
+ test('contentEdge.width with border-box', () {
+ var all1 = queryAll('#test');
+ div.style.boxSizing = 'border-box';
+ expect(all1.contentEdge.width, 3);
+ div.style.padding = '20pc';
+ expect(all1.contentEdge.width, 0);
+ div.style.border = '2px solid #fff';
+ expect(all1.contentEdge.width, 0);
+
+ });
+
+ test('paddingEdge.height', () {
+ var all1 = queryAll('#test');
+ expect(all1.paddingEdge.height, 18);
+ all1[0].style.visibility = 'hidden';
+ expect(all1.paddingEdge.height, 18);
+ all1[0].style.visibility = 'visible';
+
+ // Adding border shouldn't affect the paddingEdge.height.
+ div.style.border = '2px solid #fff';
+ expect(all1.paddingEdge.height, 18);
+ // Adding padding should affect the paddingEdge.height.
+ div.style.padding = '20pc';
+ expect(all1.paddingEdge.height, 650);
+ });
+
+ test('paddingEdge.height with border-box', () {
+ var all1 = queryAll('#test');
+ div.style.boxSizing = 'border-box';
+ expect(all1.paddingEdge.height, 10);
+ div.style.padding = '20pc';
+ expect(all1.paddingEdge.height, 640);
+ div.style.border = '2px solid #fff';
+ expect(all1.paddingEdge.height, 640);
+ });
+
+ test('paddingEdge.width', () {
+ var all1 = queryAll('#test');
+ expect(all1.paddingEdge.width, 19);
+ all1[0].style.visibility = 'hidden';
+ expect(all1.paddingEdge.width, 19);
+ all1[0].style.visibility = 'visible';
+
+ // Adding border shouldn't affect the width.
+ div.style.border = '2px solid #fff';
+ expect(all1.paddingEdge.width, 19);
+
+ // Adding padding should affect the paddingEdge.width.
+ div.style.padding = '20pc';
+ expect(all1.paddingEdge.width, 651);
+ });
+
+ test('paddingEdge.width with border-box', () {
+ var all1 = queryAll('#test');
+ div.style.boxSizing = 'border-box';
+ expect(all1.paddingEdge.width, 11);
+ div.style.padding = '20pc';
+ expect(all1.paddingEdge.width, 640);
+ div.style.border = '2px solid #fff';
+ expect(all1.paddingEdge.width, 640);
+ });
+
+ test('borderEdge.height and marginEdge.height', () {
+ var all1 = queryAll('#test');
+ expect(div.borderEdge.height, 18);
+ expect(div.marginEdge.height, 30);
+ expect(all1.borderEdge.height, 18);
+ expect(all1.marginEdge.height, 30);
+ all1[0].style.visibility = 'hidden';
+ expect(all1.borderEdge.height, 18);
+ all1[0].style.visibility = 'visible';
+
+ // Adding border should affect the borderEdge.height.
+ div.style.border = '2px solid #fff';
+ expect(all1.borderEdge.height, 22);
+ // Adding padding should affect the borderEdge.height.
+ div.style.padding = '20pc';
+ expect(all1.borderEdge.height, 654);
+ expect(all1.marginEdge.height, 666);
+ });
+
+
+ test('borderEdge.height and marginEdge.height with border-box', () {
+ var all1 = queryAll('#test');
+ div.style.boxSizing = 'border-box';
+ expect(all1.borderEdge.height, 10);
+ expect(all1.marginEdge.height, 22);
+ div.style.padding = '20pc';
+ expect(all1.borderEdge.height, 640);
+ expect(all1.marginEdge.height, 652);
+ div.style.border = '2px solid #fff';
+ expect(all1.borderEdge.height, 644);
+ expect(all1.marginEdge.height, 656);
+ });
+
+ test('borderEdge.width and marginEdge.width', () {
+ var all1 = queryAll('#test');
+ expect(all1.borderEdge.width, 19);
+ expect(all1.marginEdge.width, 31);
+
+ // Adding border should affect the width.
+ div.style.border = '2px solid #fff';
+ expect(all1.borderEdge.width, 23);
+
+ // Adding padding should affect the borderEdge.width.
+ div.style.padding = '20pc';
+ expect(all1.borderEdge.width, 655);
+ expect(all1.marginEdge.width, 667);
+ });
+
+ test('borderEdge.width and marginEdge.width with border-box', () {
+ var all1 = queryAll('#test');
+ div.style.boxSizing = 'border-box';
+ expect(all1.borderEdge.width, 11);
+ expect(all1.marginEdge.width, 23);
+ div.style.padding = '20pc';
+ expect(all1.borderEdge.width, 640);
+ expect(all1.marginEdge.width, 652);
+ div.style.border = '2px solid #fff';
+ expect(all1.borderEdge.width, 644);
+ expect(all1.marginEdge.width, 656);
+ });
+
+ test('left and top', () {
+ div.style.border = '1px solid #fff';
+ div.style.margin = '6px 7px';
+ div.style.padding = '4px 5px';
+ var all1 = queryAll('#test');
+
+ expect(all1.borderEdge.left, all1[0].getBoundingClientRect().left);
+ expect(all1.borderEdge.top, all1[0].getBoundingClientRect().top);
+
+ expect(all1.contentEdge.left,
+ all1[0].getBoundingClientRect().left + 1 + 5);
+ expect(all1.contentEdge.top, all1[0].getBoundingClientRect().top + 1 + 4);
+
+ expect(all1.marginEdge.left, all1[0].getBoundingClientRect().left - 7);
+ expect(all1.marginEdge.top, all1[0].getBoundingClientRect().top - 6);
+
+ expect(all1.paddingEdge.left, all1[0].getBoundingClientRect().left + 1);
+ expect(all1.paddingEdge.top, all1[0].getBoundingClientRect().top + 1);
+ });
+
+ test('setHeight ElementList', () {
+ div.style.border = '1px solid #fff';
+ div.style.margin = '6px 7px';
+ div.style.padding = '4px 5px';
+ var all1 = queryAll('div');
+ all1.contentEdge.height = new Dimension.px(200);
+ all1.contentEdge.height = 200;
+ for (Element elem in all1) {
+ expect(elem.contentEdge.height, 200);
+ }
+ all1.contentEdge.height = new Dimension.px(10);
+ for (Element elem in all1) {
+ expect(elem.contentEdge.height, 10);
+ }
+ });
+ });
+}
diff --git a/tests/language/library1.dart b/tests/language/library1.dart
index 849a188..96cdd1b 100644
--- a/tests/language/library1.dart
+++ b/tests/language/library1.dart
@@ -6,3 +6,13 @@
library library1.dart;
var foo;
+
+bar() => "library1.dart bar()";
+
+baz() => "library1.dart baz()";
+
+var bay;
+
+typedef int bax(int a, int b);
+
+class baw {}
diff --git a/tests/language/library1_negative_test.dart b/tests/language/library1_negative_test.dart
deleted file mode 100644
index aa5f869..0000000
--- a/tests/language/library1_negative_test.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This test should fail to load because we are importing two libraries
-// which define the same top level name foo, and we are referring to the name.
-
-library Library1NegativeTest.dart;
-import "package:expect/expect.dart";
-import "library1.dart"; // Defines top level variable 'foo'
-import "library2.dart"; // Defines top level variable 'foo'
-
-
-main() {
- Expect.equals(0, foo); // Reference ambiguous name 'foo'
-}
diff --git a/tests/language/library2.dart b/tests/language/library2.dart
index 1632878..275bf26 100644
--- a/tests/language/library2.dart
+++ b/tests/language/library2.dart
@@ -7,3 +7,13 @@
var foo;
var foo1 = 0;
+
+bar() => "library2.dart bar()";
+
+var baz;
+
+bay() => "library2.dart bay()";
+
+typedef double bax(int a, int b);
+
+var baw;
\ No newline at end of file
diff --git a/tests/language/library_ambiguous_test.dart b/tests/language/library_ambiguous_test.dart
new file mode 100644
index 0000000..4a16f92
--- /dev/null
+++ b/tests/language/library_ambiguous_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test should fail to load because we are importing two libraries
+// which define the same top level name foo, and we are referring to the name.
+
+library Library1NegativeTest.dart;
+import "library1.dart"; // Defines top level variable 'foo'
+import "library2.dart"; // Defines top level variable 'foo'
+
+class X
+extends baw /// 05: compile-time error
+{}
+
+main() {
+ print(foo); /// 00: compile-time error
+ print(bar()); /// 01: compile-time error
+ print(baz()); /// 02: compile-time error
+ print(bay()); /// 03: compile-time error
+ print(main is bax); /// 04: compile-time error
+ var x = new X(); /// 05: continued
+ print("No error expected if ambiguous definitions are not used.");
+}
diff --git a/tests/language/mixin_prefix_lib.dart b/tests/language/mixin_prefix_lib.dart
new file mode 100644
index 0000000..9c1295f
--- /dev/null
+++ b/tests/language/mixin_prefix_lib.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library mixin_prefix_lib;
+
+import 'dart:json' as json;
+
+class MixinClass {
+ String bar() => json.stringify({'a':1});
+}
diff --git a/tests/language/mixin_prefix_test.dart b/tests/language/mixin_prefix_test.dart
new file mode 100644
index 0000000..eea64ce
--- /dev/null
+++ b/tests/language/mixin_prefix_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for issue 11891.
+
+import "package:expect/expect.dart";
+import "mixin_prefix_lib.dart";
+
+class A extends Object with MixinClass {
+ String baz() => bar();
+}
+
+void main() {
+ var a = new A();
+ Expect.equals('{"a":1}', a.baz());
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 9b5952c..81eb98d 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -17,6 +17,7 @@
typed_data/float32x4_list_test: Fail, OK
typed_data/float32x4_unbox_phi_test: Fail, OK
typed_data/float32x4_unbox_regress_test: Fail, OK
+typed_data/float32x4_shuffle_test: Fail, OK
[ $compiler == dart2js && ($runtime == d8 || $runtime == ie9) ]
typed_data/byte_data_test: Fail, OK # d8/ie9 doesn't support DataView
@@ -64,6 +65,7 @@
typed_data/float32x4_list_test: Fail # Issue 10961
typed_data/float32x4_unbox_phi_test: Fail # Issue 10961
typed_data/float32x4_unbox_regress_test: Fail # Issue 10961
+typed_data/float32x4_shuffle_test: Fail # Issue 10961
[ $runtime == ff ]
# FF setTimeout can fire early: https://bugzilla.mozilla.org/show_bug.cgi?id=291386
@@ -109,6 +111,7 @@
[ $arch == arm || $arch == simarm ]
typed_data/float32x4_test: Crash # Unimplemented
+typed_data/float32x4_shuffle_test: Crash # Unimplemented
[ $arch == mips ]
*: Skip
@@ -118,3 +121,4 @@
typed_data/float32x4_unbox_phi_test: Crash # Unimplemented
typed_data/float32x4_list_test: Crash # Unimplemented
typed_data/float32x4_test: Crash # Unimplemented
+typed_data/float32x4_shuffle_test: Crash # Unimplemented
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
index 1b9a999..bf108ce 100644
--- a/tests/lib/mirrors/mirrors_test.dart
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -254,6 +254,11 @@
expect(typedefMirror.simpleName, equals(const Symbol('Typedef')));
expect(typedefMirror.qualifiedName,
equals(const Symbol('MirrorsTest.Typedef')));
+
+ var typedefMirrorDeNovo = reflectClass(Typedef);
+ expect(typedefMirrorDeNovo.simpleName, equals(const Symbol('Typedef')));
+ expect(typedefMirrorDeNovo.qualifiedName,
+ equals(const Symbol('MirrorsTest.Typedef')));
}
expect(methodMirror.simpleName, equals(const Symbol('testNames')));
diff --git a/tests/lib/typed_data/float32x4_shuffle_test.dart b/tests/lib/typed_data/float32x4_shuffle_test.dart
new file mode 100644
index 0000000..5492259
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_shuffle_test.dart
@@ -0,0 +1,1319 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Library tag to be able to run in html test framework.
+library float32x4_shuffle_test;
+
+import "package:expect/expect.dart";
+import 'dart:typed_data';
+
+void testShuffle0() {
+ var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+ var c;
+ c = m.xxxx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xxxy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xxxz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xxxw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xxyx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xxyy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xxyz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xxyw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xxzx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xxzy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xxzz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xxzw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xxwx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xxwy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xxwz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xxww;
+ Expect.equals(1.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xyxx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xyxy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xyxz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xyxw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xyyx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xyyy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xyyz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xyyw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xyzx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xyzy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xyzz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xyzw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xywx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xywy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xywz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xyww;
+ Expect.equals(1.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xzxx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xzxy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xzxz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xzxw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xzyx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xzyy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xzyz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xzyw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xzzx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xzzy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xzzz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xzzw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xzwx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xzwy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xzwz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xzww;
+ Expect.equals(1.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xwxx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xwxy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xwxz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xwxw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xwyx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xwyy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xwyz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xwyw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xwzx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xwzy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xwzz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xwzw;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.xwwx;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.xwwy;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.xwwz;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.xwww;
+ Expect.equals(1.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+}
+
+void testShuffle1() {
+ var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+ var c;
+ c = m.yxxx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yxxy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yxxz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yxxw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.yxyx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yxyy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yxyz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yxyw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.yxzx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yxzy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yxzz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yxzw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.yxwx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yxwy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yxwz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yxww;
+ Expect.equals(2.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.yyxx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yyxy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yyxz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yyxw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.yyyx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yyyy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yyyz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yyyw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.yyzx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yyzy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yyzz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yyzw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.yywx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yywy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yywz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yyww;
+ Expect.equals(2.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.yzxx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yzxy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yzxz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yzxw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.yzyx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yzyy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yzyz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yzyw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.yzzx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yzzy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yzzz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yzzw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.yzwx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.yzwy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.yzwz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.yzww;
+ Expect.equals(2.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.ywxx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.ywxy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.ywxz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.ywxw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.ywyx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.ywyy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.ywyz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.ywyw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.ywzx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.ywzy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.ywzz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.ywzw;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.ywwx;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.ywwy;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.ywwz;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.ywww;
+ Expect.equals(2.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+}
+
+void testShuffle2() {
+ var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+ var c;
+ c = m.zxxx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zxxy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zxxz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zxxw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zxyx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zxyy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zxyz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zxyw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zxzx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zxzy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zxzz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zxzw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zxwx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zxwy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zxwz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zxww;
+ Expect.equals(3.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zyxx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zyxy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zyxz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zyxw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zyyx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zyyy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zyyz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zyyw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zyzx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zyzy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zyzz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zyzw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zywx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zywy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zywz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zyww;
+ Expect.equals(3.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zzxx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zzxy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zzxz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zzxw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zzyx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zzyy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zzyz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zzyw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zzzx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zzzy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zzzz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zzzw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zzwx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zzwy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zzwz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zzww;
+ Expect.equals(3.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zwxx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zwxy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zwxz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zwxw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zwyx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zwyy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zwyz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zwyw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zwzx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zwzy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zwzz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zwzw;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.zwwx;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.zwwy;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.zwwz;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.zwww;
+ Expect.equals(3.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+}
+
+void testShuffle3() {
+ var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+ var c;
+ c = m.wxxx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wxxy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wxxz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wxxw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wxyx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wxyy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wxyz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wxyw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wxzx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wxzy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wxzz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wxzw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wxwx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wxwy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wxwz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wxww;
+ Expect.equals(4.0, c.x);
+ Expect.equals(1.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wyxx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wyxy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wyxz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wyxw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wyyx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wyyy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wyyz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wyyw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wyzx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wyzy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wyzz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wyzw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wywx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wywy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wywz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wyww;
+ Expect.equals(4.0, c.x);
+ Expect.equals(2.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wzxx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wzxy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wzxz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wzxw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wzyx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wzyy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wzyz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wzyw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wzzx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wzzy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wzzz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wzzw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wzwx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wzwy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wzwz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wzww;
+ Expect.equals(4.0, c.x);
+ Expect.equals(3.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wwxx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wwxy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wwxz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wwxw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(1.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wwyx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wwyy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wwyz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wwyw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(2.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wwzx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wwzy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wwzz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wwzw;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(3.0, c.z);
+ Expect.equals(4.0, c.w);
+ c = m.wwwx;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(1.0, c.w);
+ c = m.wwwy;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(2.0, c.w);
+ c = m.wwwz;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(3.0, c.w);
+ c = m.wwww;
+ Expect.equals(4.0, c.x);
+ Expect.equals(4.0, c.y);
+ Expect.equals(4.0, c.z);
+ Expect.equals(4.0, c.w);
+}
+
+
+main() {
+ for (int i = 0; i < 4000; i++) {
+ testShuffle0();
+ testShuffle1();
+ testShuffle2();
+ testShuffle3();
+ }
+}
diff --git a/tests/lib/typed_data/float32x4_test.dart b/tests/lib/typed_data/float32x4_test.dart
index 4d2c15e..35ee655 100644
--- a/tests/lib/typed_data/float32x4_test.dart
+++ b/tests/lib/typed_data/float32x4_test.dart
@@ -149,6 +149,26 @@
Expect.equals(4.0, wwww.y);
Expect.equals(4.0, wwww.z);
Expect.equals(4.0, wwww.w);
+ var wzyx = m.wzyx;
+ Expect.equals(4.0, wzyx.x);
+ Expect.equals(3.0, wzyx.y);
+ Expect.equals(2.0, wzyx.z);
+ Expect.equals(1.0, wzyx.w);
+ var wwzz = m.wwzz;
+ Expect.equals(4.0, wwzz.x);
+ Expect.equals(4.0, wwzz.y);
+ Expect.equals(3.0, wwzz.z);
+ Expect.equals(3.0, wwzz.w);
+ var xxyy = m.xxyy;
+ Expect.equals(1.0, xxyy.x);
+ Expect.equals(1.0, xxyy.y);
+ Expect.equals(2.0, xxyy.z);
+ Expect.equals(2.0, xxyy.w);
+ var yyww = m.yyww;
+ Expect.equals(2.0, yyww.x);
+ Expect.equals(2.0, yyww.y);
+ Expect.equals(4.0, yyww.z);
+ Expect.equals(4.0, yyww.w);
}
testMin() {
diff --git a/tools/VERSION b/tools/VERSION
index de9958b..0655e7f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 0
MINOR 6
-BUILD 8
+BUILD 9
PATCH 0
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index b2fd1ba..7ce71fb 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -527,7 +527,7 @@
" * The data received as a reponse from the request.",
" *",
" * The data could be in the",
- " * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a",
+ " * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a",
" * [String]). `null` indicates request failure.",
" */"
],
diff --git a/tools/dom/dom.py b/tools/dom/dom.py
index f4a5c85..54844a6 100755
--- a/tools/dom/dom.py
+++ b/tools/dom/dom.py
@@ -40,10 +40,10 @@
def analyze():
''' Runs the dart analyzer. '''
return call([
- os.path.join(dart_out_dir, 'dart-sdk', 'bin', 'dart_analyzer'),
+ os.path.join(dart_out_dir, 'dart-sdk', 'bin', 'dartanalyzer'),
os.path.join('tests', 'html', 'element_test.dart'),
- '--dart-sdk', 'sdk',
- '--show-sdk-warnings',
+ '--dart-sdk=sdk',
+ '--show-package-warnings',
])
def build():
diff --git a/tools/dom/src/CssRectangle.dart b/tools/dom/src/CssRectangle.dart
new file mode 100644
index 0000000..6808927
--- /dev/null
+++ b/tools/dom/src/CssRectangle.dart
@@ -0,0 +1,261 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of html;
+
+/**
+ * A rectangle representing all the content of the element in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssRect extends CssRect {
+
+ _ContentCssRect(element) : super(element);
+
+ num get height => _element.offsetHeight +
+ _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);
+
+ num get width => _element.offsetWidth +
+ _addOrSubtractToBoxModel(_WIDTH, _CONTENT);
+
+ /**
+ * Set the height to `newHeight`.
+ *
+ * newHeight can be either a [num] representing the height in pixels or a
+ * [Dimension] object. Values of newHeight that are less than zero are
+ * converted to effectively setting the height to 0. This is equivalent to the
+ * `height` function in jQuery and the calculated `height` CSS value,
+ * converted to a num in pixels.
+ */
+ void set height(newHeight) {
+ if (newHeight is Dimension) {
+ if (newHeight.value < 0) newHeight = new Dimension.px(0);
+ _element.style.height = newHeight.toString();
+ } else {
+ if (newHeight < 0) newHeight = 0;
+ _element.style.height = '${newHeight}px';
+ }
+ }
+
+ /**
+ * Set the current computed width in pixels of this element.
+ *
+ * newWidth can be either a [num] representing the width in pixels or a
+ * [Dimension] object. This is equivalent to the `width` function in jQuery
+ * and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels.
+ */
+ void set width(newWidth) {
+ if (newWidth is Dimension) {
+ if (newWidth.value < 0) newWidth = new Dimension.px(0);
+ _element.style.width = newWidth.toString();
+ } else {
+ if (newWidth < 0) newWidth = 0;
+ _element.style.width = '${newWidth}px';
+ }
+ }
+
+ num get left => _element.getBoundingClientRect().left -
+ _addOrSubtractToBoxModel(['left'], _CONTENT);
+ num get top => _element.getBoundingClientRect().top -
+ _addOrSubtractToBoxModel(['top'], _CONTENT);
+}
+
+/**
+ * A list of element content rectangles in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssListRect extends _ContentCssRect {
+ List<Element> _elementList;
+
+ _ContentCssListRect(elementList) : super(elementList.first) {
+ _elementList = elementList;
+ }
+
+ /**
+ * Set the height to `newHeight`.
+ *
+ * Values of newHeight that are less than zero are converted to effectively
+ * setting the height to 0. This is equivalent to the `height`
+ * function in jQuery and the calculated `height` CSS value, converted to a
+ * num in pixels.
+ */
+ void set height(newHeight) {
+ _elementList.forEach((e) => e.contentEdge.height = newHeight);
+ }
+
+ /**
+ * Set the current computed width in pixels of this element.
+ *
+ * This is equivalent to the `width` function in jQuery and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels.
+ */
+ void set width(newWidth) {
+ _elementList.forEach((e) => e.contentEdge.width = newWidth);
+ }
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _PaddingCssRect extends CssRect {
+ _PaddingCssRect(element) : super(element);
+ num get height => _element.offsetHeight +
+ _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
+ num get width => _element.offsetWidth +
+ _addOrSubtractToBoxModel(_WIDTH, _PADDING);
+
+ num get left => _element.getBoundingClientRect().left -
+ _addOrSubtractToBoxModel(['left'], _PADDING);
+ num get top => _element.getBoundingClientRect().top -
+ _addOrSubtractToBoxModel(['top'], _PADDING);
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _BorderCssRect extends CssRect {
+ _BorderCssRect(element) : super(element);
+ num get height => _element.offsetHeight;
+ num get width => _element.offsetWidth;
+
+ num get left => _element.getBoundingClientRect().left;
+ num get top => _element.getBoundingClientRect().top;
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border + margin in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _MarginCssRect extends CssRect {
+ _MarginCssRect(element) : super(element);
+ num get height => _element.offsetHeight +
+ _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
+ num get width =>
+ _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);
+
+ num get left => _element.getBoundingClientRect().left -
+ _addOrSubtractToBoxModel(['left'], _MARGIN);
+ num get top => _element.getBoundingClientRect().top -
+ _addOrSubtractToBoxModel(['top'], _MARGIN);
+}
+
+/**
+ * A class for representing CSS dimensions.
+ *
+ * In contrast to the more general purpose [Rect] class, this class's values are
+ * mutable, so one can change the height of an element programmatically.
+ *
+ * _Important_ _note_: use of these methods will perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of these properties _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+abstract class CssRect extends RectBase implements Rect {
+ Element _element;
+
+ CssRect(this._element);
+
+ num get left;
+
+ num get top;
+
+ /**
+ * The height of this rectangle.
+ *
+ * This is equivalent to the `height` function in jQuery and the calculated
+ * `height` CSS value, converted to a dimensionless num in pixels. Unlike
+ * [getBoundingClientRect], `height` will return the same numerical width if
+ * the element is hidden or not.
+ */
+ num get height;
+
+ /**
+ * The width of this rectangle.
+ *
+ * This is equivalent to the `width` function in jQuery and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels. Unlike
+ * [getBoundingClientRect], `width` will return the same numerical width if
+ * the element is hidden or not.
+ */
+ num get width;
+
+ /**
+ * Set the height to `newHeight`.
+ *
+ * newHeight can be either a [num] representing the height in pixels or a
+ * [Dimension] object. Values of newHeight that are less than zero are
+ * converted to effectively setting the height to 0. This is equivalent to the
+ * `height` function in jQuery and the calculated `height` CSS value,
+ * converted to a num in pixels.
+ *
+ * Note that only the content height can actually be set via this method.
+ */
+ void set height(newHeight) {
+ throw new UnsupportedError("Can only set height for content rect.");
+ }
+
+ /**
+ * Set the current computed width in pixels of this element.
+ *
+ * newWidth can be either a [num] representing the width in pixels or a
+ * [Dimension] object. This is equivalent to the `width` function in jQuery
+ * and the calculated
+ * `width` CSS value, converted to a dimensionless num in pixels.
+ *
+ * Note that only the content width can be set via this method.
+ */
+ void set width(newWidth) {
+ throw new UnsupportedError("Can only set width for content rect.");
+ }
+
+ /**
+ * Return a value that is used to modify the initial height or width
+ * measurement of an element. Depending on the value (ideally an enum) passed
+ * to augmentingMeasurement, we may need to add or subtract margin, padding,
+ * or border values, depending on the measurement we're trying to obtain.
+ */
+ num _addOrSubtractToBoxModel(List<String> dimensions,
+ String augmentingMeasurement) {
+ // getComputedStyle always returns pixel values (hence, computed), so we're
+ // always dealing with pixels in this method.
+ var styles = _element.getComputedStyle();
+
+ var val = 0;
+
+ for (String measurement in dimensions) {
+ // The border-box and default box model both exclude margin in the regular
+ // height/width calculation, so add it if we want it for this measurement.
+ if (augmentingMeasurement == _MARGIN) {
+ val += new Dimension.css(styles.getPropertyValue(
+ '$augmentingMeasurement-$measurement')).value;
+ }
+
+ // The border-box includes padding and border, so remove it if we want
+ // just the content itself.
+ if (augmentingMeasurement == _CONTENT) {
+ val -= new Dimension.css(
+ styles.getPropertyValue('${_PADDING}-$measurement')).value;
+ }
+
+ // At this point, we don't wan't to augment with border or margin,
+ // so remove border.
+ if (augmentingMeasurement != _MARGIN) {
+ val -= new Dimension.css(styles.getPropertyValue(
+ 'border-${measurement}-width')).value;
+ }
+ }
+ return val;
+ }
+}
+
+final _HEIGHT = ['top', 'bottom'];
+final _WIDTH = ['right', 'left'];
+final _CONTENT = 'content';
+final _PADDING = 'padding';
+final _MARGIN = 'margin';
diff --git a/tools/dom/src/Dimension.dart b/tools/dom/src/Dimension.dart
new file mode 100644
index 0000000..96014c3
--- /dev/null
+++ b/tools/dom/src/Dimension.dart
@@ -0,0 +1,83 @@
+part of html;
+
+/**
+ * Class representing a
+ * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
+ * in CSS.
+ */
+@Experimental()
+class Dimension {
+ num _value;
+ String _unit;
+
+ /** Set this CSS Dimension to a percentage `value`. */
+ Dimension.percent(this._value) : _unit = '%';
+
+ /** Set this CSS Dimension to a pixel `value`. */
+ Dimension.px(this._value) : _unit = 'px';
+
+ /** Set this CSS Dimension to a pica `value`. */
+ Dimension.pc(this._value) : _unit = 'pc';
+
+ /** Set this CSS Dimension to a point `value`. */
+ Dimension.pt(this._value) : _unit = 'pt';
+
+ /** Set this CSS Dimension to an inch `value`. */
+ Dimension.inch(this._value) : _unit = 'in';
+
+ /** Set this CSS Dimension to a centimeter `value`. */
+ Dimension.cm(this._value) : _unit = 'cm';
+
+ /** Set this CSS Dimension to a millimeter `value`. */
+ Dimension.mm(this._value) : _unit = 'mm';
+
+ /**
+ * Set this CSS Dimension to the specified number of ems.
+ *
+ * 1em is equal to the current font size. (So 2ems is equal to double the font
+ * size). This is useful for producing website layouts that scale nicely with
+ * the user's desired font size.
+ */
+ Dimension.em(this._value) : _unit = 'em';
+
+ /**
+ * Set this CSS Dimension to the specified number of x-heights.
+ *
+ * One ex is equal to the the x-height of a font's baseline to its mean line,
+ * generally the height of the letter "x" in the font, which is usually about
+ * half the font-size.
+ */
+ Dimension.ex(this._value) : _unit = 'ex';
+
+ /**
+ * Construct a Dimension object from the valid, simple CSS string `cssValue`
+ * that represents a distance measurement.
+ *
+ * This constructor is intended as a convenience method for working with
+ * simplistic CSS length measurements. Non-numeric values such as `auto` or
+ * `inherit` or invalid CSS will cause this constructor to throw a
+ * FormatError.
+ */
+ Dimension.css(String cssValue) {
+ if (cssValue == '') cssValue = '0px';
+ if (cssValue.endsWith('%')) {
+ _unit = '%';
+ } else {
+ _unit = cssValue.substring(cssValue.length - 2);
+ }
+ if (cssValue.contains('.')) {
+ _value = double.parse(cssValue.substring(0,
+ cssValue.length - _unit.length));
+ } else {
+ _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
+ }
+ }
+
+ /** Print out the CSS String representation of this value. */
+ String toString() {
+ return '${_value}${_unit}';
+ }
+
+ /** Return a unitless, numerical value of this CSS value. */
+ num get value => this._value;
+}
diff --git a/tools/dom/src/Rectangle.dart b/tools/dom/src/Rectangle.dart
index e6a80b2..294fa85 100644
--- a/tools/dom/src/Rectangle.dart
+++ b/tools/dom/src/Rectangle.dart
@@ -5,44 +5,24 @@
part of html;
/**
- * A class for representing two-dimensional rectangles.
+ * A base class for representing two-dimensional rectangles. This will hopefully
+ * be moved merged with the dart:math Rect.
*/
-class Rect {
- final num left;
- final num top;
- final num width;
- final num height;
+// TODO(efortuna): Merge with Math rect after finalizing with Florian.
+abstract class RectBase {
+ // Not used, but keeps the VM from complaining about Rect having a const
+ // constructor and this one not.
+ const RectBase();
- const Rect(this.left, this.top, this.width, this.height);
-
- factory Rect.fromPoints(Point a, Point b) {
- var left;
- var width;
- if (a.x < b.x) {
- left = a.x;
- width = b.x - left;
- } else {
- left = b.x;
- width = a.x - left;
- }
- var top;
- var height;
- if (a.y < b.y) {
- top = a.y;
- height = b.y - top;
- } else {
- top = b.y;
- height = a.y - top;
- }
-
- return new Rect(left, top, width, height);
- }
+ num get left;
+ num get top;
+ num get width;
+ num get height;
num get right => left + width;
num get bottom => top + height;
// NOTE! All code below should be common with Rect.
- // TODO: implement with mixins when available.
String toString() {
return '($left, $top, $width, $height)';
@@ -136,3 +116,43 @@
Point get bottomRight => new Point(this.left + this.width,
this.top + this.height);
}
+
+
+
+/**
+ * A class for representing two-dimensional rectangles.
+ *
+ * This class is distinctive from RectBase in that it enforces that its
+ * properties are immutable.
+ */
+class Rect extends RectBase {
+ final num left;
+ final num top;
+ final num width;
+ final num height;
+
+ const Rect(this.left, this.top, this.width, this.height): super();
+
+ factory Rect.fromPoints(Point a, Point b) {
+ var left;
+ var width;
+ if (a.x < b.x) {
+ left = a.x;
+ width = b.x - left;
+ } else {
+ left = b.x;
+ width = a.x - left;
+ }
+ var top;
+ var height;
+ if (a.y < b.y) {
+ top = a.y;
+ height = b.y - top;
+ } else {
+ top = b.y;
+ height = a.y - top;
+ }
+
+ return new Rect(left, top, width, height);
+ }
+}
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 4a94db8..bfe368c 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -38,6 +38,8 @@
part '$AUXILIARY_DIR/CanvasImageSource.dart';
part '$AUXILIARY_DIR/CrossFrameTypes.dart';
part '$AUXILIARY_DIR/CssClassSet.dart';
+part '$AUXILIARY_DIR/CssRectangle.dart';
+part '$AUXILIARY_DIR/Dimension.dart';
part '$AUXILIARY_DIR/EventListener.dart';
part '$AUXILIARY_DIR/EventStreamProvider.dart';
part '$AUXILIARY_DIR/ImmutableListMixin.dart';
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index f8973eb..dd64ae7 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -34,6 +34,8 @@
part '$AUXILIARY_DIR/CanvasImageSource.dart';
part '$AUXILIARY_DIR/CrossFrameTypes.dart';
part '$AUXILIARY_DIR/CssClassSet.dart';
+part '$AUXILIARY_DIR/CssRectangle.dart';
+part '$AUXILIARY_DIR/Dimension.dart';
part '$AUXILIARY_DIR/EventListener.dart';
part '$AUXILIARY_DIR/EventStreamProvider.dart';
part '$AUXILIARY_DIR/ImmutableListMixin.dart';
diff --git a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
index cddb5da..984f10d 100644
--- a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
@@ -918,12 +918,17 @@
}
/** Gets the value of "box-sizing" */
- String get boxSizing =>
- getPropertyValue('box-sizing');
+ String get boxSizing => Device.isFirefox ?
+ getPropertyValue('${Device.cssPrefix}box-sizing') :
+ getPropertyValue('box-sizing');
/** Sets the value of "box-sizing" */
void set boxSizing(String value) {
- setProperty('box-sizing', value, '');
+ if (Device.isFirefox) {
+ setProperty('${Device.cssPrefix}box-sizing', value, '');
+ } else {
+ setProperty('box-sizing', value, '');
+ }
}
/** Gets the value of "caption-side" */
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 305d5f2..abe094c 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -157,7 +157,8 @@
/**
* An immutable list containing HTML elements. This list contains some
- * additional methods for ease of CSS manipulation on a group of elements.
+ * additional methods when compared to regular lists for ease of CSS
+ * manipulation on a group of elements.
*/
abstract class ElementList<T extends Element> extends ListBase<T> {
/**
@@ -174,6 +175,63 @@
/** Replace the classes with `value` for every element in this list. */
set classes(Iterable<String> value);
+
+ /**
+ * Access dimensions and position of the Elements in this list.
+ *
+ * Setting the height or width properties will set the height or width
+ * property for all elements in the list. This returns a rectangle with the
+ * dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Getting the height or width returns the height or width of the
+ * first Element in this list.
+ *
+ * Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not.
+ */
+ @Experimental()
+ CssRect get contentEdge;
+
+ /**
+ * Access dimensions and position of the first Element's content + padding box
+ * in this list.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's `innerHeight` value for an element. This
+ * is also a rectangle equalling the dimensions of clientHeight and
+ * clientWidth.
+ */
+ @Experimental()
+ CssRect get paddingEdge;
+
+ /**
+ * Access dimensions and position of the first Element's content + padding +
+ * border box in this list.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's `outerHeight` value for an element.
+ */
+ @Experimental()
+ CssRect get borderEdge;
+
+ /**
+ * Access dimensions and position of the first Element's content + padding +
+ * border + margin box in this list.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's `outerHeight` value for an element.
+ */
+ @Experimental()
+ CssRect get marginEdge;
}
// TODO(jacobr): this is an inefficient implementation but it is hard to see
@@ -182,8 +240,12 @@
// contains Node objects that are not Elements.
class _FrozenElementList<T extends Element> extends ListBase<T> implements ElementList {
final List<Node> _nodeList;
+ // The subset of _nodeList that are Elements.
+ List<Element> _elementList;
- _FrozenElementList._wrap(this._nodeList);
+ _FrozenElementList._wrap(this._nodeList) {
+ _elementList = _nodeList.where((e) => e is Element).toList();
+ }
int get length => _nodeList.length;
@@ -207,12 +269,19 @@
Element get single => _nodeList.single;
- CssClassSet get classes => new _MultiElementCssClassSet(
- _nodeList.where((e) => e is Element));
+ CssClassSet get classes => new _MultiElementCssClassSet(_elementList);
void set classes(Iterable<String> value) {
- _nodeList.where((e) => e is Element).forEach((e) => e.classes = value);
+ _elementList.forEach((e) => e.classes = value);
}
+
+ CssRect get contentEdge => new _ContentCssListRect(_elementList);
+
+ CssRect get paddingEdge => _elementList.first.paddingEdge;
+
+ CssRect get borderEdge => _elementList.first.borderEdge;
+
+ CssRect get marginEdge => _elementList.first.marginEdge;
}
/**
@@ -924,6 +993,79 @@
TemplateElement.decorate(this);
}
+ /**
+ * Access this element's content position.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not.
+ *
+ * _Important_ _note_: use of this method _will_ perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get contentEdge => new _ContentCssRect(this);
+
+ /**
+ * Access the dimensions and position of this element's content + padding box.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's
+ * [innerHeight](http://api.jquery.com/innerHeight/) value for an element.
+ * This is also a rectangle equalling the dimensions of clientHeight and
+ * clientWidth.
+ *
+ * _Important_ _note_: use of this method _will_ perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get paddingEdge => new _PaddingCssRect(this);
+
+ /**
+ * Access the dimensions and position of this element's content + padding +
+ * border box.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's
+ * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+ *
+ * _Important_ _note_: use of this method _will_ perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get borderEdge => new _BorderCssRect(this);
+
+ /**
+ * Access the dimensions and position of this element's content + padding +
+ * border + margin box.
+ *
+ * This returns a rectangle with the dimenions actually available for content
+ * in this element, in pixels, regardless of this element's box-sizing
+ * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+ * will return the same numerical height if the element is hidden or not. This
+ * can be used to retrieve jQuery's
+ * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+ *
+ * _Important_ _note_: use of this method will perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of this property _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+ @Experimental()
+ CssRect get marginEdge => new _MarginCssRect(this);
$!MEMBERS
}