MySQL 9.3.0
Source Code Documentation
polyglot_language.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024, 2025, Oracle and/or its affiliates.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2.0,
6 * as published by the Free Software Foundation.
7 *
8 * This program is designed to work with certain software (including
9 * but not limited to OpenSSL) that is licensed under separate terms,
10 * as designated in a particular file or component or in included license
11 * documentation. The authors of MySQL hereby grant you an additional
12 * permission to link the program and your derivative works with the
13 * separately licensed software that they have either included with
14 * the program or referenced in the documentation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
19 * the GNU General Public License, version 2.0, for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#ifndef MYSQLSHDK_SCRIPTING_POLYGLOT_LANGUAGES_POLYGLOT_LANGUAGE_H_
27#define MYSQLSHDK_SCRIPTING_POLYGLOT_LANGUAGES_POLYGLOT_LANGUAGE_H_
28
29#include <cassert>
30#include <list>
31#include <memory>
32#include <stack>
33#include <string>
34#include <vector>
35
37
46
47namespace shcore {
48namespace polyglot {
49
50class ICollectable;
51class Polyglot_language;
52/**
53 * Allows creating a temporary global variable with a random name which will
54 * only live until the execution context of the instance of this class ends.
55 *
56 * The reason this is needed is because in graal, non primitive values
57 * originating from guest languages (like JS) are not sharable, this means:
58 *
59 * - A guest language specific object is not mappable to C++ equivalent, i.e.
60 * (i.e. undefined, ArrayBuffer)
61 * - There's no way we can generate a guest language specific object from C++
62 * (i.e. undefined, ArrayBuffer or Exception Objects)
63 *
64 * The way this problem is addressed, is by creating a temporary object in the
65 * global context, to create the object in the guest language and then if
66 * needed, storing it to create a reference so the object can be deleted from
67 * the main context (to avoid pollution) without actually losing the object,
68 * then the reference is provided to the guest language.
69 *
70 * Additional Information:
71 * https://github.com/oracle/graaljs/issues/70#issuecomment-436257058
72 * https://github.com/oracle/graal/blob/master/sdk/CHANGELOG.md#version-10-rc9
73 */
74class Scoped_global final {
75 public:
76 Scoped_global() = delete;
77
78 // Generates a random name for the scoped value, if value is provided, it will
79 // be set as the global value, otherwise just a random name is created to be
80 // used in the execute function.
81 Scoped_global(const Polyglot_language *language, poly_value value = nullptr);
82
83 Scoped_global(const Scoped_global &) = delete;
85
88
89 // Executes some code referencing the scoped value, the string <<global>>
90 // should be used in the text to refer to the created global (internally
91 // <<global>> will be replaced with the generated value), returns the result
92 // of the code execution
93 poly_value execute(const std::string &code);
94
96
97 private:
99 std::string m_name;
100};
101
102/**
103 * The polyglot library may support several languages (guest languages), and
104 * provides out of the box C++ interfaces to handle common language elements,
105 * such as Objects, Maps, Arrays, Functions and primitive data types.
106 *
107 * However, it does not provide out of the box C++ interface for guest language
108 * non primitive data types or specific objects.
109 *
110 * This class is to be used as the base class to handle the common language
111 * elements supported in the polyglot library, any guest language supported by
112 * the shell is meant to extend this class and add handling of the elements that
113 * are specific to it.
114 */
116 : public std::enable_shared_from_this<Polyglot_language> {
117 public:
118 class Script_scope final {
119 public:
120 Script_scope() = delete;
121
122 Script_scope(Polyglot_language *owner, const std::string &s)
123 : m_owner(owner) {
124 assert(m_owner);
126 }
127
128 Script_scope(const Script_scope &) = delete;
130
133
135
136 private:
138 };
139
141 public:
143
146
149
150 void push(const std::string &script);
151
152 void pop() { m_scripts.pop(); }
153
154 std::string current_script() const { return m_scripts.top(); }
155
156 std::string current_folder() const;
157
158 private:
159 std::string m_root;
160 std::stack<std::string> m_scripts;
161 };
162
164 const std::string &debug_port = "");
165
168
171
172 virtual ~Polyglot_language() = default;
173
174 virtual const char *get_language_id() const = 0;
175
176 virtual void init_context_builder();
177
178 virtual void initialize(const std::shared_ptr<IFile_system> &fs = {});
179
180 virtual void finalize();
181
182 /**
183 * The polyglot_utils file has the following functions that can be used to
184 * export C++ functions as polyglot global functions:
185 *
186 * - polyglot_handler*
187 * - native_handler*
188 *
189 * These wrappers allow exposing class functions as long as the class
190 * containing them contains a language() function that returns a pointer to a
191 * Polyglot language.
192 *
193 * This function, basically enables subclasses to expose functions as polyglot
194 * globals.
195 */
196 Polyglot_language *language() { return this; }
197
198 /**
199 * Throws a specific exception type in the GraalVM environment, with a
200 * specific message
201 */
203
204 // These functions represent operations than have specific handling depending
205 // on the guest language, for that reason only the interface is defined here
206 // and the subclasses provide specific language handling.
207
208 /**
209 * Return the a guest language interpretation of the Undefined C++ value.
210 */
211 virtual poly_value undefined() const = 0;
212
213 /**
214 * Returns true if the provided value is undefined in the guest language.
215 */
216 virtual bool is_undefined(poly_value value) const = 0;
217
218 /**
219 * Return the guest language interpretation of a binary string.
220 */
221 virtual poly_value array_buffer(const std::string &data) const = 0;
222
223 /**
224 * Return true if the guest language identifies the value as an object
225 */
226 virtual bool is_object(poly_value object,
227 std::string *class_name = nullptr) const = 0;
228
229 /**
230 * Converts a C++ object into a representation of the object in the guest
231 * language
232 */
233 virtual poly_value from_native_object(
234 const Object_bridge_t &object) const = 0;
235
236 /**
237 * Converts a guest language object into its C++ representation
238 */
239 virtual shcore::Value to_native_object(poly_value object,
240 const std::string &class_name);
241
242 /**
243 * Translates a dictionary object into an exception in the guest language.
244 */
245 void throw_exception_object(const shcore::Dictionary_t &data) const;
246
247 /**
248 * Translates a Polyglot_error into an exception in the guest language.
249 */
250 void throw_exception_object(const Polyglot_error &data) const;
251
252 /**
253 * Retrieves the list of keywords in the guest language
254 */
255 virtual const std::vector<std::string> &keywords() const = 0;
256
257 /**
258 * Wraps a call to poly_context_eval
259 */
260 int64_t eval(const std::string &source, const std::string &code_str,
261 poly_value *result) const;
262
263 poly_value create_source(const std::string &path) const;
264
265 /**
266 * Debugs the given script
267 */
268 std::pair<Value, bool> debug(const std::string &path);
269
270 /**
271 * Executes the given script
272 */
273 std::pair<Value, bool> execute(const std::string &code_str,
274 const std::string &source);
275
276 /**
277 * This function should be implemented to provide plugin load support
278 */
279 virtual bool load_plugin([[maybe_unused]] const std::string &path) {
280 throw std::runtime_error("Plugin support is not available.");
281 }
282
283 /**
284 * Creates a copy of the global context
285 */
286 poly_context copy_global_context() const;
287
288 poly_value poly_string(const std::string &data) const;
289 std::string to_string(poly_value obj) const;
290
291 poly_context context() const;
292 poly_thread thread() const;
293 const std::shared_ptr<Polyglot_object> &globals() const;
294
295 poly_reference store(poly_value value);
296 void erase(poly_reference value);
297
298 void set_global(const std::string &name, const Value &value) const;
299 void set_global(const std::string &name, poly_value value) const;
300 void set_global_function(const std::string &name, poly_callback callback,
301 void *data = nullptr);
302 Store get_global(const std::string &name) const;
303
304 void terminate();
305 bool is_terminating() const;
306
307 Script_scope enter_script(const std::string &s);
308
309 Value convert(poly_value value) const;
310 poly_value convert(const Value &value) const;
311
312 Argument_list convert_args(const std::vector<poly_value> &args) const;
313 poly_value type_info(poly_value value) const;
314
315 bool get_member(poly_value object, const char *name,
316 poly_value *member) const;
317
318 std::string current_script_folder() const;
319
321
322 protected:
323 poly_value wrap_callback(poly_callback callback, void *data) const;
325
327
328 poly_thread m_thread = nullptr;
329 poly_context_builder m_context_builder = nullptr;
331 std::unique_ptr<Polyglot_type_bridger> m_types;
332 std::shared_ptr<Polyglot_object> m_globals;
334 std::unique_ptr<Polyglot_storage> m_storage;
335 std::shared_ptr<IFile_system> m_file_system;
336
337 protected:
338 std::string m_debug_port;
339
340 private:
341 std::unique_ptr<Polyglot_scope> m_scope;
342 bool m_terminating = false;
343 void set_file_system();
344 void throw_exception_object(poly_value exception) const;
345 static void output_callback(const char *bytes, size_t length, void *data);
346 static void error_callback(const char *bytes, size_t length, void *data);
347
348 virtual poly_value create_exception_object(
349 const std::string &error, poly_value exception_object) const = 0;
350 virtual void output_handler(const char *bytes, size_t length) = 0;
351 virtual void error_handler(const char *bytes, size_t length) = 0;
352 void enable_debug();
353 virtual std::optional<std::string> get_debug_port() const { return {}; }
354};
355
356} // namespace polyglot
357} // namespace shcore
358
359#endif // MYSQLSHDK_SCRIPTING_POLYGLOT_LANGUAGES_POLYGLOT_LANGUAGE_H_
Definition: jit_executor_exceptions.h:34
Common context for GraalVM Languages.
Definition: polyglot_common_context.h:57
Represents polyglot errors that will be created from information available in the polyglot library st...
Definition: polyglot_error.h:77
Definition: polyglot_language.h:140
void push(const std::string &script)
Definition: polyglot_language.cc:64
std::stack< std::string > m_scripts
Definition: polyglot_language.h:160
std::string m_root
Definition: polyglot_language.h:159
Current_script()
Definition: polyglot_language.cc:54
std::string current_folder() const
Definition: polyglot_language.cc:60
Current_script & operator=(const Current_script &)=delete
Current_script & operator=(Current_script &&)=delete
std::string current_script() const
Definition: polyglot_language.h:154
Current_script(const Current_script &)=delete
void pop()
Definition: polyglot_language.h:152
Definition: polyglot_language.h:118
Polyglot_language * m_owner
Definition: polyglot_language.h:137
~Script_scope()
Definition: polyglot_language.h:134
Script_scope & operator=(Script_scope &&)=default
Script_scope & operator=(const Script_scope &)=delete
Script_scope(Polyglot_language *owner, const std::string &s)
Definition: polyglot_language.h:122
The polyglot library may support several languages (guest languages), and provides out of the box C++...
Definition: polyglot_language.h:116
bool get_member(poly_value object, const char *name, poly_value *member) const
Definition: polyglot_language.cc:440
virtual bool is_object(poly_value object, std::string *class_name=nullptr) const =0
Return true if the guest language identifies the value as an object.
Script_scope enter_script(const std::string &s)
Definition: polyglot_language.cc:452
const std::shared_ptr< Polyglot_object > & globals() const
Definition: polyglot_language.cc:413
static void error_callback(const char *bytes, size_t length, void *data)
Definition: polyglot_language.cc:286
std::pair< Value, bool > execute(const std::string &code_str, const std::string &source)
Executes the given script.
Definition: polyglot_language.cc:265
poly_value poly_string(const std::string &data) const
Definition: polyglot_language.cc:342
Polyglot_language(Polyglot_language &&)=delete
void erase(poly_reference value)
Definition: polyglot_language.cc:438
Current_script m_current_script
Definition: polyglot_language.h:333
void terminate()
Definition: polyglot_language.cc:350
Argument_list convert_args(const std::vector< poly_value > &args) const
Definition: polyglot_language.cc:425
poly_reference store(poly_value value)
Definition: polyglot_language.cc:434
int64_t eval(const std::string &source, const std::string &code_str, poly_value *result) const
Wraps a call to poly_context_eval.
Definition: polyglot_language.cc:233
virtual poly_value undefined() const =0
Return the a guest language interpretation of the Undefined C++ value.
Store m_context
Definition: polyglot_language.h:330
Polyglot_language(const Polyglot_language &)=delete
virtual poly_value array_buffer(const std::string &data) const =0
Return the guest language interpretation of a binary string.
Polyglot_language * language()
The polyglot_utils file has the following functions that can be used to export C++ functions as polyg...
Definition: polyglot_language.h:196
std::string to_string(poly_value obj) const
Definition: polyglot_language.cc:346
Polyglot_common_context * m_common_context
Definition: polyglot_language.h:326
Polyglot_language & operator=(Polyglot_language &&)=delete
virtual void output_handler(const char *bytes, size_t length)=0
std::string current_script_folder() const
Definition: polyglot_language.cc:292
virtual const char * get_language_id() const =0
std::shared_ptr< IFile_system > m_file_system
Definition: polyglot_language.h:335
void clear_is_terminating()
Definition: polyglot_language.cc:367
virtual const std::vector< std::string > & keywords() const =0
Retrieves the list of keywords in the guest language.
poly_context context() const
Definition: polyglot_language.cc:409
bool is_terminating() const
Definition: polyglot_language.cc:365
virtual poly_value from_native_object(const Object_bridge_t &object) const =0
Converts a C++ object into a representation of the object in the guest language.
virtual void finalize()
Definition: polyglot_language.cc:203
virtual shcore::Value to_native_object(poly_value object, const std::string &class_name)
Converts a guest language object into its C++ representation.
Definition: polyglot_language.cc:227
virtual void error_handler(const char *bytes, size_t length)=0
poly_context copy_global_context() const
Creates a copy of the global context.
Definition: polyglot_language.cc:384
Store get_global(const std::string &name) const
Definition: polyglot_language.cc:338
poly_thread thread() const
Definition: polyglot_language.cc:411
std::string m_debug_port
Definition: polyglot_language.h:338
void throw_exception_object(const shcore::Dictionary_t &data) const
Translates a dictionary object into an exception in the guest language.
Definition: polyglot_language.cc:304
Polyglot_common_context * common_context()
Definition: polyglot_language.h:320
virtual bool is_undefined(poly_value value) const =0
Returns true if the provided value is undefined in the guest language.
virtual poly_value create_exception_object(const std::string &error, poly_value exception_object) const =0
void set_file_system()
Definition: polyglot_language.cc:457
Value convert(poly_value value) const
Definition: polyglot_language.cc:417
virtual void initialize(const std::shared_ptr< IFile_system > &fs={})
Definition: polyglot_language.cc:143
poly_value wrap_callback(poly_callback callback, void *data) const
Definition: polyglot_language.cc:369
Polyglot_language & operator=(const Polyglot_language &)=delete
void set_global(const std::string &name, const Value &value) const
Definition: polyglot_language.cc:321
poly_value type_info(poly_value value) const
Definition: polyglot_language.cc:430
std::unique_ptr< Polyglot_type_bridger > m_types
Definition: polyglot_language.h:331
poly_value create_source(const std::string &path) const
Definition: polyglot_language.cc:244
virtual std::optional< std::string > get_debug_port() const
Definition: polyglot_language.h:353
std::unique_ptr< Polyglot_scope > m_scope
Definition: polyglot_language.h:341
static void output_callback(const char *bytes, size_t length, void *data)
Definition: polyglot_language.cc:280
virtual void init_context_builder()
Definition: polyglot_language.cc:120
void enable_debug()
Definition: polyglot_language.cc:109
Polyglot_language(Polyglot_common_context *common_context, const std::string &debug_port="")
Definition: polyglot_language.cc:105
void throw_jit_executor_exception(const Jit_executor_exception &exception)
Throws a specific exception type in the GraalVM environment, with a specific message.
Definition: polyglot_language.cc:221
std::pair< Value, bool > debug(const std::string &path)
Debugs the given script.
Definition: polyglot_language.cc:252
virtual bool load_plugin(const std::string &path)
This function should be implemented to provide plugin load support.
Definition: polyglot_language.h:279
bool m_terminating
Definition: polyglot_language.h:342
poly_thread m_thread
Definition: polyglot_language.h:328
poly_context_builder m_context_builder
Definition: polyglot_language.h:329
std::shared_ptr< Polyglot_object > m_globals
Definition: polyglot_language.h:332
std::unique_ptr< Polyglot_storage > m_storage
Definition: polyglot_language.h:334
void set_global_function(const std::string &name, poly_callback callback, void *data=nullptr)
Definition: polyglot_language.cc:331
Allows creating a temporary global variable with a random name which will only live until the executi...
Definition: polyglot_language.h:74
Scoped_global(const Scoped_global &)=delete
std::string m_name
Definition: polyglot_language.h:99
const Polyglot_language * m_language
Definition: polyglot_language.h:98
Scoped_global(Scoped_global &&)=delete
Scoped_global & operator=(const Scoped_global &)=delete
poly_value execute(const std::string &code)
Definition: polyglot_language.cc:83
~Scoped_global()
Definition: polyglot_language.cc:96
Scoped_global & operator=(Scoped_global &&)=delete
Helper class to handle polyglot values made permanent.
Definition: polyglot_store.h:47
static char * path
Definition: mysqldump.cc:150
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
ValueType value(const std::optional< ValueType > &v)
Definition: gtid.h:83
std::shared_ptr< Object_bridge > Object_bridge_t
Definition: polyglot_object_bridge.h:89
Definition: file_system_exceptions.h:34
std::vector< Value > Argument_list
Definition: jit_executor_value.h:429
Value::Map_type_ref Dictionary_t
Definition: jit_executor_value.h:430
repeated Source source
Definition: replication_asynchronous_connection_failover.proto:42
Definition: result.h:30
Pointer to a function that may be implemented in any language.
Definition: jit_executor_value.h:130