v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test-declarative-accessors.cc
Go to the documentation of this file.
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 class HandleArray : public Malloced {
38  public:
39  static const unsigned kArraySize = 200;
40  explicit HandleArray() {}
41  ~HandleArray() { Reset(); }
42  void Reset() {
43  for (unsigned i = 0; i < kArraySize; i++) {
44  if (handles_[i].IsEmpty()) continue;
45  handles_[i].Reset();
46  }
47  }
48  v8::Persistent<v8::Value> handles_[kArraySize];
49  private:
51 };
52 
53 
54 // An aligned character array of size 1024.
55 class AlignedArray : public Malloced {
56  public:
57  static const unsigned kArraySize = 1024/sizeof(uint64_t);
58  AlignedArray() { Reset(); }
59 
60  void Reset() {
61  for (unsigned i = 0; i < kArraySize; i++) {
62  data_[i] = 0;
63  }
64  }
65 
66  template<typename T>
67  T As() { return reinterpret_cast<T>(data_); }
68 
69  private:
70  uint64_t data_[kArraySize];
72 };
73 
74 
76  public:
78  isolate_(NULL), array_(new AlignedArray), handle_array_(new HandleArray) {
80  isolate_ = CcTest::isolate();
81  }
83  // Data objects.
86  private:
88 };
89 
90 
91 static v8::Local<v8::ObjectTemplate> CreateConstructor(
93  const char* class_name,
94  int internal_field,
95  const char* descriptor_name = NULL,
100  v8::Local<v8::ObjectTemplate> obj_template = constructor->InstanceTemplate();
101  // Setup object template.
102  if (descriptor_name != NULL && !descriptor.IsEmpty()) {
103  bool added_accessor =
104  obj_template->SetDeclaredAccessor(v8_str(descriptor_name), descriptor);
105  CHECK(added_accessor);
106  }
107  obj_template->SetInternalFieldCount((internal_field+1)*2 + 7);
108  context->Global()->Set(v8_str(class_name), constructor->GetFunction());
109  return obj_template;
110 }
111 
112 
113 static void VerifyRead(v8::Handle<v8::DeclaredAccessorDescriptor> descriptor,
114  int internal_field,
115  void* internal_object,
116  v8::Handle<v8::Value> expected_value) {
117  LocalContext local_context;
118  v8::HandleScope scope(local_context->GetIsolate());
119  v8::Handle<v8::Context> context = local_context.local();
120  CreateConstructor(context, "Accessible", internal_field, "x", descriptor);
121  // Setup object.
122  CompileRun("var accessible = new Accessible();");
124  context->Global()->Get(v8_str("accessible")));
125  obj->SetAlignedPointerInInternalField(internal_field, internal_object);
126  bool added_accessor;
127  added_accessor = obj->SetDeclaredAccessor(v8_str("y"), descriptor);
128  CHECK(added_accessor);
129  added_accessor = obj->SetDeclaredAccessor(v8_str("13"), descriptor);
130  CHECK(added_accessor);
131  // Test access from template getter.
132  v8::Local<v8::Value> value;
133  value = CompileRun("accessible.x;");
134  CHECK_EQ(expected_value, value);
135  value = CompileRun("accessible['x'];");
136  CHECK_EQ(expected_value, value);
137  // Test access from object getter.
138  value = CompileRun("accessible.y;");
139  CHECK_EQ(expected_value, value);
140  value = CompileRun("accessible['y'];");
141  CHECK_EQ(expected_value, value);
142  value = CompileRun("accessible[13];");
143  CHECK_EQ(expected_value, value);
144  value = CompileRun("accessible['13'];");
145  CHECK_EQ(expected_value, value);
146 }
147 
148 
149 static v8::Handle<v8::Value> Convert(int32_t value, v8::Isolate* isolate) {
150  return v8::Integer::New(isolate, value);
151 }
152 
153 
154 static v8::Handle<v8::Value> Convert(float value, v8::Isolate* isolate) {
155  return v8::Number::New(isolate, value);
156 }
157 
158 
159 static v8::Handle<v8::Value> Convert(double value, v8::Isolate* isolate) {
160  return v8::Number::New(isolate, value);
161 }
162 
163 
165 
166 template<typename T>
167 static void TestPrimitiveValue(
168  T value,
170  DescriptorTestHelper* helper) {
171  v8::HandleScope handle_scope(helper->isolate_);
172  int index = 17;
173  int internal_field = 6;
175  OOD::NewInternalFieldDereference(helper->isolate_, internal_field)
176  ->NewRawShift(helper->isolate_, static_cast<uint16_t>(index*sizeof(T)))
177  ->NewPrimitiveValue(helper->isolate_, data_type, 0);
178  v8::Handle<v8::Value> expected = Convert(value, helper->isolate_);
179  helper->array_->Reset();
180  helper->array_->As<T*>()[index] = value;
181  VerifyRead(descriptor, internal_field, helper->array_.get(), expected);
182 }
183 
184 
185 TEST(PrimitiveValueRead) {
186  DescriptorTestHelper helper;
187  TestPrimitiveValue<int32_t>(203, v8::kDescriptorInt32Type, &helper);
188  TestPrimitiveValue<float>(23.7f, v8::kDescriptorFloatType, &helper);
189  TestPrimitiveValue<double>(23.7, v8::kDescriptorDoubleType, &helper);
190 }
191 
192 
193 template<typename T>
194 static void TestBitmaskCompare(T bitmask,
195  T compare_value,
196  DescriptorTestHelper* helper) {
197  v8::HandleScope handle_scope(helper->isolate_);
198  int index = 13;
199  int internal_field = 4;
201  OOD::NewInternalFieldDereference(helper->isolate_, internal_field)
202  ->NewRawShift(helper->isolate_, static_cast<uint16_t>(index*sizeof(T)));
204  switch (sizeof(T)) {
205  case 1:
206  descriptor = raw_descriptor->NewBitmaskCompare8(
207  helper->isolate_,
208  static_cast<uint8_t>(bitmask),
209  static_cast<uint8_t>(compare_value));
210  break;
211  case 2:
212  descriptor = raw_descriptor->NewBitmaskCompare16(
213  helper->isolate_,
214  static_cast<uint16_t>(bitmask),
215  static_cast<uint16_t>(compare_value));
216  break;
217  case 4:
218  descriptor = raw_descriptor->NewBitmaskCompare32(
219  helper->isolate_,
220  static_cast<uint32_t>(bitmask),
221  static_cast<uint32_t>(compare_value));
222  break;
223  default:
224  CHECK(false);
225  break;
226  }
227  AlignedArray* array = helper->array_.get();
228  array->Reset();
229  VerifyRead(descriptor, internal_field, array, v8::False(helper->isolate_));
230  array->As<T*>()[index] = compare_value;
231  VerifyRead(descriptor, internal_field, array, v8::True(helper->isolate_));
232  helper->array_->As<T*>()[index] = compare_value & bitmask;
233  VerifyRead(descriptor, internal_field, array, v8::True(helper->isolate_));
234 }
235 
236 
237 TEST(BitmaskCompareRead) {
238  DescriptorTestHelper helper;
239  TestBitmaskCompare<uint8_t>(0xf3, 0xa8, &helper);
240  TestBitmaskCompare<uint16_t>(0xfefe, 0x7d42, &helper);
241  TestBitmaskCompare<uint32_t>(0xfefeab18, 0x1234fdec, &helper);
242 }
243 
244 
245 TEST(PointerCompareRead) {
246  DescriptorTestHelper helper;
247  v8::HandleScope handle_scope(helper.isolate_);
248  int index = 35;
249  int internal_field = 3;
250  void* ptr = helper.isolate_;
252  OOD::NewInternalFieldDereference(helper.isolate_, internal_field)
253  ->NewRawShift(helper.isolate_, static_cast<uint16_t>(index*sizeof(ptr)))
254  ->NewPointerCompare(helper.isolate_, ptr);
255  AlignedArray* array = helper.array_.get();
256  VerifyRead(descriptor, internal_field, array, v8::False(helper.isolate_));
257  array->As<uintptr_t*>()[index] = reinterpret_cast<uintptr_t>(ptr);
258  VerifyRead(descriptor, internal_field, array, v8::True(helper.isolate_));
259 }
260 
261 
262 TEST(PointerDereferenceRead) {
263  DescriptorTestHelper helper;
264  v8::HandleScope handle_scope(helper.isolate_);
265  int first_index = 13;
266  int internal_field = 7;
267  int second_index = 11;
268  int pointed_to_index = 75;
269  uint16_t expected = 0x1425;
271  OOD::NewInternalFieldDereference(helper.isolate_, internal_field)
272  ->NewRawShift(helper.isolate_, first_index*kPointerSize)
273  ->NewRawDereference(helper.isolate_)
274  ->NewRawShift(helper.isolate_,
275  static_cast<uint16_t>(second_index*sizeof(int16_t)))
276  ->NewPrimitiveValue(helper.isolate_, v8::kDescriptorInt16Type, 0);
277  AlignedArray* array = helper.array_.get();
278  array->As<uintptr_t**>()[first_index] =
279  &array->As<uintptr_t*>()[pointed_to_index];
280  VerifyRead(descriptor, internal_field, array,
281  v8::Integer::New(helper.isolate_, 0));
282  second_index += pointed_to_index*sizeof(uintptr_t)/sizeof(uint16_t);
283  array->As<uint16_t*>()[second_index] = expected;
284  VerifyRead(descriptor, internal_field, array,
285  v8::Integer::New(helper.isolate_, expected));
286 }
287 
288 
289 TEST(HandleDereferenceRead) {
290  DescriptorTestHelper helper;
291  v8::HandleScope handle_scope(helper.isolate_);
292  int index = 13;
293  int internal_field = 0;
295  OOD::NewInternalFieldDereference(helper.isolate_, internal_field)
296  ->NewRawShift(helper.isolate_, index*kPointerSize)
297  ->NewHandleDereference(helper.isolate_);
298  HandleArray* array = helper.handle_array_.get();
299  v8::Handle<v8::String> expected = v8_str("whatever");
300  array->handles_[index].Reset(helper.isolate_, expected);
301  VerifyRead(descriptor, internal_field, array, expected);
302 }
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
#define CHECK_EQ(expected, value)
Definition: checks.h:252
static Local< RawOperationDescriptor > NewInternalFieldDereference(Isolate *isolate, int internal_field)
Definition: api.cc:1007
bool SetDeclaredAccessor(Local< String > name, Local< DeclaredAccessorDescriptor > descriptor, PropertyAttribute attribute=None, AccessControl settings=DEFAULT)
Definition: api.cc:3450
Local< ObjectTemplate > InstanceTemplate()
Definition: api.cc:1223
int int32_t
Definition: unicode.cc:47
v8::Persistent< v8::Value > handles_[kArraySize]
unsigned short uint16_t
Definition: unicode.cc:46
static Local< Integer > New(Isolate *isolate, int32_t value)
Definition: api.cc:6233
#define CHECK(condition)
Definition: checks.h:75
Local< DeclaredAccessorDescriptor > NewBitmaskCompare32(Isolate *isolate, uint32_t bitmask, uint32_t compare_value)
Definition: api.cc:1096
v8::Isolate * GetIsolate()
Definition: api.cc:5233
void SetAlignedPointerInInternalField(int index, void *value)
Definition: api.cc:4929
V8_INLINE Handle< Boolean > True(Isolate *isolate)
Definition: v8.h:6559
const int kPointerSize
Definition: globals.h:268
static Local< FunctionTemplate > New(Isolate *isolate, FunctionCallback callback=0, Handle< Value > data=Handle< Value >(), Handle< Signature > signature=Handle< Signature >(), int length=0)
Definition: api.cc:942
Local< Object > Global()
Definition: api.cc:5239
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:359
Local< DeclaredAccessorDescriptor > NewBitmaskCompare8(Isolate *isolate, uint8_t bitmask, uint8_t compare_value)
Definition: api.cc:1080
static Local< Number > New(Isolate *isolate, double value)
Definition: api.cc:6220
static V8_INLINE Local< T > Cast(Local< S > that)
Definition: v8.h:372
#define T(name, string, precedence)
Definition: token.cc:48
SmartPointer< AlignedArray > array_
V8_INLINE Handle< Boolean > False(Isolate *isolate)
Definition: v8.h:6568
v8::ObjectOperationDescriptor OOD
SmartPointer< HandleArray > handle_array_
Local< Function > GetFunction()
Definition: api.cc:5299
V8_INLINE void Reset()
Definition: v8.h:5808
DeclaredAccessorDescriptorDataType
Definition: v8.h:3805
HeapObject * obj
Local< DeclaredAccessorDescriptor > NewBitmaskCompare16(Isolate *isolate, uint16_t bitmask, uint16_t compare_value)
Definition: api.cc:1088
v8::Local< v8::Context > local()
Definition: cctest.h:272
signed short int16_t
Definition: unicode.cc:45
Definition: v8.h:124
static bool Initialize()
Definition: api.cc:4967
static v8::Isolate * isolate()
Definition: cctest.h:96