|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: set ts=8 sts=4 et sw=4 tw=99: |
|
3 */ |
|
4 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 #include "jscompartment.h" |
|
9 #include "jsgc.h" |
|
10 |
|
11 #include "jsapi-tests/tests.h" |
|
12 #include "vm/Shape.h" |
|
13 |
|
14 BEGIN_TEST(testRegExpInstanceProperties) |
|
15 { |
|
16 jsval regexpProtoVal; |
|
17 EVAL("RegExp.prototype", ®expProtoVal); |
|
18 |
|
19 JSObject *regexpProto = JSVAL_TO_OBJECT(regexpProtoVal); |
|
20 |
|
21 if (!helper(regexpProto)) |
|
22 return false; |
|
23 |
|
24 JS_GC(cx); |
|
25 |
|
26 CHECK_EQUAL(regexpProto->compartment()->initialRegExpShape, nullptr); |
|
27 |
|
28 jsval regexp; |
|
29 EVAL("/foopy/", ®exp); |
|
30 JSObject *robj = JSVAL_TO_OBJECT(regexp); |
|
31 |
|
32 CHECK(robj->lastProperty()); |
|
33 CHECK_EQUAL(robj->compartment()->initialRegExpShape, robj->lastProperty()); |
|
34 |
|
35 return true; |
|
36 } |
|
37 |
|
38 /* |
|
39 * Do this all in a nested function evaluation so as (hopefully) not to get |
|
40 * screwed up by the conservative stack scanner when GCing. |
|
41 */ |
|
42 MOZ_NEVER_INLINE bool helper(JSObject *regexpProto) |
|
43 { |
|
44 CHECK(!regexpProto->inDictionaryMode()); |
|
45 |
|
46 // Verify the compartment's cached shape is being used by RegExp.prototype. |
|
47 const js::Shape *shape = regexpProto->lastProperty(); |
|
48 js::AutoShapeRooter root(cx, shape); |
|
49 for (js::Shape::Range r = shape; |
|
50 &r.front() != regexpProto->compartment()->initialRegExpShape; |
|
51 r.popFront()) |
|
52 { |
|
53 CHECK(!r.empty()); |
|
54 } |
|
55 |
|
56 JS::RootedValue v(cx, INT_TO_JSVAL(17)); |
|
57 CHECK(JS_SetProperty(cx, regexpProto, "foopy", v)); |
|
58 v = INT_TO_JSVAL(42); |
|
59 CHECK(JS_SetProperty(cx, regexpProto, "bunky", v)); |
|
60 CHECK(JS_DeleteProperty(cx, regexpProto, "foopy")); |
|
61 CHECK(regexpProto->inDictionaryMode()); |
|
62 |
|
63 const js::Shape *shape2 = regexpProto->lastProperty(); |
|
64 js::AutoShapeRooter root2(cx, shape2); |
|
65 js::Shape::Range r2 = shape2; |
|
66 while (!r2.empty()) { |
|
67 CHECK(&r2.front() != regexpProto->compartment()->initialRegExpShape); |
|
68 r2.popFront(); |
|
69 } |
|
70 |
|
71 return true; |
|
72 } |
|
73 END_TEST(testRegExpInstanceProperties) |