Make the RegExp.prototype object be a RegExp object.

BUG=v8:1217
TEST=mjsunit/regress/regress-1217

Review URL: http://codereview.chromium.org/8041015

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9419 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
lrn@chromium.org 2011-09-26 08:42:01 +00:00
parent e6509e77d2
commit b9d39c48b8
5 changed files with 52 additions and 27 deletions

View File

@ -995,6 +995,26 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
initial_map->instance_size() + 5 * kPointerSize);
initial_map->set_instance_descriptors(*descriptors);
initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
// RegExp prototype object is itself a RegExp.
Handle<Map> proto_map = factory->CopyMapDropTransitions(initial_map);
proto_map->set_prototype(global_context()->initial_object_prototype());
Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex,
heap->empty_string());
proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex,
heap->false_value());
proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex,
heap->false_value());
proto->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex,
heap->false_value());
proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
Smi::FromInt(0),
SKIP_WRITE_BARRIER); // It's a Smi.
initial_map->set_prototype(*proto);
factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto),
JSRegExp::IRREGEXP, factory->empty_string(),
JSRegExp::Flags(0), 0);
}
{ // -- J S O N

View File

@ -95,12 +95,11 @@ function RegExpConstructor(pattern, flags) {
}
}
// Deprecated RegExp.prototype.compile method. We behave like the constructor
// were called again. In SpiderMonkey, this method returns the regexp object.
// In JSC, it returns undefined. For compatibility with JSC, we match their
// behavior.
function CompileRegExp(pattern, flags) {
function RegExpCompile(pattern, flags) {
// Both JSC and SpiderMonkey treat a missing pattern argument as the
// empty subject string, and an actual undefined value passed as the
// pattern as the string 'undefined'. Note that JSC is inconsistent
@ -108,6 +107,11 @@ function CompileRegExp(pattern, flags) {
// RegExp.prototype.compile and in the constructor, where they are
// the empty string. For compatibility with JSC, we match their
// behavior.
if (this == $RegExp.prototype) {
// We don't allow recompiling RegExp.prototype.
throw MakeTypeError('incompatible_method_receiver',
['RegExp.prototype.compile', this]);
}
if (IS_UNDEFINED(pattern) && %_ArgumentsLength() != 0) {
DoConstructRegExp(this, 'undefined', flags);
} else {
@ -408,7 +412,6 @@ var lastMatchInfoOverride = null;
function SetUpRegExp() {
%CheckIsBootstrapping();
%FunctionSetInstanceClassName($RegExp, 'RegExp');
%FunctionSetPrototype($RegExp, new $Object());
%SetProperty($RegExp.prototype, 'constructor', $RegExp, DONT_ENUM);
%SetCode($RegExp, RegExpConstructor);
@ -416,7 +419,7 @@ function SetUpRegExp() {
"exec", RegExpExec,
"test", RegExpTest,
"toString", RegExpToString,
"compile", CompileRegExp
"compile", RegExpCompile
));
// The length of compile is 1 in SpiderMonkey.

View File

@ -96,9 +96,6 @@ chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-7: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-11: FAIL_OK
# We do not implement all methods on RegExp.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-13: FAIL
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-14: FAIL_OK
@ -191,22 +188,6 @@ chapter15/15.5/15.5.4/15.5.4.20/15.5.4.20-4-10: FAIL
chapter15/15.5/15.5.4/15.5.4.20/15.5.4.20-4-18: FAIL
chapter15/15.5/15.5.4/15.5.4.20/15.5.4.20-4-34: FAIL
# RegExp.prototype is not of type RegExp - we are bug compatible with JSC.
chapter15/15.10/15.10.6/15.10.6: FAIL_OK
# We do not have the properties of a RegExp instance on RegExp.prototype.
# The spec says we should - but we are currently bug compatible with JSC.
chapter15/15.10/15.10.7/15.10.7.1/15.10.7.1-1: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.1/15.10.7.1-2: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.2/15.10.7.2-1: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.2/15.10.7.2-2: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.3/15.10.7.3-1: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.3/15.10.7.3-2: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.4/15.10.7.4-1: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.4/15.10.7.4-2: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.5/15.10.7.5-1: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.5/15.10.7.5-2: FAIL_OK
##############################################################################
# Unimplemented parts of strict mode
# Setting expectations to fail only so that the tests trigger as soon as

View File

@ -25,8 +25,26 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Check conformity to ECMA-262 15.10.6.
// The class of RegExp's prototype is RegExp.
// Check that RegExp.prototype is itself a RegExp object.
var prototype_class = ({}).toString.call(RegExp.prototype);
assertEquals("[object RegExp]", prototype_class);
var proto = RegExp.prototype;
assertEquals("[object RegExp]", Object.prototype.toString.call(proto));
assertEquals("", proto.source);
assertEquals(false, proto.global);
assertEquals(false, proto.multiline);
assertEquals(false, proto.ignoreCase);
assertEquals(0, proto.lastIndex);
assertEquals("/(?:)/", proto.toString());
var execResult = proto.exec("argle");
assertEquals(1, execResult.length);
assertEquals("", execResult[0]);
assertEquals("argle", execResult.input);
assertEquals(0, execResult.index);
assertTrue(proto.test("argle"));
// We disallow re-compiling the RegExp.prototype object.
assertThrows(function(){ proto.compile("something"); }, TypeError);

View File

@ -52,6 +52,9 @@ S15.10.6.2_A1_T16: FAIL_OK
S15.10.6.2_A12: FAIL_OK
S15.10.6.3_A1_T16: FAIL_OK
# Sputnik tests (r97) assume RegExp.prototype is an Object, not a RegExp.
S15.10.6_A2: FAIL_OK
# We are silent in some regexp cases where the spec wants us to give
# errors, for compatibility.
S15.10.2.11_A1_T2: FAIL