All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.nan_callbacks_pre_12_inl.h Maven / Gradle / Ivy

Go to download

Native Abstractions for Node.js: C++ header for Node 0.8 -> 18 compatibility

There is a newer version: 2.19.0
Show newest version
/*********************************************************************
 * NAN - Native Abstractions for Node.js
 *
 * Copyright (c) 2018 NAN contributors
 *
 * MIT License 
 ********************************************************************/

#ifndef NAN_CALLBACKS_PRE_12_INL_H_
#define NAN_CALLBACKS_PRE_12_INL_H_

namespace imp {
template class ReturnValueImp;
}  // end of namespace imp

template
class ReturnValue {
  v8::Isolate *isolate_;
  v8::Persistent *value_;
  friend class imp::ReturnValueImp;

 public:
  template 
  explicit inline ReturnValue(v8::Isolate *isolate, v8::Persistent *p) :
      isolate_(isolate), value_(p) {}
  template 
  explicit inline ReturnValue(const ReturnValue& that)
      : isolate_(that.isolate_), value_(that.value_) {
    TYPE_CHECK(T, S);
  }

  // Handle setters
  template  inline void Set(const v8::Local &handle) {
    TYPE_CHECK(T, S);
    value_->Dispose();
    *value_ = v8::Persistent::New(handle);
  }

  template  inline void Set(const Global &handle) {
    TYPE_CHECK(T, S);
    value_->Dispose();
    *value_ = v8::Persistent::New(handle.persistent);
    const_cast &>(handle).Reset();
  }

  // Fast primitive setters
  inline void Set(bool value) {
    v8::HandleScope scope;

    TYPE_CHECK(T, v8::Boolean);
    value_->Dispose();
    *value_ = v8::Persistent::New(v8::Boolean::New(value));
  }

  inline void Set(double i) {
    v8::HandleScope scope;

    TYPE_CHECK(T, v8::Number);
    value_->Dispose();
    *value_ = v8::Persistent::New(v8::Number::New(i));
  }

  inline void Set(int32_t i) {
    v8::HandleScope scope;

    TYPE_CHECK(T, v8::Integer);
    value_->Dispose();
    *value_ = v8::Persistent::New(v8::Int32::New(i));
  }

  inline void Set(uint32_t i) {
    v8::HandleScope scope;

    TYPE_CHECK(T, v8::Integer);
    value_->Dispose();
    *value_ = v8::Persistent::New(v8::Uint32::NewFromUnsigned(i));
  }

  // Fast JS primitive setters
  inline void SetNull() {
    v8::HandleScope scope;

    TYPE_CHECK(T, v8::Primitive);
    value_->Dispose();
    *value_ = v8::Persistent::New(v8::Null());
  }

  inline void SetUndefined() {
    v8::HandleScope scope;

    TYPE_CHECK(T, v8::Primitive);
    value_->Dispose();
    *value_ = v8::Persistent::New(v8::Undefined());
  }

  inline void SetEmptyString() {
    v8::HandleScope scope;

    TYPE_CHECK(T, v8::String);
    value_->Dispose();
    *value_ = v8::Persistent::New(v8::String::Empty());
  }

  // Convenience getter for isolate
  inline v8::Isolate *GetIsolate() const {
    return isolate_;
  }

  // Pointer setter: Uncompilable to prevent inadvertent misuse.
  template
  inline void Set(S *whatever) { TYPE_CHECK(S*, v8::Primitive); }
};

template
class FunctionCallbackInfo {
  const v8::Arguments &args_;
  v8::Local data_;
  ReturnValue return_value_;
  v8::Persistent retval_;

 public:
  explicit inline FunctionCallbackInfo(
      const v8::Arguments &args
    , v8::Local data) :
          args_(args)
        , data_(data)
        , return_value_(args.GetIsolate(), &retval_)
        , retval_(v8::Persistent::New(v8::Undefined())) {}

  inline ~FunctionCallbackInfo() {
    retval_.Dispose();
    retval_.Clear();
  }

  inline ReturnValue GetReturnValue() const {
    return ReturnValue(return_value_);
  }

  inline v8::Local Callee() const { return args_.Callee(); }
  inline v8::Local Data() const { return data_; }
  inline v8::Local Holder() const { return args_.Holder(); }
  inline bool IsConstructCall() const { return args_.IsConstructCall(); }
  inline int Length() const { return args_.Length(); }
  inline v8::Local operator[](int i) const { return args_[i]; }
  inline v8::Local This() const { return args_.This(); }
  inline v8::Isolate *GetIsolate() const { return args_.GetIsolate(); }


 protected:
  static const int kHolderIndex = 0;
  static const int kIsolateIndex = 1;
  static const int kReturnValueDefaultValueIndex = 2;
  static const int kReturnValueIndex = 3;
  static const int kDataIndex = 4;
  static const int kCalleeIndex = 5;
  static const int kContextSaveIndex = 6;
  static const int kArgsLength = 7;

 private:
  NAN_DISALLOW_ASSIGN_COPY_MOVE(FunctionCallbackInfo)
};

template
class PropertyCallbackInfoBase {
  const v8::AccessorInfo &info_;
  const v8::Local data_;

 public:
  explicit inline PropertyCallbackInfoBase(
      const v8::AccessorInfo &info
    , const v8::Local data) :
          info_(info)
        , data_(data) {}

  inline v8::Isolate* GetIsolate() const { return info_.GetIsolate(); }
  inline v8::Local Data() const { return data_; }
  inline v8::Local This() const { return info_.This(); }
  inline v8::Local Holder() const { return info_.Holder(); }

 protected:
  static const int kHolderIndex = 0;
  static const int kIsolateIndex = 1;
  static const int kReturnValueDefaultValueIndex = 2;
  static const int kReturnValueIndex = 3;
  static const int kDataIndex = 4;
  static const int kThisIndex = 5;
  static const int kArgsLength = 6;

 private:
  NAN_DISALLOW_ASSIGN_COPY_MOVE(PropertyCallbackInfoBase)
};

template
class PropertyCallbackInfo : public PropertyCallbackInfoBase {
  ReturnValue return_value_;
  v8::Persistent retval_;

 public:
  explicit inline PropertyCallbackInfo(
      const v8::AccessorInfo &info
    , const v8::Local data) :
          PropertyCallbackInfoBase(info, data)
        , return_value_(info.GetIsolate(), &retval_)
        , retval_(v8::Persistent::New(v8::Undefined())) {}

  inline ~PropertyCallbackInfo() {
    retval_.Dispose();
    retval_.Clear();
  }

  inline ReturnValue GetReturnValue() const { return return_value_; }
};

template<>
class PropertyCallbackInfo :
    public PropertyCallbackInfoBase {
  ReturnValue return_value_;
  v8::Persistent retval_;

 public:
  explicit inline PropertyCallbackInfo(
      const v8::AccessorInfo &info
    , const v8::Local data) :
          PropertyCallbackInfoBase(info, data)
        , return_value_(info.GetIsolate(), &retval_)
        , retval_(v8::Persistent::New(v8::Local())) {}

  inline ~PropertyCallbackInfo() {
    retval_.Dispose();
    retval_.Clear();
  }

  inline ReturnValue GetReturnValue() const {
    return return_value_;
  }
};

template<>
class PropertyCallbackInfo :
    public PropertyCallbackInfoBase {
  ReturnValue return_value_;
  v8::Persistent retval_;

 public:
  explicit inline PropertyCallbackInfo(
      const v8::AccessorInfo &info
    , const v8::Local data) :
          PropertyCallbackInfoBase(info, data)
        , return_value_(info.GetIsolate(), &retval_)
        , retval_(v8::Persistent::New(v8::Local())) {}

  inline ~PropertyCallbackInfo() {
    retval_.Dispose();
    retval_.Clear();
  }

  inline ReturnValue GetReturnValue() const {
    return return_value_;
  }
};

template<>
class PropertyCallbackInfo :
    public PropertyCallbackInfoBase {
  ReturnValue return_value_;
  v8::Persistent retval_;

 public:
  explicit inline PropertyCallbackInfo(
      const v8::AccessorInfo &info
    , const v8::Local data) :
          PropertyCallbackInfoBase(info, data)
        , return_value_(info.GetIsolate(), &retval_)
        , retval_(v8::Persistent::New(v8::Local())) {}

  inline ~PropertyCallbackInfo() {
    retval_.Dispose();
    retval_.Clear();
  }

  inline ReturnValue GetReturnValue() const {
    return return_value_;
  }
};

namespace imp {
template
class ReturnValueImp : public ReturnValue {
 public:
  explicit ReturnValueImp(ReturnValue that) :
      ReturnValue(that) {}
  inline v8::Handle Value() {
      return *ReturnValue::value_;
  }
};

static
v8::Handle FunctionCallbackWrapper(const v8::Arguments &args) {
  v8::Local obj = args.Data().As();
  FunctionCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kFunctionIndex).As()->Value()));
  FunctionCallbackInfo
      cbinfo(args, obj->GetInternalField(kDataIndex));
  callback(cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (*NativeFunction)(const v8::Arguments &);

static
v8::Handle GetterCallbackWrapper(
    v8::Local property, const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  GetterCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kGetterIndex).As()->Value()));
  callback(property, cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (*NativeGetter)
    (v8::Local, const v8::AccessorInfo &);

static
void SetterCallbackWrapper(
    v8::Local property
  , v8::Local value
  , const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  SetterCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kSetterIndex).As()->Value()));
  callback(property, value, cbinfo);
}

typedef void (*NativeSetter)
    (v8::Local, v8::Local, const v8::AccessorInfo &);

static
v8::Handle PropertyGetterCallbackWrapper(
    v8::Local property, const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  PropertyGetterCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kPropertyGetterIndex)
              .As()->Value()));
  callback(property, cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (*NativePropertyGetter)
    (v8::Local, const v8::AccessorInfo &);

static
v8::Handle PropertySetterCallbackWrapper(
    v8::Local property
  , v8::Local value
  , const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  PropertySetterCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kPropertySetterIndex)
              .As()->Value()));
  callback(property, value, cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (*NativePropertySetter)
    (v8::Local, v8::Local, const v8::AccessorInfo &);

static
v8::Handle PropertyEnumeratorCallbackWrapper(
    const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  PropertyEnumeratorCallback callback =
      reinterpret_cast(reinterpret_cast(
          obj->GetInternalField(kPropertyEnumeratorIndex)
              .As()->Value()));
  callback(cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (*NativePropertyEnumerator)
    (const v8::AccessorInfo &);

static
v8::Handle PropertyDeleterCallbackWrapper(
    v8::Local property
  , const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  PropertyDeleterCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kPropertyDeleterIndex)
              .As()->Value()));
  callback(property, cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (NativePropertyDeleter)
    (v8::Local, const v8::AccessorInfo &);

static
v8::Handle PropertyQueryCallbackWrapper(
    v8::Local property, const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  PropertyQueryCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kPropertyQueryIndex)
              .As()->Value()));
  callback(property, cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (*NativePropertyQuery)
    (v8::Local, const v8::AccessorInfo &);

static
v8::Handle IndexGetterCallbackWrapper(
    uint32_t index, const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  IndexGetterCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kIndexPropertyGetterIndex)
              .As()->Value()));
  callback(index, cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (*NativeIndexGetter)
    (uint32_t, const v8::AccessorInfo &);

static
v8::Handle IndexSetterCallbackWrapper(
    uint32_t index
  , v8::Local value
  , const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  IndexSetterCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kIndexPropertySetterIndex)
              .As()->Value()));
  callback(index, value, cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (*NativeIndexSetter)
    (uint32_t, v8::Local, const v8::AccessorInfo &);

static
v8::Handle IndexEnumeratorCallbackWrapper(
    const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  IndexEnumeratorCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kIndexPropertyEnumeratorIndex)
              .As()->Value()));
  callback(cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (*NativeIndexEnumerator)
    (const v8::AccessorInfo &);

static
v8::Handle IndexDeleterCallbackWrapper(
    uint32_t index, const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  IndexDeleterCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kIndexPropertyDeleterIndex)
              .As()->Value()));
  callback(index, cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (*NativeIndexDeleter)
    (uint32_t, const v8::AccessorInfo &);

static
v8::Handle IndexQueryCallbackWrapper(
    uint32_t index, const v8::AccessorInfo &info) {
  v8::Local obj = info.Data().As();
  PropertyCallbackInfo
      cbinfo(info, obj->GetInternalField(kDataIndex));
  IndexQueryCallback callback = reinterpret_cast(
      reinterpret_cast(
          obj->GetInternalField(kIndexPropertyQueryIndex)
              .As()->Value()));
  callback(index, cbinfo);
  return ReturnValueImp(cbinfo.GetReturnValue()).Value();
}

typedef v8::Handle (*NativeIndexQuery)
    (uint32_t, const v8::AccessorInfo &);
}  // end of namespace imp

#endif  // NAN_CALLBACKS_PRE_12_INL_H_