diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/runtime/InternalFunction.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/runtime/InternalFunction.cpp')
-rw-r--r-- | Source/JavaScriptCore/runtime/InternalFunction.cpp | 80 |
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 |