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 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 void CheckThisIndexedPropertySetter( | 261 void CheckThisIndexedPropertySetter( |
262 uint32_t index, Local<Value> value, | 262 uint32_t index, Local<Value> value, |
263 const v8::PropertyCallbackInfo<v8::Value>& info) { | 263 const v8::PropertyCallbackInfo<v8::Value>& info) { |
264 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertySetter)); | 264 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertySetter)); |
265 ApiTestFuzzer::Fuzz(); | 265 ApiTestFuzzer::Fuzz(); |
266 CHECK(info.This() | 266 CHECK(info.This() |
267 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) | 267 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) |
268 .FromJust()); | 268 .FromJust()); |
269 } | 269 } |
270 | 270 |
| 271 void CheckThisIndexedPropertyDescriptor( |
| 272 uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 273 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyDescriptor)); |
| 274 ApiTestFuzzer::Fuzz(); |
| 275 CHECK(info.This() |
| 276 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) |
| 277 .FromJust()); |
| 278 } |
| 279 |
| 280 void CheckThisNamedPropertyDescriptor( |
| 281 Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 282 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyDescriptor)); |
| 283 ApiTestFuzzer::Fuzz(); |
| 284 CHECK(info.This() |
| 285 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) |
| 286 .FromJust()); |
| 287 } |
271 | 288 |
272 void CheckThisNamedPropertySetter( | 289 void CheckThisNamedPropertySetter( |
273 Local<Name> property, Local<Value> value, | 290 Local<Name> property, Local<Value> value, |
274 const v8::PropertyCallbackInfo<v8::Value>& info) { | 291 const v8::PropertyCallbackInfo<v8::Value>& info) { |
275 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertySetter)); | 292 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertySetter)); |
276 ApiTestFuzzer::Fuzz(); | 293 ApiTestFuzzer::Fuzz(); |
277 CHECK(info.This() | 294 CHECK(info.This() |
278 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) | 295 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) |
279 .FromJust()); | 296 .FromJust()); |
280 } | 297 } |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 ->Run(env.local()) | 1232 ->Run(env.local()) |
1216 .ToLocalChecked() | 1233 .ToLocalChecked() |
1217 ->BooleanValue(env.local()) | 1234 ->BooleanValue(env.local()) |
1218 .FromJust()); | 1235 .FromJust()); |
1219 } | 1236 } |
1220 | 1237 |
1221 namespace { | 1238 namespace { |
1222 void NotInterceptingPropertyDefineCallback( | 1239 void NotInterceptingPropertyDefineCallback( |
1223 Local<Name> name, const v8::PropertyDescriptor& desc, | 1240 Local<Name> name, const v8::PropertyDescriptor& desc, |
1224 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1241 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1225 // Do not intercept by not calling info.GetReturnValue().Set() | 1242 // Do not intercept by not calling info.GetReturnValue().Set(). |
1226 } | 1243 } |
1227 | 1244 |
1228 void InterceptingPropertyDefineCallback( | 1245 void InterceptingPropertyDefineCallback( |
1229 Local<Name> name, const v8::PropertyDescriptor& desc, | 1246 Local<Name> name, const v8::PropertyDescriptor& desc, |
1230 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1247 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1231 // intercept the callback by setting a non-empty handle | 1248 // Intercept the callback by setting a non-empty handle |
1232 info.GetReturnValue().Set(name); | 1249 info.GetReturnValue().Set(name); |
1233 } | 1250 } |
1234 | 1251 |
1235 void CheckDescriptorInDefineCallback( | 1252 void CheckDescriptorInDefineCallback( |
1236 Local<Name> name, const v8::PropertyDescriptor& desc, | 1253 Local<Name> name, const v8::PropertyDescriptor& desc, |
1237 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1254 const v8::PropertyCallbackInfo<v8::Value>& info) { |
1238 CHECK(!desc.has_writable()); | 1255 CHECK(!desc.has_writable()); |
1239 CHECK(!desc.has_value()); | 1256 CHECK(!desc.has_value()); |
1240 CHECK(!desc.has_enumerable()); | 1257 CHECK(!desc.has_enumerable()); |
1241 CHECK(desc.has_configurable()); | 1258 CHECK(desc.has_configurable()); |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1641 const char* code = | 1658 const char* code = |
1642 "Object.defineProperty(obj, 'x', {set: function() {return 42;}});" | 1659 "Object.defineProperty(obj, 'x', {set: function() {return 42;}});" |
1643 "obj.x = 17;"; | 1660 "obj.x = 17;"; |
1644 CHECK_EQ(17, v8_compile(code) | 1661 CHECK_EQ(17, v8_compile(code) |
1645 ->Run(env.local()) | 1662 ->Run(env.local()) |
1646 .ToLocalChecked() | 1663 .ToLocalChecked() |
1647 ->Int32Value(env.local()) | 1664 ->Int32Value(env.local()) |
1648 .FromJust()); | 1665 .FromJust()); |
1649 } | 1666 } |
1650 | 1667 |
| 1668 namespace { |
| 1669 void EmptyPropertyDescriptorCallback( |
| 1670 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 1671 // Do not intercept by not calling info.GetReturnValue().Set(). |
| 1672 } |
| 1673 |
| 1674 void InterceptingPropertyDescriptorCallback( |
| 1675 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 1676 // Intercept the callback by setting a different descriptor. |
| 1677 const char* code = |
| 1678 "var desc = {value: 42};" |
| 1679 "desc;"; |
| 1680 Local<Value> descriptor = v8_compile(code) |
| 1681 ->Run(info.GetIsolate()->GetCurrentContext()) |
| 1682 .ToLocalChecked(); |
| 1683 info.GetReturnValue().Set(descriptor); |
| 1684 } |
| 1685 } // namespace |
| 1686 |
| 1687 THREADED_TEST(PropertyDescriptorCallback) { |
| 1688 v8::HandleScope scope(CcTest::isolate()); |
| 1689 LocalContext env; |
| 1690 |
| 1691 { // Normal behavior of getOwnPropertyDescriptor() with empty callback. |
| 1692 v8::Local<v8::FunctionTemplate> templ = |
| 1693 v8::FunctionTemplate::New(CcTest::isolate()); |
| 1694 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( |
| 1695 0, 0, EmptyPropertyDescriptorCallback, 0, 0, 0)); |
| 1696 env->Global() |
| 1697 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local()) |
| 1698 .ToLocalChecked() |
| 1699 ->NewInstance(env.local()) |
| 1700 .ToLocalChecked()) |
| 1701 .FromJust(); |
| 1702 const char* code = |
| 1703 "obj.x = 17; " |
| 1704 "var desc = Object.getOwnPropertyDescriptor(obj, 'x');" |
| 1705 "desc.value;"; |
| 1706 CHECK_EQ(17, v8_compile(code) |
| 1707 ->Run(env.local()) |
| 1708 .ToLocalChecked() |
| 1709 ->Int32Value(env.local()) |
| 1710 .FromJust()); |
| 1711 } |
| 1712 |
| 1713 { // Intercept getOwnPropertyDescriptor(). |
| 1714 v8::Local<v8::FunctionTemplate> templ = |
| 1715 v8::FunctionTemplate::New(CcTest::isolate()); |
| 1716 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( |
| 1717 0, 0, InterceptingPropertyDescriptorCallback, 0, 0, 0)); |
| 1718 env->Global() |
| 1719 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local()) |
| 1720 .ToLocalChecked() |
| 1721 ->NewInstance(env.local()) |
| 1722 .ToLocalChecked()) |
| 1723 .FromJust(); |
| 1724 const char* code = |
| 1725 "obj.x = 17; " |
| 1726 "var desc = Object.getOwnPropertyDescriptor(obj, 'x');" |
| 1727 "desc.value;"; |
| 1728 CHECK_EQ(42, v8_compile(code) |
| 1729 ->Run(env.local()) |
| 1730 .ToLocalChecked() |
| 1731 ->Int32Value(env.local()) |
| 1732 .FromJust()); |
| 1733 } |
| 1734 } |
| 1735 |
1651 int echo_indexed_call_count = 0; | 1736 int echo_indexed_call_count = 0; |
1652 | 1737 |
1653 | 1738 |
1654 static void EchoIndexedProperty( | 1739 static void EchoIndexedProperty( |
1655 uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) { | 1740 uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) { |
1656 ApiTestFuzzer::Fuzz(); | 1741 ApiTestFuzzer::Fuzz(); |
1657 CHECK(v8_num(637) | 1742 CHECK(v8_num(637) |
1658 ->Equals(info.GetIsolate()->GetCurrentContext(), info.Data()) | 1743 ->Equals(info.GetIsolate()->GetCurrentContext(), info.Data()) |
1659 .FromJust()); | 1744 .FromJust()); |
1660 echo_indexed_call_count++; | 1745 echo_indexed_call_count++; |
(...skipping 21 matching lines...) Expand all Loading... |
1682 .FromJust(), | 1767 .FromJust(), |
1683 900); | 1768 900); |
1684 } | 1769 } |
1685 | 1770 |
1686 | 1771 |
1687 THREADED_TEST(PropertyHandlerInPrototype) { | 1772 THREADED_TEST(PropertyHandlerInPrototype) { |
1688 LocalContext env; | 1773 LocalContext env; |
1689 v8::Isolate* isolate = env->GetIsolate(); | 1774 v8::Isolate* isolate = env->GetIsolate(); |
1690 v8::HandleScope scope(isolate); | 1775 v8::HandleScope scope(isolate); |
1691 | 1776 |
1692 // Set up a prototype chain with three interceptors. | |
1693 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); | 1777 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); |
1694 templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( | 1778 templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( |
1695 CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, | 1779 CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, |
1696 CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter, | 1780 CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter, |
1697 CheckThisIndexedPropertyEnumerator, CheckThisIndexedPropertyDefiner)); | 1781 CheckThisIndexedPropertyEnumerator)); |
1698 | 1782 |
1699 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( | 1783 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( |
1700 CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter, | 1784 CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter, |
1701 CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter, | 1785 CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter, |
1702 CheckThisNamedPropertyEnumerator, CheckThisNamedPropertyDefiner)); | 1786 CheckThisNamedPropertyEnumerator)); |
1703 | 1787 |
1704 bottom = templ->GetFunction(env.local()) | 1788 bottom = templ->GetFunction(env.local()) |
1705 .ToLocalChecked() | 1789 .ToLocalChecked() |
1706 ->NewInstance(env.local()) | 1790 ->NewInstance(env.local()) |
1707 .ToLocalChecked(); | 1791 .ToLocalChecked(); |
1708 Local<v8::Object> top = templ->GetFunction(env.local()) | 1792 Local<v8::Object> top = templ->GetFunction(env.local()) |
1709 .ToLocalChecked() | 1793 .ToLocalChecked() |
1710 ->NewInstance(env.local()) | 1794 ->NewInstance(env.local()) |
1711 .ToLocalChecked(); | 1795 .ToLocalChecked(); |
1712 Local<v8::Object> middle = templ->GetFunction(env.local()) | 1796 Local<v8::Object> middle = templ->GetFunction(env.local()) |
(...skipping 16 matching lines...) Expand all Loading... |
1729 // Indexed and named query. | 1813 // Indexed and named query. |
1730 CompileRun("0 in obj"); | 1814 CompileRun("0 in obj"); |
1731 CompileRun("'x' in obj"); | 1815 CompileRun("'x' in obj"); |
1732 | 1816 |
1733 // Indexed and named deleter. | 1817 // Indexed and named deleter. |
1734 CompileRun("delete obj[0]"); | 1818 CompileRun("delete obj[0]"); |
1735 CompileRun("delete obj.x"); | 1819 CompileRun("delete obj.x"); |
1736 | 1820 |
1737 // Enumerators. | 1821 // Enumerators. |
1738 CompileRun("for (var p in obj) ;"); | 1822 CompileRun("for (var p in obj) ;"); |
| 1823 } |
| 1824 |
| 1825 TEST(PropertyHandlerInPrototypeWithDefine) { |
| 1826 LocalContext env; |
| 1827 v8::Isolate* isolate = env->GetIsolate(); |
| 1828 v8::HandleScope scope(isolate); |
| 1829 |
| 1830 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); |
| 1831 templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( |
| 1832 CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, |
| 1833 CheckThisIndexedPropertyDescriptor, CheckThisIndexedPropertyDeleter, |
| 1834 CheckThisIndexedPropertyEnumerator, CheckThisIndexedPropertyDefiner)); |
| 1835 |
| 1836 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( |
| 1837 CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter, |
| 1838 CheckThisNamedPropertyDescriptor, CheckThisNamedPropertyDeleter, |
| 1839 CheckThisNamedPropertyEnumerator, CheckThisNamedPropertyDefiner)); |
| 1840 |
| 1841 bottom = templ->GetFunction(env.local()) |
| 1842 .ToLocalChecked() |
| 1843 ->NewInstance(env.local()) |
| 1844 .ToLocalChecked(); |
| 1845 Local<v8::Object> top = templ->GetFunction(env.local()) |
| 1846 .ToLocalChecked() |
| 1847 ->NewInstance(env.local()) |
| 1848 .ToLocalChecked(); |
| 1849 Local<v8::Object> middle = templ->GetFunction(env.local()) |
| 1850 .ToLocalChecked() |
| 1851 ->NewInstance(env.local()) |
| 1852 .ToLocalChecked(); |
| 1853 |
| 1854 bottom->SetPrototype(env.local(), middle).FromJust(); |
| 1855 middle->SetPrototype(env.local(), top).FromJust(); |
| 1856 env->Global()->Set(env.local(), v8_str("obj"), bottom).FromJust(); |
| 1857 |
| 1858 // Indexed and named get. |
| 1859 CompileRun("obj[0]"); |
| 1860 CompileRun("obj.x"); |
| 1861 |
| 1862 // Indexed and named set. |
| 1863 CompileRun("obj[1] = 42"); |
| 1864 CompileRun("obj.y = 42"); |
| 1865 |
| 1866 // Indexed and named deleter. |
| 1867 CompileRun("delete obj[0]"); |
| 1868 CompileRun("delete obj.x"); |
| 1869 |
| 1870 // Enumerators. |
| 1871 CompileRun("for (var p in obj) ;"); |
1739 | 1872 |
1740 // Indexed and named definer. | 1873 // Indexed and named definer. |
1741 CompileRun("Object.defineProperty(obj, 2, {});"); | 1874 CompileRun("Object.defineProperty(obj, 2, {});"); |
1742 CompileRun("Object.defineProperty(obj, 'z', {});"); | 1875 CompileRun("Object.defineProperty(obj, 'z', {});"); |
| 1876 |
| 1877 // Indexed and named propertyDescriptor. |
| 1878 CompileRun("Object.getOwnPropertyDescriptor(obj, 2);"); |
| 1879 CompileRun("Object.getOwnPropertyDescriptor(obj, 'z');"); |
1743 } | 1880 } |
1744 | 1881 |
1745 | 1882 |
1746 bool is_bootstrapping = false; | 1883 bool is_bootstrapping = false; |
1747 static void PrePropertyHandlerGet( | 1884 static void PrePropertyHandlerGet( |
1748 Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) { | 1885 Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) { |
1749 ApiTestFuzzer::Fuzz(); | 1886 ApiTestFuzzer::Fuzz(); |
1750 if (!is_bootstrapping && | 1887 if (!is_bootstrapping && |
1751 v8_str("pre") | 1888 v8_str("pre") |
1752 ->Equals(info.GetIsolate()->GetCurrentContext(), key) | 1889 ->Equals(info.GetIsolate()->GetCurrentContext(), key) |
(...skipping 2783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4536 ->Set(env.local(), v8_str("Fun"), | 4673 ->Set(env.local(), v8_str("Fun"), |
4537 fun_templ->GetFunction(env.local()).ToLocalChecked()) | 4674 fun_templ->GetFunction(env.local()).ToLocalChecked()) |
4538 .FromJust()); | 4675 .FromJust()); |
4539 | 4676 |
4540 CompileRun( | 4677 CompileRun( |
4541 "var f = new Fun();" | 4678 "var f = new Fun();" |
4542 "Number.prototype.__proto__ = f;" | 4679 "Number.prototype.__proto__ = f;" |
4543 "var a = 42;" | 4680 "var a = 42;" |
4544 "for (var i = 0; i<3; i++) { a.foo; }"); | 4681 "for (var i = 0; i<3; i++) { a.foo; }"); |
4545 } | 4682 } |
OLD | NEW |