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 / src / arguments.h @ f230a1cf

History | View | Annotate | Download (10.8 KB)

1
// Copyright 2012 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
#ifndef V8_ARGUMENTS_H_
29
#define V8_ARGUMENTS_H_
30

    
31
#include "allocation.h"
32

    
33
namespace v8 {
34
namespace internal {
35

    
36
// Arguments provides access to runtime call parameters.
37
//
38
// It uses the fact that the instance fields of Arguments
39
// (length_, arguments_) are "overlayed" with the parameters
40
// (no. of parameters, and the parameter pointer) passed so
41
// that inside the C++ function, the parameters passed can
42
// be accessed conveniently:
43
//
44
//   Object* Runtime_function(Arguments args) {
45
//     ... use args[i] here ...
46
//   }
47

    
48
class Arguments BASE_EMBEDDED {
49
 public:
50
  Arguments(int length, Object** arguments)
51
      : length_(length), arguments_(arguments) { }
52

    
53
  Object*& operator[] (int index) {
54
    ASSERT(0 <= index && index < length_);
55
    return *(reinterpret_cast<Object**>(reinterpret_cast<intptr_t>(arguments_) -
56
                                        index * kPointerSize));
57
  }
58

    
59
  template <class S> Handle<S> at(int index) {
60
    Object** value = &((*this)[index]);
61
    // This cast checks that the object we're accessing does indeed have the
62
    // expected type.
63
    S::cast(*value);
64
    return Handle<S>(reinterpret_cast<S**>(value));
65
  }
66

    
67
  int smi_at(int index) {
68
    return Smi::cast((*this)[index])->value();
69
  }
70

    
71
  double number_at(int index) {
72
    return (*this)[index]->Number();
73
  }
74

    
75
  // Get the total number of arguments including the receiver.
76
  int length() const { return length_; }
77

    
78
  Object** arguments() { return arguments_; }
79

    
80
 private:
81
  int length_;
82
  Object** arguments_;
83
};
84

    
85

    
86
// For each type of callback, we have a list of arguments
87
// They are used to generate the Call() functions below
88
// These aren't included in the list as they have duplicate signatures
89
// F(NamedPropertyEnumeratorCallback, ...)
90
// F(NamedPropertyGetterCallback, ...)
91

    
92
#define FOR_EACH_CALLBACK_TABLE_MAPPING_0(F) \
93
  F(IndexedPropertyEnumeratorCallback, v8::Array) \
94

    
95
#define FOR_EACH_CALLBACK_TABLE_MAPPING_1(F) \
96
  F(AccessorGetterCallback, v8::Value, v8::Local<v8::String>) \
97
  F(NamedPropertyQueryCallback, \
98
    v8::Integer, \
99
    v8::Local<v8::String>) \
100
  F(NamedPropertyDeleterCallback, \
101
    v8::Boolean, \
102
    v8::Local<v8::String>) \
103
  F(IndexedPropertyGetterCallback, \
104
    v8::Value, \
105
    uint32_t) \
106
  F(IndexedPropertyQueryCallback, \
107
    v8::Integer, \
108
    uint32_t) \
109
  F(IndexedPropertyDeleterCallback, \
110
    v8::Boolean, \
111
    uint32_t) \
112

    
113
#define FOR_EACH_CALLBACK_TABLE_MAPPING_2(F) \
114
  F(NamedPropertySetterCallback, \
115
    v8::Value, \
116
    v8::Local<v8::String>, \
117
    v8::Local<v8::Value>) \
118
  F(IndexedPropertySetterCallback, \
119
    v8::Value, \
120
    uint32_t, \
121
    v8::Local<v8::Value>) \
122

    
123
#define FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(F) \
124
  F(AccessorSetterCallback, \
125
    void, \
126
    v8::Local<v8::String>, \
127
    v8::Local<v8::Value>) \
128

    
129

    
130
// Custom arguments replicate a small segment of stack that can be
131
// accessed through an Arguments object the same way the actual stack
132
// can.
133
template<int kArrayLength>
134
class CustomArgumentsBase : public Relocatable {
135
 public:
136
  virtual inline void IterateInstance(ObjectVisitor* v) {
137
    v->VisitPointers(values_, values_ + kArrayLength);
138
  }
139
 protected:
140
  inline Object** begin() { return values_; }
141
  explicit inline CustomArgumentsBase(Isolate* isolate)
142
      : Relocatable(isolate) {}
143
  Object* values_[kArrayLength];
144
};
145

    
146

    
147
template<typename T>
148
class CustomArguments : public CustomArgumentsBase<T::kArgsLength> {
149
 public:
150
  static const int kReturnValueOffset = T::kReturnValueIndex;
151

    
152
  typedef CustomArgumentsBase<T::kArgsLength> Super;
153
  ~CustomArguments() {
154
    this->begin()[kReturnValueOffset] =
155
        reinterpret_cast<Object*>(kHandleZapValue);
156
  }
157

    
158
 protected:
159
  explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {}
160

    
161
  template<typename V>
162
  v8::Handle<V> GetReturnValue(Isolate* isolate);
163

    
164
  inline Isolate* isolate() {
165
    return reinterpret_cast<Isolate*>(this->begin()[T::kIsolateIndex]);
166
  }
167
};
168

    
169

    
170
class PropertyCallbackArguments
171
    : public CustomArguments<PropertyCallbackInfo<Value> > {
172
 public:
173
  typedef PropertyCallbackInfo<Value> T;
174
  typedef CustomArguments<T> Super;
175
  static const int kArgsLength = T::kArgsLength;
176
  static const int kThisIndex = T::kThisIndex;
177
  static const int kHolderIndex = T::kHolderIndex;
178
  static const int kDataIndex = T::kDataIndex;
179
  static const int kReturnValueDefaultValueIndex =
180
      T::kReturnValueDefaultValueIndex;
181
  static const int kIsolateIndex = T::kIsolateIndex;
182

    
183
  PropertyCallbackArguments(Isolate* isolate,
184
                            Object* data,
185
                            Object* self,
186
                            JSObject* holder)
187
      : Super(isolate) {
188
    Object** values = this->begin();
189
    values[T::kThisIndex] = self;
190
    values[T::kHolderIndex] = holder;
191
    values[T::kDataIndex] = data;
192
    values[T::kIsolateIndex] = reinterpret_cast<Object*>(isolate);
193
    // Here the hole is set as default value.
194
    // It cannot escape into js as it's remove in Call below.
195
    values[T::kReturnValueDefaultValueIndex] =
196
        isolate->heap()->the_hole_value();
197
    values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
198
    ASSERT(values[T::kHolderIndex]->IsHeapObject());
199
    ASSERT(values[T::kIsolateIndex]->IsSmi());
200
  }
201

    
202
  /*
203
   * The following Call functions wrap the calling of all callbacks to handle
204
   * calling either the old or the new style callbacks depending on which one
205
   * has been registered.
206
   * For old callbacks which return an empty handle, the ReturnValue is checked
207
   * and used if it's been set to anything inside the callback.
208
   * New style callbacks always use the return value.
209
   */
210
#define WRITE_CALL_0(Function, ReturnValue)                                  \
211
  v8::Handle<ReturnValue> Call(Function f);                                  \
212

    
213
#define WRITE_CALL_1(Function, ReturnValue, Arg1)                            \
214
  v8::Handle<ReturnValue> Call(Function f, Arg1 arg1);                       \
215

    
216
#define WRITE_CALL_2(Function, ReturnValue, Arg1, Arg2)                      \
217
  v8::Handle<ReturnValue> Call(Function f, Arg1 arg1, Arg2 arg2);            \
218

    
219
#define WRITE_CALL_2_VOID(Function, ReturnValue, Arg1, Arg2)                 \
220
  void Call(Function f, Arg1 arg1, Arg2 arg2);                               \
221

    
222
FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0)
223
FOR_EACH_CALLBACK_TABLE_MAPPING_1(WRITE_CALL_1)
224
FOR_EACH_CALLBACK_TABLE_MAPPING_2(WRITE_CALL_2)
225
FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(WRITE_CALL_2_VOID)
226

    
227
#undef WRITE_CALL_0
228
#undef WRITE_CALL_1
229
#undef WRITE_CALL_2
230
#undef WRITE_CALL_2_VOID
231
};
232

    
233

    
234
class FunctionCallbackArguments
235
    : public CustomArguments<FunctionCallbackInfo<Value> > {
236
 public:
237
  typedef FunctionCallbackInfo<Value> T;
238
  typedef CustomArguments<T> Super;
239
  static const int kArgsLength = T::kArgsLength;
240
  static const int kHolderIndex = T::kHolderIndex;
241
  static const int kDataIndex = T::kDataIndex;
242
  static const int kReturnValueDefaultValueIndex =
243
      T::kReturnValueDefaultValueIndex;
244
  static const int kIsolateIndex = T::kIsolateIndex;
245
  static const int kCalleeIndex = T::kCalleeIndex;
246
  static const int kContextSaveIndex = T::kContextSaveIndex;
247

    
248
  FunctionCallbackArguments(internal::Isolate* isolate,
249
      internal::Object* data,
250
      internal::JSFunction* callee,
251
      internal::Object* holder,
252
      internal::Object** argv,
253
      int argc,
254
      bool is_construct_call)
255
        : Super(isolate),
256
          argv_(argv),
257
          argc_(argc),
258
          is_construct_call_(is_construct_call) {
259
    Object** values = begin();
260
    values[T::kDataIndex] = data;
261
    values[T::kCalleeIndex] = callee;
262
    values[T::kHolderIndex] = holder;
263
    values[T::kContextSaveIndex] = isolate->heap()->the_hole_value();
264
    values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate);
265
    // Here the hole is set as default value.
266
    // It cannot escape into js as it's remove in Call below.
267
    values[T::kReturnValueDefaultValueIndex] =
268
        isolate->heap()->the_hole_value();
269
    values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
270
    ASSERT(values[T::kCalleeIndex]->IsJSFunction());
271
    ASSERT(values[T::kHolderIndex]->IsHeapObject());
272
    ASSERT(values[T::kIsolateIndex]->IsSmi());
273
  }
274

    
275
  /*
276
   * The following Call function wraps the calling of all callbacks to handle
277
   * calling either the old or the new style callbacks depending on which one
278
   * has been registered.
279
   * For old callbacks which return an empty handle, the ReturnValue is checked
280
   * and used if it's been set to anything inside the callback.
281
   * New style callbacks always use the return value.
282
   */
283
  v8::Handle<v8::Value> Call(FunctionCallback f);
284

    
285
 private:
286
  internal::Object** argv_;
287
  int argc_;
288
  bool is_construct_call_;
289
};
290

    
291

    
292
#define DECLARE_RUNTIME_FUNCTION(Type, Name)    \
293
Type Name(int args_length, Object** args_object, Isolate* isolate)
294

    
295
#define RUNTIME_FUNCTION(Type, Name)                                  \
296
static Type __RT_impl_##Name(Arguments args, Isolate* isolate);       \
297
Type Name(int args_length, Object** args_object, Isolate* isolate) {  \
298
  Arguments args(args_length, args_object);                           \
299
  return __RT_impl_##Name(args, isolate);                             \
300
}                                                                     \
301
static Type __RT_impl_##Name(Arguments args, Isolate* isolate)
302

    
303
#define RUNTIME_ARGUMENTS(isolate, args) \
304
  args.length(), args.arguments(), isolate
305

    
306
} }  // namespace v8::internal
307

    
308
#endif  // V8_ARGUMENTS_H_