Skip to content

Question: My class getters and setters stopped working (test case included) #226

@rayburgemeestre

Description

@rayburgemeestre

Hi Pavel, and/or others that can hopefully point me in the right direction.. 🙂

First of all great project, I've been using it for a couple of years and it's awesome!

Let me start by saying, this could very well be a user-error, so I'm submitting this as a question at first, unless someone else can confirm that something indeed did break. I might be unique that I'm not using the module feature? Because I'm not using this within the context of Nodejs...

I'm using v8pp in C++ to embed V8, and I noticed that the following commit:

a6a3a9e

And in particular this specific bit:

a6a3a9e#diff-a4ae90fbc3497ac69ffe7b5daf8f89f04f9a653c4d251f134a998e9a96ef3d95L339-L340

Has broken the behavior of calling a setter and getter on a class. I think this is the simplest way to reproduce:

#include <iostream>

#include "v8pp/class.hpp"
#include "v8pp/context.hpp"

#include "libplatform/libplatform.h"

v8::Local<v8::String> v8_str(v8::Isolate *isolate, const std::string &str) {
  return v8::String::NewFromUtf8(isolate, str.c_str(), v8::NewStringType::kNormal).ToLocalChecked();
}

class Test {
public:
  explicit Test() = default;

  double getter() {
    std::cout << "getter called" << std::endl;
    return 123;
  }
  void setter(double value) {
    std::cout << "setter called: " << value << std::endl;
  }
};

int main() {
  v8::V8::InitializeExternalStartupData("test");
  std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform(1);
  v8::V8::InitializePlatform(platform.get());
  v8::V8::Initialize();

  v8pp::context ctx;
  v8::HandleScope scope(ctx.isolate());

  Test *instance = new Test();

  v8pp::class_<Test> MyObject_class(ctx.isolate());

  MyObject_class
      .ctor()
      .property("x", &Test::getter, &Test::setter);

  v8::Local<v8::Object> obj = MyObject_class.reference_external(ctx.isolate(), instance);

  // Try setter
  obj->Set(ctx.impl(), v8_str(ctx.isolate(), "x"), v8::Number::New(ctx.isolate(), 14)).FromJust();
  
  // Try getter
  obj->Get(ctx.impl(), v8_str(ctx.isolate(), "x")).ToLocalChecked()->NumberValue(ctx.impl()).ToChecked();
}

It does not output anything, unless I revert back V8 to version 10 (which still has the old SetAccessor functions)
Then I get output that confirms calls to my getter and setter are being made..

I've tried many things in the meantime, like explicitly running a script to do "x = MyClass(); x" (playing around with x inside the same script, using ctx->class_("MyClass", MyObject_class);, and a lot of stuff I forgot from the past few days)

So any pointers would be greatly appreciated.

For others running into similar issues, this is some info I found for the API change:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions