1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jsapi-tests/testRegExpInstanceProperties.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,73 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + */ 1.7 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +#include "jscompartment.h" 1.12 +#include "jsgc.h" 1.13 + 1.14 +#include "jsapi-tests/tests.h" 1.15 +#include "vm/Shape.h" 1.16 + 1.17 +BEGIN_TEST(testRegExpInstanceProperties) 1.18 +{ 1.19 + jsval regexpProtoVal; 1.20 + EVAL("RegExp.prototype", ®expProtoVal); 1.21 + 1.22 + JSObject *regexpProto = JSVAL_TO_OBJECT(regexpProtoVal); 1.23 + 1.24 + if (!helper(regexpProto)) 1.25 + return false; 1.26 + 1.27 + JS_GC(cx); 1.28 + 1.29 + CHECK_EQUAL(regexpProto->compartment()->initialRegExpShape, nullptr); 1.30 + 1.31 + jsval regexp; 1.32 + EVAL("/foopy/", ®exp); 1.33 + JSObject *robj = JSVAL_TO_OBJECT(regexp); 1.34 + 1.35 + CHECK(robj->lastProperty()); 1.36 + CHECK_EQUAL(robj->compartment()->initialRegExpShape, robj->lastProperty()); 1.37 + 1.38 + return true; 1.39 +} 1.40 + 1.41 +/* 1.42 + * Do this all in a nested function evaluation so as (hopefully) not to get 1.43 + * screwed up by the conservative stack scanner when GCing. 1.44 + */ 1.45 +MOZ_NEVER_INLINE bool helper(JSObject *regexpProto) 1.46 +{ 1.47 + CHECK(!regexpProto->inDictionaryMode()); 1.48 + 1.49 + // Verify the compartment's cached shape is being used by RegExp.prototype. 1.50 + const js::Shape *shape = regexpProto->lastProperty(); 1.51 + js::AutoShapeRooter root(cx, shape); 1.52 + for (js::Shape::Range r = shape; 1.53 + &r.front() != regexpProto->compartment()->initialRegExpShape; 1.54 + r.popFront()) 1.55 + { 1.56 + CHECK(!r.empty()); 1.57 + } 1.58 + 1.59 + JS::RootedValue v(cx, INT_TO_JSVAL(17)); 1.60 + CHECK(JS_SetProperty(cx, regexpProto, "foopy", v)); 1.61 + v = INT_TO_JSVAL(42); 1.62 + CHECK(JS_SetProperty(cx, regexpProto, "bunky", v)); 1.63 + CHECK(JS_DeleteProperty(cx, regexpProto, "foopy")); 1.64 + CHECK(regexpProto->inDictionaryMode()); 1.65 + 1.66 + const js::Shape *shape2 = regexpProto->lastProperty(); 1.67 + js::AutoShapeRooter root2(cx, shape2); 1.68 + js::Shape::Range r2 = shape2; 1.69 + while (!r2.empty()) { 1.70 + CHECK(&r2.front() != regexpProto->compartment()->initialRegExpShape); 1.71 + r2.popFront(); 1.72 + } 1.73 + 1.74 + return true; 1.75 +} 1.76 +END_TEST(testRegExpInstanceProperties)