summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/InternalFunction.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/runtime/InternalFunction.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/runtime/InternalFunction.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/InternalFunction.cpp80
1 files changed, 67 insertions, 13 deletions
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.cpp b/Source/JavaScriptCore/runtime/InternalFunction.cpp
index 69120bea5..7b8b76f47 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.cpp
+++ b/Source/JavaScriptCore/runtime/InternalFunction.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2007-2008, 2016-2017 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,35 +26,50 @@
#include "FunctionPrototype.h"
#include "JSGlobalObject.h"
#include "JSString.h"
-#include "Operations.h"
+#include "JSCInlines.h"
namespace JSC {
STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(InternalFunction);
-const ClassInfo InternalFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) };
+const ClassInfo InternalFunction::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(InternalFunction) };
InternalFunction::InternalFunction(VM& vm, Structure* structure)
: JSDestructibleObject(vm, structure)
{
+ // exec->vm() wants callees to not be large allocations.
+ RELEASE_ASSERT(!isLargeAllocation());
}
void InternalFunction::finishCreation(VM& vm, const String& name)
{
Base::finishCreation(vm);
- ASSERT(inherits(info()));
+ ASSERT(inherits(vm, info()));
ASSERT(methodTable()->getCallData != InternalFunction::info()->methodTable.getCallData);
- putDirect(vm, vm.propertyNames->name, jsString(&vm, name), DontDelete | ReadOnly | DontEnum);
+ JSString* nameString = jsString(&vm, name);
+ m_originalName.set(vm, this, nameString);
+ putDirect(vm, vm.propertyNames->name, nameString, ReadOnly | DontEnum);
}
-const String& InternalFunction::name(ExecState* exec)
+void InternalFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
- return asString(getDirect(exec->vm(), exec->vm().propertyNames->name))->tryGetValue();
+ InternalFunction* thisObject = jsCast<InternalFunction*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitChildren(thisObject, visitor);
+
+ visitor.append(thisObject->m_originalName);
+}
+
+const String& InternalFunction::name()
+{
+ const String& name = m_originalName->tryGetValue();
+ ASSERT(name); // m_originalName was built from a String, and hence, there is no rope to resolve.
+ return name;
}
-const String InternalFunction::displayName(ExecState* exec)
+const String InternalFunction::displayName(VM& vm)
{
- JSValue displayName = getDirect(exec->vm(), exec->vm().propertyNames->displayName);
+ JSValue displayName = getDirect(vm, vm.propertyNames->displayName);
if (displayName && isJSString(displayName))
return asString(displayName)->tryGetValue();
@@ -65,17 +80,56 @@ const String InternalFunction::displayName(ExecState* exec)
CallType InternalFunction::getCallData(JSCell*, CallData&)
{
RELEASE_ASSERT_NOT_REACHED();
- return CallTypeNone;
+ return CallType::None;
}
-const String InternalFunction::calculatedDisplayName(ExecState* exec)
+const String InternalFunction::calculatedDisplayName(VM& vm)
{
- const String explicitName = displayName(exec);
+ const String explicitName = displayName(vm);
if (!explicitName.isEmpty())
return explicitName;
- return name(exec);
+ return name();
}
+Structure* InternalFunction::createSubclassStructure(ExecState* exec, JSValue newTarget, Structure* baseClass)
+{
+
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ // We allow newTarget == JSValue() because the API needs to be able to create classes without having a real JS frame.
+ // Since we don't allow subclassing in the API we just treat newTarget == JSValue() as newTarget == exec->jsCallee()
+ ASSERT(!newTarget || newTarget.isConstructor());
+
+ if (newTarget && newTarget != exec->jsCallee()) {
+ // newTarget may be an InternalFunction if we were called from Reflect.construct.
+ JSFunction* targetFunction = jsDynamicCast<JSFunction*>(vm, newTarget);
+ JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
+
+ if (LIKELY(targetFunction)) {
+ Structure* structure = targetFunction->rareData(vm)->internalFunctionAllocationStructure();
+ if (LIKELY(structure && structure->classInfo() == baseClass->classInfo()))
+ return structure;
+
+ // Note, Reflect.construct might cause the profile to churn but we don't care.
+ JSValue prototypeValue = newTarget.get(exec, exec->propertyNames().prototype);
+ RETURN_IF_EXCEPTION(scope, nullptr);
+ if (JSObject* prototype = jsDynamicCast<JSObject*>(vm, prototypeValue))
+ return targetFunction->rareData(vm)->createInternalFunctionAllocationStructureFromBase(vm, lexicalGlobalObject, prototype, baseClass);
+ } else {
+ JSValue prototypeValue = newTarget.get(exec, exec->propertyNames().prototype);
+ RETURN_IF_EXCEPTION(scope, nullptr);
+ if (JSObject* prototype = jsDynamicCast<JSObject*>(vm, prototypeValue)) {
+ // This only happens if someone Reflect.constructs our builtin constructor with another builtin constructor as the new.target.
+ // Thus, we don't care about the cost of looking up the structure from our hash table every time.
+ return vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(lexicalGlobalObject, prototype, baseClass);
+ }
+ }
+ }
+
+ return baseClass;
+}
+
+
} // namespace JSC