Fix crash when using the built-in regexp syntax
authorSimon Hausmann <simon.hausmann@digia.com>
Wed, 23 Jan 2013 10:50:01 +0000 (11:50 +0100)
committerLars Knoll <lars.knoll@digia.com>
Wed, 23 Jan 2013 12:11:48 +0000 (13:11 +0100)
When /someregexp/ appears in the source, we generate a new regexp
object in the MASM back-end at run-time. That object is memory
managed but it's never marked, because we only store its address
in the generated code.

This patch adds a way for the code generator to collect values that
are generated like this and encoded only in the code directly, and
therefore require extra book-keeping when collecting the roots.

Change-Id: Ia4cc3f4578e2e7e4378ea7ab1a32c66f0e6ab4bf
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
qv4functionobject.h
qv4isel_masm.cpp
qv4isel_masm_p.h
qv4mm.cpp

index 912c103..95e06e1 100644 (file)
@@ -107,6 +107,7 @@ struct Function {
 
     QList<QString> formals;
     QList<QString> locals;
+    QVector<Value> generatedValues;
 
     bool hasNestedFunctions  : 1;
     bool hasDirectEval       : 1;
index 3aead74..2e60f72 100644 (file)
@@ -370,6 +370,7 @@ InstructionSelection::InstructionSelection(VM::ExecutionEngine *engine, IR::Modu
     : EvalInstructionSelection(engine, module)
     , _block(0)
     , _function(0)
+    , _vmFunction(0)
     , _asm(0)
 {
 }
@@ -382,6 +383,7 @@ InstructionSelection::~InstructionSelection()
 void InstructionSelection::run(VM::Function *vmFunction, IR::Function *function)
 {
     qSwap(_function, function);
+    qSwap(_vmFunction, vmFunction);
     Assembler* oldAssembler = _asm;
     _asm = new Assembler(_function);
 
@@ -423,8 +425,9 @@ void InstructionSelection::run(VM::Function *vmFunction, IR::Function *function)
 #endif
     _asm->ret();
 
-    _asm->link(vmFunction);
+    _asm->link(_vmFunction);
 
+    qSwap(_vmFunction, vmFunction);
     qSwap(_function, function);
     delete _asm;
     _asm = oldAssembler;
@@ -570,6 +573,7 @@ void InstructionSelection::loadRegexp(IR::RegExp *sourceRegexp, IR::Temp *target
 {
     Value v = Value::fromObject(engine()->newRegExpObject(*sourceRegexp->value,
                                                           sourceRegexp->flags));
+    _vmFunction->generatedValues.append(v);
     _asm->storeValue(v, targetTemp);
 }
 
index 3d18036..2300377 100644 (file)
@@ -748,6 +748,7 @@ private:
 
     IR::BasicBlock *_block;
     IR::Function* _function;
+    VM::Function* _vmFunction;
     Assembler* _asm;
 };
 
index 6521ff5..f624cec 100644 (file)
--- a/qv4mm.cpp
+++ b/qv4mm.cpp
@@ -350,6 +350,12 @@ void MemoryManager::collectRoots(QVector<VM::Object *> &roots) const
                 roots.append(it->object);
     }
 
+    for (int i = 0; i < m_d->engine->functions.size(); ++i) {
+        Function* f = m_d->engine->functions.at(i);
+        for (int k = 0; k < f->generatedValues.count(); ++k)
+            add(roots, f->generatedValues.at(k));
+    }
+
     collectRootsOnStack(roots);
 }