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 CcTest::InitializeVM(); | |
Dmitry Lomov (no reviews)
2014/10/19 08:49:52
Ah, ok, then you don't need InitializeVM here - ju
| |
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 LocalContext context; | |
13520 | |
13521 Local<String> customized_tostring = v8_str("customized toString"); | |
13522 | |
13523 // Replace Object.prototype.toString | |
13524 v8_compile("Object.prototype.toString = function() {" | |
Dmitry Lomov (no reviews)
2014/10/19 08:49:52
Nit: CompileRun here
| |
13525 " return 'customized toString';" | |
13526 "}")->Run(); | |
13527 | |
13528 // Normal ToString call should call replaced Object.prototype.toString | |
13529 Local<v8::Object> instance = templ->GetFunction()->NewInstance(); | |
13530 Local<String> value = instance->ToString(); | |
13531 CHECK(value->IsString() && value->Equals(customized_tostring)); | |
13532 | |
13533 // ObjectProtoToString should not call replace toString function. | |
13534 value = instance->ObjectProtoToString(); | |
13535 CHECK(value->IsString() && value->Equals(v8_str("[object MyClass]"))); | |
13536 | |
13537 // Check global | |
13538 value = context->Global()->ObjectProtoToString(); | |
13539 CHECK(value->IsString() && value->Equals(v8_str("[object global]"))); | |
13540 | |
13541 // Check ordinary object | |
13542 Local<Value> object = v8_compile("new Object()")->Run(); | |
Dmitry Lomov (no reviews)
2014/10/19 08:49:52
Nit: CompileRun here
| |
13543 value = object.As<v8::Object>()->ObjectProtoToString(); | |
13544 CHECK(value->IsString() && value->Equals(v8_str("[object Object]"))); | |
13545 | |
13546 // Check that ES6 semantics using @@toStringTag work | |
13547 Local<v8::Symbol> toStringTag = v8::Symbol::GetToStringTag(isolate); | |
13548 | |
13549 #define TEST_TOSTRINGTAG(type, tag, expected) \ | |
13550 do { \ | |
13551 object = CompileRun("new " #type "()"); \ | |
13552 object.As<v8::Object>()->Set(toStringTag, v8_str(#tag)); \ | |
13553 value = object.As<v8::Object>()->ObjectProtoToString(); \ | |
13554 CHECK(value->IsString() && value->Equals( \ | |
13555 v8_str("[object " #expected "]"))); \ | |
13556 } while (0) | |
13557 | |
13558 TEST_TOSTRINGTAG(Array, Object, Object); | |
13559 TEST_TOSTRINGTAG(Object, Arguments, ~Arguments); | |
13560 TEST_TOSTRINGTAG(Object, Array, ~Array); | |
13561 TEST_TOSTRINGTAG(Object, Boolean, ~Boolean); | |
13562 TEST_TOSTRINGTAG(Object, Date, ~Date); | |
13563 TEST_TOSTRINGTAG(Object, Error, ~Error); | |
13564 TEST_TOSTRINGTAG(Object, Function, ~Function); | |
13565 TEST_TOSTRINGTAG(Object, Number, ~Number); | |
13566 TEST_TOSTRINGTAG(Object, RegExp, ~RegExp); | |
13567 TEST_TOSTRINGTAG(Object, String, ~String); | |
13568 TEST_TOSTRINGTAG(Object, Foo, Foo); | |
13569 | |
13570 #undef TEST_TOSTRINGTAG | |
13571 | |
13572 // @@toStringTag getter throws | |
13573 Local<Value> obj = v8::Object::New(isolate); | |
13574 obj.As<v8::Object>()->SetAccessor(toStringTag, ThrowingSymbolAccessorGetter); | |
13575 { TryCatch try_catch; | |
13576 value = obj.As<v8::Object>()->ObjectProtoToString(); | |
13577 CHECK(value.IsEmpty()); | |
13578 CHECK(try_catch.HasCaught()); | |
13579 } | |
13580 | |
13581 // @@toStringTag getter does not throw | |
13582 obj = v8::Object::New(isolate); | |
13583 obj.As<v8::Object>()->SetAccessor(toStringTag, | |
13584 SymbolAccessorGetterReturnsDefault, 0, v8_str("Test")); | |
13585 { TryCatch try_catch; | |
13586 value = obj.As<v8::Object>()->ObjectProtoToString(); | |
13587 CHECK(value->IsString() && value->Equals(v8_str("[object Test]"))); | |
13588 CHECK(!try_catch.HasCaught()); | |
13589 } | |
13590 | |
13591 // JS @@toStringTag value | |
13592 obj = CompileRun("obj = {}; obj[Symbol.toStringTag] = 'Test'; obj"); | |
13593 { TryCatch try_catch; | |
13594 value = obj.As<v8::Object>()->ObjectProtoToString(); | |
13595 CHECK(value->IsString() && value->Equals(v8_str("[object Test]"))); | |
13596 CHECK(!try_catch.HasCaught()); | |
13597 } | |
13598 | |
13599 // JS @@toStringTag getter throws | |
13600 obj = CompileRun("obj = {}; Object.defineProperty(obj, Symbol.toStringTag, {" | |
13601 " get: function() { throw 'Test'; }" | |
13602 "}); obj"); | |
13603 { TryCatch try_catch; | |
13604 value = obj.As<v8::Object>()->ObjectProtoToString(); | |
13605 CHECK(value.IsEmpty()); | |
13606 CHECK(try_catch.HasCaught()); | |
13607 } | |
13608 | |
13609 // JS @@toStringTag getter does not throw | |
13610 obj = CompileRun("obj = {}; Object.defineProperty(obj, Symbol.toStringTag, {" | |
13611 " get: function() { return 'Test'; }" | |
13612 "}); obj"); | |
13613 { TryCatch try_catch; | |
13614 value = obj.As<v8::Object>()->ObjectProtoToString(); | |
13615 CHECK(value->IsString() && value->Equals(v8_str("[object Test]"))); | |
13616 CHECK(!try_catch.HasCaught()); | |
13617 } | |
13618 } | |
13619 | |
13620 | |
13495 THREADED_TEST(ObjectGetConstructorName) { | 13621 THREADED_TEST(ObjectGetConstructorName) { |
13496 LocalContext context; | 13622 LocalContext context; |
13497 v8::HandleScope scope(context->GetIsolate()); | 13623 v8::HandleScope scope(context->GetIsolate()); |
13498 v8_compile("function Parent() {};" | 13624 v8_compile("function Parent() {};" |
13499 "function Child() {};" | 13625 "function Child() {};" |
13500 "Child.prototype = new Parent();" | 13626 "Child.prototype = new Parent();" |
13501 "var outer = { inner: function() { } };" | 13627 "var outer = { inner: function() { } };" |
13502 "var p = new Parent();" | 13628 "var p = new Parent();" |
13503 "var c = new Child();" | 13629 "var c = new Child();" |
13504 "var x = new outer.inner();")->Run(); | 13630 "var x = new outer.inner();")->Run(); |
(...skipping 10329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
23834 char chunk2[] = | 23960 char chunk2[] = |
23835 "XXr = 13;\n" | 23961 "XXr = 13;\n" |
23836 " return foob\xeb\x91\x80\xeb\x91\x80r;\n" | 23962 " return foob\xeb\x91\x80\xeb\x91\x80r;\n" |
23837 "}\n"; | 23963 "}\n"; |
23838 chunk1[strlen(chunk1) - 1] = reference[0]; | 23964 chunk1[strlen(chunk1) - 1] = reference[0]; |
23839 chunk2[0] = reference[1]; | 23965 chunk2[0] = reference[1]; |
23840 chunk2[1] = reference[2]; | 23966 chunk2[1] = reference[2]; |
23841 const char* chunks[] = {chunk1, chunk2, "foo();", NULL}; | 23967 const char* chunks[] = {chunk1, chunk2, "foo();", NULL}; |
23842 RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8); | 23968 RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8); |
23843 } | 23969 } |
OLD | NEW |