| 1 | #ifndef wren_h |
| 2 | #define wren_h |
| 3 | |
| 4 | #include <stdarg.h> |
| 5 | #include <stdlib.h> |
| 6 | #include <stdbool.h> |
| 7 | |
| 8 | // The Wren semantic version number components. |
| 9 | #define WREN_VERSION_MAJOR 0 |
| 10 | #define WREN_VERSION_MINOR 4 |
| 11 | #define WREN_VERSION_PATCH 0 |
| 12 | |
| 13 | // A human-friendly string representation of the version. |
| 14 | #define WREN_VERSION_STRING "0.4.0" |
| 15 | |
| 16 | // A monotonically increasing numeric representation of the version number. Use |
| 17 | // this if you want to do range checks over versions. |
| 18 | #define WREN_VERSION_NUMBER (WREN_VERSION_MAJOR * 1000000 + \ |
| 19 | WREN_VERSION_MINOR * 1000 + \ |
| 20 | WREN_VERSION_PATCH) |
| 21 | |
| 22 | #ifndef WREN_API |
| 23 | #if defined(_MSC_VER) && defined(WREN_API_DLLEXPORT) |
| 24 | #define WREN_API __declspec( dllexport ) |
| 25 | #else |
| 26 | #define WREN_API |
| 27 | #endif |
| 28 | #endif //WREN_API |
| 29 | |
| 30 | // A single virtual machine for executing Wren code. |
| 31 | // |
| 32 | // Wren has no global state, so all state stored by a running interpreter lives |
| 33 | // here. |
| 34 | typedef struct WrenVM WrenVM; |
| 35 | |
| 36 | // A handle to a Wren object. |
| 37 | // |
| 38 | // This lets code outside of the VM hold a persistent reference to an object. |
| 39 | // After a handle is acquired, and until it is released, this ensures the |
| 40 | // garbage collector will not reclaim the object it references. |
| 41 | typedef struct WrenHandle WrenHandle; |
| 42 | |
| 43 | // A generic allocation function that handles all explicit memory management |
| 44 | // used by Wren. It's used like so: |
| 45 | // |
| 46 | // - To allocate new memory, [memory] is NULL and [newSize] is the desired |
| 47 | // size. It should return the allocated memory or NULL on failure. |
| 48 | // |
| 49 | // - To attempt to grow an existing allocation, [memory] is the memory, and |
| 50 | // [newSize] is the desired size. It should return [memory] if it was able to |
| 51 | // grow it in place, or a new pointer if it had to move it. |
| 52 | // |
| 53 | // - To shrink memory, [memory] and [newSize] are the same as above but it will |
| 54 | // always return [memory]. |
| 55 | // |
| 56 | // - To free memory, [memory] will be the memory to free and [newSize] will be |
| 57 | // zero. It should return NULL. |
| 58 | typedef void* (*WrenReallocateFn)(void* memory, size_t newSize, void* userData); |
| 59 | |
| 60 | // A function callable from Wren code, but implemented in C. |
| 61 | typedef void (*WrenForeignMethodFn)(WrenVM* vm); |
| 62 | |
| 63 | // A finalizer function for freeing resources owned by an instance of a foreign |
| 64 | // class. Unlike most foreign methods, finalizers do not have access to the VM |
| 65 | // and should not interact with it since it's in the middle of a garbage |
| 66 | // collection. |
| 67 | typedef void (*WrenFinalizerFn)(void* data); |
| 68 | |
| 69 | // Gives the host a chance to canonicalize the imported module name, |
| 70 | // potentially taking into account the (previously resolved) name of the module |
| 71 | // that contains the import. Typically, this is used to implement relative |
| 72 | // imports. |
| 73 | typedef const char* (*WrenResolveModuleFn)(WrenVM* vm, |
| 74 | const char* importer, const char* name); |
| 75 | |
| 76 | // Forward declare |
| 77 | struct WrenLoadModuleResult; |
| 78 | |
| 79 | // Called after loadModuleFn is called for module [name]. The original returned result |
| 80 | // is handed back to you in this callback, so that you can free memory if appropriate. |
| 81 | typedef void (*WrenLoadModuleCompleteFn)(WrenVM* vm, const char* name, struct WrenLoadModuleResult result); |
| 82 | |
| 83 | // The result of a loadModuleFn call. |
| 84 | // [source] is the source code for the module, or NULL if the module is not found. |
| 85 | // [onComplete] an optional callback that will be called once Wren is done with the result. |
| 86 | typedef struct WrenLoadModuleResult |
| 87 | { |
| 88 | const char* source; |
| 89 | WrenLoadModuleCompleteFn onComplete; |
| 90 | void* userData; |
| 91 | } WrenLoadModuleResult; |
| 92 | |
| 93 | // Loads and returns the source code for the module [name]. |
| 94 | typedef WrenLoadModuleResult (*WrenLoadModuleFn)(WrenVM* vm, const char* name); |
| 95 | |
| 96 | // Returns a pointer to a foreign method on [className] in [module] with |
| 97 | // [signature]. |
| 98 | typedef WrenForeignMethodFn (*WrenBindForeignMethodFn)(WrenVM* vm, |
| 99 | const char* module, const char* className, bool isStatic, |
| 100 | const char* signature); |
| 101 | |
| 102 | // Displays a string of text to the user. |
| 103 | typedef void (*WrenWriteFn)(WrenVM* vm, const char* text); |
| 104 | |
| 105 | typedef enum |
| 106 | { |
| 107 | // A syntax or resolution error detected at compile time. |
| 108 | WREN_ERROR_COMPILE, |
| 109 | |
| 110 | // The error message for a runtime error. |
| 111 | WREN_ERROR_RUNTIME, |
| 112 | |
| 113 | // One entry of a runtime error's stack trace. |
| 114 | WREN_ERROR_STACK_TRACE |
| 115 | } WrenErrorType; |
| 116 | |
| 117 | // Reports an error to the user. |
| 118 | // |
| 119 | // An error detected during compile time is reported by calling this once with |
| 120 | // [type] `WREN_ERROR_COMPILE`, the resolved name of the [module] and [line] |
| 121 | // where the error occurs, and the compiler's error [message]. |
| 122 | // |
| 123 | // A runtime error is reported by calling this once with [type] |
| 124 | // `WREN_ERROR_RUNTIME`, no [module] or [line], and the runtime error's |
| 125 | // [message]. After that, a series of [type] `WREN_ERROR_STACK_TRACE` calls are |
| 126 | // made for each line in the stack trace. Each of those has the resolved |
| 127 | // [module] and [line] where the method or function is defined and [message] is |
| 128 | // the name of the method or function. |
| 129 | typedef void (*WrenErrorFn)( |
| 130 | WrenVM* vm, WrenErrorType type, const char* module, int line, |
| 131 | const char* message); |
| 132 | |
| 133 | typedef struct |
| 134 | { |
| 135 | // The callback invoked when the foreign object is created. |
| 136 | // |
| 137 | // This must be provided. Inside the body of this, it must call |
| 138 | // [wrenSetSlotNewForeign()] exactly once. |
| 139 | WrenForeignMethodFn allocate; |
| 140 | |
| 141 | // The callback invoked when the garbage collector is about to collect a |
| 142 | // foreign object's memory. |
| 143 | // |
| 144 | // This may be `NULL` if the foreign class does not need to finalize. |
| 145 | WrenFinalizerFn finalize; |
| 146 | } WrenForeignClassMethods; |
| 147 | |
| 148 | // Returns a pair of pointers to the foreign methods used to allocate and |
| 149 | // finalize the data for instances of [className] in resolved [module]. |
| 150 | typedef WrenForeignClassMethods (*WrenBindForeignClassFn)( |
| 151 | WrenVM* vm, const char* module, const char* className); |
| 152 | |
| 153 | typedef struct |
| 154 | { |
| 155 | // The callback Wren will use to allocate, reallocate, and deallocate memory. |
| 156 | // |
| 157 | // If `NULL`, defaults to a built-in function that uses `realloc` and `free`. |
| 158 | WrenReallocateFn reallocateFn; |
| 159 | |
| 160 | // The callback Wren uses to resolve a module name. |
| 161 | // |
| 162 | // Some host applications may wish to support "relative" imports, where the |
| 163 | // meaning of an import string depends on the module that contains it. To |
| 164 | // support that without baking any policy into Wren itself, the VM gives the |
| 165 | // host a chance to resolve an import string. |
| 166 | // |
| 167 | // Before an import is loaded, it calls this, passing in the name of the |
| 168 | // module that contains the import and the import string. The host app can |
| 169 | // look at both of those and produce a new "canonical" string that uniquely |
| 170 | // identifies the module. This string is then used as the name of the module |
| 171 | // going forward. It is what is passed to [loadModuleFn], how duplicate |
| 172 | // imports of the same module are detected, and how the module is reported in |
| 173 | // stack traces. |
| 174 | // |
| 175 | // If you leave this function NULL, then the original import string is |
| 176 | // treated as the resolved string. |
| 177 | // |
| 178 | // If an import cannot be resolved by the embedder, it should return NULL and |
| 179 | // Wren will report that as a runtime error. |
| 180 | // |
| 181 | // Wren will take ownership of the string you return and free it for you, so |
| 182 | // it should be allocated using the same allocation function you provide |
| 183 | // above. |
| 184 | WrenResolveModuleFn resolveModuleFn; |
| 185 | |
| 186 | // The callback Wren uses to load a module. |
| 187 | // |
| 188 | // Since Wren does not talk directly to the file system, it relies on the |
| 189 | // embedder to physically locate and read the source code for a module. The |
| 190 | // first time an import appears, Wren will call this and pass in the name of |
| 191 | // the module being imported. The method will return a result, which contains |
| 192 | // the source code for that module. Memory for the source is owned by the |
| 193 | // host application, and can be freed using the onComplete callback. |
| 194 | // |
| 195 | // This will only be called once for any given module name. Wren caches the |
| 196 | // result internally so subsequent imports of the same module will use the |
| 197 | // previous source and not call this. |
| 198 | // |
| 199 | // If a module with the given name could not be found by the embedder, it |
| 200 | // should return NULL and Wren will report that as a runtime error. |
| 201 | WrenLoadModuleFn loadModuleFn; |
| 202 | |
| 203 | // The callback Wren uses to find a foreign method and bind it to a class. |
| 204 | // |
| 205 | // When a foreign method is declared in a class, this will be called with the |
| 206 | // foreign method's module, class, and signature when the class body is |
| 207 | // executed. It should return a pointer to the foreign function that will be |
| 208 | // bound to that method. |
| 209 | // |
| 210 | // If the foreign function could not be found, this should return NULL and |
| 211 | // Wren will report it as runtime error. |
| 212 | WrenBindForeignMethodFn bindForeignMethodFn; |
| 213 | |
| 214 | // The callback Wren uses to find a foreign class and get its foreign methods. |
| 215 | // |
| 216 | // When a foreign class is declared, this will be called with the class's |
| 217 | // module and name when the class body is executed. It should return the |
| 218 | // foreign functions uses to allocate and (optionally) finalize the bytes |
| 219 | // stored in the foreign object when an instance is created. |
| 220 | WrenBindForeignClassFn bindForeignClassFn; |
| 221 | |
| 222 | // The callback Wren uses to display text when `System.print()` or the other |
| 223 | // related functions are called. |
| 224 | // |
| 225 | // If this is `NULL`, Wren discards any printed text. |
| 226 | WrenWriteFn writeFn; |
| 227 | |
| 228 | // The callback Wren uses to report errors. |
| 229 | // |
| 230 | // When an error occurs, this will be called with the module name, line |
| 231 | // number, and an error message. If this is `NULL`, Wren doesn't report any |
| 232 | // errors. |
| 233 | WrenErrorFn errorFn; |
| 234 | |
| 235 | // The number of bytes Wren will allocate before triggering the first garbage |
| 236 | // collection. |
| 237 | // |
| 238 | // If zero, defaults to 10MB. |
| 239 | size_t initialHeapSize; |
| 240 | |
| 241 | // After a collection occurs, the threshold for the next collection is |
| 242 | // determined based on the number of bytes remaining in use. This allows Wren |
| 243 | // to shrink its memory usage automatically after reclaiming a large amount |
| 244 | // of memory. |
| 245 | // |
| 246 | // This can be used to ensure that the heap does not get too small, which can |
| 247 | // in turn lead to a large number of collections afterwards as the heap grows |
| 248 | // back to a usable size. |
| 249 | // |
| 250 | // If zero, defaults to 1MB. |
| 251 | size_t minHeapSize; |
| 252 | |
| 253 | // Wren will resize the heap automatically as the number of bytes |
| 254 | // remaining in use after a collection changes. This number determines the |
| 255 | // amount of additional memory Wren will use after a collection, as a |
| 256 | // percentage of the current heap size. |
| 257 | // |
| 258 | // For example, say that this is 50. After a garbage collection, when there |
| 259 | // are 400 bytes of memory still in use, the next collection will be triggered |
| 260 | // after a total of 600 bytes are allocated (including the 400 already in |
| 261 | // use.) |
| 262 | // |
| 263 | // Setting this to a smaller number wastes less memory, but triggers more |
| 264 | // frequent garbage collections. |
| 265 | // |
| 266 | // If zero, defaults to 50. |
| 267 | int heapGrowthPercent; |
| 268 | |
| 269 | // User-defined data associated with the VM. |
| 270 | void* userData; |
| 271 | |
| 272 | } WrenConfiguration; |
| 273 | |
| 274 | typedef enum |
| 275 | { |
| 276 | WREN_RESULT_SUCCESS, |
| 277 | WREN_RESULT_COMPILE_ERROR, |
| 278 | WREN_RESULT_RUNTIME_ERROR |
| 279 | } WrenInterpretResult; |
| 280 | |
| 281 | // The type of an object stored in a slot. |
| 282 | // |
| 283 | // This is not necessarily the object's *class*, but instead its low level |
| 284 | // representation type. |
| 285 | typedef enum |
| 286 | { |
| 287 | WREN_TYPE_BOOL, |
| 288 | WREN_TYPE_NUM, |
| 289 | WREN_TYPE_FOREIGN, |
| 290 | WREN_TYPE_LIST, |
| 291 | WREN_TYPE_MAP, |
| 292 | WREN_TYPE_NULL, |
| 293 | WREN_TYPE_STRING, |
| 294 | |
| 295 | // The object is of a type that isn't accessible by the C API. |
| 296 | WREN_TYPE_UNKNOWN |
| 297 | } WrenType; |
| 298 | |
| 299 | // Get the current wren version number. |
| 300 | // |
| 301 | // Can be used to range checks over versions. |
| 302 | WREN_API int wrenGetVersionNumber(); |
| 303 | |
| 304 | // Initializes [configuration] with all of its default values. |
| 305 | // |
| 306 | // Call this before setting the particular fields you care about. |
| 307 | WREN_API void wrenInitConfiguration(WrenConfiguration* configuration); |
| 308 | |
| 309 | // Creates a new Wren virtual machine using the given [configuration]. Wren |
| 310 | // will copy the configuration data, so the argument passed to this can be |
| 311 | // freed after calling this. If [configuration] is `NULL`, uses a default |
| 312 | // configuration. |
| 313 | WREN_API WrenVM* wrenNewVM(WrenConfiguration* configuration); |
| 314 | |
| 315 | // Disposes of all resources is use by [vm], which was previously created by a |
| 316 | // call to [wrenNewVM]. |
| 317 | WREN_API void wrenFreeVM(WrenVM* vm); |
| 318 | |
| 319 | // Immediately run the garbage collector to free unused memory. |
| 320 | WREN_API void wrenCollectGarbage(WrenVM* vm); |
| 321 | |
| 322 | // Runs [source], a string of Wren source code in a new fiber in [vm] in the |
| 323 | // context of resolved [module]. |
| 324 | WREN_API WrenInterpretResult wrenInterpret(WrenVM* vm, const char* module, |
| 325 | const char* source); |
| 326 | |
| 327 | // Creates a handle that can be used to invoke a method with [signature] on |
| 328 | // using a receiver and arguments that are set up on the stack. |
| 329 | // |
| 330 | // This handle can be used repeatedly to directly invoke that method from C |
| 331 | // code using [wrenCall]. |
| 332 | // |
| 333 | // When you are done with this handle, it must be released using |
| 334 | // [wrenReleaseHandle]. |
| 335 | WREN_API WrenHandle* wrenMakeCallHandle(WrenVM* vm, const char* signature); |
| 336 | |
| 337 | // Calls [method], using the receiver and arguments previously set up on the |
| 338 | // stack. |
| 339 | // |
| 340 | // [method] must have been created by a call to [wrenMakeCallHandle]. The |
| 341 | // arguments to the method must be already on the stack. The receiver should be |
| 342 | // in slot 0 with the remaining arguments following it, in order. It is an |
| 343 | // error if the number of arguments provided does not match the method's |
| 344 | // signature. |
| 345 | // |
| 346 | // After this returns, you can access the return value from slot 0 on the stack. |
| 347 | WREN_API WrenInterpretResult wrenCall(WrenVM* vm, WrenHandle* method); |
| 348 | |
| 349 | // Releases the reference stored in [handle]. After calling this, [handle] can |
| 350 | // no longer be used. |
| 351 | WREN_API void wrenReleaseHandle(WrenVM* vm, WrenHandle* handle); |
| 352 | |
| 353 | // The following functions are intended to be called from foreign methods or |
| 354 | // finalizers. The interface Wren provides to a foreign method is like a |
| 355 | // register machine: you are given a numbered array of slots that values can be |
| 356 | // read from and written to. Values always live in a slot (unless explicitly |
| 357 | // captured using wrenGetSlotHandle(), which ensures the garbage collector can |
| 358 | // find them. |
| 359 | // |
| 360 | // When your foreign function is called, you are given one slot for the receiver |
| 361 | // and each argument to the method. The receiver is in slot 0 and the arguments |
| 362 | // are in increasingly numbered slots after that. You are free to read and |
| 363 | // write to those slots as you want. If you want more slots to use as scratch |
| 364 | // space, you can call wrenEnsureSlots() to add more. |
| 365 | // |
| 366 | // When your function returns, every slot except slot zero is discarded and the |
| 367 | // value in slot zero is used as the return value of the method. If you don't |
| 368 | // store a return value in that slot yourself, it will retain its previous |
| 369 | // value, the receiver. |
| 370 | // |
| 371 | // While Wren is dynamically typed, C is not. This means the C interface has to |
| 372 | // support the various types of primitive values a Wren variable can hold: bool, |
| 373 | // double, string, etc. If we supported this for every operation in the C API, |
| 374 | // there would be a combinatorial explosion of functions, like "get a |
| 375 | // double-valued element from a list", "insert a string key and double value |
| 376 | // into a map", etc. |
| 377 | // |
| 378 | // To avoid that, the only way to convert to and from a raw C value is by going |
| 379 | // into and out of a slot. All other functions work with values already in a |
| 380 | // slot. So, to add an element to a list, you put the list in one slot, and the |
| 381 | // element in another. Then there is a single API function wrenInsertInList() |
| 382 | // that takes the element out of that slot and puts it into the list. |
| 383 | // |
| 384 | // The goal of this API is to be easy to use while not compromising performance. |
| 385 | // The latter means it does not do type or bounds checking at runtime except |
| 386 | // using assertions which are generally removed from release builds. C is an |
| 387 | // unsafe language, so it's up to you to be careful to use it correctly. In |
| 388 | // return, you get a very fast FFI. |
| 389 | |
| 390 | // Returns the number of slots available to the current foreign method. |
| 391 | WREN_API int wrenGetSlotCount(WrenVM* vm); |
| 392 | |
| 393 | // Ensures that the foreign method stack has at least [numSlots] available for |
| 394 | // use, growing the stack if needed. |
| 395 | // |
| 396 | // Does not shrink the stack if it has more than enough slots. |
| 397 | // |
| 398 | // It is an error to call this from a finalizer. |
| 399 | WREN_API void wrenEnsureSlots(WrenVM* vm, int numSlots); |
| 400 | |
| 401 | // Gets the type of the object in [slot]. |
| 402 | WREN_API WrenType wrenGetSlotType(WrenVM* vm, int slot); |
| 403 | |
| 404 | // Reads a boolean value from [slot]. |
| 405 | // |
| 406 | // It is an error to call this if the slot does not contain a boolean value. |
| 407 | WREN_API bool wrenGetSlotBool(WrenVM* vm, int slot); |
| 408 | |
| 409 | // Reads a byte array from [slot]. |
| 410 | // |
| 411 | // The memory for the returned string is owned by Wren. You can inspect it |
| 412 | // while in your foreign method, but cannot keep a pointer to it after the |
| 413 | // function returns, since the garbage collector may reclaim it. |
| 414 | // |
| 415 | // Returns a pointer to the first byte of the array and fill [length] with the |
| 416 | // number of bytes in the array. |
| 417 | // |
| 418 | // It is an error to call this if the slot does not contain a string. |
| 419 | WREN_API const char* wrenGetSlotBytes(WrenVM* vm, int slot, int* length); |
| 420 | |
| 421 | // Reads a number from [slot]. |
| 422 | // |
| 423 | // It is an error to call this if the slot does not contain a number. |
| 424 | WREN_API double wrenGetSlotDouble(WrenVM* vm, int slot); |
| 425 | |
| 426 | // Reads a foreign object from [slot] and returns a pointer to the foreign data |
| 427 | // stored with it. |
| 428 | // |
| 429 | // It is an error to call this if the slot does not contain an instance of a |
| 430 | // foreign class. |
| 431 | WREN_API void* wrenGetSlotForeign(WrenVM* vm, int slot); |
| 432 | |
| 433 | // Reads a string from [slot]. |
| 434 | // |
| 435 | // The memory for the returned string is owned by Wren. You can inspect it |
| 436 | // while in your foreign method, but cannot keep a pointer to it after the |
| 437 | // function returns, since the garbage collector may reclaim it. |
| 438 | // |
| 439 | // It is an error to call this if the slot does not contain a string. |
| 440 | WREN_API const char* wrenGetSlotString(WrenVM* vm, int slot); |
| 441 | |
| 442 | // Creates a handle for the value stored in [slot]. |
| 443 | // |
| 444 | // This will prevent the object that is referred to from being garbage collected |
| 445 | // until the handle is released by calling [wrenReleaseHandle()]. |
| 446 | WREN_API WrenHandle* wrenGetSlotHandle(WrenVM* vm, int slot); |
| 447 | |
| 448 | // Stores the boolean [value] in [slot]. |
| 449 | WREN_API void wrenSetSlotBool(WrenVM* vm, int slot, bool value); |
| 450 | |
| 451 | // Stores the array [length] of [bytes] in [slot]. |
| 452 | // |
| 453 | // The bytes are copied to a new string within Wren's heap, so you can free |
| 454 | // memory used by them after this is called. |
| 455 | WREN_API void wrenSetSlotBytes(WrenVM* vm, int slot, const char* bytes, size_t length); |
| 456 | |
| 457 | // Stores the numeric [value] in [slot]. |
| 458 | WREN_API void wrenSetSlotDouble(WrenVM* vm, int slot, double value); |
| 459 | |
| 460 | // Creates a new instance of the foreign class stored in [classSlot] with [size] |
| 461 | // bytes of raw storage and places the resulting object in [slot]. |
| 462 | // |
| 463 | // This does not invoke the foreign class's constructor on the new instance. If |
| 464 | // you need that to happen, call the constructor from Wren, which will then |
| 465 | // call the allocator foreign method. In there, call this to create the object |
| 466 | // and then the constructor will be invoked when the allocator returns. |
| 467 | // |
| 468 | // Returns a pointer to the foreign object's data. |
| 469 | WREN_API void* wrenSetSlotNewForeign(WrenVM* vm, int slot, int classSlot, size_t size); |
| 470 | |
| 471 | // Stores a new empty list in [slot]. |
| 472 | WREN_API void wrenSetSlotNewList(WrenVM* vm, int slot); |
| 473 | |
| 474 | // Stores a new empty map in [slot]. |
| 475 | WREN_API void wrenSetSlotNewMap(WrenVM* vm, int slot); |
| 476 | |
| 477 | // Stores null in [slot]. |
| 478 | WREN_API void wrenSetSlotNull(WrenVM* vm, int slot); |
| 479 | |
| 480 | // Stores the string [text] in [slot]. |
| 481 | // |
| 482 | // The [text] is copied to a new string within Wren's heap, so you can free |
| 483 | // memory used by it after this is called. The length is calculated using |
| 484 | // [strlen()]. If the string may contain any null bytes in the middle, then you |
| 485 | // should use [wrenSetSlotBytes()] instead. |
| 486 | WREN_API void wrenSetSlotString(WrenVM* vm, int slot, const char* text); |
| 487 | |
| 488 | // Stores the value captured in [handle] in [slot]. |
| 489 | // |
| 490 | // This does not release the handle for the value. |
| 491 | WREN_API void wrenSetSlotHandle(WrenVM* vm, int slot, WrenHandle* handle); |
| 492 | |
| 493 | // Returns the number of elements in the list stored in [slot]. |
| 494 | WREN_API int wrenGetListCount(WrenVM* vm, int slot); |
| 495 | |
| 496 | // Reads element [index] from the list in [listSlot] and stores it in |
| 497 | // [elementSlot]. |
| 498 | WREN_API void wrenGetListElement(WrenVM* vm, int listSlot, int index, int elementSlot); |
| 499 | |
| 500 | // Sets the value stored at [index] in the list at [listSlot], |
| 501 | // to the value from [elementSlot]. |
| 502 | WREN_API void wrenSetListElement(WrenVM* vm, int listSlot, int index, int elementSlot); |
| 503 | |
| 504 | // Takes the value stored at [elementSlot] and inserts it into the list stored |
| 505 | // at [listSlot] at [index]. |
| 506 | // |
| 507 | // As in Wren, negative indexes can be used to insert from the end. To append |
| 508 | // an element, use `-1` for the index. |
| 509 | WREN_API void wrenInsertInList(WrenVM* vm, int listSlot, int index, int elementSlot); |
| 510 | |
| 511 | // Returns the number of entries in the map stored in [slot]. |
| 512 | WREN_API int wrenGetMapCount(WrenVM* vm, int slot); |
| 513 | |
| 514 | // Returns true if the key in [keySlot] is found in the map placed in [mapSlot]. |
| 515 | WREN_API bool wrenGetMapContainsKey(WrenVM* vm, int mapSlot, int keySlot); |
| 516 | |
| 517 | // Retrieves a value with the key in [keySlot] from the map in [mapSlot] and |
| 518 | // stores it in [valueSlot]. |
| 519 | WREN_API void wrenGetMapValue(WrenVM* vm, int mapSlot, int keySlot, int valueSlot); |
| 520 | |
| 521 | // Takes the value stored at [valueSlot] and inserts it into the map stored |
| 522 | // at [mapSlot] with key [keySlot]. |
| 523 | WREN_API void wrenSetMapValue(WrenVM* vm, int mapSlot, int keySlot, int valueSlot); |
| 524 | |
| 525 | // Removes a value from the map in [mapSlot], with the key from [keySlot], |
| 526 | // and place it in [removedValueSlot]. If not found, [removedValueSlot] is |
| 527 | // set to null, the same behaviour as the Wren Map API. |
| 528 | WREN_API void wrenRemoveMapValue(WrenVM* vm, int mapSlot, int keySlot, |
| 529 | int removedValueSlot); |
| 530 | |
| 531 | // Looks up the top level variable with [name] in resolved [module] and stores |
| 532 | // it in [slot]. |
| 533 | WREN_API void wrenGetVariable(WrenVM* vm, const char* module, const char* name, |
| 534 | int slot); |
| 535 | |
| 536 | // Looks up the top level variable with [name] in resolved [module], |
| 537 | // returns false if not found. The module must be imported at the time, |
| 538 | // use wrenHasModule to ensure that before calling. |
| 539 | WREN_API bool wrenHasVariable(WrenVM* vm, const char* module, const char* name); |
| 540 | |
| 541 | // Returns true if [module] has been imported/resolved before, false if not. |
| 542 | WREN_API bool wrenHasModule(WrenVM* vm, const char* module); |
| 543 | |
| 544 | // Sets the current fiber to be aborted, and uses the value in [slot] as the |
| 545 | // runtime error object. |
| 546 | WREN_API void wrenAbortFiber(WrenVM* vm, int slot); |
| 547 | |
| 548 | // Returns the user data associated with the WrenVM. |
| 549 | WREN_API void* wrenGetUserData(WrenVM* vm); |
| 550 | |
| 551 | // Sets user data associated with the WrenVM. |
| 552 | WREN_API void wrenSetUserData(WrenVM* vm, void* userData); |
| 553 | |
| 554 | #endif |
| 555 | |