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

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: 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 side-by-side diff with in-line comments
Download patch
Index: src/arguments.h
diff --git a/src/arguments.h b/src/arguments.h
index f8fb00c57538aeb32b7a0adcfdc40d0796a91332..7d00d17138ddc0a7737f5ef1046dee8df462bf0f 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -82,35 +82,216 @@ class Arguments BASE_EMBEDDED {
};
+#define FOR_EACH_CALLBACK_TABLE_MAPPING(F) \
+ F(AccessorGetter, AccessorGetterCallback) \
+ F(AccessorSetter, AccessorSetterCallback) \
+ F(InvocationCallback, FunctionCallback) \
+ F(NamedPropertySetter, NamedPropertySetterCallback) \
+ F(NamedPropertyQuery, NamedPropertyQueryCallback) \
+ F(NamedPropertyDeleter, NamedPropertyDeleterCallback) \
+ F(IndexedPropertyGetter, IndexedPropertyGetterCallback) \
+ F(IndexedPropertySetter, IndexedPropertySetterCallback) \
+ F(IndexedPropertyQuery, IndexedPropertyQueryCallback) \
+ F(IndexedPropertyDeleter, IndexedPropertyDeleterCallback) \
+ F(IndexedPropertyEnumerator, IndexedPropertyEnumeratorCallback) \
+
+// These aren't included in the list as they have duplicate signatures
+// F(NamedPropertyEnumerator, NamedPropertyEnumeratorCallback) \
+// F(NamedPropertyGetter, NamedPropertyGetterCallback) \
+
+// 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;
+ }
+
+#define WRITE_REGISTER(OldFunction, NewFunction) \
+ static OldFunction Register(Isolate* isolate, NewFunction f) { \
+ InsertCallback(isolate, reinterpret_cast<void*>(f), true); \
+ return reinterpret_cast<OldFunction>(f); \
+ } \
+ \
+ static OldFunction Register(Isolate* isolate, OldFunction f) { \
+ InsertCallback(isolate, reinterpret_cast<void*>(f), false); \
+ return f; \
+ }
+ FOR_EACH_CALLBACK_TABLE_MAPPING(WRITE_REGISTER)
+#undef WRITE_REGISTER
+
+ private:
+ CallbackTable(): map_(Match, 64) {}
+ typedef HashMap::Entry Entry;
+ static bool Match(void* a, void* b) {
+ return a == b;
+ }
+ static uint32_t Hash(void* function) {
+ uintptr_t as_int = reinterpret_cast<uintptr_t>(function);
+ if (sizeof(function) == 4) return static_cast<uint32_t>(as_int);
+ uint64_t as_64 = static_cast<uint64_t>(as_int);
+ return
+ static_cast<uint32_t>(as_64 >> 32) ^
+ static_cast<uint32_t>(as_64);
+ }
+ bool Contains(void* function) {
+ ASSERT(function != NULL);
+ return map_.Lookup(function, Hash(function), false) != NULL;
+ }
+ static void InsertCallback(Isolate* isolate,
+ void* function,
+ bool returns_void) {
+ if (function == NULL) return;
+ // Don't store for performance.
+ if (kStoreVoidFunctions != returns_void) return;
+ CallbackTable* table = isolate->callback_table();
+ if (table == NULL) {
+ table = new CallbackTable();
+ isolate->set_callback_table(table);
+ }
+ table->Insert(function);
+ }
+ void Insert(void* function) {
+ ASSERT(function != NULL);
+ Entry* entry = map_.Lookup(function, Hash(function), true);
+ ASSERT(entry != NULL);
+ ASSERT(entry->value == NULL || entry->value == function);
+ entry->value = function;
+ }
+ 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);
- }
-
- 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);
+ 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);
+ }
+
+#define WRITE_CALLBACK_RESULT(OldFunction, NewFunction) \
+ template<typename V> \
+ inline v8::Handle<V> GetCallbackResult(Isolate* isolate, \
+ OldFunction function, \
+ v8::Handle<V> call_result) { \
+ return GetCallbackResult(isolate, \
+ reinterpret_cast<void*>(function), \
+ call_result); \
+ }
+ FOR_EACH_CALLBACK_TABLE_MAPPING(WRITE_CALLBACK_RESULT)
+#undef WRITE_CALLBACK_RESULT
+
+ protected:
+ template<typename V>
+ inline v8::Handle<V> GetCallbackResult(Isolate* isolate,
+ void* function,
+ v8::Handle<V> call_result) {
+ // For non-void calls, return the result only if call_result is set.
+ if (!CallbackTable::ReturnsVoid(isolate, function) &&
+ !call_result.IsEmpty()) {
+ return call_result;
}
-#endif
+ // Check the ReturnValue.
+ Object* object = this->end()[kReturnValueOffset];
+ // Nothing was set, return empty handle as per previous behaviour.
+ if (object->IsTheHole()) return v8::Handle<V>();
+ // We shouldn't need this, but play it safe for now.
+ // TODO(dcarney) Remove once all calls to this are verified as safe??
+ return v8::Local<V>::New(reinterpret_cast<v8::Isolate*>(isolate),
+ v8::Handle<V>(reinterpret_cast<V*>(&object)));
}
- void IterateInstance(ObjectVisitor* v);
- Object** end() { return values_ + ARRAY_SIZE(values_) - 1; }
+ explicit inline CustomArguments(Isolate* isolate) : Super(isolate) {}
+};
- private:
- Object* values_[4];
+
+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());
+ }
+
+ inline v8::AccessorInfo NewInfo() {
+ return v8::AccessorInfo(end());
+ }
+};
+
+
+class FunctionCallbackArguments
+ : public CustomArguments<FunctionCallbackInfo<Value> > {
+ public:
+ typedef FunctionCallbackInfo<Value> T;
+ typedef CustomArguments<T> Super;
+ static const int kArgsLength = T::kArgsLength;
+
+ FunctionCallbackArguments(internal::Isolate* isolate,
+ internal::Object* data,
+ internal::JSFunction* callee,
+ internal::Object* holder)
+ : Super(isolate) {
+ 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());
+ }
+
+ inline v8::Arguments NewArguments(internal::Object** argv,
+ int argc,
+ bool is_construct_call) {
+ return v8::Arguments(this->end(), argv, argc, is_construct_call);
+ }
};
« 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