// Copyright 2012 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/runtime/runtime.h" #include "src/assembler.h" #include "src/contexts.h" #include "src/handles-inl.h" #include "src/heap/heap.h" #include "src/isolate.h" #include "src/runtime/runtime-utils.h" namespace v8 { namespace internal { // Header of runtime functions. #define F(name, number_of_args, result_size) \ Object* Runtime_##name(int args_length, Object** args_object, \ Isolate* isolate); FOR_EACH_INTRINSIC_RETURN_OBJECT(F) #undef F #define P(name, number_of_args, result_size) \ ObjectPair Runtime_##name(int args_length, Object** args_object, \ Isolate* isolate); FOR_EACH_INTRINSIC_RETURN_PAIR(P) #undef P #define T(name, number_of_args, result_size) \ ObjectTriple Runtime_##name(int args_length, Object** args_object, \ Isolate* isolate); FOR_EACH_INTRINSIC_RETURN_TRIPLE(T) #undef T #define F(name, number_of_args, result_size) \ { \ Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \ number_of_args, result_size \ } \ , #define I(name, number_of_args, result_size) \ { \ Runtime::kInline##name, Runtime::INLINE, "_" #name, \ FUNCTION_ADDR(Runtime_##name), number_of_args, result_size \ } \ , static const Runtime::Function kIntrinsicFunctions[] = { FOR_EACH_INTRINSIC(F) FOR_EACH_INTRINSIC(I) }; #undef I #undef F void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate, Handle<NameDictionary> dict) { DCHECK(dict->NumberOfElements() == 0); HandleScope scope(isolate); for (int i = 0; i < kNumFunctions; ++i) { const char* name = kIntrinsicFunctions[i].name; if (name == NULL) continue; Handle<NameDictionary> new_dict = NameDictionary::Add( dict, isolate->factory()->InternalizeUtf8String(name), Handle<Smi>(Smi::FromInt(i), isolate), PropertyDetails::Empty()); // The dictionary does not need to grow. CHECK(new_dict.is_identical_to(dict)); } } const Runtime::Function* Runtime::FunctionForName(Handle<String> name) { Heap* heap = name->GetHeap(); int entry = heap->intrinsic_function_names()->FindEntry(name); if (entry != kNotFound) { Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry); int function_index = Smi::cast(smi_index)->value(); return &(kIntrinsicFunctions[function_index]); } return NULL; } const Runtime::Function* Runtime::FunctionForEntry(Address entry) { for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) { if (entry == kIntrinsicFunctions[i].entry) { return &(kIntrinsicFunctions[i]); } } return NULL; } const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { return &(kIntrinsicFunctions[static_cast<int>(id)]); } const Runtime::Function* Runtime::RuntimeFunctionTable(Isolate* isolate) { if (isolate->external_reference_redirector()) { // When running with the simulator we need to provide a table which has // redirected runtime entry addresses. if (!isolate->runtime_state()->redirected_intrinsic_functions()) { size_t function_count = arraysize(kIntrinsicFunctions); Function* redirected_functions = new Function[function_count]; memcpy(redirected_functions, kIntrinsicFunctions, sizeof(kIntrinsicFunctions)); for (size_t i = 0; i < function_count; i++) { ExternalReference redirected_entry(static_cast<Runtime::FunctionId>(i), isolate); redirected_functions[i].entry = redirected_entry.address(); } isolate->runtime_state()->set_redirected_intrinsic_functions( redirected_functions); } return isolate->runtime_state()->redirected_intrinsic_functions(); } else { return kIntrinsicFunctions; } } std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) { return os << Runtime::FunctionForId(id)->name; } } // namespace internal } // namespace v8