Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(722)

Side by Side Diff: src/arguments.h

Issue 12494012: new style of property/function callbacks (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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 #define FOR_EACH_CALLBACK_TABLE_MAPPING(F) \
86 F(AccessorGetter, AccessorGetterCallback) \
87 F(AccessorSetter, AccessorSetterCallback) \
88 F(InvocationCallback, FunctionCallback) \
89 F(NamedPropertySetter, NamedPropertySetterCallback) \
90 F(NamedPropertyQuery, NamedPropertyQueryCallback) \
91 F(NamedPropertyDeleter, NamedPropertyDeleterCallback) \
92 F(IndexedPropertyGetter, IndexedPropertyGetterCallback) \
93 F(IndexedPropertySetter, IndexedPropertySetterCallback) \
94 F(IndexedPropertyQuery, IndexedPropertyQueryCallback) \
95 F(IndexedPropertyDeleter, IndexedPropertyDeleterCallback) \
96 F(IndexedPropertyEnumerator, IndexedPropertyEnumeratorCallback) \
97
98 // These aren't included in the list as they have duplicate signatures
99 // F(NamedPropertyEnumerator, NamedPropertyEnumeratorCallback) \
100 // F(NamedPropertyGetter, NamedPropertyGetterCallback) \
101
102 // TODO(dcarney): Remove this class when old callbacks are gone.
103 class CallbackTable {
104 public:
105 // TODO(dcarney): Flip this when it makes sense for performance.
106 static const bool kStoreVoidFunctions = true;
107 static inline bool ReturnsVoid(Isolate* isolate, void* function) {
108 CallbackTable* table = isolate->callback_table();
109 bool contains =
110 table != NULL &&
111 table->map_.occupancy() != 0 &&
112 table->Contains(function);
113 return contains == kStoreVoidFunctions;
114 }
115
116 #define WRITE_REGISTER(OldFunction, NewFunction) \
117 static OldFunction Register(Isolate* isolate, NewFunction f) { \
118 InsertCallback(isolate, reinterpret_cast<void*>(f), true); \
119 return reinterpret_cast<OldFunction>(f); \
120 } \
121 \
122 static OldFunction Register(Isolate* isolate, OldFunction f) { \
123 InsertCallback(isolate, reinterpret_cast<void*>(f), false); \
124 return f; \
125 }
126 FOR_EACH_CALLBACK_TABLE_MAPPING(WRITE_REGISTER)
127 #undef WRITE_REGISTER
128
129 private:
130 CallbackTable(): map_(Match, 64) {}
131 typedef HashMap::Entry Entry;
132 static bool Match(void* a, void* b) {
133 return a == b;
134 }
135 static uint32_t Hash(void* function) {
136 uintptr_t as_int = reinterpret_cast<uintptr_t>(function);
137 if (sizeof(function) == 4) return static_cast<uint32_t>(as_int);
138 uint64_t as_64 = static_cast<uint64_t>(as_int);
139 return
140 static_cast<uint32_t>(as_64 >> 32) ^
141 static_cast<uint32_t>(as_64);
142 }
143 bool Contains(void* function) {
144 ASSERT(function != NULL);
145 return map_.Lookup(function, Hash(function), false) != NULL;
146 }
147 static void InsertCallback(Isolate* isolate,
148 void* function,
149 bool returns_void) {
150 if (function == NULL) return;
151 // Don't store for performance.
152 if (kStoreVoidFunctions != returns_void) return;
153 CallbackTable* table = isolate->callback_table();
154 if (table == NULL) {
155 table = new CallbackTable();
156 isolate->set_callback_table(table);
157 }
158 table->Insert(function);
159 }
160 void Insert(void* function) {
161 ASSERT(function != NULL);
162 Entry* entry = map_.Lookup(function, Hash(function), true);
163 ASSERT(entry != NULL);
164 ASSERT(entry->value == NULL || entry->value == function);
165 entry->value = function;
166 }
167 HashMap map_;
168 DISALLOW_COPY_AND_ASSIGN(CallbackTable);
169 };
170
171
85 // Custom arguments replicate a small segment of stack that can be 172 // Custom arguments replicate a small segment of stack that can be
86 // accessed through an Arguments object the same way the actual stack 173 // accessed through an Arguments object the same way the actual stack
87 // can. 174 // can.
88 class CustomArguments : public Relocatable { 175 template<int kArrayLength>
89 public: 176 class CustomArgumentsBase : public Relocatable {
90 inline CustomArguments(Isolate* isolate, 177 public:
91 Object* data, 178 virtual inline void IterateInstance(ObjectVisitor* v) {
92 Object* self, 179 v->VisitPointers(values_, values_ + kArrayLength);
93 JSObject* holder) : Relocatable(isolate) { 180 }
94 ASSERT(reinterpret_cast<Object*>(isolate)->IsSmi()); 181 protected:
95 values_[3] = self; 182 inline Object** end() { return values_ + kArrayLength - 1; }
96 values_[2] = holder; 183 explicit inline CustomArgumentsBase(Isolate* isolate)
97 values_[1] = data; 184 : Relocatable(isolate) {}
98 values_[0] = reinterpret_cast<Object*>(isolate); 185 Object* values_[kArrayLength];
99 } 186 };
100 187
101 inline explicit CustomArguments(Isolate* isolate) : Relocatable(isolate) { 188
102 #ifdef DEBUG 189 template<typename T>
103 for (size_t i = 0; i < ARRAY_SIZE(values_); i++) { 190 class CustomArguments : public CustomArgumentsBase<T::kArgsLength> {
104 values_[i] = reinterpret_cast<Object*>(kZapValue); 191 public:
192 static const int kReturnValueOffset = T::kReturnValueIndex;
193
194 typedef CustomArgumentsBase<T::kArgsLength> Super;
195 ~CustomArguments() {
196 // TODO(dcarney): create a new zap value for this.
197 this->end()[kReturnValueOffset] =
198 reinterpret_cast<Object*>(kHandleZapValue);
199 }
200
201 #define WRITE_CALLBACK_RESULT(OldFunction, NewFunction) \
202 template<typename V> \
203 inline v8::Handle<V> GetCallbackResult(Isolate* isolate, \
204 OldFunction function, \
205 v8::Handle<V> call_result) { \
206 return GetCallbackResult(isolate, \
207 reinterpret_cast<void*>(function), \
208 call_result); \
209 }
210 FOR_EACH_CALLBACK_TABLE_MAPPING(WRITE_CALLBACK_RESULT)
211 #undef WRITE_CALLBACK_RESULT
212
213 protected:
214 template<typename V>
215 inline v8::Handle<V> GetCallbackResult(Isolate* isolate,
216 void* function,
217 v8::Handle<V> call_result) {
218 // For non-void calls, return the result only if call_result is set.
219 if (!CallbackTable::ReturnsVoid(isolate, function) &&
220 !call_result.IsEmpty()) {
221 return call_result;
105 } 222 }
106 #endif 223 // Check the ReturnValue.
107 } 224 Object* object = this->end()[kReturnValueOffset];
108 225 // Nothing was set, return empty handle as per previous behaviour.
109 void IterateInstance(ObjectVisitor* v); 226 if (object->IsTheHole()) return v8::Handle<V>();
110 Object** end() { return values_ + ARRAY_SIZE(values_) - 1; } 227 // We shouldn't need this, but play it safe for now.
111 228 // TODO(dcarney) Remove once all calls to this are verified as safe??
112 private: 229 return v8::Local<V>::New(reinterpret_cast<v8::Isolate*>(isolate),
113 Object* values_[4]; 230 v8::Handle<V>(reinterpret_cast<V*>(&object)));
114 }; 231 }
115 232
116 233 explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {}
234 };
235
236
237 class PropertyCallbackArguments
238 : public CustomArguments<PropertyCallbackInfo<Value> > {
239 public:
240 typedef PropertyCallbackInfo<Value> T;
241 typedef CustomArguments<T> Super;
242 static const int kArgsLength = T::kArgsLength;
243 static const int kThisIndex = T::kThisIndex;
244 static const int kHolderIndex = T::kHolderIndex;
245
246 PropertyCallbackArguments(Isolate* isolate,
247 Object* data,
248 Object* self,
249 JSObject* holder)
250 : Super(isolate) {
251 Object** values = this->end();
252 values[T::kThisIndex] = self;
253 values[T::kHolderIndex] = holder;
254 values[T::kDataIndex] = data;
255 values[T::kIsolateIndex] = reinterpret_cast<Object*>(isolate);
256 values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
257 ASSERT(values[T::kHolderIndex]->IsHeapObject());
258 ASSERT(values[T::kIsolateIndex]->IsSmi());
259 }
260
261 inline v8::AccessorInfo NewInfo() {
262 return v8::AccessorInfo(end());
263 }
264 };
265
266
267 class FunctionCallbackArguments
268 : public CustomArguments<FunctionCallbackInfo<Value> > {
269 public:
270 typedef FunctionCallbackInfo<Value> T;
271 typedef CustomArguments<T> Super;
272 static const int kArgsLength = T::kArgsLength;
273
274 FunctionCallbackArguments(internal::Isolate* isolate,
275 internal::Object* data,
276 internal::JSFunction* callee,
277 internal::Object* holder)
278 : Super(isolate) {
279 Object** values = end();
280 values[T::kDataIndex] = data;
281 values[T::kCalleeIndex] = callee;
282 values[T::kHolderIndex] = holder;
283 values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate);
284 values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
285 ASSERT(values[T::kCalleeIndex]->IsJSFunction());
286 ASSERT(values[T::kHolderIndex]->IsHeapObject());
287 ASSERT(values[T::kIsolateIndex]->IsSmi());
288 }
289
290 inline v8::Arguments NewArguments(internal::Object** argv,
291 int argc,
292 bool is_construct_call) {
293 return v8::Arguments(this->end(), argv, argc, is_construct_call);
294 }
295 };
296
297
117 #define DECLARE_RUNTIME_FUNCTION(Type, Name) \ 298 #define DECLARE_RUNTIME_FUNCTION(Type, Name) \
118 Type Name(Arguments args, Isolate* isolate) 299 Type Name(Arguments args, Isolate* isolate)
119 300
120 301
121 #define RUNTIME_FUNCTION(Type, Name) \ 302 #define RUNTIME_FUNCTION(Type, Name) \
122 Type Name(Arguments args, Isolate* isolate) 303 Type Name(Arguments args, Isolate* isolate)
123 304
124 305
125 #define RUNTIME_ARGUMENTS(isolate, args) args, isolate 306 #define RUNTIME_ARGUMENTS(isolate, args) args, isolate
126 307
127 308
128 } } // namespace v8::internal 309 } } // namespace v8::internal
129 310
130 #endif // V8_ARGUMENTS_H_ 311 #endif // V8_ARGUMENTS_H_
OLDNEW
« no previous file with comments | « src/apiutils.h ('k') | src/builtins.cc » ('j') | src/x64/macro-assembler-x64.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698