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;
}