blob: 93b25347b1c7568b89104bc32ed54ee283825838 [file] [log] [blame]
Avi Drissman468e51b62022-09-13 20:47:011// Copyright 2013 The Chromium Authors
[email protected]e87f3122013-11-12 00:41:272// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef GIN_ARGUMENTS_H_
6#define GIN_ARGUMENTS_H_
7
Keishi Hattori0e45c022021-11-27 09:25:528#include "base/memory/raw_ptr.h"
Keishi Hattori0a5df3792023-01-22 11:09:579#include "base/memory/raw_ptr_exclusion.h"
[email protected]e87f3122013-11-12 00:41:2710#include "gin/converter.h"
[email protected]48c21632013-12-12 21:32:3411#include "gin/gin_export.h"
[email protected]e87f3122013-11-12 00:41:2712
13namespace gin {
14
[email protected]60531d52013-11-27 02:10:1515// Arguments is a wrapper around v8::FunctionCallbackInfo that integrates
16// with Converter to make it easier to marshall arguments and return values
17// between V8 and C++.
Jeremy Roman6a1242b2019-02-04 17:51:5718//
19// If constructed instead with a v8::PropertyCallbackInfo, behaves as though a
20// function with no arguments had been called.
[email protected]48c21632013-12-12 21:32:3421class GIN_EXPORT Arguments {
[email protected]e87f3122013-11-12 00:41:2722 public:
[email protected]7618ebbb2013-11-27 03:38:2623 Arguments();
[email protected]e87f3122013-11-12 00:41:2724 explicit Arguments(const v8::FunctionCallbackInfo<v8::Value>& info);
Jeremy Roman6a1242b2019-02-04 17:51:5725 explicit Arguments(const v8::PropertyCallbackInfo<v8::Value>& info);
[email protected]e87f3122013-11-12 00:41:2726 ~Arguments();
27
Michael Lippautz5b64e892018-09-24 11:10:0028 template <typename T>
29 bool GetHolder(T* out) const {
Jeremy Roman6a1242b2019-02-04 17:51:5730 v8::Local<v8::Object> holder = is_for_property_
31 ? info_for_property_->Holder()
Igor Sheludko1202f172024-04-23 08:06:5332 : info_for_function_->This();
Jeremy Roman6a1242b2019-02-04 17:51:5733 return ConvertFromV8(isolate_, holder, out);
[email protected]e87f3122013-11-12 00:41:2734 }
35
36 template<typename T>
[email protected]314cde12013-11-23 20:26:5137 bool GetData(T* out) {
Jeremy Roman6a1242b2019-02-04 17:51:5738 v8::Local<v8::Value> data = is_for_property_ ? info_for_property_->Data()
39 : info_for_function_->Data();
40 return ConvertFromV8(isolate_, data, out);
[email protected]314cde12013-11-23 20:26:5141 }
42
43 template<typename T>
[email protected]e87f3122013-11-12 00:41:2744 bool GetNext(T* out) {
Jeremy Roman6a1242b2019-02-04 17:51:5745 if (is_for_property_ || next_ >= info_for_function_->Length()) {
[email protected]e87f3122013-11-12 00:41:2746 insufficient_arguments_ = true;
47 return false;
48 }
Jeremy Roman6a1242b2019-02-04 17:51:5749 v8::Local<v8::Value> val = (*info_for_function_)[next_++];
[email protected]7618ebbb2013-11-27 03:38:2650 return ConvertFromV8(isolate_, val, out);
[email protected]e87f3122013-11-12 00:41:2751 }
52
53 template<typename T>
[email protected]858eeea0a2013-11-19 05:17:1254 bool GetRemaining(std::vector<T>* out) {
Jeremy Roman6a1242b2019-02-04 17:51:5755 if (is_for_property_ || next_ >= info_for_function_->Length()) {
[email protected]858eeea0a2013-11-19 05:17:1256 insufficient_arguments_ = true;
57 return false;
58 }
Jeremy Roman6a1242b2019-02-04 17:51:5759 int remaining = info_for_function_->Length() - next_;
[email protected]858eeea0a2013-11-19 05:17:1260 out->resize(remaining);
61 for (int i = 0; i < remaining; ++i) {
Jeremy Roman6a1242b2019-02-04 17:51:5762 v8::Local<v8::Value> val = (*info_for_function_)[next_++];
[email protected]7618ebbb2013-11-27 03:38:2663 if (!ConvertFromV8(isolate_, val, &out->at(i)))
[email protected]858eeea0a2013-11-19 05:17:1264 return false;
65 }
66 return true;
67 }
68
[email protected]97f9a7952014-03-14 11:50:3369 bool Skip() {
Jeremy Roman6a1242b2019-02-04 17:51:5770 if (is_for_property_)
71 return false;
72 if (next_ >= info_for_function_->Length())
[email protected]97f9a7952014-03-14 11:50:3373 return false;
74 next_++;
75 return true;
76 }
77
78 int Length() const {
Jeremy Roman6a1242b2019-02-04 17:51:5779 return is_for_property_ ? 0 : info_for_function_->Length();
[email protected]97f9a7952014-03-14 11:50:3380 }
81
Tom Sepezd6e548a2024-10-11 17:26:2582 template <typename T>
83 void Return(const T& val) {
bashidbd2ef9bb2015-06-02 01:39:3284 v8::Local<v8::Value> v8_value;
Tom Sepezd6e548a2024-10-11 17:26:2585 if (!TryConvertToV8(isolate_, val, &v8_value)) {
bashidbd2ef9bb2015-06-02 01:39:3286 return;
Tom Sepezd6e548a2024-10-11 17:26:2587 }
Jeremy Roman6a1242b2019-02-04 17:51:5788 (is_for_property_ ? info_for_property_->GetReturnValue()
89 : info_for_function_->GetReturnValue())
90 .Set(v8_value);
[email protected]e87f3122013-11-12 00:41:2791 }
92
rdevlin.cronind982fdf2017-03-23 22:17:4393 // Returns the creation context of the Holder.
Dan Elphick3a8863f2018-07-30 11:02:4294 v8::Local<v8::Context> GetHolderCreationContext() const;
rdevlin.cronind982fdf2017-03-23 22:17:4395
jochen87d2fee2015-07-13 08:21:3496 // Always check the return value whether the handle is empty before
97 // dereferencing the handle.
deepak.sfaaa1b62015-04-30 07:30:4898 v8::Local<v8::Value> PeekNext() const;
[email protected]97f21ca2013-11-17 17:46:0799
rdevlin.cronincd6754502017-04-19 16:14:14100 // Returns all arguments. Since this doesn't require any conversion, it
101 // cannot fail. This does not rely on or modify the current position in the
102 // array used by Get/PeekNext().
Nikolaos Papaspyrou5ce2a2f2023-10-19 09:09:00103 v8::LocalVector<v8::Value> GetAll() const;
rdevlin.cronincd6754502017-04-19 16:14:14104
Katie Dektarbcdde52f2022-11-04 21:29:53105 // Returns the original v8::FunctionCallbackInfo used to construct this
106 // Arguments if it exists, or nullptr otherwise.
107 const v8::FunctionCallbackInfo<v8::Value>* GetFunctionCallbackInfo() const {
108 return info_for_function_;
109 }
110
[email protected]481d2492013-12-13 23:55:25111 void ThrowError() const;
112 void ThrowTypeError(const std::string& message) const;
[email protected]e87f3122013-11-12 00:41:27113
114 v8::Isolate* isolate() const { return isolate_; }
115
[email protected]744a4942014-07-18 16:46:14116 // Allows the function handler to distinguish between normal invocation
117 // and object construction.
118 bool IsConstructCall() const;
119
[email protected]e87f3122013-11-12 00:41:27120 private:
Keishi Hattori0e45c022021-11-27 09:25:52121 raw_ptr<v8::Isolate> isolate_;
Jeremy Roman6a1242b2019-02-04 17:51:57122 union {
Keishi Hattori0a5df3792023-01-22 11:09:57123 // This field is not a raw_ptr<> because it was filtered by the rewriter
124 // for: #union
125 RAW_PTR_EXCLUSION const v8::FunctionCallbackInfo<v8::Value>*
126 info_for_function_;
127 // This field is not a raw_ptr<> because it was filtered by the rewriter
128 // for: #union
129 RAW_PTR_EXCLUSION const v8::PropertyCallbackInfo<v8::Value>*
130 info_for_property_;
Jeremy Roman6a1242b2019-02-04 17:51:57131 };
132 int next_ = 0;
133 bool insufficient_arguments_ = false;
134 bool is_for_property_ = false;
[email protected]e87f3122013-11-12 00:41:27135};
136
[email protected]e87f3122013-11-12 00:41:27137} // namespace gin
138
139#endif // GIN_ARGUMENTS_H_