Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: test/cctest/test-declarative-accessors.cc

Issue 12297012: Runtime version of declarative native accessors. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« test/cctest/SConscript ('K') | « test/cctest/cctest.gyp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include <stdlib.h>
29
30 #include "v8.h"
31
32 #include "cctest.h"
33
34 using namespace v8::internal;
35
36
37 template<typename Type>
38 struct Checker {
39 static void CheckEq(const Type expected, const Type value) {
40 CHECK_EQ(static_cast<int64_t>(expected), static_cast<int64_t>(value));
41 }
42 };
43
44
45 template<>
46 struct Checker<void*> {
47 static void CheckEq(const void* expected, const void* value) {
48 CHECK_EQ(expected, value);
49 }
50 };
51
52
53 template<typename Type>
54 static void CheckSerialization(const Type expected) {
55 using namespace v8;
56 uint8_t smi_storage[AccessorDescriptorSerialization<Type>::kArraySize];
57 AccessorDescriptorSerialization<Type>::Serialize(expected, smi_storage);
58 const Type value =
59 AccessorDescriptorSerialization<Type>::Deserialize(smi_storage);
60 Checker<Type>::CheckEq(expected, value);
61 }
62
63
64 template<typename Type>
65 static void CheckBounds(Type min, Type max) {
66 CheckSerialization<Type>(static_cast<Type>(0));
67 CheckSerialization(min);
68 CheckSerialization(max);
69 }
70
71
72 TEST(MemberSerialization) {
73 CheckBounds<v8::AccessorDescriptorDataType>(
74 static_cast<v8::AccessorDescriptorDataType>(0),
75 static_cast<v8::AccessorDescriptorDataType>(INT16_MAX));
76 CheckBounds<v8::AccessorDescriptorType>(
77 static_cast<v8::AccessorDescriptorType>(0),
78 static_cast<v8::AccessorDescriptorType>(INT16_MAX));
79 CheckBounds<uint8_t>(0, UINT8_MAX);
80 CheckBounds<int8_t>(INT8_MIN, INT8_MAX);
81 CheckBounds<uint16_t>(0, INT16_MAX);
82 CheckBounds<int16_t>(INT16_MIN, INT16_MAX);
83 CheckBounds<uint32_t>(0, INT32_MAX);
84 CheckBounds<int32_t>(INT32_MIN, INT32_MAX);
85 CheckBounds<uint64_t>(0, INT64_MAX);
86 CheckBounds<int64_t>(INT64_MIN, INT64_MAX);
87 CheckBounds<void*>(reinterpret_cast<void*>(INTPTR_MIN),
88 reinterpret_cast<void*>(INTPTR_MAX));
89 }
90
91
92 TEST(DescriptorSerialization) {
93 v8::V8::Initialize();
94 v8::HandleScope scope;
95 LocalContext context;
96 // Create a descriptor.
97 v8::AccessorDescriptor accessor_descriptor =
98 { 6, -12, v8::kDescriptorPointerDereference, { NULL } };
99 v8::AccessorDescriptor sub_descriptor =
100 { 7, -11, v8::kDescriptorPointerCompare, { NULL } };
101 int arbitrary_value;
102 v8::PointerCompareDescriptor pointer_compare_descriptor =
103 { &arbitrary_value };
104 sub_descriptor.pointer_compare_descriptor = pointer_compare_descriptor;
105 accessor_descriptor.derefence_descriptor = &sub_descriptor;
106 // Serialize
107 uint16_t length;
108 uint8_t* storage;
109 {
110 length = DeclaredAccessorDescriptor::SerializedLength(&accessor_descriptor);
111 Handle<DeclaredAccessorDescriptor> descriptor =
112 DeclaredAccessorDescriptor::Create(&accessor_descriptor,
113 Isolate::Current());
114 AssertNoAllocation no_allocation;
115 ByteArray* array = descriptor->serialized_descriptor();
116 CHECK_EQ(length, array->length());
117 storage = new uint8_t[length];
118 for (int i = 0; i < length; i++) {
119 storage[i] = array->get(i);
120 }
121 }
122 // Deserialize
123 AccessorDescriptorDeserializer deserializer(length, storage);
124 v8::AccessorDescriptor deserialized;
125 deserializer.Next(&deserialized);
126 CHECK(!deserializer.Complete());
127 CHECK_EQ(6, deserialized.internal_field);
128 CHECK_EQ(-12, deserialized.byte_offset);
129 CHECK_EQ(v8::kDescriptorPointerDereference, deserialized.type);
130 deserializer.Next(&deserialized);
131 CHECK(deserializer.Complete());
132 CHECK_EQ(7, deserialized.internal_field);
133 CHECK_EQ(-11, deserialized.byte_offset);
134 CHECK_EQ(v8::kDescriptorPointerCompare, deserialized.type);
135 CHECK_EQ(&arbitrary_value,
136 deserialized.pointer_compare_descriptor.compare_value);
137 delete[] storage;
138 }
139
140
141 class HandleArray : public Malloced {
142 public:
143 static const unsigned kArraySize = 200;
144 explicit HandleArray() {}
145 ~HandleArray() { Reset(v8::Isolate::GetCurrent()); }
146 void Reset(v8::Isolate* isolate) {
147 for (unsigned i = 0; i < kArraySize; i++) {
148 if (handles[i].IsEmpty()) continue;
149 handles[i].Dispose(isolate);
150 handles[i].Clear();
151 }
152 }
153 v8::Persistent<v8::Value> handles[kArraySize];
154 private:
155 DISALLOW_COPY_AND_ASSIGN(HandleArray);
156 };
157
158
159 // An aligned character array of size 1024.
160 class AlignedArray : public Malloced {
161 public:
162 static const unsigned kArraySize = 1024/sizeof(uint64_t);
163 AlignedArray() { Reset(); }
164
165 void Reset() {
166 for (unsigned i = 0; i < kArraySize; i++) {
167 data[i] = 0;
168 }
169 }
170
171 template<typename T>
172 T As() { return reinterpret_cast<T>(data); }
173
174 private:
175 uint64_t data[kArraySize];
176 DISALLOW_COPY_AND_ASSIGN(AlignedArray);
177 };
178
179
180 class DescriptorTestHelper {
181 public:
182 DescriptorTestHelper() :
183 isolate_(NULL), array_(new AlignedArray), handle_array_(new HandleArray) {
184 v8::V8::Initialize();
185 isolate_ = v8::Isolate::GetCurrent();
186 }
187 v8::Isolate* isolate_;
188 // Data objects.
189 SmartPointer<AlignedArray> array_;
190 SmartPointer<HandleArray> handle_array_;
191 private:
192 DISALLOW_COPY_AND_ASSIGN(DescriptorTestHelper);
193 };
194
195
196 static v8::Local<v8::ObjectTemplate> CreateConstructor(
197 v8::Handle<v8::Context> context,
198 const char* class_name,
199 int internal_fields,
200 const char* descriptor_name = NULL,
201 const v8::AccessorDescriptor* descriptor = NULL) {
202 v8::Local<v8::FunctionTemplate> constructor = v8::FunctionTemplate::New();
203 v8::Local<v8::ObjectTemplate> obj_template = constructor->InstanceTemplate();
204 // Setup object template.
205 if (descriptor_name != NULL && descriptor != NULL) {
206 bool added_accessor =
207 obj_template->SetAccessor(v8_str(descriptor_name), descriptor);
208 CHECK(added_accessor);
209 }
210 obj_template->SetInternalFieldCount(internal_fields);
211 context->Global()->Set(v8_str(class_name), constructor->GetFunction());
212 return obj_template;
213 }
214
215
216 static void VerifyRead(const v8::AccessorDescriptor* descriptor,
217 void* internal_object,
218 v8::Handle<v8::Value> expected_value,
219 v8::Local<v8::Context> context =
220 v8::Local<v8::Context>()) {
221 v8::HandleScope scope;
222 // Generate a context if necessary and retry.
223 if (context.IsEmpty()) {
224 LocalContext local_context;
225 VerifyRead(descriptor,
226 internal_object,
227 expected_value,
228 local_context.local());
229 return;
230 }
231 int internal_field = descriptor->internal_field;
232 int total_fields = (internal_field+1)*2 + 7;
233 CreateConstructor(context, "Accessible", total_fields, "x", descriptor);
234 // Setup object.
235 CompileRun("var accessible = new Accessible();");
236 v8::Local<v8::Object> obj(
237 v8::Object::Cast(*context->Global()->Get(v8_str("accessible"))));
238 obj->SetAlignedPointerInInternalField(internal_field, internal_object);
239 bool added_accessor;
240 added_accessor = obj->SetAccessor(v8_str("y"), descriptor);
241 CHECK(added_accessor);
242 added_accessor = obj->SetAccessor(v8_str("13"), descriptor);
243 CHECK(added_accessor);
244 // Test access from template getter.
245 v8::Local<v8::Value> value;
246 value = CompileRun("accessible.x;");
247 CHECK_EQ(expected_value, value);
248 value = CompileRun("accessible['x'];");
249 CHECK_EQ(expected_value, value);
250 // Test access from object getter.
251 value = CompileRun("accessible.y;");
252 CHECK_EQ(expected_value, value);
253 value = CompileRun("accessible['y'];");
254 CHECK_EQ(expected_value, value);
255 value = CompileRun("accessible[13];");
256 CHECK_EQ(expected_value, value);
257 value = CompileRun("accessible['13'];");
258 CHECK_EQ(expected_value, value);
259 }
260
261
262 static v8::Handle<v8::Value> Convert(int32_t value, v8::Isolate* isolate) {
263 return v8::Integer::New(value, isolate);
264 }
265
266
267 static v8::Handle<v8::Value> Convert(float value, v8::Isolate*) {
268 return v8::Number::New(value);
269 }
270
271
272 static v8::Handle<v8::Value> Convert(double value, v8::Isolate*) {
273 return v8::Number::New(value);
274 }
275
276
277 template<typename T>
278 static void TestPrimitiveValue(T value,
279 v8::AccessorDescriptorDataType data_type,
280 DescriptorTestHelper* helper) {
281 v8::HandleScope handle_scope;
282 int index = 17;
283 v8::AccessorDescriptor descriptor =
284 { 3, index*sizeof(T), v8::kDescriptorPrimitiveValue, { NULL } };
285 v8::PrimitiveValueDescriptor sub_descriptor = { data_type, 0 };
286 descriptor.primitive_value_descriptor = sub_descriptor;
287 v8::Handle<v8::Value> expected = Convert(value, helper->isolate_);
288 helper->array_->Reset();
289 helper->array_->As<T*>()[index] = value;
290 VerifyRead(&descriptor, *helper->array_, expected);
291 }
292
293
294 TEST(PrimitiveValueRead) {
295 DescriptorTestHelper helper;
296 TestPrimitiveValue<int32_t>(203, v8::kDescriptorInt32Type, &helper);
297 TestPrimitiveValue<float>(23.7f, v8::kDescriptorFloatType, &helper);
298 TestPrimitiveValue<double>(23.7, v8::kDescriptorDoubleType, &helper);
299 }
300
301
302 template<typename T>
303 static void TestBitmaskCompare(uint32_t bitmask,
304 uint32_t compare_value,
305 DescriptorTestHelper* helper) {
306 v8::HandleScope handle_scope;
307 int index = 13;
308 v8::AccessorDescriptor descriptor =
309 { 3, index*sizeof(T), v8::kDescriptorBitmaskCompare, { NULL } };
310 v8::BitmaskCompareDescriptor sub_descriptor =
311 { bitmask, compare_value, sizeof(T) };
312 descriptor.bitmask_compare_descriptor = sub_descriptor;
313 helper->array_->Reset();
314 VerifyRead(&descriptor, *helper->array_, v8::False(helper->isolate_));
315 helper->array_->As<T*>()[index] = compare_value;
316 VerifyRead(&descriptor, *helper->array_, v8::True(helper->isolate_));
317 helper->array_->As<T*>()[index] = compare_value & bitmask;
318 VerifyRead(&descriptor, *helper->array_, v8::True(helper->isolate_));
319 }
320
321
322 TEST(BitmaskCompareRead) {
323 DescriptorTestHelper helper;
324 TestBitmaskCompare<uint8_t>(0xf3, 0xa8, &helper);
325 TestBitmaskCompare<uint16_t>(0xfefe, 0x7d42, &helper);
326 TestBitmaskCompare<uint32_t>(0xfefeab18, 0x1234fdec, &helper);
327 }
328
329
330 TEST(PointerCompareRead) {
331 DescriptorTestHelper helper;
332 v8::HandleScope handle_scope;
333 void* ptr = helper.isolate_;
334 int index = 35;
335 v8::AccessorDescriptor descriptor =
336 { 3, index * sizeof(ptr), v8::kDescriptorPointerCompare, { NULL } };
337 v8::PointerCompareDescriptor sub_descriptor = { ptr };
338 descriptor.pointer_compare_descriptor = sub_descriptor;
339 VerifyRead(&descriptor, *helper.array_, v8::False(helper.isolate_));
340 helper.array_->As<uintptr_t*>()[index] = reinterpret_cast<uintptr_t>(ptr);
341 VerifyRead(&descriptor, *helper.array_, v8::True(helper.isolate_));
342 }
343
344
345 TEST(PointerDeferenceRead) {
346 DescriptorTestHelper helper;
347 v8::HandleScope handle_scope;
348 int first_index = 13;
349 int pointed_to_index = 75;
350 int second_index = 11;
351 uint16_t expected = 0x1425;
352 v8::AccessorDescriptor descriptor =
353 { 3, first_index*kPointerSize, v8::kDescriptorPointerDereference,
354 { NULL } };
355 v8::AccessorDescriptor sub_descriptor =
356 { 0, second_index*sizeof(int16_t), v8::kDescriptorPrimitiveValue,
357 { NULL } };
358 v8::PrimitiveValueDescriptor sub_sub_descriptor =
359 { v8::kDescriptorInt16Type, 0 };
360 descriptor.derefence_descriptor = &sub_descriptor;
361 sub_descriptor.primitive_value_descriptor = sub_sub_descriptor;
362 AlignedArray* array = *helper.array_;
363 array->As<uintptr_t**>()[first_index] =
364 &array->As<uintptr_t*>()[pointed_to_index];
365 VerifyRead(&descriptor, array, v8::Integer::New(0));
366 second_index += pointed_to_index*sizeof(uintptr_t)/sizeof(uint16_t);
367 array->As<uint16_t*>()[second_index] = expected;
368 VerifyRead(&descriptor, array, v8::Integer::New(expected));
369 }
370
371 TEST(HandleDeferenceRead) {
372 DescriptorTestHelper helper;
373 v8::HandleScope handle_scope;
374 int first_index = 13;
375 int second_index = 11;
376 uint16_t expected = 0x1425;
377 v8::AccessorDescriptor descriptor =
378 { 3, first_index*kPointerSize, v8::kDescriptorInternalFieldDereference,
379 { NULL } };
380 v8::AccessorDescriptor sub_descriptor =
381 { 2, second_index*sizeof(int16_t), v8::kDescriptorPrimitiveValue,
382 { NULL } };
383 v8::PrimitiveValueDescriptor sub_sub_descriptor =
384 { v8::kDescriptorInt16Type, 0 };
385 descriptor.derefence_descriptor = &sub_descriptor;
386 sub_descriptor.primitive_value_descriptor = sub_sub_descriptor;
387 // Setup object.
388 LocalContext local_context;
389 v8::Local<v8::Context> context = local_context.local();
390 v8::Local<v8::Object> object;
391 {
392 CreateConstructor(context, "SomeObject", 7);
393 CompileRun("var some_object = new SomeObject();");
394 v8::Local<v8::Object> object(
395 v8::Object::Cast(*context->Global()->Get(v8_str("some_object"))));
396 object->SetAlignedPointerInInternalField(
397 sub_descriptor.internal_field, *helper.array_);
398 helper.handle_array_->handles[first_index] =
399 v8::Persistent<v8::Value>::New(helper.isolate_, object);
400 }
401 VerifyRead(&descriptor, *helper.handle_array_, v8::Integer::New(0), context);
402 helper.array_->As<uint16_t*>()[second_index] = expected;
403 VerifyRead(&descriptor, *helper.handle_array_, v8::Integer::New(expected));
404 }
405
OLDNEW
« test/cctest/SConscript ('K') | « test/cctest/cctest.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698