OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 int length() const { return length_; } | 75 int length() const { return length_; } |
76 | 76 |
77 Object** arguments() { return arguments_; } | 77 Object** arguments() { return arguments_; } |
78 | 78 |
79 private: | 79 private: |
80 int length_; | 80 int length_; |
81 Object** arguments_; | 81 Object** arguments_; |
82 }; | 82 }; |
83 | 83 |
84 | 84 |
| 85 // mappings from old property callbacks to new ones |
| 86 // F(old name, new name, return value, parameters...) |
| 87 // |
| 88 // These aren't included in the list as they have duplicate signatures |
| 89 // F(NamedPropertyEnumerator, NamedPropertyEnumeratorCallback, ...) |
| 90 // F(NamedPropertyGetter, NamedPropertyGetterCallback, ...) |
| 91 |
| 92 #define FOR_EACH_CALLBACK_TABLE_MAPPING_0(F) \ |
| 93 F(IndexedPropertyEnumerator, IndexedPropertyEnumeratorCallback, v8::Array) \ |
| 94 |
| 95 #define FOR_EACH_CALLBACK_TABLE_MAPPING_1(F) \ |
| 96 F(AccessorGetter, AccessorGetterCallback, v8::Value, v8::Local<v8::String>) \ |
| 97 F(NamedPropertyQuery, \ |
| 98 NamedPropertyQueryCallback, \ |
| 99 v8::Integer, \ |
| 100 v8::Local<v8::String>) \ |
| 101 F(NamedPropertyDeleter, \ |
| 102 NamedPropertyDeleterCallback, \ |
| 103 v8::Boolean, \ |
| 104 v8::Local<v8::String>) \ |
| 105 F(IndexedPropertyGetter, \ |
| 106 IndexedPropertyGetterCallback, \ |
| 107 v8::Value, \ |
| 108 uint32_t) \ |
| 109 F(IndexedPropertyQuery, \ |
| 110 IndexedPropertyQueryCallback, \ |
| 111 v8::Integer, \ |
| 112 uint32_t) \ |
| 113 F(IndexedPropertyDeleter, \ |
| 114 IndexedPropertyDeleterCallback, \ |
| 115 v8::Boolean, \ |
| 116 uint32_t) \ |
| 117 |
| 118 #define FOR_EACH_CALLBACK_TABLE_MAPPING_2(F) \ |
| 119 F(NamedPropertySetter, \ |
| 120 NamedPropertySetterCallback, \ |
| 121 v8::Value, \ |
| 122 v8::Local<v8::String>, \ |
| 123 v8::Local<v8::Value>) \ |
| 124 F(IndexedPropertySetter, \ |
| 125 IndexedPropertySetterCallback, \ |
| 126 v8::Value, \ |
| 127 uint32_t, \ |
| 128 v8::Local<v8::Value>) \ |
| 129 |
| 130 #define FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(F) \ |
| 131 F(AccessorSetter, \ |
| 132 AccessorSetterCallback, \ |
| 133 void, \ |
| 134 v8::Local<v8::String>, \ |
| 135 v8::Local<v8::Value>) \ |
| 136 |
| 137 // All property callbacks as well as invocation callbacks |
| 138 #define FOR_EACH_CALLBACK_TABLE_MAPPING(F) \ |
| 139 F(InvocationCallback, FunctionCallback) \ |
| 140 F(AccessorGetter, AccessorGetterCallback) \ |
| 141 F(AccessorSetter, AccessorSetterCallback) \ |
| 142 F(NamedPropertySetter, NamedPropertySetterCallback) \ |
| 143 F(NamedPropertyQuery, NamedPropertyQueryCallback) \ |
| 144 F(NamedPropertyDeleter, NamedPropertyDeleterCallback) \ |
| 145 F(IndexedPropertyGetter, IndexedPropertyGetterCallback) \ |
| 146 F(IndexedPropertySetter, IndexedPropertySetterCallback) \ |
| 147 F(IndexedPropertyQuery, IndexedPropertyQueryCallback) \ |
| 148 F(IndexedPropertyDeleter, IndexedPropertyDeleterCallback) \ |
| 149 F(IndexedPropertyEnumerator, IndexedPropertyEnumeratorCallback) \ |
| 150 |
| 151 |
| 152 // TODO(dcarney): Remove this class when old callbacks are gone. |
| 153 class CallbackTable { |
| 154 public: |
| 155 // TODO(dcarney): Flip this when it makes sense for performance. |
| 156 static const bool kStoreVoidFunctions = true; |
| 157 static inline bool ReturnsVoid(Isolate* isolate, void* function) { |
| 158 CallbackTable* table = isolate->callback_table(); |
| 159 bool contains = |
| 160 table != NULL && |
| 161 table->map_.occupancy() != 0 && |
| 162 table->Contains(function); |
| 163 return contains == kStoreVoidFunctions; |
| 164 } |
| 165 |
| 166 STATIC_ASSERT(sizeof(intptr_t) == sizeof(AccessorGetterCallback)); |
| 167 |
| 168 template<typename F> |
| 169 static inline void* FunctionToVoidPtr(F function) { |
| 170 return reinterpret_cast<void*>(reinterpret_cast<intptr_t>(function)); |
| 171 } |
| 172 |
| 173 #define WRITE_REGISTER(OldFunction, NewFunction) \ |
| 174 static OldFunction Register(Isolate* isolate, NewFunction f) { \ |
| 175 InsertCallback(isolate, FunctionToVoidPtr(f), true); \ |
| 176 return reinterpret_cast<OldFunction>(f); \ |
| 177 } \ |
| 178 \ |
| 179 static OldFunction Register(Isolate* isolate, OldFunction f) { \ |
| 180 InsertCallback(isolate, FunctionToVoidPtr(f), false); \ |
| 181 return f; \ |
| 182 } |
| 183 FOR_EACH_CALLBACK_TABLE_MAPPING(WRITE_REGISTER) |
| 184 #undef WRITE_REGISTER |
| 185 |
| 186 private: |
| 187 CallbackTable(); |
| 188 bool Contains(void* function); |
| 189 static void InsertCallback(Isolate* isolate, |
| 190 void* function, |
| 191 bool returns_void); |
| 192 HashMap map_; |
| 193 DISALLOW_COPY_AND_ASSIGN(CallbackTable); |
| 194 }; |
| 195 |
| 196 |
85 // Custom arguments replicate a small segment of stack that can be | 197 // Custom arguments replicate a small segment of stack that can be |
86 // accessed through an Arguments object the same way the actual stack | 198 // accessed through an Arguments object the same way the actual stack |
87 // can. | 199 // can. |
88 class CustomArguments : public Relocatable { | 200 template<int kArrayLength> |
89 public: | 201 class CustomArgumentsBase : public Relocatable { |
90 inline CustomArguments(Isolate* isolate, | 202 public: |
91 Object* data, | 203 virtual inline void IterateInstance(ObjectVisitor* v) { |
92 Object* self, | 204 v->VisitPointers(values_, values_ + kArrayLength); |
93 JSObject* holder) : Relocatable(isolate) { | 205 } |
94 ASSERT(reinterpret_cast<Object*>(isolate)->IsSmi()); | 206 protected: |
95 values_[3] = self; | 207 inline Object** end() { return values_ + kArrayLength - 1; } |
96 values_[2] = holder; | 208 explicit inline CustomArgumentsBase(Isolate* isolate) |
97 values_[1] = data; | 209 : Relocatable(isolate) {} |
98 values_[0] = reinterpret_cast<Object*>(isolate); | 210 Object* values_[kArrayLength]; |
99 } | 211 }; |
100 | 212 |
101 inline explicit CustomArguments(Isolate* isolate) : Relocatable(isolate) { | 213 |
102 #ifdef DEBUG | 214 template<typename T> |
103 for (size_t i = 0; i < ARRAY_SIZE(values_); i++) { | 215 class CustomArguments : public CustomArgumentsBase<T::kArgsLength> { |
104 values_[i] = reinterpret_cast<Object*>(kZapValue); | 216 public: |
105 } | 217 static const int kReturnValueOffset = T::kReturnValueIndex; |
106 #endif | 218 |
107 } | 219 typedef CustomArgumentsBase<T::kArgsLength> Super; |
108 | 220 ~CustomArguments() { |
109 void IterateInstance(ObjectVisitor* v); | 221 // TODO(dcarney): create a new zap value for this. |
110 Object** end() { return values_ + ARRAY_SIZE(values_) - 1; } | 222 this->end()[kReturnValueOffset] = |
| 223 reinterpret_cast<Object*>(kHandleZapValue); |
| 224 } |
| 225 |
| 226 protected: |
| 227 explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {} |
| 228 |
| 229 template<typename V> |
| 230 v8::Handle<V> GetReturnValue(Isolate* isolate); |
| 231 |
| 232 inline Isolate* isolate() { |
| 233 return reinterpret_cast<Isolate*>(this->end()[T::kIsolateIndex]); |
| 234 } |
| 235 }; |
| 236 |
| 237 |
| 238 class PropertyCallbackArguments |
| 239 : public CustomArguments<PropertyCallbackInfo<Value> > { |
| 240 public: |
| 241 typedef PropertyCallbackInfo<Value> T; |
| 242 typedef CustomArguments<T> Super; |
| 243 static const int kArgsLength = T::kArgsLength; |
| 244 static const int kThisIndex = T::kThisIndex; |
| 245 static const int kHolderIndex = T::kHolderIndex; |
| 246 |
| 247 PropertyCallbackArguments(Isolate* isolate, |
| 248 Object* data, |
| 249 Object* self, |
| 250 JSObject* holder) |
| 251 : Super(isolate) { |
| 252 Object** values = this->end(); |
| 253 values[T::kThisIndex] = self; |
| 254 values[T::kHolderIndex] = holder; |
| 255 values[T::kDataIndex] = data; |
| 256 values[T::kIsolateIndex] = reinterpret_cast<Object*>(isolate); |
| 257 values[T::kReturnValueIndex] = isolate->heap()->the_hole_value(); |
| 258 ASSERT(values[T::kHolderIndex]->IsHeapObject()); |
| 259 ASSERT(values[T::kIsolateIndex]->IsSmi()); |
| 260 } |
| 261 |
| 262 #define WRITE_CALL_0(OldFunction, NewFunction, ReturnValue) \ |
| 263 v8::Handle<ReturnValue> Call(OldFunction f); \ |
| 264 |
| 265 #define WRITE_CALL_1(OldFunction, NewFunction, ReturnValue, Arg1) \ |
| 266 v8::Handle<ReturnValue> Call(OldFunction f, Arg1 arg1); \ |
| 267 |
| 268 #define WRITE_CALL_2(OldFunction, NewFunction, ReturnValue, Arg1, Arg2) \ |
| 269 v8::Handle<ReturnValue> Call(OldFunction f, Arg1 arg1, Arg2 arg2); \ |
| 270 |
| 271 #define WRITE_CALL_2_VOID(OldFunction, NewFunction, ReturnValue, Arg1, Arg2) \ |
| 272 void Call(OldFunction f, Arg1 arg1, Arg2 arg2); \ |
| 273 |
| 274 FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0) |
| 275 FOR_EACH_CALLBACK_TABLE_MAPPING_1(WRITE_CALL_1) |
| 276 FOR_EACH_CALLBACK_TABLE_MAPPING_2(WRITE_CALL_2) |
| 277 FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(WRITE_CALL_2_VOID) |
| 278 |
| 279 #undef WRITE_CALL_0 |
| 280 #undef WRITE_CALL_1 |
| 281 #undef WRITE_CALL_2 |
| 282 #undef WRITE_CALL_2_VOID |
| 283 }; |
| 284 |
| 285 |
| 286 class FunctionCallbackArguments |
| 287 : public CustomArguments<FunctionCallbackInfo<Value> > { |
| 288 public: |
| 289 typedef FunctionCallbackInfo<Value> T; |
| 290 typedef CustomArguments<T> Super; |
| 291 static const int kArgsLength = T::kArgsLength; |
| 292 |
| 293 FunctionCallbackArguments(internal::Isolate* isolate, |
| 294 internal::Object* data, |
| 295 internal::JSFunction* callee, |
| 296 internal::Object* holder, |
| 297 internal::Object** argv, |
| 298 int argc, |
| 299 bool is_construct_call) |
| 300 : Super(isolate), |
| 301 argv_(argv), |
| 302 argc_(argc), |
| 303 is_construct_call_(is_construct_call) { |
| 304 Object** values = end(); |
| 305 values[T::kDataIndex] = data; |
| 306 values[T::kCalleeIndex] = callee; |
| 307 values[T::kHolderIndex] = holder; |
| 308 values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate); |
| 309 values[T::kReturnValueIndex] = isolate->heap()->the_hole_value(); |
| 310 ASSERT(values[T::kCalleeIndex]->IsJSFunction()); |
| 311 ASSERT(values[T::kHolderIndex]->IsHeapObject()); |
| 312 ASSERT(values[T::kIsolateIndex]->IsSmi()); |
| 313 } |
| 314 |
| 315 v8::Handle<v8::Value> Call(InvocationCallback f); |
111 | 316 |
112 private: | 317 private: |
113 Object* values_[4]; | 318 internal::Object** argv_; |
114 }; | 319 int argc_; |
115 | 320 bool is_construct_call_; |
116 | 321 }; |
| 322 |
| 323 |
117 #define DECLARE_RUNTIME_FUNCTION(Type, Name) \ | 324 #define DECLARE_RUNTIME_FUNCTION(Type, Name) \ |
118 Type Name(int args_length, Object** args_object, Isolate* isolate) | 325 Type Name(int args_length, Object** args_object, Isolate* isolate) |
119 | 326 |
120 #define RUNTIME_FUNCTION(Type, Name) \ | 327 #define RUNTIME_FUNCTION(Type, Name) \ |
121 static Type __RT_impl_##Name(Arguments args, Isolate* isolate); \ | 328 static Type __RT_impl_##Name(Arguments args, Isolate* isolate); \ |
122 Type Name(int args_length, Object** args_object, Isolate* isolate) { \ | 329 Type Name(int args_length, Object** args_object, Isolate* isolate) { \ |
123 Arguments args(args_length, args_object); \ | 330 Arguments args(args_length, args_object); \ |
124 return __RT_impl_##Name(args, isolate); \ | 331 return __RT_impl_##Name(args, isolate); \ |
125 } \ | 332 } \ |
126 static Type __RT_impl_##Name(Arguments args, Isolate* isolate) | 333 static Type __RT_impl_##Name(Arguments args, Isolate* isolate) |
127 | 334 |
128 #define RUNTIME_ARGUMENTS(isolate, args) \ | 335 #define RUNTIME_ARGUMENTS(isolate, args) \ |
129 args.length(), args.arguments(), isolate | 336 args.length(), args.arguments(), isolate |
130 | 337 |
131 } } // namespace v8::internal | 338 } } // namespace v8::internal |
132 | 339 |
133 #endif // V8_ARGUMENTS_H_ | 340 #endif // V8_ARGUMENTS_H_ |
OLD | NEW |