OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include "test/cctest/test-api.h" | 7 #include "test/cctest/test-api.h" |
8 | 8 |
9 #include "include/v8-util.h" | 9 #include "include/v8-util.h" |
10 #include "src/api.h" | 10 #include "src/api.h" |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 void CheckThisIndexedPropertySetter( | 262 void CheckThisIndexedPropertySetter( |
263 uint32_t index, Local<Value> value, | 263 uint32_t index, Local<Value> value, |
264 const v8::PropertyCallbackInfo<v8::Value>& info) { | 264 const v8::PropertyCallbackInfo<v8::Value>& info) { |
265 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertySetter)); | 265 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertySetter)); |
266 ApiTestFuzzer::Fuzz(); | 266 ApiTestFuzzer::Fuzz(); |
267 CHECK(info.This() | 267 CHECK(info.This() |
268 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) | 268 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) |
269 .FromJust()); | 269 .FromJust()); |
270 } | 270 } |
271 | 271 |
| 272 void CheckThisIndexedPropertyDescriptor( |
| 273 uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 274 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyDescriptor)); |
| 275 ApiTestFuzzer::Fuzz(); |
| 276 CHECK(info.This() |
| 277 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) |
| 278 .FromJust()); |
| 279 } |
| 280 |
| 281 void CheckThisNamedPropertyDescriptor( |
| 282 Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 283 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyDescriptor)); |
| 284 ApiTestFuzzer::Fuzz(); |
| 285 CHECK(info.This() |
| 286 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) |
| 287 .FromJust()); |
| 288 } |
272 | 289 |
273 void CheckThisNamedPropertySetter( | 290 void CheckThisNamedPropertySetter( |
274 Local<Name> property, Local<Value> value, | 291 Local<Name> property, Local<Value> value, |
275 const v8::PropertyCallbackInfo<v8::Value>& info) { | 292 const v8::PropertyCallbackInfo<v8::Value>& info) { |
276 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertySetter)); | 293 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertySetter)); |
277 ApiTestFuzzer::Fuzz(); | 294 ApiTestFuzzer::Fuzz(); |
278 CHECK(info.This() | 295 CHECK(info.This() |
279 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) | 296 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) |
280 .FromJust()); | 297 .FromJust()); |
281 } | 298 } |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1216 ->Run(env.local()) | 1233 ->Run(env.local()) |
1217 .ToLocalChecked() | 1234 .ToLocalChecked() |
1218 ->BooleanValue(env.local()) | 1235 ->BooleanValue(env.local()) |
1219 .FromJust()); | 1236 .FromJust()); |
1220 } | 1237 } |
1221 | 1238 |
1222 namespace { | 1239 namespace { |
1223 void NotInterceptingPropertyDefineCallback( | 1240 void NotInterceptingPropertyDefineCallback( |
1224 Local<Name> name, const v8::PropertyDescriptor& desc, | 1241 Local<Name> name, const v8::PropertyDescriptor& desc, |
1225 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1242 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1226 // Do not intercept by not calling info.GetReturnValue().Set() | 1243 // Do not intercept by not calling info.GetReturnValue().Set(). |
1227 } | 1244 } |
1228 | 1245 |
1229 void InterceptingPropertyDefineCallback( | 1246 void InterceptingPropertyDefineCallback( |
1230 Local<Name> name, const v8::PropertyDescriptor& desc, | 1247 Local<Name> name, const v8::PropertyDescriptor& desc, |
1231 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1248 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1232 // intercept the callback by setting a non-empty handle | 1249 // Intercept the callback by setting a non-empty handle |
1233 info.GetReturnValue().Set(name); | 1250 info.GetReturnValue().Set(name); |
1234 } | 1251 } |
1235 | 1252 |
1236 void CheckDescriptorInDefineCallback( | 1253 void CheckDescriptorInDefineCallback( |
1237 Local<Name> name, const v8::PropertyDescriptor& desc, | 1254 Local<Name> name, const v8::PropertyDescriptor& desc, |
1238 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1255 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1239 CHECK(!desc.has_writable()); | 1256 CHECK(!desc.has_writable()); |
1240 CHECK(!desc.has_value()); | 1257 CHECK(!desc.has_value()); |
1241 CHECK(!desc.has_enumerable()); | 1258 CHECK(!desc.has_enumerable()); |
1242 CHECK(desc.has_configurable()); | 1259 CHECK(desc.has_configurable()); |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1642 const char* code = | 1659 const char* code = |
1643 "Object.defineProperty(obj, 'x', {set: function() {return 42;}});" | 1660 "Object.defineProperty(obj, 'x', {set: function() {return 42;}});" |
1644 "obj.x = 17;"; | 1661 "obj.x = 17;"; |
1645 CHECK_EQ(17, v8_compile(code) | 1662 CHECK_EQ(17, v8_compile(code) |
1646 ->Run(env.local()) | 1663 ->Run(env.local()) |
1647 .ToLocalChecked() | 1664 .ToLocalChecked() |
1648 ->Int32Value(env.local()) | 1665 ->Int32Value(env.local()) |
1649 .FromJust()); | 1666 .FromJust()); |
1650 } | 1667 } |
1651 | 1668 |
| 1669 namespace { |
| 1670 void EmptyPropertyDescriptorCallback( |
| 1671 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 1672 // Do not intercept by not calling info.GetReturnValue().Set(). |
| 1673 } |
| 1674 |
| 1675 void InterceptingPropertyDescriptorCallback( |
| 1676 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 1677 // Intercept the callback by setting a different descriptor. |
| 1678 const char* code = |
| 1679 "var desc = {value: 42};" |
| 1680 "desc;"; |
| 1681 Local<Value> descriptor = v8_compile(code) |
| 1682 ->Run(info.GetIsolate()->GetCurrentContext()) |
| 1683 .ToLocalChecked(); |
| 1684 info.GetReturnValue().Set(descriptor); |
| 1685 } |
| 1686 |
| 1687 void InterceptingPropertyDescriptorCallbackInvalid( |
| 1688 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 1689 // Intercept the callback and set an invalid descriptor. |
| 1690 const char* code = |
| 1691 "var desc = {set: 42};" |
| 1692 "desc;"; |
| 1693 Local<Value> descriptor = v8_compile(code) |
| 1694 ->Run(info.GetIsolate()->GetCurrentContext()) |
| 1695 .ToLocalChecked(); |
| 1696 info.GetReturnValue().Set(descriptor); |
| 1697 } |
| 1698 } // namespace |
| 1699 |
| 1700 THREADED_TEST(PropertyDescriptorCallback) { |
| 1701 v8::HandleScope scope(CcTest::isolate()); |
| 1702 LocalContext env; |
| 1703 |
| 1704 { // Normal behavior of getOwnPropertyDescriptor() with empty callback. |
| 1705 v8::Local<v8::FunctionTemplate> templ = |
| 1706 v8::FunctionTemplate::New(CcTest::isolate()); |
| 1707 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( |
| 1708 0, 0, EmptyPropertyDescriptorCallback, 0, 0, 0)); |
| 1709 env->Global() |
| 1710 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local()) |
| 1711 .ToLocalChecked() |
| 1712 ->NewInstance(env.local()) |
| 1713 .ToLocalChecked()) |
| 1714 .FromJust(); |
| 1715 const char* code = |
| 1716 "obj.x = 17; " |
| 1717 "var desc = Object.getOwnPropertyDescriptor(obj, 'x');" |
| 1718 "desc.value;"; |
| 1719 CHECK_EQ(17, v8_compile(code) |
| 1720 ->Run(env.local()) |
| 1721 .ToLocalChecked() |
| 1722 ->Int32Value(env.local()) |
| 1723 .FromJust()); |
| 1724 } |
| 1725 |
| 1726 { // Intercept getOwnPropertyDescriptor(). |
| 1727 v8::Local<v8::FunctionTemplate> templ = |
| 1728 v8::FunctionTemplate::New(CcTest::isolate()); |
| 1729 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( |
| 1730 0, 0, InterceptingPropertyDescriptorCallback, 0, 0, 0)); |
| 1731 env->Global() |
| 1732 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local()) |
| 1733 .ToLocalChecked() |
| 1734 ->NewInstance(env.local()) |
| 1735 .ToLocalChecked()) |
| 1736 .FromJust(); |
| 1737 const char* code = |
| 1738 "obj.x = 17; " |
| 1739 "var desc = Object.getOwnPropertyDescriptor(obj, 'x');" |
| 1740 "desc.value;"; |
| 1741 CHECK_EQ(42, v8_compile(code) |
| 1742 ->Run(env.local()) |
| 1743 .ToLocalChecked() |
| 1744 ->Int32Value(env.local()) |
| 1745 .FromJust()); |
| 1746 } |
| 1747 |
| 1748 { // Intercept getOwnPropertyDescriptor() with invalid descriptor. |
| 1749 v8::Local<v8::FunctionTemplate> templ = |
| 1750 v8::FunctionTemplate::New(CcTest::isolate()); |
| 1751 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( |
| 1752 0, 0, InterceptingPropertyDescriptorCallbackInvalid, 0, 0, 0)); |
| 1753 env->Global() |
| 1754 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local()) |
| 1755 .ToLocalChecked() |
| 1756 ->NewInstance(env.local()) |
| 1757 .ToLocalChecked()) |
| 1758 .FromJust(); |
| 1759 const char* code = |
| 1760 "obj.x = 17; " |
| 1761 "var desc = Object.getOwnPropertyDescriptor(obj, 'x');" |
| 1762 "desc"; |
| 1763 CHECK(v8_compile(code)->Run(env.local()).IsEmpty()); |
| 1764 } |
| 1765 } |
| 1766 |
1652 int echo_indexed_call_count = 0; | 1767 int echo_indexed_call_count = 0; |
1653 | 1768 |
1654 | 1769 |
1655 static void EchoIndexedProperty( | 1770 static void EchoIndexedProperty( |
1656 uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) { | 1771 uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) { |
1657 ApiTestFuzzer::Fuzz(); | 1772 ApiTestFuzzer::Fuzz(); |
1658 CHECK(v8_num(637) | 1773 CHECK(v8_num(637) |
1659 ->Equals(info.GetIsolate()->GetCurrentContext(), info.Data()) | 1774 ->Equals(info.GetIsolate()->GetCurrentContext(), info.Data()) |
1660 .FromJust()); | 1775 .FromJust()); |
1661 echo_indexed_call_count++; | 1776 echo_indexed_call_count++; |
(...skipping 21 matching lines...) Expand all Loading... |
1683 .FromJust(), | 1798 .FromJust(), |
1684 900); | 1799 900); |
1685 } | 1800 } |
1686 | 1801 |
1687 | 1802 |
1688 THREADED_TEST(PropertyHandlerInPrototype) { | 1803 THREADED_TEST(PropertyHandlerInPrototype) { |
1689 LocalContext env; | 1804 LocalContext env; |
1690 v8::Isolate* isolate = env->GetIsolate(); | 1805 v8::Isolate* isolate = env->GetIsolate(); |
1691 v8::HandleScope scope(isolate); | 1806 v8::HandleScope scope(isolate); |
1692 | 1807 |
1693 // Set up a prototype chain with three interceptors. | |
1694 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); | 1808 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); |
1695 templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( | 1809 templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( |
1696 CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, | 1810 CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, |
1697 CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter, | 1811 CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter, |
1698 CheckThisIndexedPropertyEnumerator, CheckThisIndexedPropertyDefiner)); | 1812 CheckThisIndexedPropertyEnumerator)); |
1699 | 1813 |
1700 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( | 1814 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( |
1701 CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter, | 1815 CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter, |
1702 CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter, | 1816 CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter, |
1703 CheckThisNamedPropertyEnumerator, CheckThisNamedPropertyDefiner)); | 1817 CheckThisNamedPropertyEnumerator)); |
1704 | 1818 |
1705 bottom = templ->GetFunction(env.local()) | 1819 bottom = templ->GetFunction(env.local()) |
1706 .ToLocalChecked() | 1820 .ToLocalChecked() |
1707 ->NewInstance(env.local()) | 1821 ->NewInstance(env.local()) |
1708 .ToLocalChecked(); | 1822 .ToLocalChecked(); |
1709 Local<v8::Object> top = templ->GetFunction(env.local()) | 1823 Local<v8::Object> top = templ->GetFunction(env.local()) |
1710 .ToLocalChecked() | 1824 .ToLocalChecked() |
1711 ->NewInstance(env.local()) | 1825 ->NewInstance(env.local()) |
1712 .ToLocalChecked(); | 1826 .ToLocalChecked(); |
1713 Local<v8::Object> middle = templ->GetFunction(env.local()) | 1827 Local<v8::Object> middle = templ->GetFunction(env.local()) |
(...skipping 16 matching lines...) Expand all Loading... |
1730 // Indexed and named query. | 1844 // Indexed and named query. |
1731 CompileRun("0 in obj"); | 1845 CompileRun("0 in obj"); |
1732 CompileRun("'x' in obj"); | 1846 CompileRun("'x' in obj"); |
1733 | 1847 |
1734 // Indexed and named deleter. | 1848 // Indexed and named deleter. |
1735 CompileRun("delete obj[0]"); | 1849 CompileRun("delete obj[0]"); |
1736 CompileRun("delete obj.x"); | 1850 CompileRun("delete obj.x"); |
1737 | 1851 |
1738 // Enumerators. | 1852 // Enumerators. |
1739 CompileRun("for (var p in obj) ;"); | 1853 CompileRun("for (var p in obj) ;"); |
| 1854 } |
| 1855 |
| 1856 TEST(PropertyHandlerInPrototypeWithDefine) { |
| 1857 LocalContext env; |
| 1858 v8::Isolate* isolate = env->GetIsolate(); |
| 1859 v8::HandleScope scope(isolate); |
| 1860 |
| 1861 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); |
| 1862 templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( |
| 1863 CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, |
| 1864 CheckThisIndexedPropertyDescriptor, CheckThisIndexedPropertyDeleter, |
| 1865 CheckThisIndexedPropertyEnumerator, CheckThisIndexedPropertyDefiner)); |
| 1866 |
| 1867 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( |
| 1868 CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter, |
| 1869 CheckThisNamedPropertyDescriptor, CheckThisNamedPropertyDeleter, |
| 1870 CheckThisNamedPropertyEnumerator, CheckThisNamedPropertyDefiner)); |
| 1871 |
| 1872 bottom = templ->GetFunction(env.local()) |
| 1873 .ToLocalChecked() |
| 1874 ->NewInstance(env.local()) |
| 1875 .ToLocalChecked(); |
| 1876 Local<v8::Object> top = templ->GetFunction(env.local()) |
| 1877 .ToLocalChecked() |
| 1878 ->NewInstance(env.local()) |
| 1879 .ToLocalChecked(); |
| 1880 Local<v8::Object> middle = templ->GetFunction(env.local()) |
| 1881 .ToLocalChecked() |
| 1882 ->NewInstance(env.local()) |
| 1883 .ToLocalChecked(); |
| 1884 |
| 1885 bottom->SetPrototype(env.local(), middle).FromJust(); |
| 1886 middle->SetPrototype(env.local(), top).FromJust(); |
| 1887 env->Global()->Set(env.local(), v8_str("obj"), bottom).FromJust(); |
| 1888 |
| 1889 // Indexed and named get. |
| 1890 CompileRun("obj[0]"); |
| 1891 CompileRun("obj.x"); |
| 1892 |
| 1893 // Indexed and named set. |
| 1894 CompileRun("obj[1] = 42"); |
| 1895 CompileRun("obj.y = 42"); |
| 1896 |
| 1897 // Indexed and named deleter. |
| 1898 CompileRun("delete obj[0]"); |
| 1899 CompileRun("delete obj.x"); |
| 1900 |
| 1901 // Enumerators. |
| 1902 CompileRun("for (var p in obj) ;"); |
1740 | 1903 |
1741 // Indexed and named definer. | 1904 // Indexed and named definer. |
1742 CompileRun("Object.defineProperty(obj, 2, {});"); | 1905 CompileRun("Object.defineProperty(obj, 2, {});"); |
1743 CompileRun("Object.defineProperty(obj, 'z', {});"); | 1906 CompileRun("Object.defineProperty(obj, 'z', {});"); |
| 1907 |
| 1908 // Indexed and named propertyDescriptor. |
| 1909 CompileRun("Object.getOwnPropertyDescriptor(obj, 2);"); |
| 1910 CompileRun("Object.getOwnPropertyDescriptor(obj, 'z');"); |
1744 } | 1911 } |
1745 | 1912 |
1746 | 1913 |
1747 bool is_bootstrapping = false; | 1914 bool is_bootstrapping = false; |
1748 static void PrePropertyHandlerGet( | 1915 static void PrePropertyHandlerGet( |
1749 Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) { | 1916 Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) { |
1750 ApiTestFuzzer::Fuzz(); | 1917 ApiTestFuzzer::Fuzz(); |
1751 if (!is_bootstrapping && | 1918 if (!is_bootstrapping && |
1752 v8_str("pre") | 1919 v8_str("pre") |
1753 ->Equals(info.GetIsolate()->GetCurrentContext(), key) | 1920 ->Equals(info.GetIsolate()->GetCurrentContext(), key) |
(...skipping 2780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4534 ->Set(env.local(), v8_str("Fun"), | 4701 ->Set(env.local(), v8_str("Fun"), |
4535 fun_templ->GetFunction(env.local()).ToLocalChecked()) | 4702 fun_templ->GetFunction(env.local()).ToLocalChecked()) |
4536 .FromJust()); | 4703 .FromJust()); |
4537 | 4704 |
4538 CompileRun( | 4705 CompileRun( |
4539 "var f = new Fun();" | 4706 "var f = new Fun();" |
4540 "Number.prototype.__proto__ = f;" | 4707 "Number.prototype.__proto__ = f;" |
4541 "var a = 42;" | 4708 "var a = 42;" |
4542 "for (var i = 0; i<3; i++) { a.foo; }"); | 4709 "for (var i = 0; i<3; i++) { a.foo; }"); |
4543 } | 4710 } |
OLD | NEW |