vmFunction->sourceFile = irFunction->sourceFile;
if (outer)
- outer->nestedFunctions.append(vmFunction);
+ outer->addNestedFunction(vmFunction);
foreach (const QString *formal, irFunction->formals)
if (formal)
MemoryManager::GCBlocker gcBlocker(memoryManager);
if (!factory) {
-#ifdef V4_ENABLE_JIT
+#if 0
factory = new QQmlJS::MASM::ISelFactory;
#else // !V4_ENABLE_JIT
factory = new QQmlJS::Moth::ISelFactory;
delete bumperPointerAllocator;
delete regExpCache;
UnwindHelper::deregisterFunctions(functions);
- qDeleteAll(functions);
delete regExpAllocator;
delete executableAllocator;
}
Function *ExecutionEngine::newFunction(const QString &name)
{
- Function *f = new Function(newIdentifier(name));
+ Function *f = new Function(this, newIdentifier(name));
functions.append(f);
functionsNeedSort = true;
return f;
#include "qv4managed_p.h"
#include "qv4string_p.h"
#include "qv4value_p.h"
+#include "qv4engine_p.h"
+#include "qv4lookup_p.h"
+#include "qv4unwindhelper_p.h"
QT_BEGIN_NAMESPACE
Function::~Function()
{
+ engine->functions.remove(engine->functions.indexOf(this));
+ UnwindHelper::deregisterFunction(this);
+
+ Q_ASSERT(!refCount);
delete[] codeData;
+ delete[] lookups;
+ foreach (Function *f, nestedFunctions)
+ f->deref();
}
void Function::mark()
};
struct Function {
+ int refCount;
String *name;
Value (*code)(ExecutionContext *, const uchar *);
QString sourceFile;
QVector<LineNumberMapping> lineNumberMappings;
- Function(String *name)
- : name(name)
+ ExecutionEngine *engine;
+
+ Function(ExecutionEngine *engine, String *name)
+ : refCount(0)
+ , name(name)
, code(0)
, codeData(0)
, codeSize(0)
, usesArgumentsObject(false)
, isStrict(false)
, isNamedExpression(false)
+ , engine(engine)
{}
~Function();
+ void ref() { ++refCount; }
+ void deref() { if (!--refCount) delete this; }
+
+ void addNestedFunction(Function *f)
+ {
+ f->ref();
+ nestedFunctions.append(f);
+ }
+
inline bool needsActivation() const { return hasNestedFunctions || hasDirectEval || usesArgumentsObject; }
void mark();
defineReadonlyProperty(scope->engine->id_name, Value::fromString(name));
}
+FunctionObject::~FunctionObject()
+{
+ if (function)
+ function->deref();
+}
+
Value FunctionObject::newInstance()
{
return construct(0, 0);
{
vtbl = &static_vtbl;
this->function = function;
+ this->function->ref();
assert(function);
assert(function->code);
Function *function;
FunctionObject(ExecutionContext *scope, String *name = 0);
+ ~FunctionObject();
Value newInstance();
static const ManagedVTable static_vtbl;
static void markObjects(Managed *that);
static bool hasInstance(Managed *that, const Value &value);
+ static void destroy(Managed *that)
+ { static_cast<FunctionObject*>(that)->~FunctionObject(); }
};
struct FunctionCtor: FunctionObject
{
vtbl = &static_vtbl;
function = f;
+ function->ref();
usesArgumentsObject = function->usesArgumentsObject;
needsActivation = function->needsActivation();
defineReadonlyProperty(scope->engine->id_length, Value::fromInt32(1));
}
+Script::~Script()
+{
+}
+
void Script::parse()
{
if (parsed)
QScopedPointer<EvalInstructionSelection> isel(v4->iselFactory->create(v4, &module));
if (inheritContext)
isel->setUseFastLookups(false);
- if (globalIRCode)
+ if (globalIRCode) {
vmFunction = isel->vmFunction(globalIRCode);
+ }
}
if (!vmFunction)
: sourceFile(source), line(line), column(column), sourceCode(sourceCode)
, scope(engine->rootContext), strictMode(false), inheritContext(true), parsed(false)
, qml(Value::fromObject(qml)), vmFunction(0), parseAsBinding(true) {}
+ ~Script();
QString sourceFile;
int line;
int column;