The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / test / cctest / test-declarative-accessors.cc @ f230a1cf

History | View | Annotate | Download (10.6 KB)

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].Dispose();
46
      handles_[i].Clear();
47
    }
48
  }
49
  v8::Persistent<v8::Value> handles_[kArraySize];
50
 private:
51
  DISALLOW_COPY_AND_ASSIGN(HandleArray);
52
};
53

    
54

    
55
// An aligned character array of size 1024.
56
class AlignedArray : public Malloced {
57
 public:
58
  static const unsigned kArraySize = 1024/sizeof(uint64_t);
59
  AlignedArray() { Reset(); }
60

    
61
  void Reset() {
62
    for (unsigned i = 0; i < kArraySize; i++) {
63
      data_[i] = 0;
64
    }
65
  }
66

    
67
  template<typename T>
68
  T As() { return reinterpret_cast<T>(data_); }
69

    
70
 private:
71
  uint64_t data_[kArraySize];
72
  DISALLOW_COPY_AND_ASSIGN(AlignedArray);
73
};
74

    
75

    
76
class DescriptorTestHelper {
77
 public:
78
  DescriptorTestHelper() :
79
      isolate_(NULL), array_(new AlignedArray), handle_array_(new HandleArray) {
80
    v8::V8::Initialize();
81
    isolate_ = CcTest::isolate();
82
  }
83
  v8::Isolate* isolate_;
84
  // Data objects.
85
  SmartPointer<AlignedArray> array_;
86
  SmartPointer<HandleArray> handle_array_;
87
 private:
88
  DISALLOW_COPY_AND_ASSIGN(DescriptorTestHelper);
89
};
90

    
91

    
92
static v8::Local<v8::ObjectTemplate> CreateConstructor(
93
    v8::Handle<v8::Context> context,
94
    const char* class_name,
95
    int internal_field,
96
    const char* descriptor_name = NULL,
97
    v8::Handle<v8::DeclaredAccessorDescriptor> descriptor =
98
        v8::Handle<v8::DeclaredAccessorDescriptor>()) {
99
  v8::Local<v8::FunctionTemplate> constructor = v8::FunctionTemplate::New();
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();");
123
  v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(
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(value, isolate);
151
}
152

    
153

    
154
static v8::Handle<v8::Value> Convert(float value, v8::Isolate*) {
155
  return v8::Number::New(value);
156
}
157

    
158

    
159
static v8::Handle<v8::Value> Convert(double value, v8::Isolate*) {
160
  return v8::Number::New(value);
161
}
162

    
163

    
164
typedef v8::ObjectOperationDescriptor OOD;
165

    
166
template<typename T>
167
static void TestPrimitiveValue(
168
    T value,
169
    v8::DeclaredAccessorDescriptorDataType data_type,
170
    DescriptorTestHelper* helper) {
171
  v8::HandleScope handle_scope(helper->isolate_);
172
  int index = 17;
173
  int internal_field = 6;
174
  v8::Handle<v8::DeclaredAccessorDescriptor> descriptor =
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_, 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;
200
  v8::Handle<v8::RawOperationDescriptor> raw_descriptor =
201
      OOD::NewInternalFieldDereference(helper->isolate_, internal_field)
202
      ->NewRawShift(helper->isolate_, static_cast<uint16_t>(index*sizeof(T)));
203
  v8::Handle<v8::DeclaredAccessorDescriptor> descriptor;
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_;
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_;
251
  v8::Handle<v8::DeclaredAccessorDescriptor> descriptor =
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_;
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;
270
  v8::Handle<v8::DeclaredAccessorDescriptor> descriptor =
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_;
278
  array->As<uintptr_t**>()[first_index] =
279
      &array->As<uintptr_t*>()[pointed_to_index];
280
  VerifyRead(descriptor, internal_field, array, v8::Integer::New(0));
281
  second_index += pointed_to_index*sizeof(uintptr_t)/sizeof(uint16_t);
282
  array->As<uint16_t*>()[second_index] = expected;
283
  VerifyRead(descriptor, internal_field, array, v8::Integer::New(expected));
284
}
285

    
286

    
287
TEST(HandleDereferenceRead) {
288
  DescriptorTestHelper helper;
289
  v8::HandleScope handle_scope(helper.isolate_);
290
  int index = 13;
291
  int internal_field = 0;
292
  v8::Handle<v8::DeclaredAccessorDescriptor> descriptor =
293
      OOD::NewInternalFieldDereference(helper.isolate_, internal_field)
294
      ->NewRawShift(helper.isolate_, index*kPointerSize)
295
      ->NewHandleDereference(helper.isolate_);
296
  HandleArray* array = *helper.handle_array_;
297
  v8::Handle<v8::String> expected = v8_str("whatever");
298
  array->handles_[index].Reset(helper.isolate_, expected);
299
  VerifyRead(descriptor, internal_field, array, expected);
300
}