| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #ifndef V8_ARGUMENTS_H_ | 5 #ifndef V8_ARGUMENTS_H_ |
| 6 #define V8_ARGUMENTS_H_ | 6 #define V8_ARGUMENTS_H_ |
| 7 | 7 |
| 8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
| 9 #include "src/isolate.h" | 9 #include "src/objects-inl.h" |
| 10 #include "src/tracing/trace-event.h" | 10 #include "src/tracing/trace-event.h" |
| 11 | 11 |
| 12 namespace v8 { | 12 namespace v8 { |
| 13 namespace internal { | 13 namespace internal { |
| 14 | 14 |
| 15 // Arguments provides access to runtime call parameters. | 15 // Arguments provides access to runtime call parameters. |
| 16 // | 16 // |
| 17 // It uses the fact that the instance fields of Arguments | 17 // It uses the fact that the instance fields of Arguments |
| 18 // (length_, arguments_) are "overlayed" with the parameters | 18 // (length_, arguments_) are "overlayed" with the parameters |
| 19 // (no. of parameters, and the parameter pointer) passed so | 19 // (no. of parameters, and the parameter pointer) passed so |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 | 64 |
| 65 Object** lowest_address() { return &this->operator[](length() - 1); } | 65 Object** lowest_address() { return &this->operator[](length() - 1); } |
| 66 | 66 |
| 67 Object** highest_address() { return &this->operator[](0); } | 67 Object** highest_address() { return &this->operator[](0); } |
| 68 | 68 |
| 69 private: | 69 private: |
| 70 intptr_t length_; | 70 intptr_t length_; |
| 71 Object** arguments_; | 71 Object** arguments_; |
| 72 }; | 72 }; |
| 73 | 73 |
| 74 | |
| 75 // For each type of callback, we have a list of arguments | |
| 76 // They are used to generate the Call() functions below | |
| 77 // These aren't included in the list as they have duplicate signatures | |
| 78 // F(GenericNamedPropertyEnumeratorCallback, ...) | |
| 79 // F(GenericNamedPropertyGetterCallback, ...) | |
| 80 | |
| 81 #define FOR_EACH_CALLBACK_TABLE_MAPPING_0(F) \ | |
| 82 F(IndexedPropertyEnumeratorCallback, v8::Array) | |
| 83 | |
| 84 #define FOR_EACH_CALLBACK_TABLE_MAPPING_1(F) \ | |
| 85 F(AccessorNameGetterCallback, v8::Value, v8::Local<v8::Name>) \ | |
| 86 F(GenericNamedPropertyQueryCallback, v8::Integer, v8::Local<v8::Name>) \ | |
| 87 F(GenericNamedPropertyDeleterCallback, v8::Boolean, v8::Local<v8::Name>) \ | |
| 88 F(IndexedPropertyGetterCallback, v8::Value, uint32_t) \ | |
| 89 F(IndexedPropertyQueryCallback, v8::Integer, uint32_t) \ | |
| 90 F(IndexedPropertyDeleterCallback, v8::Boolean, uint32_t) | |
| 91 | |
| 92 #define FOR_EACH_CALLBACK_TABLE_MAPPING_2(F) \ | |
| 93 F(GenericNamedPropertySetterCallback, v8::Value, v8::Local<v8::Name>, \ | |
| 94 v8::Local<v8::Value>) \ | |
| 95 F(IndexedPropertySetterCallback, v8::Value, uint32_t, v8::Local<v8::Value>) | |
| 96 | |
| 97 #define FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(F) \ | |
| 98 F(AccessorNameSetterCallback, \ | |
| 99 void, \ | |
| 100 v8::Local<v8::Name>, \ | |
| 101 v8::Local<v8::Value>) \ | |
| 102 | |
| 103 | |
| 104 // Custom arguments replicate a small segment of stack that can be | |
| 105 // accessed through an Arguments object the same way the actual stack | |
| 106 // can. | |
| 107 template<int kArrayLength> | |
| 108 class CustomArgumentsBase : public Relocatable { | |
| 109 public: | |
| 110 virtual inline void IterateInstance(ObjectVisitor* v) { | |
| 111 v->VisitPointers(values_, values_ + kArrayLength); | |
| 112 } | |
| 113 protected: | |
| 114 inline Object** begin() { return values_; } | |
| 115 explicit inline CustomArgumentsBase(Isolate* isolate) | |
| 116 : Relocatable(isolate) {} | |
| 117 Object* values_[kArrayLength]; | |
| 118 }; | |
| 119 | |
| 120 | |
| 121 template<typename T> | |
| 122 class CustomArguments : public CustomArgumentsBase<T::kArgsLength> { | |
| 123 public: | |
| 124 static const int kReturnValueOffset = T::kReturnValueIndex; | |
| 125 | |
| 126 typedef CustomArgumentsBase<T::kArgsLength> Super; | |
| 127 ~CustomArguments() { | |
| 128 this->begin()[kReturnValueOffset] = | |
| 129 reinterpret_cast<Object*>(kHandleZapValue); | |
| 130 } | |
| 131 | |
| 132 protected: | |
| 133 explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {} | |
| 134 | |
| 135 template <typename V> | |
| 136 v8::Local<V> GetReturnValue(Isolate* isolate); | |
| 137 | |
| 138 inline Isolate* isolate() { | |
| 139 return reinterpret_cast<Isolate*>(this->begin()[T::kIsolateIndex]); | |
| 140 } | |
| 141 }; | |
| 142 | |
| 143 | |
| 144 class PropertyCallbackArguments | |
| 145 : public CustomArguments<PropertyCallbackInfo<Value> > { | |
| 146 public: | |
| 147 typedef PropertyCallbackInfo<Value> T; | |
| 148 typedef CustomArguments<T> Super; | |
| 149 static const int kArgsLength = T::kArgsLength; | |
| 150 static const int kThisIndex = T::kThisIndex; | |
| 151 static const int kHolderIndex = T::kHolderIndex; | |
| 152 static const int kDataIndex = T::kDataIndex; | |
| 153 static const int kReturnValueDefaultValueIndex = | |
| 154 T::kReturnValueDefaultValueIndex; | |
| 155 static const int kIsolateIndex = T::kIsolateIndex; | |
| 156 static const int kShouldThrowOnErrorIndex = T::kShouldThrowOnErrorIndex; | |
| 157 | |
| 158 PropertyCallbackArguments(Isolate* isolate, Object* data, Object* self, | |
| 159 JSObject* holder, Object::ShouldThrow should_throw) | |
| 160 : Super(isolate) { | |
| 161 Object** values = this->begin(); | |
| 162 values[T::kThisIndex] = self; | |
| 163 values[T::kHolderIndex] = holder; | |
| 164 values[T::kDataIndex] = data; | |
| 165 values[T::kIsolateIndex] = reinterpret_cast<Object*>(isolate); | |
| 166 values[T::kShouldThrowOnErrorIndex] = | |
| 167 Smi::FromInt(should_throw == Object::THROW_ON_ERROR ? 1 : 0); | |
| 168 | |
| 169 // Here the hole is set as default value. | |
| 170 // It cannot escape into js as it's remove in Call below. | |
| 171 values[T::kReturnValueDefaultValueIndex] = | |
| 172 isolate->heap()->the_hole_value(); | |
| 173 values[T::kReturnValueIndex] = isolate->heap()->the_hole_value(); | |
| 174 DCHECK(values[T::kHolderIndex]->IsHeapObject()); | |
| 175 DCHECK(values[T::kIsolateIndex]->IsSmi()); | |
| 176 } | |
| 177 | |
| 178 /* | |
| 179 * The following Call functions wrap the calling of all callbacks to handle | |
| 180 * calling either the old or the new style callbacks depending on which one | |
| 181 * has been registered. | |
| 182 * For old callbacks which return an empty handle, the ReturnValue is checked | |
| 183 * and used if it's been set to anything inside the callback. | |
| 184 * New style callbacks always use the return value. | |
| 185 */ | |
| 186 #define WRITE_CALL_0(Function, ReturnValue) \ | |
| 187 v8::Local<ReturnValue> Call(Function f); | |
| 188 | |
| 189 #define WRITE_CALL_1(Function, ReturnValue, Arg1) \ | |
| 190 v8::Local<ReturnValue> Call(Function f, Arg1 arg1); | |
| 191 | |
| 192 #define WRITE_CALL_2(Function, ReturnValue, Arg1, Arg2) \ | |
| 193 v8::Local<ReturnValue> Call(Function f, Arg1 arg1, Arg2 arg2); | |
| 194 | |
| 195 #define WRITE_CALL_2_VOID(Function, ReturnValue, Arg1, Arg2) \ | |
| 196 void Call(Function f, Arg1 arg1, Arg2 arg2); \ | |
| 197 | |
| 198 FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0) | |
| 199 FOR_EACH_CALLBACK_TABLE_MAPPING_1(WRITE_CALL_1) | |
| 200 FOR_EACH_CALLBACK_TABLE_MAPPING_2(WRITE_CALL_2) | |
| 201 FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(WRITE_CALL_2_VOID) | |
| 202 | |
| 203 #undef WRITE_CALL_0 | |
| 204 #undef WRITE_CALL_1 | |
| 205 #undef WRITE_CALL_2 | |
| 206 #undef WRITE_CALL_2_VOID | |
| 207 }; | |
| 208 | |
| 209 | |
| 210 class FunctionCallbackArguments | |
| 211 : public CustomArguments<FunctionCallbackInfo<Value> > { | |
| 212 public: | |
| 213 typedef FunctionCallbackInfo<Value> T; | |
| 214 typedef CustomArguments<T> Super; | |
| 215 static const int kArgsLength = T::kArgsLength; | |
| 216 static const int kHolderIndex = T::kHolderIndex; | |
| 217 static const int kDataIndex = T::kDataIndex; | |
| 218 static const int kReturnValueDefaultValueIndex = | |
| 219 T::kReturnValueDefaultValueIndex; | |
| 220 static const int kIsolateIndex = T::kIsolateIndex; | |
| 221 static const int kCalleeIndex = T::kCalleeIndex; | |
| 222 static const int kContextSaveIndex = T::kContextSaveIndex; | |
| 223 | |
| 224 FunctionCallbackArguments(internal::Isolate* isolate, internal::Object* data, | |
| 225 internal::HeapObject* callee, | |
| 226 internal::Object* holder, internal::Object** argv, | |
| 227 int argc, bool is_construct_call) | |
| 228 : Super(isolate), | |
| 229 argv_(argv), | |
| 230 argc_(argc), | |
| 231 is_construct_call_(is_construct_call) { | |
| 232 Object** values = begin(); | |
| 233 values[T::kDataIndex] = data; | |
| 234 values[T::kCalleeIndex] = callee; | |
| 235 values[T::kHolderIndex] = holder; | |
| 236 values[T::kContextSaveIndex] = isolate->heap()->the_hole_value(); | |
| 237 values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate); | |
| 238 // Here the hole is set as default value. | |
| 239 // It cannot escape into js as it's remove in Call below. | |
| 240 values[T::kReturnValueDefaultValueIndex] = | |
| 241 isolate->heap()->the_hole_value(); | |
| 242 values[T::kReturnValueIndex] = isolate->heap()->the_hole_value(); | |
| 243 DCHECK(values[T::kCalleeIndex]->IsJSFunction() || | |
| 244 values[T::kCalleeIndex]->IsFunctionTemplateInfo()); | |
| 245 DCHECK(values[T::kHolderIndex]->IsHeapObject()); | |
| 246 DCHECK(values[T::kIsolateIndex]->IsSmi()); | |
| 247 } | |
| 248 | |
| 249 /* | |
| 250 * The following Call function wraps the calling of all callbacks to handle | |
| 251 * calling either the old or the new style callbacks depending on which one | |
| 252 * has been registered. | |
| 253 * For old callbacks which return an empty handle, the ReturnValue is checked | |
| 254 * and used if it's been set to anything inside the callback. | |
| 255 * New style callbacks always use the return value. | |
| 256 */ | |
| 257 v8::Local<v8::Value> Call(FunctionCallback f); | |
| 258 | |
| 259 private: | |
| 260 internal::Object** argv_; | |
| 261 int argc_; | |
| 262 bool is_construct_call_; | |
| 263 }; | |
| 264 | |
| 265 | |
| 266 double ClobberDoubleRegisters(double x1, double x2, double x3, double x4); | 74 double ClobberDoubleRegisters(double x1, double x2, double x3, double x4); |
| 267 | 75 |
| 268 | |
| 269 #ifdef DEBUG | 76 #ifdef DEBUG |
| 270 #define CLOBBER_DOUBLE_REGISTERS() ClobberDoubleRegisters(1, 2, 3, 4); | 77 #define CLOBBER_DOUBLE_REGISTERS() ClobberDoubleRegisters(1, 2, 3, 4); |
| 271 #else | 78 #else |
| 272 #define CLOBBER_DOUBLE_REGISTERS() | 79 #define CLOBBER_DOUBLE_REGISTERS() |
| 273 #endif | 80 #endif |
| 274 | 81 |
| 275 #define RUNTIME_FUNCTION_RETURNS_TYPE(Type, Name) \ | 82 #define RUNTIME_FUNCTION_RETURNS_TYPE(Type, Name) \ |
| 276 static INLINE(Type __RT_impl_##Name(Arguments args, Isolate* isolate)); \ | 83 static INLINE(Type __RT_impl_##Name(Arguments args, Isolate* isolate)); \ |
| 277 Type Name(int args_length, Object** args_object, Isolate* isolate) { \ | 84 Type Name(int args_length, Object** args_object, Isolate* isolate) { \ |
| 278 CLOBBER_DOUBLE_REGISTERS(); \ | 85 CLOBBER_DOUBLE_REGISTERS(); \ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 293 #define RUNTIME_FUNCTION(Name) RUNTIME_FUNCTION_RETURNS_TYPE(Object*, Name) | 100 #define RUNTIME_FUNCTION(Name) RUNTIME_FUNCTION_RETURNS_TYPE(Object*, Name) |
| 294 #define RUNTIME_FUNCTION_RETURN_PAIR(Name) \ | 101 #define RUNTIME_FUNCTION_RETURN_PAIR(Name) \ |
| 295 RUNTIME_FUNCTION_RETURNS_TYPE(ObjectPair, Name) | 102 RUNTIME_FUNCTION_RETURNS_TYPE(ObjectPair, Name) |
| 296 #define RUNTIME_FUNCTION_RETURN_TRIPLE(Name) \ | 103 #define RUNTIME_FUNCTION_RETURN_TRIPLE(Name) \ |
| 297 RUNTIME_FUNCTION_RETURNS_TYPE(ObjectTriple, Name) | 104 RUNTIME_FUNCTION_RETURNS_TYPE(ObjectTriple, Name) |
| 298 | 105 |
| 299 } // namespace internal | 106 } // namespace internal |
| 300 } // namespace v8 | 107 } // namespace v8 |
| 301 | 108 |
| 302 #endif // V8_ARGUMENTS_H_ | 109 #endif // V8_ARGUMENTS_H_ |
| OLD | NEW |