-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutilities.h
431 lines (396 loc) · 16.5 KB
/
utilities.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
#ifndef RBIMPL_INTERN_VM_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_VM_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to rb_cRubyVM.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/attr/noreturn.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* vm.c */
/**
* Resembles `__LINE__`.
*
* @retval 0 Current execution context not in a ruby method.
* @retval otherwise The current line number of the current thread of the
* current ractor of the current execution context.
*/
int rb_sourceline(void);
/**
* Resembles `__FILE__`.
*
* @retval 0 Current execution context not in a ruby method.
* @retval otherwise The current source path of the current thread of the
* current ractor of the current execution context.
* @note This may or may not be an absolute path.
*/
const char *rb_sourcefile(void);
/**
* Resembles `__method__`.
*
* @param[out] idp Return buffer for method id.
* @param[out] klassp Return buffer for class.
* @retval 0 Current execution context not in a method.
* @retval 1 Successful return.
* @post Upon successful return `*idp` and `*klassp` are updated to have
* the current method name and its defined class respectively.
* @note Both parameters can be `NULL`.
*/
int rb_frame_method_id_and_class(ID *idp, VALUE *klassp);
/* vm_eval.c */
/**
* Identical to rb_funcallv(), except it returns ::RUBY_Qundef instead of
* raising ::rb_eNoMethodError.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @retval RUBY_Qundef `recv` doesn't respond to `mid`.
* @retval otherwise What the method evaluates to.
*/
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv);
/**
* Identical to rb_check_funcall(), except you can specify how to handle the
* last element of the given array. It can also be seen as a routine identical
* to rb_funcallv_kw(), except it returns ::RUBY_Qundef instead of raising
* ::rb_eNoMethodError.
*
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] argc Number of arguments.
* @param[in] argv Arbitrary number of method arguments.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `argv`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `argv`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @retval RUBY_Qundef `recv` doesn't respond to `mid`.
* @retval otherwise What the method evaluates to.
*/
VALUE rb_check_funcall_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat);
/**
* This API is practically a variant of rb_proc_call_kw() now. Historically
* when there still was a concept called `$SAFE`, this was an API for that.
* But we no longer have that. This function basically ended its role. It
* just remains here because of no harm.
*
* @param[in] cmd A string, or something callable.
* @param[in] arg Argument passed to the call.
* @param[in] kw_splat Handling of keyword parameters:
* - RB_NO_KEYWORDS `arg`'s last is not a keyword argument.
* - RB_PASS_KEYWORDS `arg`'s last is a keyword argument.
* - RB_PASS_CALLED_KEYWORDS it depends if there is a passed block.
* @return What the command evaluates to.
*/
VALUE rb_eval_cmd_kw(VALUE cmd, VALUE arg, int kw_splat);
/**
* Identical to rb_funcallv(), except it takes Ruby's array instead of C's.
* @param[in,out] recv Receiver of the method.
* @param[in] mid Name of the method to call.
* @param[in] args An instance of ::RArray.
* @exception rb_eNoMethodError No such method.
* @exception rb_eException Any exceptions happen inside.
* @return What the method evaluates to.
* @pre `args` must be an ::RArray. Call `to_ary` beforehand when
* necessary.
*/
VALUE rb_apply(VALUE recv, ID mid, VALUE args);
/**
* Evaluates a string containing Ruby source code, or the given block, within
* the context of the receiver. In order to set the context, the variable
* `self` is set to `recv` while the code is executing, giving the code access
* to `recv`'s instance variables and private methods.
*
* When given a block, `recv` is also passed in as the block's only argument.
*
* When given a string, the optional second and third parameters supply a
* filename and starting line number that are used when reporting compilation
* errors.
*
* @param[in] argc Number of objects in `argv`
* @param[in] argv C array of 0 up to 3 elements.
* @param[in] recv The object in question.
* @return What was evaluated.
*/
VALUE rb_obj_instance_eval(int argc, const VALUE *argv, VALUE recv);
/**
* Executes the given block within the context of the receiver. In order to
* set the context, the variable `self` is set to `recv` while the code is
* executing, giving the code access to `recv`'s instance variables. Arguments
* are passed as block parameters.
*
* @param[in] argc Number of objects in `argv`
* @param[in] argv Arbitrary parameters to be passed to the block.
* @param[in] recv The object in question.
* @return What was evaluated.
* @note Don't confuse this with rb_obj_instance_eval(). The key
* difference is whether you can pass arbitrary parameters to the
* block, like this:
*
* ```ruby
* class Foo
* def initialize
* @foo = 5
* end
* end
* Foo.new.instance_exec(7) {|i| @foo + i } # => 12
* ```
*/
VALUE rb_obj_instance_exec(int argc, const VALUE *argv, VALUE recv);
/**
* Identical to rb_obj_instance_eval(), except it evaluates within the context
* of module.
*
* @param[in] argc Number of objects in `argv`
* @param[in] argv C array of 0 up to 3 elements.
* @param[in] mod The module in question.
* @pre `mod` must be a Module.
* @return What was evaluated.
*/
VALUE rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod);
/**
* Identical to rb_obj_instance_exec(), except it evaluates within the context
* of module.
*
* @param[in] argc Number of objects in `argv`
* @param[in] argv Arbitrary parameters to be passed to the block.
* @param[in] mod The module in question.
* @pre `mod` must be a Module.
* @return What was evaluated.
*/
VALUE rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod);
/* vm_method.c */
/**
* @private
*
* @deprecated This macro once was a thing in the old days, but makes no sense
* any longer today. Exists here for backwards compatibility
* only. You can safely forget about it.
*/
#define HAVE_RB_DEFINE_ALLOC_FUNC 1
/**
* This is the type of functions that ruby calls when trying to allocate an
* object. It is sometimes necessary to allocate extra memory regions for an
* object. When you define a class that uses ::RTypedData, it is typically the
* case. On such situations define a function of this type and pass it to
* rb_define_alloc_func().
*
* @param[in] klass The class that this function is registered.
* @return A newly allocated instance of `klass`.
*/
typedef VALUE (*rb_alloc_func_t)(VALUE klass);
/**
* Sets the allocator function of a class.
*
* @param[out] klass The class to modify.
* @param[in] func An allocator function for the class.
* @pre `klass` must be an instance of Class.
*/
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func);
/**
* Deletes the allocator function of a class. It is sometimes desirable to
* restrict creation of an instance of a class. For example it rarely makes
* sense for a DB adaptor class to allow programmers creating DB row objects
* without querying the DB itself. You can kill sporadic creation of such
* objects then, by nullifying the allocator function using this API. Your
* object shall be allocated using #RB_NEWOBJ_OF() directly.
*
* @param[out] klass The class to modify.
* @pre `klass` must be an instance of Class.
*/
void rb_undef_alloc_func(VALUE klass);
/**
* Queries the allocator function of a class.
*
* @param[in] klass The class in question.
* @pre `klass` must be an instance of Class.
* @retval 0 No allocator function is registered.
* @retval otherwise The allocator function.
*
* @internal
*
* Who cares? @shyouhei finds no practical usage of the return value. Maybe we
* need KonMari.
*/
rb_alloc_func_t rb_get_alloc_func(VALUE klass);
/**
* Clears the inline constant caches associated with a particular ID. Extension
* libraries should not bother with such things. Just forget about this API (or
* even, the presence of constant caches).
*/
void rb_clear_constant_cache_for_id(ID id);
/**
* Resembles `alias`.
*
* @param[out] klass Where to define an alias.
* @param[in] dst New name.
* @param[in] src Existing name.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eFrozenError `klass` is frozen.
* @exception rb_eNameError No such method named `src`.
* @post `klass` has a method named `dst`, which is the identical to its
* method named `src`.
*/
void rb_alias(VALUE klass, ID dst, ID src);
/**
* This function resembles now-deprecated `Module#attr`.
*
* @param[out] klass Where to define an attribute.
* @param[in] name Name of an instance variable.
* @param[in] need_reader Whether attr_reader is needed.
* @param[in] need_writer Whether attr_writer is needed.
* @param[in] honour_visibility Whether to use the current visibility.
* @exception rb_eTypeError `klass` is not a class.
* @exception rb_eFrozenError `klass` is frozen.
* @post If `need_reader` is set `klass` has a method named `name`.
* @post If `need_writer` is set `klass` has a method named `name=`.
*
* @internal
*
* The three `int` arguments should have been bool, but there was no such thing
* like a bool when K&R was used in this project.
*/
void rb_attr(VALUE klass, ID name, int need_reader, int need_writer, int honour_visibility);
RBIMPL_ATTR_NONNULL(())
/**
* Removes a method. Don't confuse this to rb_undef_method(), which doesn't
* remove a method. This one resembles `Module#remove_method`.
*
* @param[out] klass The class to remove a method.
* @param[in] name Name of a method to be removed.
* @exception rb_eTypeError `klass` is a non-module.
* @exception rb_eFrozenError `klass` is frozen.
* @exception rb_eNameError No such method.
* @see rb_undef_method
*/
void rb_remove_method(VALUE klass, const char *name);
/**
* Identical to rb_remove_method(), except it accepts the method name as ::ID.
*
* @param[out] klass The class to remove a method.
* @param[in] mid Name of a method to be removed.
* @exception rb_eTypeError `klass` is a non-module.
* @exception rb_eFrozenError `klass` is frozen.
* @exception rb_eNameError No such method.
* @see rb_undef
*/
void rb_remove_method_id(VALUE klass, ID mid);
/**
* Queries if the klass has this method. This function has only one line of
* document in the implementation that states "// deprecated". Don't know what
* that means though.
*
* @param[in] klass The class in question.
* @param[in] id The method name to query.
* @param[in] ex Undocumented magic value.
* @retval false Method not found.
* @retval true There is a method.
* @pre `klass` must be a module.
*
* @internal
*
* @shyouhei has no motivation to describe what should be passed to `ex`. It
* seems this function should just be trashed.
*/
int rb_method_boundp(VALUE klass, ID id, int ex);
/**
* Well... Let us hesitate from describing what a "basic definition" is. This
* nuanced concept should have been kept private. Just please. Don't touch
* it. This function is a badly distributed random number generator. Right?
*
* @param[in] klass The class in question.
* @param[in] mid The method name in question.
* @retval 1 It is.
* @retval 0 It isn't.
*/
int rb_method_basic_definition_p(VALUE klass, ID mid);
/**
* Identical to rb_respond_to(), except it additionally takes the visibility
* parameter. This does not make difference unless the object has
* `respond_to?` undefined, but has `respond_to_missing?` defined. That case
* the passed argument becomes the second argument of `respond_to_missing?`.
*
* @param[in] obj The object in question.
* @param[in] mid The method name in question.
* @param[in] private_p This is the second argument of `obj`'s
* `respond_to_missing?`.
* @retval 1 Yes it does.
* @retval 0 No it doesn't.
*/
int rb_obj_respond_to(VALUE obj, ID mid, int private_p);
/**
* Queries if the object responds to the method. This involves calling the
* object's `respond_to?` method.
*
* @param[in] obj The object in question.
* @param[in] mid The method name in question.
* @retval 1 Yes it does.
* @retval 0 No it doesn't.
*/
int rb_respond_to(VALUE obj, ID mid);
RBIMPL_ATTR_NORETURN()
/**
* Raises ::rb_eNotImpError. This function is used as an argument to
* rb_define_method() etc.
*
* ```CXX
* rb_define_method(rb_cFoo, "foo", rb_f_notimplement, -1);
* ```
*
* @param argc Unused parameter.
* @param argv Unused parameter.
* @param obj Unused parameter.
* @param marker Unused parameter.
* @exception rb_eNotImpError Always.
* @return Never returns.
*
* @internal
*
* See also the Q&A section of include/ruby/internal/anyargs.h.
*/
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj, VALUE marker);
#if !defined(RUBY_EXPORT) && defined(_WIN32)
RUBY_EXTERN VALUE (*const rb_f_notimplement_)(int, const VALUE *, VALUE, VALUE marker);
#define rb_f_notimplement (*rb_f_notimplement_)
#endif
/* vm_backtrace.c */
/**
* Prints the backtrace out to the standard error. This just confuses people
* for no reason. Evil souls must only use it.
*
* @internal
*
* Actually it is very useful when called from an interactive GDB session.
*/
void rb_backtrace(void);
/**
* Creates the good old fashioned array-of-strings style backtrace info.
*
* @return An array which contains strings, which are the textual
* representations of the backtrace locations of the current thread of
* the current ractor of the current execution context.
* @note Ruby scripts can access more sophisticated
* `Thread::Backtrace::Location`. But it seems there is no way for C
* extensions to use that API.
*/
VALUE rb_make_backtrace(void);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_VM_H */