github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-objmodel.c (about) 1 /* 2 * jit-objmodel.c - Interfaces for pluggable object models. 3 * 4 * Copyright (C) 2004 Southern Storm Software, Pty Ltd. 5 * 6 * This file is part of the libjit library. 7 * 8 * The libjit library is free software: you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public License 10 * as published by the Free Software Foundation, either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * The libjit library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with the libjit library. If not, see 20 * <http://www.gnu.org/licenses/>. 21 */ 22 23 #include <jit/jit.h> 24 #include <jit/jit-objmodel-private.h> 25 26 /*@ 27 28 The @code{libjit} library does not implement a particular object model 29 of its own, so that it is generic across bytecode formats and front end 30 languages. However, it does provide support for plugging object models 31 into the JIT process, and for transparently proxying to external libraries 32 that may use a foreign object model. 33 34 There may be more than one object model active in the system at any 35 one time. For example, a JVM implementation might have a primary 36 object model for its own use, and a secondary object model for 37 calling methods in an imported Objective C library. 38 39 The functions in this section support pluggable object models. There is 40 no requirement that you use them: you can ignore them and use the rest 41 of @code{libjit} directly if you wish. 42 43 To create a new object model, you would include the file 44 @code{<jit/jit-objmodel-private.h>} and create an instance of 45 the @code{struct jit_objmodel} type. This instance should be 46 populated with pointers to your object model's handler routines. 47 You then use functions from the list below to access the 48 object model. 49 50 Some standard object models are distributed with @code{libjit} 51 for invoking methods in external C++, Objective C, GCJ, and JNI 52 based libraries. 53 54 @*/ 55 56 /*@ 57 * @deftypefun void jitom_destroy_model (jit_objmodel_t @var{model}) 58 * Destroy an object model handler that is no longer required. 59 * It is undefined what will happen to the objects and classes 60 * that were being managed by the object model: they may still persist, 61 * or they may now be invalid. 62 * @end deftypefun 63 @*/ 64 void jitom_destroy_model(jit_objmodel_t model) 65 { 66 if(model) 67 { 68 (*(model->destroy_model))(model); 69 } 70 } 71 72 /*@ 73 * @deftypefun jitom_class_t jitom_get_class_by_name (jit_objmodel_t @var{model}, const char *@var{name}) 74 * Get the class descriptor from the object model for a class 75 * called @var{name}. Returns NULL if the class was not found. 76 * If the name includes namespace or nested scope qualifiers, 77 * they must be separated by periods (@code{.}). 78 * @end deftypefun 79 @*/ 80 jitom_class_t jitom_get_class_by_name(jit_objmodel_t model, const char *name) 81 { 82 return (*(model->get_class_by_name))(model, name); 83 } 84 85 /*@ 86 * @deftypefun {char *} jitom_class_get_name (jit_objmodel_t @var{model}, jitom_class_t @var{klass}) 87 * Get the name of a particular class. The return value must be freed 88 * with @code{jit_free}. 89 * @end deftypefun 90 @*/ 91 char *jitom_class_get_name(jit_objmodel_t model, jitom_class_t klass) 92 { 93 return (*(model->class_get_name))(model, klass); 94 } 95 96 /*@ 97 * @deftypefun int jitom_class_get_modifiers (jit_objmodel_t @var{model}, jitom_class_t @var{klass}) 98 * Get the access modifiers for a particular class. The following lists 99 * all access modifiers, for classes, fields and methods: 100 * 101 * @table @code 102 * @vindex JITOM_MODIFIER_ACCESS_MASK 103 * @item JITOM_MODIFIER_ACCESS_MASK 104 * Mask to strip out just the public, private, etc access flags. 105 * 106 * @vindex JITOM_MODIFIER_PUBLIC 107 * @vindex JITOM_MODIFIER_PRIVATE 108 * @vindex JITOM_MODIFIER_PROTECTED 109 * @vindex JITOM_MODIFIER_PACKAGE 110 * @vindex JITOM_MODIFIER_PACKAGE_OR_PROTECTED 111 * @vindex JITOM_MODIFIER_PACKAGE_AND_PROTECTED 112 * @vindex JITOM_MODIFIER_OTHER1 113 * @vindex JITOM_MODIFIER_OTHER2 114 * @item JITOM_MODIFIER_PUBLIC 115 * @item JITOM_MODIFIER_PRIVATE 116 * @item JITOM_MODIFIER_PROTECTED 117 * @item JITOM_MODIFIER_PACKAGE 118 * @item JITOM_MODIFIER_PACKAGE_OR_PROTECTED 119 * @item JITOM_MODIFIER_PACKAGE_AND_PROTECTED 120 * @item JITOM_MODIFIER_OTHER1 121 * @item JITOM_MODIFIER_OTHER2 122 * The declared access level on the class, field, or method. The scope 123 * of a "package" will typically be model-specific: Java uses namespaces 124 * to define packages, whereas C# uses compile units ("assemblies"). 125 * 126 * Object model handlers do not need to enforce the above access levels. 127 * It is assumed that any caller with access to @code{libjit} has complete 128 * access to the entire system, and will use its own rules for determining 129 * when it is appropriate to grant access to fields and methods. 130 * 131 * @vindex JITOM_MODIFIER_STATIC 132 * @item JITOM_MODIFIER_STATIC 133 * The field or method is static, rather than instance-based. 134 * 135 * @vindex JITOM_MODIFIER_VIRTUAL 136 * @item JITOM_MODIFIER_VIRTUAL 137 * The method is instance-based and virtual. 138 * 139 * @vindex JITOM_MODIFIER_NEW_SLOT 140 * @item JITOM_MODIFIER_NEW_SLOT 141 * The method is virtual, but occupies a new slot. Provided for languages 142 * like C# that can declare virtual methods with the same name as in a 143 * superclass, but within a new slot in the vtable. 144 * 145 * @vindex JITOM_MODIFIER_ABSTRACT 146 * @item JITOM_MODIFIER_ABSTRACT 147 * When used on a class, this indicates that the class contains abstract 148 * methods. When used on a method, this indicates that the method does 149 * not have any associated code in its defining class. It is not possible 150 * to invoke such a method with @code{jitom_method_invoke}, only 151 * @code{jitom_method_invoke_virtual}. 152 * 153 * @vindex JITOM_MODIFIER_LITERAL 154 * @item JITOM_MODIFIER_LITERAL 155 * A hint flag, used on fields, to indicate that the field has a constant 156 * value associated with it and does not occupy any real space. If the 157 * @code{jitom_field_load} function is used on such a field, it will load 158 * the constant value. 159 * 160 * @vindex JITOM_MODIFIER_CTOR 161 * @item JITOM_MODIFIER_CTOR 162 * A hint flag that indicates that the method is an instance constructor. 163 * 164 * @vindex JITOM_MODIFIER_STATIC_CTOR 165 * @item JITOM_MODIFIER_STATIC_CTOR 166 * A hint flag that indicates that the method is a static constructor. 167 * The object model handler is normally responsible for outputting calls to 168 * static constructors; the caller shouldn't need to perform any 169 * special handling. 170 * 171 * @vindex JITOM_MODIFIER_DTOR 172 * @item JITOM_MODIFIER_DTOR 173 * A hint flag that indicates that the method is an instance destructor. 174 * The class should also have the @code{JITOM_MODIFIER_DELETE} flag. 175 * Note: do not use this for object models that support automatic 176 * garbage collection and finalization. 177 * 178 * @vindex JITOM_MODIFIER_INTERFACE 179 * @item JITOM_MODIFIER_INTERFACE 180 * The class is an interface. 181 * 182 * @vindex JITOM_MODIFIER_VALUE 183 * @item JITOM_MODIFIER_VALUE 184 * Instances of this class can be stored inline on the stack. 185 * 186 * @vindex JITOM_MODIFIER_FINAL 187 * @item JITOM_MODIFIER_FINAL 188 * When used on a class, this indicates that it cannot be subclassed. 189 * When used on a virtual method, this indicates that it cannot be 190 * overridden in subclasses. 191 * 192 * @vindex JITOM_MODIFIER_DELETE 193 * @item JITOM_MODIFIER_DELETE 194 * When used on a class, this indicates that its objects must be 195 * explicitly deleted when no longer required. 196 * 197 * @vindex JITOM_MODIFIER_REFERENCE_COUNTED 198 * @item JITOM_MODIFIER_REFERENCE_COUNTED 199 * When used on a class, this indicates that its objects are 200 * reference-counted. Calling @code{jitom_class_delete} will 201 * reduce the reference count and delete the object for real 202 * when the count reaches zero. 203 * @end table 204 * @end deftypefun 205 @*/ 206 int jitom_class_get_modifiers(jit_objmodel_t model, jitom_class_t klass) 207 { 208 return (*(model->class_get_modifiers))(model, klass); 209 } 210 211 /*@ 212 * @deftypefun jit_type_t jitom_class_get_type (jit_objmodel_t @var{model}, jitom_class_t @var{klass}) 213 * Get the JIT type descriptor that represents pointer-based 214 * object references to a class. The object model handler should 215 * use @code{jitom_type_tag_as_class} to tag the return value. 216 * The caller should use @code{jit_type_free} to free the returned 217 * value when it is no longer required. 218 * @end deftypefun 219 @*/ 220 jit_type_t jitom_class_get_type(jit_objmodel_t model, jitom_class_t klass) 221 { 222 return (*(model->class_get_type))(model, klass); 223 } 224 225 /*@ 226 * @deftypefun jit_type_t jitom_class_get_value_type (jit_objmodel_t @var{model}, jitom_class_t @var{klass}) 227 * Get the JIT type descriptor that represents inline stack instances 228 * of the class. The object model handler should use 229 * @code{jitom_type_tag_as_value} to tag the return value. 230 * The caller should use @code{jit_type_free} to free the returned 231 * value when it is no longer required. 232 * @end deftypefun 233 @*/ 234 jit_type_t jitom_class_get_value_type 235 (jit_objmodel_t model, jitom_class_t klass) 236 { 237 return (*(model->class_get_value_type))(model, klass); 238 } 239 240 /*@ 241 * @deftypefun jitom_class_t jitom_class_get_primary_super (jit_objmodel_t @var{model}, jitom_class_t @var{klass}) 242 * Get the primary superclass for @var{klass}. If the object model supports 243 * true multiple inheritance, then this should return the first superclass. 244 * Note: for the purposes of this function, interfaces are not considered 245 * superclasses. Use @code{jitom_class_get_interfaces} instead. 246 * @end deftypefun 247 @*/ 248 jitom_class_t jitom_class_get_primary_super 249 (jit_objmodel_t model, jitom_class_t klass) 250 { 251 return (*(model->class_get_primary_super))(model, klass); 252 } 253 254 /*@ 255 * @deftypefun {jitom_class_t *} jitom_class_get_all_supers (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, unsigned int *@var{num}) 256 * Return an array of all superclasses for @var{klass}, with the number of 257 * elements returned in @var{num}. Returns NULL if out of memory. 258 * Use @code{jit_free} to free the return array. 259 * @end deftypefun 260 @*/ 261 jitom_class_t *jitom_class_get_all_supers 262 (jit_objmodel_t model, jitom_class_t klass, unsigned int *num) 263 { 264 return (*(model->class_get_all_supers))(model, klass, num); 265 } 266 267 /*@ 268 * @deftypefun {jitom_class_t *} jitom_class_get_interfaces (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, unsigned int *@var{num}) 269 * Return an array of all interfaces for @var{klass}, with the number 270 * of elements returned in @var{num}. The list does not include interfaces 271 * that are declared on superclasses. Returns NULL if out of memory. 272 * Use @code{jit_free} to free the return array. 273 * @end deftypefun 274 @*/ 275 jitom_class_t *jitom_class_get_interfaces 276 (jit_objmodel_t model, jitom_class_t klass, unsigned int *num) 277 { 278 return (*(model->class_get_interfaces))(model, klass, num); 279 } 280 281 /*@ 282 * @deftypefun {jitom_field_t *} jitom_class_get_fields (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, unsigned int *@var{num}) 283 * Return an array of all fields for @var{klass}, with the number 284 * of elements returned in @var{num}. The list does not include fields 285 * that are declared on superclasses. Returns NULL if out of memory. 286 * Use @code{jit_free} to free the return array. 287 * @end deftypefun 288 @*/ 289 jitom_field_t *jitom_class_get_fields 290 (jit_objmodel_t model, jitom_class_t klass, unsigned int *num) 291 { 292 return (*(model->class_get_fields))(model, klass, num); 293 } 294 295 /*@ 296 * @deftypefun {jitom_method_t *} jitom_class_get_methods (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, unsigned int *@var{num}) 297 * Return an array of all methods for @var{klass}, with the number 298 * of elements returned in @var{num}. The list does not include methods 299 * that are declared on superclasses. Returns NULL if out of memory. 300 * Use @code{jit_free} to free the return array. 301 * @end deftypefun 302 @*/ 303 jitom_method_t *jitom_class_get_methods 304 (jit_objmodel_t model, jitom_class_t klass, unsigned int *num) 305 { 306 return (*(model->class_get_methods))(model, klass, num); 307 } 308 309 /*@ 310 * @deftypefun jit_value_t jitom_class_new (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_method_t @var{ctor}, jit_function_t @var{func}, jit_value_t *@var{args}, unsigned int @var{num_args}, int @var{flags}) 311 * Add instructions to @var{func} to create a new instance of the 312 * specified class. If @var{ctor} is not NULL, then it indicates a 313 * constructor that should be invoked with the arguments in @var{args}. 314 * If @var{ctor} is NULL, then memory should be allocated, but no 315 * constructor should be invoked. Returns a JIT value representing 316 * the newly allocated object. The type of the value will be the same 317 * as the the result from @code{jitom_class_get_type}. 318 * @end deftypefun 319 @*/ 320 jit_value_t jitom_class_new 321 (jit_objmodel_t model, jitom_class_t klass, 322 jitom_method_t ctor, jit_function_t func, 323 jit_value_t *args, unsigned int num_args, int flags) 324 { 325 return (*(model->class_new)) 326 (model, klass, ctor, func, args, num_args, flags); 327 } 328 329 /*@ 330 * @deftypefun jit_value_t jitom_class_new_value (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_method_t @var{ctor}, jit_function_t @var{func}, jit_value_t *@var{args}, unsigned int @var{num_args}, int @var{flags}) 331 * Add instructions to @var{func} to create a new instance of the 332 * specified class, inline on the stack. If @var{ctor} is not NULL, then 333 * it indicates a constructor that should be invoked with the arguments 334 * in @var{args}. If @var{ctor} is NULL, then stack space should be 335 * allocated, but no constructor should be invoked. Returns a JIT 336 * value representing the newly allocated stack space. The type of the 337 * value will be the same as the the result from 338 * @code{jitom_class_get_value_type}. 339 * @end deftypefun 340 @*/ 341 jit_value_t jitom_class_new_value 342 (jit_objmodel_t model, jitom_class_t klass, 343 jitom_method_t ctor, jit_function_t func, 344 jit_value_t *args, unsigned int num_args, int flags) 345 { 346 return (*(model->class_new_value)) 347 (model, klass, ctor, func, args, num_args, flags); 348 } 349 350 /*@ 351 * @deftypefun int jitom_class_delete (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jit_value_t @var{obj_value}) 352 * Delete an instance of a particular class, calling the destructor if 353 * necessary. The @var{obj_value} may be an inline stack value, 354 * in which case the destructor is called, but the memory is not freed. 355 * Ignored if the class does not have the @code{JITOM_MODIFIER_DELETE} 356 * modifier. 357 * 358 * Note: no attempt is made to destroy inline stack values automatically when 359 * they go out of scope. It is up to the caller to output instructions 360 * in the appropriate places to do this. 361 * @end deftypefun 362 @*/ 363 int jitom_class_delete 364 (jit_objmodel_t model, jitom_class_t klass, jit_value_t obj_value) 365 { 366 return (*(model->class_delete))(model, klass, obj_value); 367 } 368 369 /*@ 370 * @deftypefun int jitom_class_add_ref (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jit_value_t @var{obj_value}) 371 * Add a reference to a reference-counted object. Ignored if the 372 * class does not have the @code{JITOM_MODIFIER_REFERENCE_COUNTED} modifier, 373 * or the value is stored inline on the stack. 374 * 375 * Other functions, such as @code{jitom_field_store}, may also change the 376 * reference count, but such behavior is object model specific. 377 * @end deftypefun 378 @*/ 379 int jitom_class_add_ref 380 (jit_objmodel_t model, jitom_class_t klass, jit_value_t obj_value) 381 { 382 return (*(model->class_add_ref))(model, klass, obj_value); 383 } 384 385 /*@ 386 * @deftypefun {char *} jitom_field_get_name (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_field_t @var{field}) 387 * Get the name of a particular object model field. The return value must 388 * be freed with @code{jit_free}. 389 * @end deftypefun 390 @*/ 391 char *jitom_field_get_name 392 (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field) 393 { 394 return (*(model->field_get_name))(model, klass, field); 395 } 396 397 /*@ 398 * @deftypefun jit_type_t jitom_field_get_type (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_field_t @var{field}) 399 * Get the type of a particular object model field. 400 * @end deftypefun 401 @*/ 402 jit_type_t jitom_field_get_type 403 (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field) 404 { 405 return (*(model->field_get_type))(model, klass, field); 406 } 407 408 /*@ 409 * @deftypefun int jitom_field_get_modifiers (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_field_t @var{field}) 410 * Get the access modifiers that are associated with a particular 411 * object model field. 412 * @end deftypefun 413 @*/ 414 int jitom_field_get_modifiers 415 (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field) 416 { 417 return (*(model->field_get_modifiers))(model, klass, field); 418 } 419 420 /*@ 421 * @deftypefun jit_value_t jitom_field_load (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_field_t @var{field}, jit_function_t @var{func}, jit_value_t @var{obj_value}) 422 * Create instructions within @var{func} to effect a load from a 423 * field within the object @var{obj_value}. If @var{obj_value} is 424 * NULL, then it indicates a static field reference. 425 * 426 * If the field has the @code{JITOM_MODIFIER_LITERAL} modifier, then this 427 * function will load the constant value associated with the field. 428 * Literal fields cannot be stored to. 429 * @end deftypefun 430 @*/ 431 jit_value_t jitom_field_load 432 (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field, 433 jit_function_t func, jit_value_t obj_value) 434 { 435 return (*(model->field_load))(model, klass, field, func, obj_value); 436 } 437 438 /*@ 439 * @deftypefun jit_value_t jitom_field_load_address (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_field_t @var{field}, jit_function_t @var{func}, jit_value_t @var{obj_value}) 440 * Create instructions within @var{func} to get the address of a 441 * field within the object @var{obj_value}. If @var{obj_value} is 442 * NULL, then it indicates that we want the address of a static field. 443 * Some object models may not support this function, and will return NULL. 444 * @end deftypefun 445 @*/ 446 jit_value_t jitom_field_load_address 447 (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field, 448 jit_function_t func, jit_value_t obj_value) 449 { 450 return (*(model->field_load_address)) 451 (model, klass, field, func, obj_value); 452 } 453 454 /*@ 455 * @deftypefun int jitom_field_store (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_field_t @var{field}, jit_function_t @var{func}, jit_value_t @var{obj_value}, jit_value_t @var{value}) 456 * Create instructions within @var{func} to store @var{value} into a 457 * field within the object @var{obj_value}. If @var{obj_value} is 458 * NULL, then it indicates a static field store. 459 * @end deftypefun 460 @*/ 461 int jitom_field_store 462 (jit_objmodel_t model, jitom_class_t klass, jitom_field_t field, 463 jit_function_t func, jit_value_t obj_value, jit_value_t value) 464 { 465 return (*(model->field_store)) 466 (model, klass, field, func, obj_value, value); 467 } 468 469 /*@ 470 * @deftypefun {char *} jitom_method_get_name (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_method_t @var{method}) 471 * Get the name of an object model method. The return value must 472 * be freed with @code{jit_free}. 473 * @end deftypefun 474 @*/ 475 char *jitom_method_get_name 476 (jit_objmodel_t model, jitom_class_t klass, jitom_method_t method) 477 { 478 return (*(model->method_get_name))(model, klass, method); 479 } 480 481 /*@ 482 * @deftypefun jit_type_t jitom_method_get_type (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_method_t @var{method}) 483 * Get the signature type of an object model method. If the method 484 * is instance-based, then the first argument will be an object reference 485 * type indicating the @code{this} pointer. 486 * @end deftypefun 487 @*/ 488 jit_type_t jitom_method_get_type 489 (jit_objmodel_t model, jitom_class_t klass, jitom_method_t method) 490 { 491 return (*(model->method_get_type))(model, klass, method); 492 } 493 494 /*@ 495 * @deftypefun int jitom_method_get_modifiers (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_method_t @var{method}) 496 * Get the access modifiers for an object model method. 497 * @end deftypefun 498 @*/ 499 int jitom_method_get_modifiers 500 (jit_objmodel_t model, jitom_class_t klass, jitom_method_t method) 501 { 502 return (*(model->method_get_modifiers))(model, klass, method); 503 } 504 505 /*@ 506 * @deftypefun jit_value_t jitom_method_invoke (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_method_t @var{method}, jit_function_t @var{func}, jit_value_t *@var{args}, unsigned int @var{num_args}, int @var{flags}) 507 * Create instructions within @var{func} to invoke a static or 508 * instance method. If an instance method is virtual, then this will 509 * ignore the virtual property to invoke the designated method directly. 510 * The first element in @var{args} should be the @code{this} pointer 511 * for instance methods. 512 * @end deftypefun 513 @*/ 514 jit_value_t jitom_method_invoke 515 (jit_objmodel_t model, jitom_class_t klass, jitom_method_t method, 516 jit_function_t func, jit_value_t *args, unsigned int num_args, int flags) 517 { 518 return (*(model->method_invoke)) 519 (model, klass, method, func, args, num_args, flags); 520 } 521 522 /*@ 523 * @deftypefun jit_value_t jitom_method_invoke_virtual (jit_objmodel_t @var{model}, jitom_class_t @var{klass}, jitom_method_t @var{method}, jit_function_t @var{func}, jit_value_t *@var{args}, unsigned int @var{num_args}, int @var{flags}) 524 * Create instructions within @var{func} to invoke a virtual or interface 525 * method. The first element in @var{args} should be the @code{this} 526 * pointer for the call. 527 * @end deftypefun 528 @*/ 529 jit_value_t jitom_method_invoke_virtual 530 (jit_objmodel_t model, jitom_class_t klass, jitom_method_t method, 531 jit_function_t func, jit_value_t *args, unsigned int num_args, int flags) 532 { 533 return (*(model->method_invoke_virtual)) 534 (model, klass, method, func, args, num_args, flags); 535 } 536 537 /* 538 * Information that is stored for class-tagged types. 539 */ 540 typedef struct 541 { 542 jit_objmodel_t model; 543 jitom_class_t klass; 544 545 } jitom_tag_info; 546 547 /*@ 548 * @deftypefun jit_type_t jitom_type_tag_as_class (jit_type_t @var{type}, jit_objmodel_t @var{model}, jitom_class_t @var{klass}, int @var{incref}) 549 * Tag a JIT type as an object reference belonging to a specific class. 550 * Returns NULL if there is insufficient memory to tag the type. 551 * @end deftypefun 552 @*/ 553 jit_type_t jitom_type_tag_as_class 554 (jit_type_t type, jit_objmodel_t model, jitom_class_t klass, int incref) 555 { 556 jitom_tag_info *info; 557 if((info = jit_new(jitom_tag_info)) == 0) 558 { 559 return 0; 560 } 561 info->model = model; 562 info->klass = klass; 563 type = jit_type_create_tagged 564 (type, JITOM_TYPETAG_CLASS, info, jit_free, incref); 565 if(!type) 566 { 567 jit_free(info); 568 } 569 return type; 570 } 571 572 /*@ 573 * @deftypefun jit_type_t jitom_type_tag_as_value (jit_type_t @var{type}, jit_objmodel_t @var{model}, jitom_class_t @var{klass}, int @var{incref}) 574 * Tag a JIT type as an inline static value belonging to a specific class. 575 * Returns NULL if there is insufficient memory to tag the type. 576 * @end deftypefun 577 @*/ 578 jit_type_t jitom_type_tag_as_value 579 (jit_type_t type, jit_objmodel_t model, jitom_class_t klass, int incref) 580 { 581 jitom_tag_info *info; 582 if((info = jit_new(jitom_tag_info)) == 0) 583 { 584 return 0; 585 } 586 info->model = model; 587 info->klass = klass; 588 type = jit_type_create_tagged 589 (type, JITOM_TYPETAG_VALUE, info, jit_free, incref); 590 if(!type) 591 { 592 jit_free(info); 593 } 594 return type; 595 } 596 597 /*@ 598 * @deftypefun int jitom_type_is_class (jit_type_t @var{type}) 599 * Determine if a type is tagged as an object reference. 600 * @end deftypefun 601 @*/ 602 int jitom_type_is_class(jit_type_t type) 603 { 604 return (jit_type_get_tagged_kind(type) == JITOM_TYPETAG_CLASS); 605 } 606 607 /*@ 608 * @deftypefun int jitom_type_is_value (jit_type_t @var{type}) 609 * Determine if a type is tagged as an inline static value. 610 * @end deftypefun 611 @*/ 612 int jitom_type_is_value(jit_type_t type) 613 { 614 return (jit_type_get_tagged_kind(type) == JITOM_TYPETAG_VALUE); 615 } 616 617 /*@ 618 * @deftypefun jit_objmodel_t jitom_type_get_model (jit_type_t @var{type}) 619 * Get the object model associated with a type that was tagged with 620 * @code{jitom_type_tag_as_class} or @code{jitom_type_tag_as_value}. 621 * @end deftypefun 622 @*/ 623 jit_objmodel_t jitom_type_get_model(jit_type_t type) 624 { 625 if(jit_type_get_tagged_kind(type) == JITOM_TYPETAG_CLASS || 626 jit_type_get_tagged_kind(type) == JITOM_TYPETAG_VALUE) 627 { 628 return ((jitom_tag_info *)jit_type_get_tagged_data(type))->model; 629 } 630 else 631 { 632 return 0; 633 } 634 } 635 636 /*@ 637 * @deftypefun jitom_class_t jitom_type_get_class (jit_type_t @var{type}) 638 * Get the class associated with a type that was tagged with 639 * @code{jitom_type_tag_as_class} or @code{jitom_type_tag_as_value}. 640 * @end deftypefun 641 @*/ 642 jitom_class_t jitom_type_get_class(jit_type_t type) 643 { 644 if(jit_type_get_tagged_kind(type) == JITOM_TYPETAG_CLASS || 645 jit_type_get_tagged_kind(type) == JITOM_TYPETAG_VALUE) 646 { 647 return ((jitom_tag_info *)jit_type_get_tagged_data(type))->klass; 648 } 649 else 650 { 651 return 0; 652 } 653 }