InternalFunction.cpp [plain text]
#include "config.h"
#include "InternalFunction.h"
#include "FunctionPrototype.h"
#include "JSGlobalObject.h"
#include "JSString.h"
#include "JSCInlines.h"
namespace JSC {
STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(InternalFunction);
const ClassInfo InternalFunction::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(InternalFunction) };
InternalFunction::InternalFunction(VM& vm, Structure* structure)
: JSDestructibleObject(vm, structure)
{
}
void InternalFunction::finishCreation(VM& vm, const String& name)
{
Base::finishCreation(vm);
ASSERT(inherits(info()));
ASSERT(methodTable()->getCallData != InternalFunction::info()->methodTable.getCallData);
JSString* nameString = jsString(&vm, name);
m_originalName.set(vm, this, nameString);
putDirect(vm, vm.propertyNames->name, nameString, ReadOnly | DontEnum);
}
void InternalFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
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); return name;
}
const String InternalFunction::displayName(VM& vm)
{
JSValue displayName = getDirect(vm, vm.propertyNames->displayName);
if (displayName && isJSString(displayName))
return asString(displayName)->tryGetValue();
return String();
}
CallType InternalFunction::getCallData(JSCell*, CallData&)
{
RELEASE_ASSERT_NOT_REACHED();
return CallType::None;
}
const String InternalFunction::calculatedDisplayName(VM& vm)
{
const String explicitName = displayName(vm);
if (!explicitName.isEmpty())
return explicitName;
return name();
}
Structure* InternalFunction::createSubclassStructure(ExecState* exec, JSValue newTarget, Structure* baseClass)
{
VM& vm = exec->vm();
ASSERT(!newTarget || newTarget.isConstructor());
if (newTarget && newTarget != exec->callee()) {
JSFunction* targetFunction = jsDynamicCast<JSFunction*>(newTarget);
if (LIKELY(targetFunction)) {
Structure* structure = targetFunction->rareData(vm)->internalFunctionAllocationStructure();
if (LIKELY(structure && structure->classInfo() == baseClass->classInfo()))
return structure;
JSValue prototypeValue = newTarget.get(exec, exec->propertyNames().prototype);
if (UNLIKELY(vm.exception()))
return nullptr;
if (JSObject* prototype = jsDynamicCast<JSObject*>(prototypeValue))
return targetFunction->rareData(vm)->createInternalFunctionAllocationStructureFromBase(vm, prototype, baseClass);
} else {
JSValue prototypeValue = newTarget.get(exec, exec->propertyNames().prototype);
if (UNLIKELY(vm.exception()))
return nullptr;
if (JSObject* prototype = jsDynamicCast<JSObject*>(prototypeValue)) {
return vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(prototype, baseClass);
}
}
}
return baseClass;
}
}