In addition to what Simon said: from a V8 API point of view, we have a strict type system and class hierarchy (this is C++ after all, not JavaScript). A v8::Name is a name, not a function. For a v8::Local<v8::Name> key, it will and must always be the case that key->IsName() returns true, and key->IsFunction() returns false. Anything else would be a very serious bug.
On Thu, Sep 26, 2019 at 8:44 AM 'Simon Zünd' via v8-users < v8-users@googlegroups.com> wrote: > In terms of the JavaScript spec, you are performing a [[Set]] operation > with `dict[x] = x`. The key for [[Set]] must be a valid property key, which > is either a String or a Symbol. In this case, the code actually looks more > like `dict[x.toString()] = x`. This is just how JavaScript works, and is > intended. > > On Thu, Sep 26, 2019 at 8:07 AM Gautham B A <gautham.bangal...@gmail.com> > wrote: > >> Hi all, >> >> Calling IsFunction() on v8::Local<v8::Name> is returning false, even >> though v8::Local<v8::Name> was pointing to a function in JavaScript. Is >> this expected? Consider the following code - >> >> #include <iostream> >> #include <libplatform/libplatform.h> >> #include <ostream> >> #include <v8.h> >> >> >> void Getter(v8::Local<v8::Name> key, >> const v8::PropertyCallbackInfo<v8::Value> &info) { >> std::cout << "Getter:" << std::endl; >> std::cout << "IsFunction: " << key->IsFunction() << std::endl; >> } >> >> >> void Setter(v8::Local<v8::Name> key, v8::Local<v8::Value> value, >> const v8::PropertyCallbackInfo<v8::Value> &info) { >> std::cout << "Setter:" << std::endl; >> // key->IsFunction() returns false, expected to be true >> std::cout << "Key IsFunction: " << key->IsFunction() << std::endl; >> >> >> // value->IsFunction() returns true, as expected >> std::cout << "\nValue IsFunction:" << value->IsFunction() << std::endl; >> } >> >> >> void Deleter(v8::Local<v8::Name> key, >> const v8::PropertyCallbackInfo<v8::Boolean> &info) {} >> >> >> bool InstallMap(v8::Isolate *isolate, const v8::Local<v8::Context> & >> context) { >> v8::HandleScope handle_scope(isolate); >> auto obj_template = v8::ObjectTemplate::New(isolate); >> obj_template->SetHandler( >> v8::NamedPropertyHandlerConfiguration(Getter, Setter, nullptr, >> Deleter)); >> >> >> v8::Local<v8::Object> obj; >> if (!obj_template->NewInstance(context).ToLocal(&obj)) { >> std::cerr << "Unable to instantiate object template" << std::endl; >> return false; >> } >> >> >> v8::Local<v8::String> obj_name; >> if (!v8::String::NewFromUtf8(isolate, "dict", v8::String::kNormalString >> ) >> ->ToString(context) >> .ToLocal(&obj_name)) { >> std::cerr << "Unable to create map key name" << std::endl; >> return false; >> } >> >> >> auto global = context->Global(); >> if (!global->Set(context, obj_name, obj).FromJust()) { >> std::cerr << "Unable to install object into global scope" << std:: >> endl; >> return false; >> } >> return true; >> } >> >> >> int main(int argc, char *argv[]) { >> const auto script_str = R"( >> function x() { >> } >> >> >> dict[x] = x; >> )"; >> >> >> v8::V8::InitializeICUDefaultLocation(argv[0]); >> v8::V8::InitializeExternalStartupData(argv[0]); >> auto platform = v8::platform::NewDefaultPlatform(); >> v8::V8::InitializePlatform(platform.get()); >> v8::V8::Initialize(); >> >> >> v8::Isolate::CreateParams create_params; >> create_params.array_buffer_allocator = >> v8::ArrayBuffer::Allocator::NewDefaultAllocator(); >> v8::Isolate *isolate = v8::Isolate::New(create_params); >> { >> v8::Isolate::Scope isolate_scope(isolate); >> v8::HandleScope handle_scope(isolate); >> auto context = v8::Context::New(isolate); >> v8::Context::Scope context_scope(context); >> >> >> InstallMap(isolate, context); >> >> >> auto source = >> v8::String::NewFromUtf8(isolate, script_str, v8::NewStringType:: >> kNormal) >> .ToLocalChecked(); >> auto script = v8::Script::Compile(context, source).ToLocalChecked(); >> auto result = script->Run(context).ToLocalChecked(); >> v8::String::Utf8Value result_utf8(isolate, result); >> std::cout << *result_utf8 << std::endl; >> } >> isolate->Dispose(); >> v8::V8::Dispose(); >> v8::V8::ShutdownPlatform(); >> delete create_params.array_buffer_allocator; >> return 0; >> } >> >> >> As seen in the code above, I'm exposing a global variable dict which has >> the Setter, Getter and Deleter callbacks set appropriately on dict. >> >> function x() { >> } >> dict[x] = x; >> When I run the above JavaScript code, The Setter callback gets called and >> I see that *name* and *value* have different results upon calling >> IsFunction() on them. >> Could someone please tell me if this is the expected behavior, if so, the >> reason behind why it is so? >> >> Thanks, >> --Gautham >> >> -- > > -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/v8-users/CAKSzg3T_3HQC5tYfDpXMV2QHWNyyM846Qgs2KxzzgQ1LjAe_LQ%40mail.gmail.com.