JSFunction.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  3. * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
  4. * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
  5. * Copyright (C) 2007 Maks Orlovich
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Library General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Library General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Library General Public License
  18. * along with this library; see the file COPYING.LIB. If not, write to
  19. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  20. * Boston, MA 02110-1301, USA.
  21. *
  22. */
  23. #ifndef JSFunction_h
  24. #define JSFunction_h
  25. #include "InternalFunction.h"
  26. #include "JSDestructibleObject.h"
  27. #include "JSScope.h"
  28. #include "ObjectAllocationProfile.h"
  29. #include "Watchpoint.h"
  30. namespace JSC {
  31. class ExecutableBase;
  32. class FunctionExecutable;
  33. class FunctionPrototype;
  34. class JSActivation;
  35. class JSGlobalObject;
  36. class LLIntOffsetsExtractor;
  37. class NativeExecutable;
  38. class SourceCode;
  39. namespace DFG {
  40. class SpeculativeJIT;
  41. class JITCompiler;
  42. }
  43. JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
  44. JS_EXPORT_PRIVATE String getCalculatedDisplayName(CallFrame*, JSObject*);
  45. class JSFunction : public JSDestructibleObject {
  46. friend class JIT;
  47. friend class DFG::SpeculativeJIT;
  48. friend class DFG::JITCompiler;
  49. friend class VM;
  50. public:
  51. typedef JSDestructibleObject Base;
  52. JS_EXPORT_PRIVATE static JSFunction* create(ExecState*, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
  53. static JSFunction* create(ExecState* exec, FunctionExecutable* executable, JSScope* scope)
  54. {
  55. VM& vm = exec->vm();
  56. JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope);
  57. ASSERT(function->structure()->globalObject());
  58. function->finishCreation(vm);
  59. return function;
  60. }
  61. static void destroy(JSCell*);
  62. JS_EXPORT_PRIVATE String name(ExecState*);
  63. JS_EXPORT_PRIVATE String displayName(ExecState*);
  64. const String calculatedDisplayName(ExecState*);
  65. JSScope* scope()
  66. {
  67. ASSERT(!isHostFunctionNonInline());
  68. return m_scope.get();
  69. }
  70. // This method may be called for host functins, in which case it
  71. // will return an arbitrary value. This should only be used for
  72. // optimized paths in which the return value does not matter for
  73. // host functions, and checking whether the function is a host
  74. // function is deemed too expensive.
  75. JSScope* scopeUnchecked()
  76. {
  77. return m_scope.get();
  78. }
  79. void setScope(VM& vm, JSScope* scope)
  80. {
  81. ASSERT(!isHostFunctionNonInline());
  82. m_scope.set(vm, this, scope);
  83. }
  84. ExecutableBase* executable() const { return m_executable.get(); }
  85. // To call either of these methods include Executable.h
  86. inline bool isHostFunction() const;
  87. FunctionExecutable* jsExecutable() const;
  88. JS_EXPORT_PRIVATE const SourceCode* sourceCode() const;
  89. static JS_EXPORTDATA const ClassInfo s_info;
  90. static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
  91. {
  92. ASSERT(globalObject);
  93. return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), &s_info);
  94. }
  95. NativeFunction nativeFunction();
  96. NativeFunction nativeConstructor();
  97. static ConstructType getConstructData(JSCell*, ConstructData&);
  98. static CallType getCallData(JSCell*, CallData&);
  99. static inline ptrdiff_t offsetOfScopeChain()
  100. {
  101. return OBJECT_OFFSETOF(JSFunction, m_scope);
  102. }
  103. static inline ptrdiff_t offsetOfExecutable()
  104. {
  105. return OBJECT_OFFSETOF(JSFunction, m_executable);
  106. }
  107. static inline ptrdiff_t offsetOfAllocationProfile()
  108. {
  109. return OBJECT_OFFSETOF(JSFunction, m_allocationProfile);
  110. }
  111. ObjectAllocationProfile* allocationProfile(ExecState* exec, unsigned inlineCapacity)
  112. {
  113. if (UNLIKELY(m_allocationProfile.isNull()))
  114. return createAllocationProfile(exec, inlineCapacity);
  115. return &m_allocationProfile;
  116. }
  117. ObjectAllocationProfile* tryGetAllocationProfile()
  118. {
  119. if (m_allocationProfile.isNull())
  120. return 0;
  121. if (m_allocationProfileWatchpoint.hasBeenInvalidated())
  122. return 0;
  123. return &m_allocationProfile;
  124. }
  125. void addAllocationProfileWatchpoint(Watchpoint* watchpoint)
  126. {
  127. ASSERT(tryGetAllocationProfile());
  128. m_allocationProfileWatchpoint.add(watchpoint);
  129. }
  130. protected:
  131. const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
  132. JS_EXPORT_PRIVATE JSFunction(ExecState*, JSGlobalObject*, Structure*);
  133. JSFunction(VM&, FunctionExecutable*, JSScope*);
  134. void finishCreation(ExecState*, NativeExecutable*, int length, const String& name);
  135. using Base::finishCreation;
  136. ObjectAllocationProfile* createAllocationProfile(ExecState*, size_t inlineCapacity);
  137. static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
  138. static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
  139. static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode = ExcludeDontEnumProperties);
  140. static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
  141. static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
  142. static bool deleteProperty(JSCell*, ExecState*, PropertyName);
  143. static void visitChildren(JSCell*, SlotVisitor&);
  144. private:
  145. friend class LLIntOffsetsExtractor;
  146. JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
  147. static JSValue argumentsGetter(ExecState*, JSValue, PropertyName);
  148. static JSValue callerGetter(ExecState*, JSValue, PropertyName);
  149. static JSValue lengthGetter(ExecState*, JSValue, PropertyName);
  150. static JSValue nameGetter(ExecState*, JSValue, PropertyName);
  151. WriteBarrier<ExecutableBase> m_executable;
  152. WriteBarrier<JSScope> m_scope;
  153. ObjectAllocationProfile m_allocationProfile;
  154. InlineWatchpointSet m_allocationProfileWatchpoint;
  155. };
  156. } // namespace JSC
  157. #endif // JSFunction_h