OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2014 | 2014 |
2015 void SymbolAccessorSetter(Local<Name> name, Local<Value> value, | 2015 void SymbolAccessorSetter(Local<Name> name, Local<Value> value, |
2016 const v8::PropertyCallbackInfo<void>& info) { | 2016 const v8::PropertyCallbackInfo<void>& info) { |
2017 CHECK(name->IsSymbol()); | 2017 CHECK(name->IsSymbol()); |
2018 Local<Symbol> sym = Local<Symbol>::Cast(name); | 2018 Local<Symbol> sym = Local<Symbol>::Cast(name); |
2019 if (sym->Name()->IsUndefined()) | 2019 if (sym->Name()->IsUndefined()) |
2020 return; | 2020 return; |
2021 SimpleAccessorSetter(Local<String>::Cast(sym->Name()), value, info); | 2021 SimpleAccessorSetter(Local<String>::Cast(sym->Name()), value, info); |
2022 } | 2022 } |
2023 | 2023 |
| 2024 void SymbolAccessorGetterReturnsDefault(Local<Name> name, |
| 2025 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 2026 CHECK(name->IsSymbol()); |
| 2027 Local<Symbol> sym = Local<Symbol>::Cast(name); |
| 2028 if (sym->Name()->IsUndefined()) |
| 2029 return; |
| 2030 info.GetReturnValue().Set(info.Data()); |
| 2031 } |
| 2032 |
| 2033 static void ThrowingSymbolAccessorGetter( |
| 2034 Local<Name> name, |
| 2035 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 2036 info.GetReturnValue().Set(info.GetIsolate()->ThrowException(name)); |
| 2037 } |
| 2038 |
2024 void EmptyInterceptorGetter(Local<String> name, | 2039 void EmptyInterceptorGetter(Local<String> name, |
2025 const v8::PropertyCallbackInfo<v8::Value>& info) { | 2040 const v8::PropertyCallbackInfo<v8::Value>& info) { |
2026 } | 2041 } |
2027 | 2042 |
2028 void EmptyInterceptorSetter(Local<String> name, | 2043 void EmptyInterceptorSetter(Local<String> name, |
2029 Local<Value> value, | 2044 Local<Value> value, |
2030 const v8::PropertyCallbackInfo<v8::Value>& info) { | 2045 const v8::PropertyCallbackInfo<v8::Value>& info) { |
2031 } | 2046 } |
2032 | 2047 |
2033 void InterceptorGetter(Local<String> name, | 2048 void InterceptorGetter(Local<String> name, |
(...skipping 11451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13485 value = context->Global()->ObjectProtoToString(); | 13500 value = context->Global()->ObjectProtoToString(); |
13486 CHECK(value->IsString() && value->Equals(v8_str("[object global]"))); | 13501 CHECK(value->IsString() && value->Equals(v8_str("[object global]"))); |
13487 | 13502 |
13488 // Check ordinary object | 13503 // Check ordinary object |
13489 Local<Value> object = v8_compile("new Object()")->Run(); | 13504 Local<Value> object = v8_compile("new Object()")->Run(); |
13490 value = object.As<v8::Object>()->ObjectProtoToString(); | 13505 value = object.As<v8::Object>()->ObjectProtoToString(); |
13491 CHECK(value->IsString() && value->Equals(v8_str("[object Object]"))); | 13506 CHECK(value->IsString() && value->Equals(v8_str("[object Object]"))); |
13492 } | 13507 } |
13493 | 13508 |
13494 | 13509 |
| 13510 TEST(ObjectProtoToStringES6) { |
| 13511 // TODO(dslomov, caitp): merge into ObjectProtoToString test once shipped. |
| 13512 i::FLAG_harmony_tostring = true; |
| 13513 LocalContext context; |
| 13514 v8::Isolate* isolate = CcTest::isolate(); |
| 13515 v8::HandleScope scope(isolate); |
| 13516 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); |
| 13517 templ->SetClassName(v8_str("MyClass")); |
| 13518 |
| 13519 Local<String> customized_tostring = v8_str("customized toString"); |
| 13520 |
| 13521 // Replace Object.prototype.toString |
| 13522 CompileRun("Object.prototype.toString = function() {" |
| 13523 " return 'customized toString';" |
| 13524 "}"); |
| 13525 |
| 13526 // Normal ToString call should call replaced Object.prototype.toString |
| 13527 Local<v8::Object> instance = templ->GetFunction()->NewInstance(); |
| 13528 Local<String> value = instance->ToString(); |
| 13529 CHECK(value->IsString() && value->Equals(customized_tostring)); |
| 13530 |
| 13531 // ObjectProtoToString should not call replace toString function. |
| 13532 value = instance->ObjectProtoToString(); |
| 13533 CHECK(value->IsString() && value->Equals(v8_str("[object MyClass]"))); |
| 13534 |
| 13535 // Check global |
| 13536 value = context->Global()->ObjectProtoToString(); |
| 13537 CHECK(value->IsString() && value->Equals(v8_str("[object global]"))); |
| 13538 |
| 13539 // Check ordinary object |
| 13540 Local<Value> object = CompileRun("new Object()"); |
| 13541 value = object.As<v8::Object>()->ObjectProtoToString(); |
| 13542 CHECK(value->IsString() && value->Equals(v8_str("[object Object]"))); |
| 13543 |
| 13544 // Check that ES6 semantics using @@toStringTag work |
| 13545 Local<v8::Symbol> toStringTag = v8::Symbol::GetToStringTag(isolate); |
| 13546 |
| 13547 #define TEST_TOSTRINGTAG(type, tag, expected) \ |
| 13548 do { \ |
| 13549 object = CompileRun("new " #type "()"); \ |
| 13550 object.As<v8::Object>()->Set(toStringTag, v8_str(#tag)); \ |
| 13551 value = object.As<v8::Object>()->ObjectProtoToString(); \ |
| 13552 CHECK(value->IsString() && value->Equals( \ |
| 13553 v8_str("[object " #expected "]"))); \ |
| 13554 } while (0) |
| 13555 |
| 13556 TEST_TOSTRINGTAG(Array, Object, Object); |
| 13557 TEST_TOSTRINGTAG(Object, Arguments, ~Arguments); |
| 13558 TEST_TOSTRINGTAG(Object, Array, ~Array); |
| 13559 TEST_TOSTRINGTAG(Object, Boolean, ~Boolean); |
| 13560 TEST_TOSTRINGTAG(Object, Date, ~Date); |
| 13561 TEST_TOSTRINGTAG(Object, Error, ~Error); |
| 13562 TEST_TOSTRINGTAG(Object, Function, ~Function); |
| 13563 TEST_TOSTRINGTAG(Object, Number, ~Number); |
| 13564 TEST_TOSTRINGTAG(Object, RegExp, ~RegExp); |
| 13565 TEST_TOSTRINGTAG(Object, String, ~String); |
| 13566 TEST_TOSTRINGTAG(Object, Foo, Foo); |
| 13567 |
| 13568 #undef TEST_TOSTRINGTAG |
| 13569 |
| 13570 // @@toStringTag getter throws |
| 13571 Local<Value> obj = v8::Object::New(isolate); |
| 13572 obj.As<v8::Object>()->SetAccessor(toStringTag, ThrowingSymbolAccessorGetter); |
| 13573 { TryCatch try_catch; |
| 13574 value = obj.As<v8::Object>()->ObjectProtoToString(); |
| 13575 CHECK(value.IsEmpty()); |
| 13576 CHECK(try_catch.HasCaught()); |
| 13577 } |
| 13578 |
| 13579 // @@toStringTag getter does not throw |
| 13580 obj = v8::Object::New(isolate); |
| 13581 obj.As<v8::Object>()->SetAccessor(toStringTag, |
| 13582 SymbolAccessorGetterReturnsDefault, 0, v8_str("Test")); |
| 13583 { TryCatch try_catch; |
| 13584 value = obj.As<v8::Object>()->ObjectProtoToString(); |
| 13585 CHECK(value->IsString() && value->Equals(v8_str("[object Test]"))); |
| 13586 CHECK(!try_catch.HasCaught()); |
| 13587 } |
| 13588 |
| 13589 // JS @@toStringTag value |
| 13590 obj = CompileRun("obj = {}; obj[Symbol.toStringTag] = 'Test'; obj"); |
| 13591 { TryCatch try_catch; |
| 13592 value = obj.As<v8::Object>()->ObjectProtoToString(); |
| 13593 CHECK(value->IsString() && value->Equals(v8_str("[object Test]"))); |
| 13594 CHECK(!try_catch.HasCaught()); |
| 13595 } |
| 13596 |
| 13597 // JS @@toStringTag getter throws |
| 13598 obj = CompileRun("obj = {}; Object.defineProperty(obj, Symbol.toStringTag, {" |
| 13599 " get: function() { throw 'Test'; }" |
| 13600 "}); obj"); |
| 13601 { TryCatch try_catch; |
| 13602 value = obj.As<v8::Object>()->ObjectProtoToString(); |
| 13603 CHECK(value.IsEmpty()); |
| 13604 CHECK(try_catch.HasCaught()); |
| 13605 } |
| 13606 |
| 13607 // JS @@toStringTag getter does not throw |
| 13608 obj = CompileRun("obj = {}; Object.defineProperty(obj, Symbol.toStringTag, {" |
| 13609 " get: function() { return 'Test'; }" |
| 13610 "}); obj"); |
| 13611 { TryCatch try_catch; |
| 13612 value = obj.As<v8::Object>()->ObjectProtoToString(); |
| 13613 CHECK(value->IsString() && value->Equals(v8_str("[object Test]"))); |
| 13614 CHECK(!try_catch.HasCaught()); |
| 13615 } |
| 13616 } |
| 13617 |
| 13618 |
13495 THREADED_TEST(ObjectGetConstructorName) { | 13619 THREADED_TEST(ObjectGetConstructorName) { |
13496 LocalContext context; | 13620 LocalContext context; |
13497 v8::HandleScope scope(context->GetIsolate()); | 13621 v8::HandleScope scope(context->GetIsolate()); |
13498 v8_compile("function Parent() {};" | 13622 v8_compile("function Parent() {};" |
13499 "function Child() {};" | 13623 "function Child() {};" |
13500 "Child.prototype = new Parent();" | 13624 "Child.prototype = new Parent();" |
13501 "var outer = { inner: function() { } };" | 13625 "var outer = { inner: function() { } };" |
13502 "var p = new Parent();" | 13626 "var p = new Parent();" |
13503 "var c = new Child();" | 13627 "var c = new Child();" |
13504 "var x = new outer.inner();")->Run(); | 13628 "var x = new outer.inner();")->Run(); |
(...skipping 10329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
23834 char chunk2[] = | 23958 char chunk2[] = |
23835 "XXr = 13;\n" | 23959 "XXr = 13;\n" |
23836 " return foob\xeb\x91\x80\xeb\x91\x80r;\n" | 23960 " return foob\xeb\x91\x80\xeb\x91\x80r;\n" |
23837 "}\n"; | 23961 "}\n"; |
23838 chunk1[strlen(chunk1) - 1] = reference[0]; | 23962 chunk1[strlen(chunk1) - 1] = reference[0]; |
23839 chunk2[0] = reference[1]; | 23963 chunk2[0] = reference[1]; |
23840 chunk2[1] = reference[2]; | 23964 chunk2[1] = reference[2]; |
23841 const char* chunks[] = {chunk1, chunk2, "foo();", NULL}; | 23965 const char* chunks[] = {chunk1, chunk2, "foo();", NULL}; |
23842 RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8); | 23966 RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8); |
23843 } | 23967 } |
OLD | NEW |