diff options
Diffstat (limited to 'deps/v8/src/api.cc')
-rw-r--r-- | deps/v8/src/api.cc | 220 |
1 files changed, 124 insertions, 96 deletions
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 479be5af1..35b8aa0fc 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -185,7 +185,10 @@ void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) { int end_marker; heap_stats.end_marker = &end_marker; i::Isolate* isolate = i::Isolate::Current(); - isolate->heap()->RecordStats(&heap_stats, take_snapshot); + // BUG(1718): + // Don't use the take_snapshot since we don't support HeapIterator here + // without doing a special GC. + isolate->heap()->RecordStats(&heap_stats, false); i::V8::SetFatalError(); FatalErrorCallback callback = GetFatalErrorHandler(); { @@ -483,7 +486,7 @@ RegisteredExtension* RegisteredExtension::first_extension_ = NULL; RegisteredExtension::RegisteredExtension(Extension* extension) - : extension_(extension), state_(UNVISITED) { } + : extension_(extension) { } void RegisteredExtension::Register(RegisteredExtension* that) { @@ -501,9 +504,12 @@ void RegisterExtension(Extension* that) { Extension::Extension(const char* name, const char* source, int dep_count, - const char** deps) + const char** deps, + int source_length) : name_(name), - source_(source), + source_length_(source_length >= 0 ? + source_length : (source ? strlen(source) : 0)), + source_(source, source_length_), dep_count_(dep_count), deps_(deps), auto_enable_(false) { } @@ -1407,7 +1413,7 @@ void ObjectTemplate::SetInternalFieldCount(int value) { ScriptData* ScriptData::PreCompile(const char* input, int length) { i::Utf8ToUC16CharacterStream stream( reinterpret_cast<const unsigned char*>(input), length); - return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_block_scoping); + return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_scoping); } @@ -1416,10 +1422,10 @@ ScriptData* ScriptData::PreCompile(v8::Handle<String> source) { if (str->IsExternalTwoByteString()) { i::ExternalTwoByteStringUC16CharacterStream stream( i::Handle<i::ExternalTwoByteString>::cast(str), 0, str->length()); - return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_block_scoping); + return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_scoping); } else { i::GenericStringUC16CharacterStream stream(str, 0, str->length()); - return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_block_scoping); + return i::ParserApi::PreParse(&stream, NULL, i::FLAG_harmony_scoping); } } @@ -1781,7 +1787,7 @@ v8::Handle<v8::StackTrace> Message::GetStackTrace() const { static i::Handle<i::Object> CallV8HeapFunction(const char* name, i::Handle<i::Object> recv, int argc, - i::Object** argv[], + i::Handle<i::Object> argv[], bool* has_pending_exception) { i::Isolate* isolate = i::Isolate::Current(); i::Handle<i::String> fmt_str = isolate->factory()->LookupAsciiSymbol(name); @@ -1798,10 +1804,10 @@ static i::Handle<i::Object> CallV8HeapFunction(const char* name, static i::Handle<i::Object> CallV8HeapFunction(const char* name, i::Handle<i::Object> data, bool* has_pending_exception) { - i::Object** argv[1] = { data.location() }; + i::Handle<i::Object> argv[] = { data }; return CallV8HeapFunction(name, i::Isolate::Current()->js_builtins_object(), - 1, + ARRAY_SIZE(argv), argv, has_pending_exception); } @@ -2621,10 +2627,11 @@ bool Value::Equals(Handle<Value> that) const { if (obj->IsJSObject() && other->IsJSObject()) { return *obj == *other; } - i::Object** args[1] = { other.location() }; + i::Handle<i::Object> args[] = { other }; EXCEPTION_PREAMBLE(isolate); i::Handle<i::Object> result = - CallV8HeapFunction("EQUALS", obj, 1, args, &has_pending_exception); + CallV8HeapFunction("EQUALS", obj, ARRAY_SIZE(args), args, + &has_pending_exception); EXCEPTION_BAILOUT_CHECK(isolate, false); return *result == i::Smi::FromInt(i::EQUAL); } @@ -2787,7 +2794,7 @@ Local<Value> v8::Object::Get(uint32_t index) { ENTER_V8(isolate); i::Handle<i::JSObject> self = Utils::OpenHandle(this); EXCEPTION_PREAMBLE(isolate); - i::Handle<i::Object> result = i::GetElement(self, index); + i::Handle<i::Object> result = i::Object::GetElement(self, index); has_pending_exception = result.is_null(); EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>()); return Utils::ToLocal(result); @@ -2867,8 +2874,10 @@ Local<Array> v8::Object::GetPropertyNames() { ENTER_V8(isolate); i::HandleScope scope(isolate); i::Handle<i::JSObject> self = Utils::OpenHandle(this); + bool threw = false; i::Handle<i::FixedArray> value = - i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS); + i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS, &threw); + if (threw) return Local<v8::Array>(); // Because we use caching to speed up enumeration it is important // to never change the result of the basic enumeration function so // we clone the result. @@ -2886,8 +2895,10 @@ Local<Array> v8::Object::GetOwnPropertyNames() { ENTER_V8(isolate); i::HandleScope scope(isolate); i::Handle<i::JSObject> self = Utils::OpenHandle(this); + bool threw = false; i::Handle<i::FixedArray> value = - i::GetKeysInFixedArrayFor(self, i::LOCAL_ONLY); + i::GetKeysInFixedArrayFor(self, i::LOCAL_ONLY, &threw); + if (threw) return Local<v8::Array>(); // Because we use caching to speed up enumeration it is important // to never change the result of the basic enumeration function so // we clone the result. @@ -3086,7 +3097,10 @@ static Local<Value> GetPropertyByLookup(i::Isolate* isolate, // If the property being looked up is a callback, it can throw // an exception. EXCEPTION_PREAMBLE(isolate); - i::Handle<i::Object> result = i::GetProperty(receiver, name, lookup); + PropertyAttributes ignored; + i::Handle<i::Object> result = + i::Object::GetProperty(receiver, receiver, lookup, name, + &ignored); has_pending_exception = result.is_null(); EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>()); @@ -3103,7 +3117,7 @@ Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain( ENTER_V8(isolate); i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this); i::Handle<i::String> key_obj = Utils::OpenHandle(*key); - i::LookupResult lookup; + i::LookupResult lookup(isolate); self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup); return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup); } @@ -3116,7 +3130,7 @@ Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) { ENTER_V8(isolate); i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this); i::Handle<i::String> key_obj = Utils::OpenHandle(*key); - i::LookupResult lookup; + i::LookupResult lookup(isolate); self_obj->LookupRealNamedProperty(*key_obj, &lookup); return GetPropertyByLookup(isolate, self_obj, key_obj, &lookup); } @@ -3204,21 +3218,10 @@ bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key, ENTER_V8(isolate); i::HandleScope scope(isolate); i::Handle<i::JSObject> self = Utils::OpenHandle(this); - i::Handle<i::Object> hidden_props(i::GetHiddenProperties( - self, - i::JSObject::ALLOW_CREATION)); - i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); + i::Handle<i::String> key_obj = Utils::OpenHandle(*key); i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); - EXCEPTION_PREAMBLE(isolate); - i::Handle<i::Object> obj = i::SetProperty( - hidden_props, - key_obj, - value_obj, - static_cast<PropertyAttributes>(None), - i::kNonStrictMode); - has_pending_exception = obj.is_null(); - EXCEPTION_BAILOUT_CHECK(isolate, false); - return true; + i::Handle<i::Object> result = i::SetHiddenProperty(self, key_obj, value_obj); + return *result == *self; } @@ -3228,20 +3231,9 @@ v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) { return Local<v8::Value>()); ENTER_V8(isolate); i::Handle<i::JSObject> self = Utils::OpenHandle(this); - i::Handle<i::Object> hidden_props(i::GetHiddenProperties( - self, - i::JSObject::OMIT_CREATION)); - if (hidden_props->IsUndefined()) { - return v8::Local<v8::Value>(); - } i::Handle<i::String> key_obj = Utils::OpenHandle(*key); - EXCEPTION_PREAMBLE(isolate); - i::Handle<i::Object> result = i::GetProperty(hidden_props, key_obj); - has_pending_exception = result.is_null(); - EXCEPTION_BAILOUT_CHECK(isolate, v8::Local<v8::Value>()); - if (result->IsUndefined()) { - return v8::Local<v8::Value>(); - } + i::Handle<i::Object> result(self->GetHiddenProperty(*key_obj)); + if (result->IsUndefined()) return v8::Local<v8::Value>(); return Utils::ToLocal(result); } @@ -3252,15 +3244,9 @@ bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) { ENTER_V8(isolate); i::HandleScope scope(isolate); i::Handle<i::JSObject> self = Utils::OpenHandle(this); - i::Handle<i::Object> hidden_props(i::GetHiddenProperties( - self, - i::JSObject::OMIT_CREATION)); - if (hidden_props->IsUndefined()) { - return true; - } - i::Handle<i::JSObject> js_obj(i::JSObject::cast(*hidden_props)); i::Handle<i::String> key_obj = Utils::OpenHandle(*key); - return i::DeleteProperty(js_obj, key_obj)->IsTrue(); + self->DeleteHiddenProperty(*key_obj); + return true; } @@ -3310,22 +3296,12 @@ void PrepareExternalArrayElements(i::Handle<i::JSObject> object, i::Handle<i::ExternalArray> array = isolate->factory()->NewExternalArray(length, array_type, data); - // If the object already has external elements, create a new, unique - // map if the element type is now changing, because assumptions about - // generated code based on the receiver's map will be invalid. - i::Handle<i::HeapObject> elements(object->elements()); - bool cant_reuse_map = - elements->map()->IsUndefined() || - !elements->map()->has_external_array_elements() || - elements->map() != isolate->heap()->MapForExternalArrayType(array_type); - if (cant_reuse_map) { - i::Handle<i::Map> external_array_map = - isolate->factory()->GetElementsTransitionMap( - i::Handle<i::Map>(object->map()), - GetElementsKindFromExternalArrayType(array_type), - object->HasFastProperties()); - object->set_map(*external_array_map); - } + i::Handle<i::Map> external_array_map = + isolate->factory()->GetElementsTransitionMap( + object, + GetElementsKindFromExternalArrayType(array_type)); + + object->set_map(*external_array_map); object->set_elements(*array); } @@ -3484,7 +3460,8 @@ bool v8::Object::IsCallable() { } -Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc, +Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, + int argc, v8::Handle<v8::Value> argv[]) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ON_BAILOUT(isolate, "v8::Object::CallAsFunction()", @@ -3495,7 +3472,7 @@ Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc, i::Handle<i::JSObject> obj = Utils::OpenHandle(this); i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv); STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**)); - i::Object*** args = reinterpret_cast<i::Object***>(argv); + i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv); i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>(); if (obj->IsJSFunction()) { fun = i::Handle<i::JSFunction>::cast(obj); @@ -3525,7 +3502,7 @@ Local<v8::Value> Object::CallAsConstructor(int argc, i::HandleScope scope(isolate); i::Handle<i::JSObject> obj = Utils::OpenHandle(this); STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**)); - i::Object*** args = reinterpret_cast<i::Object***>(argv); + i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv); if (obj->IsJSFunction()) { i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj); EXCEPTION_PREAMBLE(isolate); @@ -3567,7 +3544,7 @@ Local<v8::Object> Function::NewInstance(int argc, HandleScope scope; i::Handle<i::JSFunction> function = Utils::OpenHandle(this); STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**)); - i::Object*** args = reinterpret_cast<i::Object***>(argv); + i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv); EXCEPTION_PREAMBLE(isolate); i::Handle<i::Object> returned = i::Execution::New(function, argc, args, &has_pending_exception); @@ -3588,7 +3565,7 @@ Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc, i::Handle<i::JSFunction> fun = Utils::OpenHandle(this); i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv); STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**)); - i::Object*** args = reinterpret_cast<i::Object***>(argv); + i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv); EXCEPTION_PREAMBLE(isolate); i::Handle<i::Object> returned = i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception); @@ -3642,6 +3619,23 @@ int Function::GetScriptLineNumber() const { } +int Function::GetScriptColumnNumber() const { + i::Handle<i::JSFunction> func = Utils::OpenHandle(this); + if (func->shared()->script()->IsScript()) { + i::Handle<i::Script> script(i::Script::cast(func->shared()->script())); + return i::GetScriptColumnNumber(script, func->shared()->start_position()); + } + return kLineOffsetNotFound; +} + +Handle<Value> Function::GetScriptId() const { + i::Handle<i::JSFunction> func = Utils::OpenHandle(this); + if (!func->shared()->script()->IsScript()) + return v8::Undefined(); + i::Handle<i::Script> script(i::Script::cast(func->shared()->script())); + return Utils::ToLocal(i::Handle<i::Object>(script->id())); +} + int String::Length() const { i::Handle<i::String> str = Utils::OpenHandle(this); if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0; @@ -3664,13 +3658,30 @@ int String::WriteUtf8(char* buffer, if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0; LOG_API(isolate, "String::WriteUtf8"); ENTER_V8(isolate); - i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer(); i::Handle<i::String> str = Utils::OpenHandle(this); + if (str->IsAsciiRepresentation()) { + int len; + if (capacity == -1) { + capacity = str->length() + 1; + len = str->length(); + } else { + len = i::Min(capacity, str->length()); + } + i::String::WriteToFlat(*str, buffer, 0, len); + if (nchars_ref != NULL) *nchars_ref = len; + if (!(options & NO_NULL_TERMINATION) && capacity > len) { + buffer[len] = '\0'; + return len + 1; + } + return len; + } + + i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer(); isolate->string_tracker()->RecordWrite(str); if (options & HINT_MANY_WRITES_EXPECTED) { // Flatten the string for efficiency. This applies whether we are // using StringInputBuffer or Get(i) to access the characters. - str->TryFlatten(); + FlattenString(str); } write_input_buffer.Reset(0, *str); int len = str->length(); @@ -3799,10 +3810,11 @@ bool v8::String::IsExternalAscii() const { void v8::String::VerifyExternalStringResource( v8::String::ExternalStringResource* value) const { i::Handle<i::String> str = Utils::OpenHandle(this); - v8::String::ExternalStringResource* expected; + const v8::String::ExternalStringResource* expected; if (i::StringShape(*str).IsExternalTwoByte()) { - void* resource = i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); - expected = reinterpret_cast<ExternalStringResource*>(resource); + const void* resource = + i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); + expected = reinterpret_cast<const ExternalStringResource*>(resource); } else { expected = NULL; } @@ -3810,7 +3822,7 @@ void v8::String::VerifyExternalStringResource( } -v8::String::ExternalAsciiStringResource* +const v8::String::ExternalAsciiStringResource* v8::String::GetExternalAsciiStringResource() const { i::Handle<i::String> str = Utils::OpenHandle(this); if (IsDeadCheck(str->GetIsolate(), @@ -3818,8 +3830,9 @@ v8::String::ExternalAsciiStringResource* return NULL; } if (i::StringShape(*str).IsExternalAscii()) { - void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource(); - return reinterpret_cast<ExternalAsciiStringResource*>(resource); + const void* resource = + i::Handle<i::ExternalAsciiString>::cast(str)->resource(); + return reinterpret_cast<const ExternalAsciiStringResource*>(resource); } else { return NULL; } @@ -3989,6 +4002,15 @@ HeapStatistics::HeapStatistics(): total_heap_size_(0), void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) { + if (!i::Isolate::Current()->IsInitialized()) { + // Isolate is unitialized thus heap is not configured yet. + heap_statistics->set_total_heap_size(0); + heap_statistics->set_total_heap_size_executable(0); + heap_statistics->set_used_heap_size(0); + heap_statistics->set_heap_size_limit(0); + return; + } + i::Heap* heap = i::Isolate::Current()->heap(); heap_statistics->set_total_heap_size(heap->CommittedMemory()); heap_statistics->set_total_heap_size_executable( @@ -3998,18 +4020,19 @@ void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) { } -bool v8::V8::IdleNotification() { +bool v8::V8::IdleNotification(int hint) { // Returning true tells the caller that it need not // continue to call IdleNotification. - if (!i::Isolate::Current()->IsInitialized()) return true; - return i::V8::IdleNotification(); + i::Isolate* isolate = i::Isolate::Current(); + if (isolate == NULL || !isolate->IsInitialized()) return true; + return i::V8::IdleNotification(hint); } void v8::V8::LowMemoryNotification() { i::Isolate* isolate = i::Isolate::Current(); - if (!isolate->IsInitialized()) return; - isolate->heap()->CollectAllGarbage(true); + if (isolate == NULL || !isolate->IsInitialized()) return; + isolate->heap()->CollectAllAvailableGarbage(); } @@ -4103,8 +4126,9 @@ Persistent<Context> v8::Context::New( } // Leave V8. - if (env.is_null()) + if (env.is_null()) { return Persistent<Context>(); + } return Persistent<Context>(Utils::ToLocal(env)); } @@ -4292,7 +4316,7 @@ static Local<External> ExternalNewImpl(void* data) { } static void* ExternalValueImpl(i::Handle<i::Object> obj) { - return reinterpret_cast<void*>(i::Foreign::cast(*obj)->address()); + return reinterpret_cast<void*>(i::Foreign::cast(*obj)->foreign_address()); } @@ -4318,7 +4342,7 @@ void* v8::Object::SlowGetPointerFromInternalField(int index) { if (value->IsSmi()) { return i::Internals::GetExternalPointerFromSmi(value); } else if (value->IsForeign()) { - return reinterpret_cast<void*>(i::Foreign::cast(value)->address()); + return reinterpret_cast<void*>(i::Foreign::cast(value)->foreign_address()); } else { return NULL; } @@ -4528,15 +4552,13 @@ bool v8::String::MakeExternal( bool v8::String::CanMakeExternal() { + if (!internal::FLAG_clever_optimizations) return false; i::Handle<i::String> obj = Utils::OpenHandle(this); i::Isolate* isolate = obj->GetIsolate(); if (IsDeadCheck(isolate, "v8::String::CanMakeExternal()")) return false; - if (isolate->string_tracker()->IsFreshUnusedString(obj)) { - return false; - } + if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false; int size = obj->Size(); // Byte size of the original string. - if (size < i::ExternalString::kSize) - return false; + if (size < i::ExternalString::kShortSize) return false; i::StringShape shape(*obj); return !shape.IsExternal(); } @@ -4870,7 +4892,7 @@ void V8::RemoveMessageListeners(MessageCallback that) { NeanderObject listener(i::JSObject::cast(listeners.get(i))); i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0))); - if (callback_obj->address() == FUNCTION_ADDR(that)) { + if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) { listeners.set(i, isolate->heap()->undefined_value()); } } @@ -5480,6 +5502,12 @@ bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) { wait_for_connection); } + +void Debug::DisableAgent() { + return i::Isolate::Current()->debugger()->StopAgent(); +} + + void Debug::ProcessDebugMessages() { i::Execution::ProcessDebugMesssages(true); } |