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

Unified 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: make arm look like other architectures Created 7 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/apiutils.h ('k') | src/arguments.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arguments.h
diff --git a/src/arguments.h b/src/arguments.h
index 1423d5642b3912e896d7060bef3e67da24a337c6..a80b6136151716fdccc398657e7ea79c5e395ca6 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -82,35 +82,258 @@ class Arguments BASE_EMBEDDED {
};
+// mappings from old property callbacks to new ones
+// F(old name, new name, return value, parameters...)
+//
+// These aren't included in the list as they have duplicate signatures
+// F(NamedPropertyEnumerator, NamedPropertyEnumeratorCallback, ...)
+// F(NamedPropertyGetter, NamedPropertyGetterCallback, ...)
+
+#define FOR_EACH_CALLBACK_TABLE_MAPPING_0(F) \
+ F(IndexedPropertyEnumerator, IndexedPropertyEnumeratorCallback, v8::Array) \
+
+#define FOR_EACH_CALLBACK_TABLE_MAPPING_1(F) \
+ F(AccessorGetter, AccessorGetterCallback, v8::Value, v8::Local<v8::String>) \
+ F(NamedPropertyQuery, \
+ NamedPropertyQueryCallback, \
+ v8::Integer, \
+ v8::Local<v8::String>) \
+ F(NamedPropertyDeleter, \
+ NamedPropertyDeleterCallback, \
+ v8::Boolean, \
+ v8::Local<v8::String>) \
+ F(IndexedPropertyGetter, \
+ IndexedPropertyGetterCallback, \
+ v8::Value, \
+ uint32_t) \
+ F(IndexedPropertyQuery, \
+ IndexedPropertyQueryCallback, \
+ v8::Integer, \
+ uint32_t) \
+ F(IndexedPropertyDeleter, \
+ IndexedPropertyDeleterCallback, \
+ v8::Boolean, \
+ uint32_t) \
+
+#define FOR_EACH_CALLBACK_TABLE_MAPPING_2(F) \
+ F(NamedPropertySetter, \
+ NamedPropertySetterCallback, \
+ v8::Value, \
+ v8::Local<v8::String>, \
+ v8::Local<v8::Value>) \
+ F(IndexedPropertySetter, \
+ IndexedPropertySetterCallback, \
+ v8::Value, \
+ uint32_t, \
+ v8::Local<v8::Value>) \
+
+#define FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(F) \
+ F(AccessorSetter, \
+ AccessorSetterCallback, \
+ void, \
+ v8::Local<v8::String>, \
+ v8::Local<v8::Value>) \
+
+// All property callbacks as well as invocation callbacks
+#define FOR_EACH_CALLBACK_TABLE_MAPPING(F) \
+ F(InvocationCallback, FunctionCallback) \
+ F(AccessorGetter, AccessorGetterCallback) \
+ F(AccessorSetter, AccessorSetterCallback) \
+ F(NamedPropertySetter, NamedPropertySetterCallback) \
+ F(NamedPropertyQuery, NamedPropertyQueryCallback) \
+ F(NamedPropertyDeleter, NamedPropertyDeleterCallback) \
+ F(IndexedPropertyGetter, IndexedPropertyGetterCallback) \
+ F(IndexedPropertySetter, IndexedPropertySetterCallback) \
+ F(IndexedPropertyQuery, IndexedPropertyQueryCallback) \
+ F(IndexedPropertyDeleter, IndexedPropertyDeleterCallback) \
+ F(IndexedPropertyEnumerator, IndexedPropertyEnumeratorCallback) \
+
+
+// TODO(dcarney): Remove this class when old callbacks are gone.
+class CallbackTable {
+ public:
+ // TODO(dcarney): Flip this when it makes sense for performance.
+ static const bool kStoreVoidFunctions = true;
+ static inline bool ReturnsVoid(Isolate* isolate, void* function) {
+ CallbackTable* table = isolate->callback_table();
+ bool contains =
+ table != NULL &&
+ table->map_.occupancy() != 0 &&
+ table->Contains(function);
+ return contains == kStoreVoidFunctions;
+ }
+
+ STATIC_ASSERT(sizeof(intptr_t) == sizeof(AccessorGetterCallback));
+
+ template<typename F>
+ static inline void* FunctionToVoidPtr(F function) {
+ return reinterpret_cast<void*>(reinterpret_cast<intptr_t>(function));
+ }
+
+#define WRITE_REGISTER(OldFunction, NewFunction) \
+ static OldFunction Register(Isolate* isolate, NewFunction f) { \
+ InsertCallback(isolate, FunctionToVoidPtr(f), true); \
+ return reinterpret_cast<OldFunction>(f); \
+ } \
+ \
+ static OldFunction Register(Isolate* isolate, OldFunction f) { \
+ InsertCallback(isolate, FunctionToVoidPtr(f), false); \
+ return f; \
+ }
+ FOR_EACH_CALLBACK_TABLE_MAPPING(WRITE_REGISTER)
+#undef WRITE_REGISTER
+
+ private:
+ CallbackTable();
+ bool Contains(void* function);
+ static void InsertCallback(Isolate* isolate,
+ void* function,
+ bool returns_void);
+ HashMap map_;
+ DISALLOW_COPY_AND_ASSIGN(CallbackTable);
+};
+
+
// Custom arguments replicate a small segment of stack that can be
// accessed through an Arguments object the same way the actual stack
// can.
-class CustomArguments : public Relocatable {
+template<int kArrayLength>
+class CustomArgumentsBase : public Relocatable {
+ public:
+ virtual inline void IterateInstance(ObjectVisitor* v) {
+ v->VisitPointers(values_, values_ + kArrayLength);
+ }
+ protected:
+ inline Object** end() { return values_ + kArrayLength - 1; }
+ explicit inline CustomArgumentsBase(Isolate* isolate)
+ : Relocatable(isolate) {}
+ Object* values_[kArrayLength];
+};
+
+
+template<typename T>
+class CustomArguments : public CustomArgumentsBase<T::kArgsLength> {
public:
- inline CustomArguments(Isolate* isolate,
- Object* data,
- Object* self,
- JSObject* holder) : Relocatable(isolate) {
- ASSERT(reinterpret_cast<Object*>(isolate)->IsSmi());
- values_[3] = self;
- values_[2] = holder;
- values_[1] = data;
- values_[0] = reinterpret_cast<Object*>(isolate);
+ static const int kReturnValueOffset = T::kReturnValueIndex;
+
+ typedef CustomArgumentsBase<T::kArgsLength> Super;
+ ~CustomArguments() {
+ // TODO(dcarney): create a new zap value for this.
+ this->end()[kReturnValueOffset] =
+ reinterpret_cast<Object*>(kHandleZapValue);
+ }
+
+ protected:
+ explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {}
+
+ template<typename V>
+ v8::Handle<V> GetReturnValue(Isolate* isolate);
+
+ inline Isolate* isolate() {
+ return reinterpret_cast<Isolate*>(this->end()[T::kIsolateIndex]);
}
+};
+
+
+class PropertyCallbackArguments
+ : public CustomArguments<PropertyCallbackInfo<Value> > {
+ public:
+ typedef PropertyCallbackInfo<Value> T;
+ typedef CustomArguments<T> Super;
+ static const int kArgsLength = T::kArgsLength;
+ static const int kThisIndex = T::kThisIndex;
+ static const int kHolderIndex = T::kHolderIndex;
+
+ PropertyCallbackArguments(Isolate* isolate,
+ Object* data,
+ Object* self,
+ JSObject* holder)
+ : Super(isolate) {
+ Object** values = this->end();
+ values[T::kThisIndex] = self;
+ values[T::kHolderIndex] = holder;
+ values[T::kDataIndex] = data;
+ values[T::kIsolateIndex] = reinterpret_cast<Object*>(isolate);
+ values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
+ ASSERT(values[T::kHolderIndex]->IsHeapObject());
+ ASSERT(values[T::kIsolateIndex]->IsSmi());
+ }
+
+ /*
+ * The following Call functions wrap the calling of all callbacks to handle
+ * calling either the old or the new style callbacks depending on which one
+ * has been registered.
+ * For old callbacks which return an empty handle, the ReturnValue is checked
+ * and used if it's been set to anything inside the callback.
+ * New style callbacks always use the return value.
+ */
+#define WRITE_CALL_0(OldFunction, NewFunction, ReturnValue) \
+ v8::Handle<ReturnValue> Call(OldFunction f); \
+
+#define WRITE_CALL_1(OldFunction, NewFunction, ReturnValue, Arg1) \
+ v8::Handle<ReturnValue> Call(OldFunction f, Arg1 arg1); \
+
+#define WRITE_CALL_2(OldFunction, NewFunction, ReturnValue, Arg1, Arg2) \
+ v8::Handle<ReturnValue> Call(OldFunction f, Arg1 arg1, Arg2 arg2); \
+
+#define WRITE_CALL_2_VOID(OldFunction, NewFunction, ReturnValue, Arg1, Arg2) \
+ void Call(OldFunction f, Arg1 arg1, Arg2 arg2); \
+
+FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0)
+FOR_EACH_CALLBACK_TABLE_MAPPING_1(WRITE_CALL_1)
+FOR_EACH_CALLBACK_TABLE_MAPPING_2(WRITE_CALL_2)
+FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(WRITE_CALL_2_VOID)
+
+#undef WRITE_CALL_0
+#undef WRITE_CALL_1
+#undef WRITE_CALL_2
+#undef WRITE_CALL_2_VOID
+};
+
+
+class FunctionCallbackArguments
+ : public CustomArguments<FunctionCallbackInfo<Value> > {
+ public:
+ typedef FunctionCallbackInfo<Value> T;
+ typedef CustomArguments<T> Super;
+ static const int kArgsLength = T::kArgsLength;
- inline explicit CustomArguments(Isolate* isolate) : Relocatable(isolate) {
-#ifdef DEBUG
- for (size_t i = 0; i < ARRAY_SIZE(values_); i++) {
- values_[i] = reinterpret_cast<Object*>(kZapValue);
- }
-#endif
+ FunctionCallbackArguments(internal::Isolate* isolate,
+ internal::Object* data,
+ internal::JSFunction* callee,
+ internal::Object* holder,
+ internal::Object** argv,
+ int argc,
+ bool is_construct_call)
+ : Super(isolate),
+ argv_(argv),
+ argc_(argc),
+ is_construct_call_(is_construct_call) {
+ Object** values = end();
+ values[T::kDataIndex] = data;
+ values[T::kCalleeIndex] = callee;
+ values[T::kHolderIndex] = holder;
+ values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate);
+ values[T::kReturnValueIndex] = isolate->heap()->the_hole_value();
+ ASSERT(values[T::kCalleeIndex]->IsJSFunction());
+ ASSERT(values[T::kHolderIndex]->IsHeapObject());
+ ASSERT(values[T::kIsolateIndex]->IsSmi());
}
- void IterateInstance(ObjectVisitor* v);
- Object** end() { return values_ + ARRAY_SIZE(values_) - 1; }
+ /*
+ * The following Call function wraps the calling of all callbacks to handle
+ * calling either the old or the new style callbacks depending on which one
+ * has been registered.
+ * For old callbacks which return an empty handle, the ReturnValue is checked
+ * and used if it's been set to anything inside the callback.
+ * New style callbacks always use the return value.
+ */
+ v8::Handle<v8::Value> Call(InvocationCallback f);
private:
- Object* values_[4];
+ internal::Object** argv_;
+ int argc_;
+ bool is_construct_call_;
};
« no previous file with comments | « src/apiutils.h ('k') | src/arguments.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698