1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_BUILTINS_H_ 29 #define V8_BUILTINS_H_ 30 31 namespace v8 { 32 namespace internal { 33 34 // Specifies extra arguments required by a C++ builtin. 35 enum BuiltinExtraArguments { 36 NO_EXTRA_ARGUMENTS = 0, 37 NEEDS_CALLED_FUNCTION = 1 38 }; 39 40 41 // Define list of builtins implemented in C++. 42 #define BUILTIN_LIST_C(V) \ 43 V(Illegal, NO_EXTRA_ARGUMENTS) \ 44 \ 45 V(EmptyFunction, NO_EXTRA_ARGUMENTS) \ 46 \ 47 V(ArrayCodeGeneric, NO_EXTRA_ARGUMENTS) \ 48 \ 49 V(ArrayPush, NO_EXTRA_ARGUMENTS) \ 50 V(ArrayPop, NO_EXTRA_ARGUMENTS) \ 51 V(ArrayShift, NO_EXTRA_ARGUMENTS) \ 52 V(ArrayUnshift, NO_EXTRA_ARGUMENTS) \ 53 V(ArraySlice, NO_EXTRA_ARGUMENTS) \ 54 V(ArraySplice, NO_EXTRA_ARGUMENTS) \ 55 \ 56 V(HandleApiCall, NEEDS_CALLED_FUNCTION) \ 57 V(FastHandleApiCall, NO_EXTRA_ARGUMENTS) \ 58 V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION) \ 59 V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS) \ 60 V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS) 61 62 63 // Define list of builtins implemented in assembly. 64 #define BUILTIN_LIST_A(V) \ 65 V(ArgumentsAdaptorTrampoline, BUILTIN, UNINITIALIZED) \ 66 V(JSConstructCall, BUILTIN, UNINITIALIZED) \ 67 V(JSConstructStubGeneric, BUILTIN, UNINITIALIZED) \ 68 V(JSConstructStubApi, BUILTIN, UNINITIALIZED) \ 69 V(JSEntryTrampoline, BUILTIN, UNINITIALIZED) \ 70 V(JSConstructEntryTrampoline, BUILTIN, UNINITIALIZED) \ 71 \ 72 V(LoadIC_Miss, BUILTIN, UNINITIALIZED) \ 73 V(KeyedLoadIC_Miss, BUILTIN, UNINITIALIZED) \ 74 V(StoreIC_Miss, BUILTIN, UNINITIALIZED) \ 75 V(KeyedStoreIC_Miss, BUILTIN, UNINITIALIZED) \ 76 \ 77 V(LoadIC_Initialize, LOAD_IC, UNINITIALIZED) \ 78 V(LoadIC_PreMonomorphic, LOAD_IC, PREMONOMORPHIC) \ 79 V(LoadIC_Normal, LOAD_IC, MONOMORPHIC) \ 80 V(LoadIC_ArrayLength, LOAD_IC, MONOMORPHIC) \ 81 V(LoadIC_StringLength, LOAD_IC, MONOMORPHIC) \ 82 V(LoadIC_FunctionPrototype, LOAD_IC, MONOMORPHIC) \ 83 V(LoadIC_Megamorphic, LOAD_IC, MEGAMORPHIC) \ 84 \ 85 V(KeyedLoadIC_Initialize, KEYED_LOAD_IC, UNINITIALIZED) \ 86 V(KeyedLoadIC_PreMonomorphic, KEYED_LOAD_IC, PREMONOMORPHIC) \ 87 V(KeyedLoadIC_Generic, KEYED_LOAD_IC, MEGAMORPHIC) \ 88 V(KeyedLoadIC_String, KEYED_LOAD_IC, MEGAMORPHIC) \ 89 V(KeyedLoadIC_ExternalByteArray, KEYED_LOAD_IC, MEGAMORPHIC) \ 90 V(KeyedLoadIC_ExternalUnsignedByteArray, KEYED_LOAD_IC, MEGAMORPHIC) \ 91 V(KeyedLoadIC_ExternalShortArray, KEYED_LOAD_IC, MEGAMORPHIC) \ 92 V(KeyedLoadIC_ExternalUnsignedShortArray, KEYED_LOAD_IC, MEGAMORPHIC) \ 93 V(KeyedLoadIC_ExternalIntArray, KEYED_LOAD_IC, MEGAMORPHIC) \ 94 V(KeyedLoadIC_ExternalUnsignedIntArray, KEYED_LOAD_IC, MEGAMORPHIC) \ 95 V(KeyedLoadIC_ExternalFloatArray, KEYED_LOAD_IC, MEGAMORPHIC) \ 96 V(KeyedLoadIC_IndexedInterceptor, KEYED_LOAD_IC, MEGAMORPHIC) \ 97 \ 98 V(StoreIC_Initialize, STORE_IC, UNINITIALIZED) \ 99 V(StoreIC_Megamorphic, STORE_IC, MEGAMORPHIC) \ 100 \ 101 V(KeyedStoreIC_Initialize, KEYED_STORE_IC, UNINITIALIZED) \ 102 V(KeyedStoreIC_Generic, KEYED_STORE_IC, MEGAMORPHIC) \ 103 V(KeyedStoreIC_ExternalByteArray, KEYED_STORE_IC, MEGAMORPHIC) \ 104 V(KeyedStoreIC_ExternalUnsignedByteArray, KEYED_STORE_IC, MEGAMORPHIC) \ 105 V(KeyedStoreIC_ExternalShortArray, KEYED_STORE_IC, MEGAMORPHIC) \ 106 V(KeyedStoreIC_ExternalUnsignedShortArray, KEYED_STORE_IC, MEGAMORPHIC) \ 107 V(KeyedStoreIC_ExternalIntArray, KEYED_STORE_IC, MEGAMORPHIC) \ 108 V(KeyedStoreIC_ExternalUnsignedIntArray, KEYED_STORE_IC, MEGAMORPHIC) \ 109 V(KeyedStoreIC_ExternalFloatArray, KEYED_STORE_IC, MEGAMORPHIC) \ 110 \ 111 /* Uses KeyedLoadIC_Initialize; must be after in list. */ \ 112 V(FunctionCall, BUILTIN, UNINITIALIZED) \ 113 V(FunctionApply, BUILTIN, UNINITIALIZED) \ 114 \ 115 V(ArrayCode, BUILTIN, UNINITIALIZED) \ 116 V(ArrayConstructCode, BUILTIN, UNINITIALIZED) 117 118 #ifdef ENABLE_DEBUGGER_SUPPORT 119 // Define list of builtins used by the debugger implemented in assembly. 120 #define BUILTIN_LIST_DEBUG_A(V) \ 121 V(Return_DebugBreak, BUILTIN, DEBUG_BREAK) \ 122 V(ConstructCall_DebugBreak, BUILTIN, DEBUG_BREAK) \ 123 V(StubNoRegisters_DebugBreak, BUILTIN, DEBUG_BREAK) \ 124 V(LoadIC_DebugBreak, LOAD_IC, DEBUG_BREAK) \ 125 V(KeyedLoadIC_DebugBreak, KEYED_LOAD_IC, DEBUG_BREAK) \ 126 V(StoreIC_DebugBreak, STORE_IC, DEBUG_BREAK) \ 127 V(KeyedStoreIC_DebugBreak, KEYED_STORE_IC, DEBUG_BREAK) 128 #else 129 #define BUILTIN_LIST_DEBUG_A(V) 130 #endif 131 132 // Define list of builtins implemented in JavaScript. 133 #define BUILTINS_LIST_JS(V) \ 134 V(EQUALS, 1) \ 135 V(STRICT_EQUALS, 1) \ 136 V(COMPARE, 2) \ 137 V(ADD, 1) \ 138 V(SUB, 1) \ 139 V(MUL, 1) \ 140 V(DIV, 1) \ 141 V(MOD, 1) \ 142 V(BIT_OR, 1) \ 143 V(BIT_AND, 1) \ 144 V(BIT_XOR, 1) \ 145 V(UNARY_MINUS, 0) \ 146 V(BIT_NOT, 0) \ 147 V(SHL, 1) \ 148 V(SAR, 1) \ 149 V(SHR, 1) \ 150 V(DELETE, 1) \ 151 V(IN, 1) \ 152 V(INSTANCE_OF, 1) \ 153 V(GET_KEYS, 0) \ 154 V(FILTER_KEY, 1) \ 155 V(CALL_NON_FUNCTION, 0) \ 156 V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \ 157 V(TO_OBJECT, 0) \ 158 V(TO_NUMBER, 0) \ 159 V(TO_STRING, 0) \ 160 V(STRING_ADD_LEFT, 1) \ 161 V(STRING_ADD_RIGHT, 1) \ 162 V(APPLY_PREPARE, 1) \ 163 V(APPLY_OVERFLOW, 1) \ 164 V(STRING_CHAR_AT, 1) 165 166 167 class ObjectVisitor; 168 169 170 class Builtins : public AllStatic { 171 public: 172 // Generate all builtin code objects. Should be called once during 173 // VM initialization. 174 static void Setup(bool create_heap_objects); 175 static void TearDown(); 176 177 // Garbage collection support. 178 static void IterateBuiltins(ObjectVisitor* v); 179 180 // Disassembler support. 181 static const char* Lookup(byte* pc); 182 183 enum Name { 184 #define DEF_ENUM_C(name, ignore) name, 185 #define DEF_ENUM_A(name, kind, state) name, 186 BUILTIN_LIST_C(DEF_ENUM_C) 187 BUILTIN_LIST_A(DEF_ENUM_A) 188 BUILTIN_LIST_DEBUG_A(DEF_ENUM_A) 189 #undef DEF_ENUM_C 190 #undef DEF_ENUM_A 191 builtin_count 192 }; 193 194 enum CFunctionId { 195 #define DEF_ENUM_C(name, ignore) c_##name, 196 BUILTIN_LIST_C(DEF_ENUM_C) 197 #undef DEF_ENUM_C 198 cfunction_count 199 }; 200 201 enum JavaScript { 202 #define DEF_ENUM(name, ignore) name, 203 BUILTINS_LIST_JS(DEF_ENUM) 204 #undef DEF_ENUM 205 id_count 206 }; 207 builtin(Name name)208 static Code* builtin(Name name) { 209 // Code::cast cannot be used here since we access builtins 210 // during the marking phase of mark sweep. See IC::Clear. 211 return reinterpret_cast<Code*>(builtins_[name]); 212 } 213 builtin_address(Name name)214 static Address builtin_address(Name name) { 215 return reinterpret_cast<Address>(&builtins_[name]); 216 } 217 c_function_address(CFunctionId id)218 static Address c_function_address(CFunctionId id) { 219 return c_functions_[id]; 220 } 221 GetName(JavaScript id)222 static const char* GetName(JavaScript id) { return javascript_names_[id]; } GetArgumentsCount(JavaScript id)223 static int GetArgumentsCount(JavaScript id) { return javascript_argc_[id]; } 224 static Handle<Code> GetCode(JavaScript id, bool* resolved); NumberOfJavaScriptBuiltins()225 static int NumberOfJavaScriptBuiltins() { return id_count; } 226 227 private: 228 // The external C++ functions called from the code. 229 static Address c_functions_[cfunction_count]; 230 231 // Note: These are always Code objects, but to conform with 232 // IterateBuiltins() above which assumes Object**'s for the callback 233 // function f, we use an Object* array here. 234 static Object* builtins_[builtin_count]; 235 static const char* names_[builtin_count]; 236 static const char* javascript_names_[id_count]; 237 static int javascript_argc_[id_count]; 238 239 static void Generate_Adaptor(MacroAssembler* masm, 240 CFunctionId id, 241 BuiltinExtraArguments extra_args); 242 static void Generate_JSConstructCall(MacroAssembler* masm); 243 static void Generate_JSConstructStubGeneric(MacroAssembler* masm); 244 static void Generate_JSConstructStubApi(MacroAssembler* masm); 245 static void Generate_JSEntryTrampoline(MacroAssembler* masm); 246 static void Generate_JSConstructEntryTrampoline(MacroAssembler* masm); 247 static void Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm); 248 249 static void Generate_FunctionCall(MacroAssembler* masm); 250 static void Generate_FunctionApply(MacroAssembler* masm); 251 252 static void Generate_ArrayCode(MacroAssembler* masm); 253 static void Generate_ArrayConstructCode(MacroAssembler* masm); 254 }; 255 256 } } // namespace v8::internal 257 258 #endif // V8_BUILTINS_H_ 259