I've been working on a project built upon V8 and I tried to write
C++ versions of Seal() and isSealed() functions you can use with the API.
I've managed to develop a solution and it works fine except when the
object that I want to be sealed has an interceptor returning back
anything but the empty value (Handle<Value>()). I wrote a simplified
version of the code that emphasizes the core of my problem. I attached it
to this mail (v8_test.patch) along with a source for testing it
(v8_test.cpp).
The static method Object::Test() works as follows: It takes an object,
gets its properties and sets them into a newly created object. It seems
to me that the GetKeysInFixedArrayFor() function behaves strangely in
this snippet. If you call the Object::Test() method the printf statements
(after the for-loop that sets the properties) work as expected - printing
the number of local properties - but when there is an interceptor that
returns any non-empty value they print out zeroes. I checked the properties
with the HasOwnProperty() method in another piece of code and they were
there.
My questions are:
 - Is this the way the GetKeysInFixedArrayFor() function is supposed to
work?
 - If that is so how am I to evade that limitation?

Regards:
Gabor Ballabas

-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
diff --git a/include/v8.h b/include/v8.h
index 3ce6b87..c61c7a6 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1417,6 +1417,8 @@ enum AccessControl {
  */
 class Object : public Value {
  public:
+  V8EXPORT static void Test(Handle<Object>& object);
+
   V8EXPORT bool Set(Handle<Value> key,
                     Handle<Value> value,
                     PropertyAttribute attribs = None);
diff --git a/src/api.cc b/src/api.cc
index ecd5101..f1c95ba 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2522,6 +2522,35 @@ uint32_t Value::Uint32Value() const {
   }
 }
 
+void v8::Object::Test(v8::Handle<Object>& object) {
+  i::Isolate* isolate = i::Isolate::Current();
+  EnsureInitializedForIsolate(isolate, "v8::Object::Test()");
+  LOG_API(isolate, "Object::Test()");
+  ENTER_V8(isolate);
+  i::Handle<i::JSObject> new_obj = isolate->factory()->NewJSObject(isolate->object_function());
+  i::Handle<i::JSObject> old_obj = Utils::OpenHandle(*object);
+  i::Handle<i::FixedArray> keys = i::GetKeysInFixedArrayFor(old_obj, i::LOCAL_ONLY);
+  i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(keys);
+  PropertyAttributes attribs;
+  i::Handle<i::String> name;
+  i::Handle<i::Object> value;
+  for (int i = 0; i < elms->length(); ++i) {
+    i::Handle<i::Object> tmp(elms->get(i));
+    name = i::Handle<i::String>::cast(tmp);
+    value = i::GetProperty(old_obj, name);
+    attribs = old_obj->GetPropertyAttribute(*name);
+    i::Handle<i::Object> obj = i::SetProperty(
+        new_obj,
+        name,
+        value,
+        static_cast<PropertyAttributes>(attribs | DONT_DELETE),
+        i::kNonStrictMode);
+  }
+  i::Handle<i::FixedArray> keys2 = i::GetKeysInFixedArrayFor(new_obj, i::LOCAL_ONLY);
+  printf("keys2 length: %d\n", keys2->length());
+  i::Handle<i::FixedArray> elms2 = isolate->factory()->CopyFixedArray(keys2);
+  printf("elms2 length: %d\n", elms2->length());
+}
 
 bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
                      v8::PropertyAttribute attribs) {
#include <v8.h>

using namespace v8;

Handle<Value> Iceptor(Local<String> name, const AccessorInfo& info) {
  return String::New("Iceptor");
  // If you comment out the line above and uncomment the line below
  // it will work as expected.
  //return Handle<Value>();
}

int main(int argc, char* argv[]) {

  HandleScope handle_scope;

  Handle<ObjectTemplate> global = ObjectTemplate::New();

  Persistent<Context> context = Context::New(NULL, global);
  Context::Scope global_scope(context);

  Handle<ObjectTemplate> tmpl = ObjectTemplate::New();
  tmpl->SetNamedPropertyHandler(Iceptor);

  Local<Object> obj = tmpl->NewInstance();
  obj->Set(String::New("x"), Number::New(666));
  obj->Set(String::New("y"), Number::New(888));

  Object::Test(obj);

  context.Dispose();

  return 0;
}

Reply via email to