summaryrefslogtreecommitdiff
path: root/src/qml/jsruntime/qv4functionobject.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-03-05 08:40:11 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-07 16:55:12 +0100
commitb8ca4132433c2d1eef0a6cda8be8a1754786702b (patch)
tree4ace1513d0aaaa09b98bcc39f2a4fb2e08e0d59d /src/qml/jsruntime/qv4functionobject.cpp
parentf836b9837dda09c09c2ee3307300998ca5dff5c4 (diff)
downloadqtdeclarative-b8ca4132433c2d1eef0a6cda8be8a1754786702b.tar.gz
Better way of retrieving the prototype property for FunctionObjects
Make sure FunctionObjects always have the prototype property at index 0. This way we can speed up the instanceOf operator even more, and at the same time save 16-28 bytes of memory per FunctionObject. Change-Id: I8527bc8f9dc7b04a9db8395b5f05bab47ddc21ce Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime/qv4functionobject.cpp')
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp75
1 files changed, 22 insertions, 53 deletions
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index f0966492a9..9a3aa331dc 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -75,21 +75,17 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(FunctionObject);
FunctionObject::FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto)
- : Object(createProto ? scope->engine->functionWithProtoClass : scope->engine->functionClass)
+ : Object(scope->engine->functionClass)
, scope(scope)
, function(0)
- , protoCacheClass(0)
- , protoCacheIndex(UINT_MAX)
{
init(name, createProto);
}
FunctionObject::FunctionObject(ExecutionContext *scope, const QString &name, bool createProto)
- : Object(createProto ? scope->engine->functionWithProtoClass : scope->engine->functionClass)
+ : Object(scope->engine->functionClass)
, scope(scope)
, function(0)
- , protoCacheClass(0)
- , protoCacheIndex(UINT_MAX)
{
Scope s(scope);
ScopedValue protectThis(s, this);
@@ -101,8 +97,6 @@ FunctionObject::FunctionObject(ExecutionContext *scope, const ReturnedValue name
: Object(scope->engine->functionClass)
, scope(scope)
, function(0)
- , protoCacheClass(0)
- , protoCacheIndex(UINT_MAX)
{
Scope s(scope);
ScopedValue protectThis(s, this);
@@ -117,6 +111,7 @@ FunctionObject::FunctionObject(InternalClass *ic)
{
needsActivation = false;
strictMode = false;
+ memberData[Index_Prototype].value = Encode::undefined();
}
FunctionObject::~FunctionObject()
@@ -137,6 +132,9 @@ void FunctionObject::init(const StringRef n, bool createProto)
Scoped<Object> proto(s, scope->engine->newObject(scope->engine->protoClass));
proto->memberData[Index_ProtoConstructor].value = this->asReturnedValue();
memberData[Index_Prototype].value = proto.asReturnedValue();
+ } else {
+ // ### Empty or undefined?
+ memberData[Index_Prototype].value = Encode::undefined();
}
ScopedValue v(s, n.asReturnedValue());
@@ -158,13 +156,8 @@ ReturnedValue FunctionObject::newInstance()
ReturnedValue FunctionObject::construct(Managed *that, CallData *)
{
- ExecutionEngine *v4 = that->internalClass->engine;
- Scope scope(v4);
- Scoped<FunctionObject> f(scope, that, Scoped<FunctionObject>::Cast);
-
- InternalClass *ic = f->internalClassForConstructor();
- Scoped<Object> obj(scope, v4->newObject(ic));
- return obj.asReturnedValue();
+ that->internalClass->engine->currentContext()->throwTypeError();
+ return Encode::undefined();
}
ReturnedValue FunctionObject::call(Managed *, CallData *)
@@ -190,43 +183,6 @@ FunctionObject *FunctionObject::creatScriptFunction(ExecutionContext *scope, Fun
return new (scope->engine->memoryManager) SimpleScriptFunction(scope, function, createProto);
}
-ReturnedValue FunctionObject::protoProperty()
-{
- if (protoCacheClass != internalClass) {
- protoCacheClass = internalClass;
- protoCacheIndex = internalClass->find(internalClass->engine->id_prototype);
- }
- if (protoCacheIndex < UINT_MAX) {
- if (internalClass->propertyData.at(protoCacheIndex).isData()) {
- ReturnedValue v = memberData[protoCacheIndex].value.asReturnedValue();
- if (v != protoValue) {
- classForConstructor = 0;
- protoValue = v;
- }
- return v;
- }
- }
- classForConstructor = 0;
- return get(internalClass->engine->id_prototype);
-}
-
-InternalClass *FunctionObject::internalClassForConstructor()
-{
- // need to call this first to ensure we don't use a wrong class
- ReturnedValue proto = protoProperty();
- if (classForConstructor)
- return classForConstructor;
-
- Scope scope(internalClass->engine);
- ScopedObject p(scope, proto);
- if (p)
- classForConstructor = InternalClass::create(scope.engine, Object::staticVTable(), p.getPointer());
- else
- classForConstructor = scope.engine->objectClass;
-
- return classForConstructor;
-}
-
DEFINE_OBJECT_VTABLE(FunctionCtor);
FunctionCtor::FunctionCtor(ExecutionContext *scope)
@@ -395,7 +351,7 @@ ReturnedValue FunctionPrototype::method_bind(CallContext *ctx)
DEFINE_OBJECT_VTABLE(ScriptFunction);
ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
- : FunctionObject(scope, function->name(), true)
+ : SimpleScriptFunction(scope, function, true)
{
setVTable(staticVTable());
@@ -583,6 +539,19 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
return result.asReturnedValue();
}
+InternalClass *SimpleScriptFunction::internalClassForConstructor()
+{
+ ReturnedValue proto = protoProperty();
+ InternalClass *classForConstructor;
+ Scope scope(internalClass->engine);
+ ScopedObject p(scope, proto);
+ if (p)
+ classForConstructor = InternalClass::create(scope.engine, Object::staticVTable(), p.getPointer());
+ else
+ classForConstructor = scope.engine->objectClass;
+
+ return classForConstructor;
+}