| Index: src/api.cc
|
| diff --git a/src/api.cc b/src/api.cc
|
| index 0c78b5f27058f923fc02ccd2b9b6dc6e53c8bca7..909335d5124f336ac4752efc231f495f49dd5056 100644
|
| --- a/src/api.cc
|
| +++ b/src/api.cc
|
| @@ -2580,13 +2580,13 @@ bool Value::IsGeneratorObject() const {
|
| }
|
|
|
|
|
| -Local<String> Value::ToString() const {
|
| +Local<String> Value::ToString(Isolate* v8_isolate) const {
|
| i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
| i::Handle<i::Object> str;
|
| if (obj->IsString()) {
|
| str = obj;
|
| } else {
|
| - i::Isolate* isolate = i::Isolate::Current();
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| LOG_API(isolate, "ToString");
|
| ENTER_V8(isolate);
|
| EXCEPTION_PREAMBLE(isolate);
|
| @@ -2598,13 +2598,13 @@ Local<String> Value::ToString() const {
|
| }
|
|
|
|
|
| -Local<String> Value::ToDetailString() const {
|
| +Local<String> Value::ToDetailString(Isolate* v8_isolate) const {
|
| i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
| i::Handle<i::Object> str;
|
| if (obj->IsString()) {
|
| str = obj;
|
| } else {
|
| - i::Isolate* isolate = i::Isolate::Current();
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| LOG_API(isolate, "ToDetailString");
|
| ENTER_V8(isolate);
|
| EXCEPTION_PREAMBLE(isolate);
|
| @@ -2616,13 +2616,13 @@ Local<String> Value::ToDetailString() const {
|
| }
|
|
|
|
|
| -Local<v8::Object> Value::ToObject() const {
|
| +Local<v8::Object> Value::ToObject(Isolate* v8_isolate) const {
|
| i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
| i::Handle<i::Object> val;
|
| if (obj->IsJSObject()) {
|
| val = obj;
|
| } else {
|
| - i::Isolate* isolate = i::Isolate::Current();
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| LOG_API(isolate, "ToObject");
|
| ENTER_V8(isolate);
|
| EXCEPTION_PREAMBLE(isolate);
|
| @@ -2634,12 +2634,12 @@ Local<v8::Object> Value::ToObject() const {
|
| }
|
|
|
|
|
| -Local<Boolean> Value::ToBoolean() const {
|
| +Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
|
| i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
| if (obj->IsBoolean()) {
|
| return ToApiHandle<Boolean>(obj);
|
| } else {
|
| - i::Isolate* isolate = i::Isolate::Current();
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| LOG_API(isolate, "ToBoolean");
|
| ENTER_V8(isolate);
|
| i::Handle<i::Object> val =
|
| @@ -2649,13 +2649,13 @@ Local<Boolean> Value::ToBoolean() const {
|
| }
|
|
|
|
|
| -Local<Number> Value::ToNumber() const {
|
| +Local<Number> Value::ToNumber(Isolate* v8_isolate) const {
|
| i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
| i::Handle<i::Object> num;
|
| if (obj->IsNumber()) {
|
| num = obj;
|
| } else {
|
| - i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| LOG_API(isolate, "ToNumber");
|
| ENTER_V8(isolate);
|
| EXCEPTION_PREAMBLE(isolate);
|
| @@ -2667,13 +2667,13 @@ Local<Number> Value::ToNumber() const {
|
| }
|
|
|
|
|
| -Local<Integer> Value::ToInteger() const {
|
| +Local<Integer> Value::ToInteger(Isolate* v8_isolate) const {
|
| i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
| i::Handle<i::Object> num;
|
| if (obj->IsSmi()) {
|
| num = obj;
|
| } else {
|
| - i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| LOG_API(isolate, "ToInteger");
|
| ENTER_V8(isolate);
|
| EXCEPTION_PREAMBLE(isolate);
|
| @@ -2935,13 +2935,13 @@ int64_t Value::IntegerValue() const {
|
| }
|
|
|
|
|
| -Local<Int32> Value::ToInt32() const {
|
| +Local<Int32> Value::ToInt32(Isolate* v8_isolate) const {
|
| i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
| i::Handle<i::Object> num;
|
| if (obj->IsSmi()) {
|
| num = obj;
|
| } else {
|
| - i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| LOG_API(isolate, "ToInt32");
|
| ENTER_V8(isolate);
|
| EXCEPTION_PREAMBLE(isolate);
|
| @@ -2952,13 +2952,13 @@ Local<Int32> Value::ToInt32() const {
|
| }
|
|
|
|
|
| -Local<Uint32> Value::ToUint32() const {
|
| +Local<Uint32> Value::ToUint32(Isolate* v8_isolate) const {
|
| i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
| i::Handle<i::Object> num;
|
| if (obj->IsSmi()) {
|
| num = obj;
|
| } else {
|
| - i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| LOG_API(isolate, "ToUInt32");
|
| ENTER_V8(isolate);
|
| EXCEPTION_PREAMBLE(isolate);
|
| @@ -3173,6 +3173,44 @@ bool v8::Object::SetPrivate(v8::Handle<Private> key, v8::Handle<Value> value) {
|
| }
|
|
|
|
|
| +i::MaybeHandle<i::Object> DeleteObjectProperty(
|
| + i::Isolate* isolate, i::Handle<i::JSReceiver> receiver,
|
| + i::Handle<i::Object> key, i::JSReceiver::DeleteMode mode) {
|
| + // Check if the given key is an array index.
|
| + uint32_t index;
|
| + if (key->ToArrayIndex(&index)) {
|
| + // In Firefox/SpiderMonkey, Safari and Opera you can access the
|
| + // characters of a string using [] notation. In the case of a
|
| + // String object we just need to redirect the deletion to the
|
| + // underlying string if the index is in range. Since the
|
| + // underlying string does nothing with the deletion, we can ignore
|
| + // such deletions.
|
| + if (receiver->IsStringObjectWithCharacterAt(index)) {
|
| + return isolate->factory()->true_value();
|
| + }
|
| +
|
| + return i::JSReceiver::DeleteElement(receiver, index, mode);
|
| + }
|
| +
|
| + i::Handle<i::Name> name;
|
| + if (key->IsName()) {
|
| + name = i::Handle<i::Name>::cast(key);
|
| + } else {
|
| + // Call-back into JavaScript to convert the key to a string.
|
| + i::Handle<i::Object> converted;
|
| + if (!i::Execution::ToString(isolate, key).ToHandle(&converted)) {
|
| + return i::MaybeHandle<i::Object>();
|
| + }
|
| + name = i::Handle<i::String>::cast(converted);
|
| + }
|
| +
|
| + if (name->IsString()) {
|
| + name = i::String::Flatten(i::Handle<i::String>::cast(name));
|
| + }
|
| + return i::JSReceiver::DeleteProperty(receiver, name, mode);
|
| +}
|
| +
|
| +
|
| bool v8::Object::ForceDelete(v8::Handle<Value> key) {
|
| i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
| ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
|
| @@ -3191,8 +3229,9 @@ bool v8::Object::ForceDelete(v8::Handle<Value> key) {
|
|
|
| EXCEPTION_PREAMBLE(isolate);
|
| i::Handle<i::Object> obj;
|
| - has_pending_exception = !i::Runtime::DeleteObjectProperty(
|
| - isolate, self, key_obj, i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
|
| + has_pending_exception =
|
| + !DeleteObjectProperty(isolate, self, key_obj,
|
| + i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
|
| EXCEPTION_BAILOUT_CHECK(isolate, false);
|
| return obj->IsTrue();
|
| }
|
| @@ -3370,6 +3409,37 @@ Local<Array> v8::Object::GetOwnPropertyNames() {
|
| }
|
|
|
|
|
| +static bool GetPredefinedToString(i::Handle<i::String> tag,
|
| + Local<String>* result) {
|
| + i::Isolate* i_isolate = tag->GetIsolate();
|
| + Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
|
| + i::Factory* factory = i_isolate->factory();
|
| +
|
| + if (i::String::Equals(tag, factory->Arguments_string())) {
|
| + *result = v8::String::NewFromUtf8(isolate, "[object ~Arguments]");
|
| + } else if (i::String::Equals(tag, factory->Array_string())) {
|
| + *result = v8::String::NewFromUtf8(isolate, "[object ~Array]");
|
| + } else if (i::String::Equals(tag, factory->Boolean_string())) {
|
| + *result = v8::String::NewFromUtf8(isolate, "[object ~Boolean]");
|
| + } else if (i::String::Equals(tag, factory->Date_string())) {
|
| + *result = v8::String::NewFromUtf8(isolate, "[object ~Date]");
|
| + } else if (i::String::Equals(tag, factory->Error_string())) {
|
| + *result = v8::String::NewFromUtf8(isolate, "[object ~Error]");
|
| + } else if (i::String::Equals(tag, factory->Function_string())) {
|
| + *result = v8::String::NewFromUtf8(isolate, "[object ~Function]");
|
| + } else if (i::String::Equals(tag, factory->Number_string())) {
|
| + *result = v8::String::NewFromUtf8(isolate, "[object ~Number]");
|
| + } else if (i::String::Equals(tag, factory->RegExp_string())) {
|
| + *result = v8::String::NewFromUtf8(isolate, "[object ~RegExp]");
|
| + } else if (i::String::Equals(tag, factory->String_string())) {
|
| + *result = v8::String::NewFromUtf8(isolate, "[object ~String]");
|
| + } else {
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +
|
| Local<String> v8::Object::ObjectProtoToString() {
|
| i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
|
| Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
|
| @@ -3379,6 +3449,7 @@ Local<String> v8::Object::ObjectProtoToString() {
|
| i::Handle<i::JSObject> self = Utils::OpenHandle(this);
|
|
|
| i::Handle<i::Object> name(self->class_name(), i_isolate);
|
| + i::Handle<i::Object> tag;
|
|
|
| // Native implementation of Object.prototype.toString (v8natives.js):
|
| // var c = %_ClassOf(this);
|
| @@ -3393,6 +3464,27 @@ Local<String> v8::Object::ObjectProtoToString() {
|
| i_isolate->factory()->Arguments_string())) {
|
| return v8::String::NewFromUtf8(isolate, "[object Object]");
|
| } else {
|
| + if (internal::FLAG_harmony_tostring) {
|
| + i::Handle<i::Symbol> toStringTag =
|
| + Utils::OpenHandle(*Symbol::GetToStringTag(isolate));
|
| + EXCEPTION_PREAMBLE(i_isolate);
|
| + has_pending_exception =
|
| + !i::Runtime::GetObjectProperty(i_isolate, self, toStringTag)
|
| + .ToHandle(&tag);
|
| + EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::String>());
|
| +
|
| + if (!tag->IsUndefined()) {
|
| + if (!tag->IsString())
|
| + return v8::String::NewFromUtf8(isolate, "[object ???]");
|
| + i::Handle<i::String> tag_name = i::Handle<i::String>::cast(tag);
|
| + if (!i::String::Equals(class_name, tag_name)) {
|
| + Local<String> result;
|
| + if (GetPredefinedToString(tag_name, &result)) return result;
|
| +
|
| + class_name = tag_name;
|
| + }
|
| + }
|
| + }
|
| const char* prefix = "[object ";
|
| Local<String> str = Utils::ToLocal(class_name);
|
| const char* postfix = "]";
|
| @@ -3445,8 +3537,9 @@ bool v8::Object::Delete(v8::Handle<Value> key) {
|
| i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
|
| EXCEPTION_PREAMBLE(isolate);
|
| i::Handle<i::Object> obj;
|
| - has_pending_exception = !i::Runtime::DeleteObjectProperty(
|
| - isolate, self, key_obj, i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
|
| + has_pending_exception =
|
| + !DeleteObjectProperty(isolate, self, key_obj,
|
| + i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
|
| EXCEPTION_BAILOUT_CHECK(isolate, false);
|
| return obj->IsTrue();
|
| }
|
| @@ -3464,11 +3557,22 @@ bool v8::Object::Has(v8::Handle<Value> key) {
|
| i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
|
| i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
|
| EXCEPTION_PREAMBLE(isolate);
|
| - i::Handle<i::Object> obj;
|
| - has_pending_exception = !i::Runtime::HasObjectProperty(
|
| - isolate, self, key_obj).ToHandle(&obj);
|
| + Maybe<bool> maybe;
|
| + // Check if the given key is an array index.
|
| + uint32_t index;
|
| + if (key_obj->ToArrayIndex(&index)) {
|
| + maybe = i::JSReceiver::HasElement(self, index);
|
| + } else {
|
| + // Convert the key to a name - possibly by calling back into JavaScript.
|
| + i::Handle<i::Name> name;
|
| + if (i::Runtime::ToName(isolate, key_obj).ToHandle(&name)) {
|
| + maybe = i::JSReceiver::HasProperty(self, name);
|
| + }
|
| + }
|
| + if (!maybe.has_value) has_pending_exception = true;
|
| EXCEPTION_BAILOUT_CHECK(isolate, false);
|
| - return obj->IsTrue();
|
| + DCHECK(maybe.has_value);
|
| + return maybe.value;
|
| }
|
|
|
|
|
| @@ -3723,11 +3827,6 @@ void v8::Object::TurnOnAccessCheck() {
|
| }
|
|
|
|
|
| -bool v8::Object::IsDirty() {
|
| - return Utils::OpenHandle(this)->IsDirty();
|
| -}
|
| -
|
| -
|
| Local<v8::Object> v8::Object::Clone() {
|
| i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
| ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
|
| @@ -6199,6 +6298,11 @@ Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) {
|
| }
|
|
|
|
|
| +Local<Symbol> v8::Symbol::GetToStringTag(Isolate* isolate) {
|
| + return GetWellKnownSymbol(isolate, "Symbol.toStringTag");
|
| +}
|
| +
|
| +
|
| Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
|
| i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| LOG_API(i_isolate, "Private::New()");
|
| @@ -6812,7 +6916,7 @@ String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
|
| ENTER_V8(isolate);
|
| i::HandleScope scope(isolate);
|
| TryCatch try_catch;
|
| - Handle<String> str = obj->ToString();
|
| + Handle<String> str = obj->ToString(reinterpret_cast<v8::Isolate*>(isolate));
|
| if (str.IsEmpty()) return;
|
| i::Handle<i::String> i_str = Utils::OpenHandle(*str);
|
| length_ = v8::Utf8Length(*i_str, isolate);
|
| @@ -6833,7 +6937,7 @@ String::Value::Value(v8::Handle<v8::Value> obj)
|
| ENTER_V8(isolate);
|
| i::HandleScope scope(isolate);
|
| TryCatch try_catch;
|
| - Handle<String> str = obj->ToString();
|
| + Handle<String> str = obj->ToString(reinterpret_cast<v8::Isolate*>(isolate));
|
| if (str.IsEmpty()) return;
|
| length_ = str->Length();
|
| str_ = i::NewArray<uint16_t>(length_ + 1);
|
|
|