Fix values of RegExp.lastIndex property
authorSimon Hausmann <simon.hausmann@digia.com>
Thu, 17 Jan 2013 14:24:58 +0000 (15:24 +0100)
committerLars Knoll <lars.knoll@digia.com>
Thu, 17 Jan 2013 20:00:24 +0000 (21:00 +0100)
The property should be writable and also set to 0 if no match is found.

Change-Id: I4288ad239980260c7610c5de0061cc42ac38bb7a
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
qmljs_engine.cpp
qmljs_objects.cpp
qmljs_objects.h
qv4ecmaobjects.cpp
qv4ecmaobjects_p.h
tests/TestExpectations

index a1f99f5..b58ff12 100644 (file)
@@ -104,7 +104,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
     arrayPrototype = new (memoryManager) ArrayPrototype(rootContext);
     datePrototype = new (memoryManager) DatePrototype();
     functionPrototype = new (memoryManager) FunctionPrototype(rootContext);
-    regExpPrototype = new (memoryManager) RegExpPrototype();
+    regExpPrototype = new (memoryManager) RegExpPrototype(this);
     errorPrototype = new (memoryManager) ErrorPrototype();
     evalErrorPrototype = new (memoryManager) EvalErrorPrototype(rootContext);
     rangeErrorPrototype = new (memoryManager) RangeErrorPrototype(rootContext);
@@ -369,7 +369,7 @@ RegExpObject *ExecutionEngine::newRegExpObject(const QString &pattern, int flags
 
 RegExpObject *ExecutionEngine::newRegExpObject(PassRefPtr<RegExp> re, bool global)
 {
-    RegExpObject *object = new (memoryManager) RegExpObject(re, global);
+    RegExpObject *object = new (memoryManager) RegExpObject(this, re, global);
     object->prototype = regExpPrototype;
     return object;
 }
index 3a700e2..5e3e0ef 100644 (file)
@@ -1105,6 +1105,20 @@ Value IsFiniteFunction::call(ExecutionContext *context, Value /*thisObject*/, Va
 }
 
 
+RegExpObject::RegExpObject(ExecutionEngine *engine, PassRefPtr<RegExp> value, bool global)
+    : value(value)
+    , global(global)
+{
+    if (!members)
+        members.reset(new PropertyTable());
+    lastIndexProperty = members->insert(engine->identifier("lastIndex"));
+    lastIndexProperty->type = PropertyDescriptor::Data;
+    lastIndexProperty->writable = PropertyDescriptor::Enabled;
+    lastIndexProperty->enumberable = PropertyDescriptor::Disabled;
+    lastIndexProperty->configurable = PropertyDescriptor::Disabled;
+    lastIndexProperty->value = Value::fromInt32(0);
+}
+
 Value RegExpObject::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
 {
     QString n = name->toQString();
@@ -1117,8 +1131,6 @@ Value RegExpObject::__get__(ExecutionContext *ctx, String *name, bool *hasProper
         v = Value::fromBoolean(value->ignoreCase());
     else if (n == QLatin1String("multiline"))
         v = Value::fromBoolean(value->multiLine());
-    else if (n == QLatin1String("lastIndex"))
-        v = lastIndex;
     if (v.type() != Value::Undefined_Type) {
         if (hasProperty)
             *hasProperty = true;
index 362fe70..01773ee 100644 (file)
@@ -361,9 +361,9 @@ struct IsFiniteFunction: FunctionObject
 
 struct RegExpObject: Object {
     RefPtr<RegExp> value;
-    Value lastIndex;
+    PropertyDescriptor *lastIndexProperty;
     bool global;
-    RegExpObject(PassRefPtr<RegExp> value, bool global): value(value), lastIndex(Value::fromInt32(0)), global(global) {}
+    RegExpObject(ExecutionEngine *engine, PassRefPtr<RegExp> value, bool global);
     virtual QString className() { return QStringLiteral("RegExp"); }
     virtual RegExpObject *asRegExpObject() { return this; }
     virtual Value __get__(ExecutionContext *ctx, String *name, bool *hasProperty);
index 84b536d..7cf5f52 100644 (file)
@@ -2985,14 +2985,18 @@ Value RegExpPrototype::method_exec(ExecutionContext *ctx)
     arg = __qmljs_to_string(arg, ctx);
     QString s = arg.stringValue()->toQString();
 
-    int offset = r->global ? r->lastIndex.toInt32(ctx) : 0;
-    if (offset < 0 || offset > s.length())
+    int offset = r->global ? r->lastIndexProperty->value.toInt32(ctx) : 0;
+    if (offset < 0 || offset > s.length()) {
+        r->lastIndexProperty->value = Value::fromInt32(0);
         return Value::nullValue();
+    }
 
     uint* matchOffsets = (uint*)alloca(r->value->captureCount() * 2 * sizeof(uint));
     int result = r->value->match(s, offset, matchOffsets);
-    if (result == -1)
+    if (result == -1) {
+        r->lastIndexProperty->value = Value::fromInt32(0);
         return Value::nullValue();
+    }
 
     // fill in result data
     ArrayObject *array = ctx->engine->newArrayObject(ctx)->asArrayObject();
@@ -3009,7 +3013,7 @@ Value RegExpPrototype::method_exec(ExecutionContext *ctx)
     array->__put__(ctx, QLatin1String("input"), arg);
 
     if (r->global)
-        r->lastIndex = Value::fromInt32(matchOffsets[1]);
+        r->lastIndexProperty->value = Value::fromInt32(matchOffsets[1]);
 
     return Value::fromObject(array);
 }
index 0576eb4..55890ef 100644 (file)
@@ -295,7 +295,7 @@ struct RegExpCtor: FunctionObject
 
 struct RegExpPrototype: RegExpObject
 {
-    RegExpPrototype(): RegExpObject(RegExp::create(0, QString()), false) {}
+    RegExpPrototype(ExecutionEngine* engine): RegExpObject(engine, RegExp::create(0, QString()), false) {}
     void init(ExecutionContext *ctx, const Value &ctor);
 
     static Value method_exec(ExecutionContext *ctx);
index 7d90fd6..4319e5b 100644 (file)
@@ -312,21 +312,6 @@ S15.10.2.12_A4_T1 failing
 S15.10.2.12_A5_T1 failing
 S15.10.2.8_A3_T18 failing
 S15.10.6.2_A1_T2 failing
-S15.10.6.2_A4_T1 failing
-S15.10.6.2_A4_T10 failing
-S15.10.6.2_A4_T11 failing
-S15.10.6.2_A4_T12 failing
-S15.10.6.2_A4_T2 failing
-S15.10.6.2_A4_T3 failing
-S15.10.6.2_A4_T4 failing
-S15.10.6.2_A4_T5 failing
-S15.10.6.2_A4_T6 failing
-S15.10.6.2_A4_T7 failing
-S15.10.6.2_A4_T8 failing
-S15.10.6.2_A4_T9 failing
-S15.10.6.2_A5_T1 failing
-S15.10.6.2_A5_T2 failing
-S15.10.6.2_A5_T3 failing
 S15.10.7_A2_T1 failing
 15.10.7.1-2 failing
 S15.10.7.1_A10 failing
@@ -344,9 +329,6 @@ S15.10.7.3_A9 failing
 S15.10.7.4_A10 failing
 S15.10.7.4_A8 failing
 S15.10.7.4_A9 failing
-15.10.7.5-2 failing
-S15.10.7.5_A8 failing
-S15.10.7.5_A9 failing
 S15.11.4.2_A1 failing
 S15.11.4.2_A2 failing
 S15.11.4.3_A1 failing