From f71bf94fc9b78309ca237c33f9b0a7a726a6afea Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 23 Jan 2013 11:50:01 +0100 Subject: [PATCH] Fix crash when using the built-in regexp syntax 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 --- qv4functionobject.h | 1 + qv4isel_masm.cpp | 6 +++++- qv4isel_masm_p.h | 1 + qv4mm.cpp | 6 ++++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/qv4functionobject.h b/qv4functionobject.h index 912c103..95e06e1 100644 --- a/qv4functionobject.h +++ b/qv4functionobject.h @@ -107,6 +107,7 @@ struct Function { QList formals; QList locals; + QVector generatedValues; bool hasNestedFunctions : 1; bool hasDirectEval : 1; diff --git a/qv4isel_masm.cpp b/qv4isel_masm.cpp index 3aead74..2e60f72 100644 --- a/qv4isel_masm.cpp +++ b/qv4isel_masm.cpp @@ -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); } diff --git a/qv4isel_masm_p.h b/qv4isel_masm_p.h index 3d18036..2300377 100644 --- a/qv4isel_masm_p.h +++ b/qv4isel_masm_p.h @@ -748,6 +748,7 @@ private: IR::BasicBlock *_block; IR::Function* _function; + VM::Function* _vmFunction; Assembler* _asm; }; diff --git a/qv4mm.cpp b/qv4mm.cpp index 6521ff5..f624cec 100644 --- a/qv4mm.cpp +++ b/qv4mm.cpp @@ -350,6 +350,12 @@ void MemoryManager::collectRoots(QVector &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); } -- 2.7.4