├── .gitignore ├── Changes ├── GCCJIT.xs ├── LICENSE ├── MANIFEST ├── MANIFEST.SKIP ├── Makefile.PL ├── README ├── Vagrantfile ├── av_to_pp.h ├── fallback ├── const-c.inc └── const-xs.inc ├── lib ├── GCCJIT.pm └── GCCJIT │ ├── Context.pm │ └── Wrapper.pm ├── ppport.h ├── t ├── 01-constants.t ├── 02-simple.t ├── 03-gcd.t ├── 04-wrapper.t └── 05-wrapper-gcd.t ├── tools ├── make.sh ├── regen.pl └── test.sh └── typemap /.gitignore: -------------------------------------------------------------------------------- 1 | const-c.inc 2 | const-xs.inc 3 | MYMETA.* 4 | Makefile 5 | blib 6 | pm_to_blib 7 | GCCJIT.c 8 | GCCJIT.bs 9 | GCCJIT.o 10 | .vagrant 11 | MANIFEST.bak 12 | Makefile.old 13 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | Revision history for Perl extension GCCJIT. 2 | 3 | 0.03 Fri Apr 22 20:18:11 2016 4 | - fix undef warning in wrapper 5 | 6 | 0.02 Mon Mar 14 21:40:26 2016 7 | - compatibility patch for older perls 8 | - more package metadata 9 | 10 | 0.01 Wed Sep 9 18:36:45 2015 11 | - original version; created by h2xs 1.23 with options 12 | -O -x -n GCCJIT gccjit-perlready.h 13 | 14 | -------------------------------------------------------------------------------- /GCCJIT.xs: -------------------------------------------------------------------------------- 1 | #define PERL_NO_GET_CONTEXT 2 | #include "EXTERN.h" 3 | #include "perl.h" 4 | #include "XSUB.h" 5 | 6 | #include "ppport.h" 7 | 8 | #include 9 | 10 | #include "const-c.inc" 11 | #include "av_to_pp.h" 12 | 13 | MODULE = GCCJIT PACKAGE = GCCJIT 14 | 15 | INCLUDE: const-xs.inc 16 | 17 | void 18 | gcc_jit_block_add_assignment(block, loc, lvalue, rvalue) 19 | gcc_jit_block * block 20 | gcc_jit_location * loc 21 | gcc_jit_lvalue * lvalue 22 | gcc_jit_rvalue * rvalue 23 | 24 | void 25 | gcc_jit_block_add_assignment_op(block, loc, lvalue, op, rvalue) 26 | gcc_jit_block * block 27 | gcc_jit_location * loc 28 | gcc_jit_lvalue * lvalue 29 | enum gcc_jit_binary_op op 30 | gcc_jit_rvalue * rvalue 31 | 32 | void 33 | gcc_jit_block_add_comment(block, loc, text) 34 | gcc_jit_block * block 35 | gcc_jit_location * loc 36 | const char * text 37 | 38 | void 39 | gcc_jit_block_add_eval(block, loc, rvalue) 40 | gcc_jit_block * block 41 | gcc_jit_location * loc 42 | gcc_jit_rvalue * rvalue 43 | 44 | gcc_jit_object * 45 | gcc_jit_block_as_object(block) 46 | gcc_jit_block * block 47 | 48 | void 49 | gcc_jit_block_end_with_conditional(block, loc, boolval, on_true, on_false) 50 | gcc_jit_block * block 51 | gcc_jit_location * loc 52 | gcc_jit_rvalue * boolval 53 | gcc_jit_block * on_true 54 | gcc_jit_block * on_false 55 | 56 | void 57 | gcc_jit_block_end_with_jump(block, loc, target) 58 | gcc_jit_block * block 59 | gcc_jit_location * loc 60 | gcc_jit_block * target 61 | 62 | void 63 | gcc_jit_block_end_with_return(block, loc, rvalue) 64 | gcc_jit_block * block 65 | gcc_jit_location * loc 66 | gcc_jit_rvalue * rvalue 67 | 68 | #ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 69 | void 70 | gcc_jit_block_end_with_switch(block, loc, expr, default_block, cases) 71 | gcc_jit_block * block 72 | gcc_jit_location * loc 73 | gcc_jit_rvalue * expr 74 | gcc_jit_block * default_block 75 | AV * cases 76 | PREINIT: 77 | AVPP_PREINIT(cases, gcc_jit_case *); 78 | CODE: 79 | AVPP_CODE(cases, "gcc_jit_block_end_with_switch", gcc_jit_case *, "gcc_jit_casePtr"); 80 | gcc_jit_block_end_with_switch(block, loc, expr, default_block, num_cases, ptr_cases); 81 | CLEANUP: 82 | AVPP_CLEANUP(cases); 83 | 84 | #endif 85 | 86 | void 87 | gcc_jit_block_end_with_void_return(block, loc) 88 | gcc_jit_block * block 89 | gcc_jit_location * loc 90 | 91 | gcc_jit_function * 92 | gcc_jit_block_get_function(block) 93 | gcc_jit_block * block 94 | 95 | #ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 96 | gcc_jit_object * 97 | gcc_jit_case_as_object(case_) 98 | gcc_jit_case * case_ 99 | 100 | #endif 101 | 102 | gcc_jit_context * 103 | gcc_jit_context_acquire() 104 | 105 | #ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option 106 | void 107 | gcc_jit_context_add_command_line_option(ctxt, optname) 108 | gcc_jit_context * ctxt 109 | const char * optname 110 | 111 | #endif 112 | 113 | gcc_jit_result * 114 | gcc_jit_context_compile(ctxt) 115 | gcc_jit_context * ctxt 116 | 117 | void 118 | gcc_jit_context_compile_to_file(ctxt, output_kind, output_path) 119 | gcc_jit_context * ctxt 120 | enum gcc_jit_output_kind output_kind 121 | const char * output_path 122 | 123 | void 124 | gcc_jit_context_dump_reproducer_to_file(ctxt, path) 125 | gcc_jit_context * ctxt 126 | const char * path 127 | 128 | void 129 | gcc_jit_context_dump_to_file(ctxt, path, update_locations) 130 | gcc_jit_context * ctxt 131 | const char * path 132 | int update_locations 133 | 134 | 135 | =for Disable 136 | 137 | Disabled, because out_ptr is hard to handle in XS: it is only written to when 138 | gcc_jit_context_compile() is called, which means there is nothing to do here, 139 | and whatever happens in gcc_jit_context_compile() wrapper must know somehow 140 | about the out_ptr we got here. Integrated wrapper that calls both 141 | gcc_jit_context_enable_dump() and gcc_jit_context_compile() together would be a 142 | solution, but meh. 143 | 144 | void 145 | gcc_jit_context_enable_dump(ctxt, dumpname, out_ptr) 146 | gcc_jit_context * ctxt 147 | const char * dumpname 148 | char ** out_ptr 149 | 150 | =cut 151 | 152 | gcc_jit_function * 153 | gcc_jit_context_get_builtin_function(ctxt, name) 154 | gcc_jit_context * ctxt 155 | const char * name 156 | 157 | const char * 158 | gcc_jit_context_get_first_error(ctxt) 159 | gcc_jit_context * ctxt 160 | 161 | gcc_jit_type * 162 | gcc_jit_context_get_int_type(ctxt, num_bytes, is_signed) 163 | gcc_jit_context * ctxt 164 | int num_bytes 165 | int is_signed 166 | 167 | const char * 168 | gcc_jit_context_get_last_error(ctxt) 169 | gcc_jit_context * ctxt 170 | 171 | gcc_jit_type * 172 | gcc_jit_context_get_type(ctxt, type_) 173 | gcc_jit_context * ctxt 174 | enum gcc_jit_types type_ 175 | 176 | gcc_jit_lvalue * 177 | gcc_jit_context_new_array_access(ctxt, loc, ptr, index) 178 | gcc_jit_context * ctxt 179 | gcc_jit_location * loc 180 | gcc_jit_rvalue * ptr 181 | gcc_jit_rvalue * index 182 | 183 | gcc_jit_type * 184 | gcc_jit_context_new_array_type(ctxt, loc, element_type, num_elements) 185 | gcc_jit_context * ctxt 186 | gcc_jit_location * loc 187 | gcc_jit_type * element_type 188 | int num_elements 189 | 190 | gcc_jit_rvalue * 191 | gcc_jit_context_new_binary_op(ctxt, loc, op, result_type, a, b) 192 | gcc_jit_context * ctxt 193 | gcc_jit_location * loc 194 | enum gcc_jit_binary_op op 195 | gcc_jit_type * result_type 196 | gcc_jit_rvalue * a 197 | gcc_jit_rvalue * b 198 | 199 | gcc_jit_rvalue * 200 | gcc_jit_context_new_call(ctxt, loc, func, args) 201 | gcc_jit_context * ctxt 202 | gcc_jit_location * loc 203 | gcc_jit_function * func 204 | AV * args 205 | PREINIT: 206 | AVPP_PREINIT(args, gcc_jit_rvalue *); 207 | CODE: 208 | AVPP_CODE(args, "gcc_jit_context_new_call", gcc_jit_rvalue *, "gcc_jit_rvaluePtr"); 209 | RETVAL = gcc_jit_context_new_call(ctxt, loc, func, num_args, ptr_args); 210 | OUTPUT: 211 | RETVAL 212 | CLEANUP: 213 | AVPP_CLEANUP(args); 214 | 215 | gcc_jit_rvalue * 216 | gcc_jit_context_new_call_through_ptr(ctxt, loc, fn_ptr, args) 217 | gcc_jit_context * ctxt 218 | gcc_jit_location * loc 219 | gcc_jit_rvalue * fn_ptr 220 | AV * args 221 | PREINIT: 222 | AVPP_PREINIT(args, gcc_jit_rvalue *); 223 | CODE: 224 | AVPP_CODE(args, "gcc_jit_context_new_call_through_ptr", gcc_jit_rvalue *, "gcc_jit_rvaluePtr"); 225 | RETVAL = gcc_jit_context_new_call_through_ptr(ctxt, loc, fn_ptr, num_args, ptr_args); 226 | OUTPUT: 227 | RETVAL 228 | CLEANUP: 229 | AVPP_CLEANUP(args); 230 | 231 | #ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS 232 | gcc_jit_case * 233 | gcc_jit_context_new_case(ctxt, min_value, max_value, dest_block) 234 | gcc_jit_context * ctxt 235 | gcc_jit_rvalue * min_value 236 | gcc_jit_rvalue * max_value 237 | gcc_jit_block * dest_block 238 | 239 | #endif 240 | 241 | gcc_jit_rvalue * 242 | gcc_jit_context_new_cast(ctxt, loc, rvalue, type) 243 | gcc_jit_context * ctxt 244 | gcc_jit_location * loc 245 | gcc_jit_rvalue * rvalue 246 | gcc_jit_type * type 247 | 248 | gcc_jit_context * 249 | gcc_jit_context_new_child_context(parent_ctxt) 250 | gcc_jit_context * parent_ctxt 251 | 252 | gcc_jit_rvalue * 253 | gcc_jit_context_new_comparison(ctxt, loc, op, a, b) 254 | gcc_jit_context * ctxt 255 | gcc_jit_location * loc 256 | enum gcc_jit_comparison op 257 | gcc_jit_rvalue * a 258 | gcc_jit_rvalue * b 259 | 260 | gcc_jit_field * 261 | gcc_jit_context_new_field(ctxt, loc, type, name) 262 | gcc_jit_context * ctxt 263 | gcc_jit_location * loc 264 | gcc_jit_type * type 265 | const char * name 266 | 267 | gcc_jit_function * 268 | gcc_jit_context_new_function(ctxt, loc, kind, return_type, name, params, is_variadic) 269 | gcc_jit_context * ctxt 270 | gcc_jit_location * loc 271 | enum gcc_jit_function_kind kind 272 | gcc_jit_type * return_type 273 | const char * name 274 | AV * params 275 | int is_variadic 276 | PREINIT: 277 | AVPP_PREINIT(params, gcc_jit_param *); 278 | CODE: 279 | AVPP_CODE(params, "gcc_jit_context_new_function", gcc_jit_param *, "gcc_jit_paramPtr"); 280 | RETVAL = gcc_jit_context_new_function(ctxt, loc, kind, return_type, name, num_params, ptr_params, is_variadic); 281 | OUTPUT: 282 | RETVAL 283 | CLEANUP: 284 | AVPP_CLEANUP(params); 285 | 286 | gcc_jit_type * 287 | gcc_jit_context_new_function_ptr_type(ctxt, loc, return_type, param_types, is_variadic) 288 | gcc_jit_context * ctxt 289 | gcc_jit_location * loc 290 | gcc_jit_type * return_type 291 | AV * param_types 292 | int is_variadic 293 | PREINIT: 294 | AVPP_PREINIT(param_types, gcc_jit_type *); 295 | CODE: 296 | AVPP_CODE(param_types, "gcc_jit_context_new_function_ptr_type", gcc_jit_type *, "gcc_jit_typePtr"); 297 | RETVAL = gcc_jit_context_new_function_ptr_type(ctxt, loc, return_type, num_param_types, ptr_param_types, is_variadic); 298 | OUTPUT: 299 | RETVAL 300 | CLEANUP: 301 | AVPP_CLEANUP(param_types); 302 | 303 | gcc_jit_lvalue * 304 | gcc_jit_context_new_global(ctxt, loc, kind, type, name) 305 | gcc_jit_context * ctxt 306 | gcc_jit_location * loc 307 | enum gcc_jit_global_kind kind 308 | gcc_jit_type * type 309 | const char * name 310 | 311 | gcc_jit_location * 312 | gcc_jit_context_new_location(ctxt, filename, line, column) 313 | gcc_jit_context * ctxt 314 | const char * filename 315 | int line 316 | int column 317 | 318 | gcc_jit_struct * 319 | gcc_jit_context_new_opaque_struct(ctxt, loc, name) 320 | gcc_jit_context * ctxt 321 | gcc_jit_location * loc 322 | const char * name 323 | 324 | gcc_jit_param * 325 | gcc_jit_context_new_param(ctxt, loc, type, name) 326 | gcc_jit_context * ctxt 327 | gcc_jit_location * loc 328 | gcc_jit_type * type 329 | const char * name 330 | 331 | gcc_jit_rvalue * 332 | gcc_jit_context_new_rvalue_from_double(ctxt, numeric_type, value) 333 | gcc_jit_context * ctxt 334 | gcc_jit_type * numeric_type 335 | double value 336 | 337 | gcc_jit_rvalue * 338 | gcc_jit_context_new_rvalue_from_int(ctxt, numeric_type, value) 339 | gcc_jit_context * ctxt 340 | gcc_jit_type * numeric_type 341 | int value 342 | 343 | gcc_jit_rvalue * 344 | gcc_jit_context_new_rvalue_from_long(ctxt, numeric_type, value) 345 | gcc_jit_context * ctxt 346 | gcc_jit_type * numeric_type 347 | long value 348 | 349 | gcc_jit_rvalue * 350 | gcc_jit_context_new_rvalue_from_ptr(ctxt, pointer_type, value) 351 | gcc_jit_context * ctxt 352 | gcc_jit_type * pointer_type 353 | void * value 354 | 355 | gcc_jit_rvalue * 356 | gcc_jit_context_new_string_literal(ctxt, value) 357 | gcc_jit_context * ctxt 358 | const char * value 359 | 360 | gcc_jit_struct * 361 | gcc_jit_context_new_struct_type(ctxt, loc, name, fields) 362 | gcc_jit_context * ctxt 363 | gcc_jit_location * loc 364 | const char * name 365 | AV * fields 366 | PREINIT: 367 | AVPP_PREINIT(fields, gcc_jit_field *); 368 | CODE: 369 | AVPP_CODE(fields, "gcc_jit_context_new_struct_type", gcc_jit_field *, "gcc_jit_fieldPtr"); 370 | RETVAL = gcc_jit_context_new_struct_type(ctxt, loc, name, num_fields, ptr_fields); 371 | OUTPUT: 372 | RETVAL 373 | CLEANUP: 374 | AVPP_CLEANUP(fields); 375 | 376 | gcc_jit_rvalue * 377 | gcc_jit_context_new_unary_op(ctxt, loc, op, result_type, rvalue) 378 | gcc_jit_context * ctxt 379 | gcc_jit_location * loc 380 | enum gcc_jit_unary_op op 381 | gcc_jit_type * result_type 382 | gcc_jit_rvalue * rvalue 383 | 384 | gcc_jit_type * 385 | gcc_jit_context_new_union_type(ctxt, loc, name, fields) 386 | gcc_jit_context * ctxt 387 | gcc_jit_location * loc 388 | const char * name 389 | AV * fields 390 | PREINIT: 391 | AVPP_PREINIT(fields, gcc_jit_field *); 392 | CODE: 393 | AVPP_CODE(fields, "gcc_jit_context_new_union_type", gcc_jit_field *, "gcc_jit_fieldPtr"); 394 | RETVAL = gcc_jit_context_new_union_type(ctxt, loc, name, num_fields, ptr_fields); 395 | OUTPUT: 396 | RETVAL 397 | CLEANUP: 398 | AVPP_CLEANUP(fields); 399 | 400 | gcc_jit_rvalue * 401 | gcc_jit_context_null(ctxt, pointer_type) 402 | gcc_jit_context * ctxt 403 | gcc_jit_type * pointer_type 404 | 405 | gcc_jit_rvalue * 406 | gcc_jit_context_one(ctxt, numeric_type) 407 | gcc_jit_context * ctxt 408 | gcc_jit_type * numeric_type 409 | 410 | void 411 | gcc_jit_context_release(ctxt) 412 | gcc_jit_context * ctxt 413 | 414 | #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks 415 | void 416 | gcc_jit_context_set_bool_allow_unreachable_blocks(ctxt, bool_value) 417 | gcc_jit_context * ctxt 418 | int bool_value 419 | 420 | #endif 421 | 422 | void 423 | gcc_jit_context_set_bool_option(ctxt, opt, value) 424 | gcc_jit_context * ctxt 425 | enum gcc_jit_bool_option opt 426 | int value 427 | 428 | void 429 | gcc_jit_context_set_int_option(ctxt, opt, value) 430 | gcc_jit_context * ctxt 431 | enum gcc_jit_int_option opt 432 | int value 433 | 434 | void 435 | gcc_jit_context_set_logfile(ctxt, logfile, flags, verbosity) 436 | gcc_jit_context * ctxt 437 | FILE * logfile 438 | int flags 439 | int verbosity 440 | 441 | void 442 | gcc_jit_context_set_str_option(ctxt, opt, value) 443 | gcc_jit_context * ctxt 444 | enum gcc_jit_str_option opt 445 | const char * value 446 | 447 | gcc_jit_rvalue * 448 | gcc_jit_context_zero(ctxt, numeric_type) 449 | gcc_jit_context * ctxt 450 | gcc_jit_type * numeric_type 451 | 452 | gcc_jit_object * 453 | gcc_jit_field_as_object(field) 454 | gcc_jit_field * field 455 | 456 | gcc_jit_object * 457 | gcc_jit_function_as_object(func) 458 | gcc_jit_function * func 459 | 460 | void 461 | gcc_jit_function_dump_to_dot(func, path) 462 | gcc_jit_function * func 463 | const char * path 464 | 465 | gcc_jit_param * 466 | gcc_jit_function_get_param(func, index) 467 | gcc_jit_function * func 468 | int index 469 | 470 | gcc_jit_block * 471 | gcc_jit_function_new_block(func, name) 472 | gcc_jit_function * func 473 | const char * name 474 | 475 | gcc_jit_lvalue * 476 | gcc_jit_function_new_local(func, loc, type, name) 477 | gcc_jit_function * func 478 | gcc_jit_location * loc 479 | gcc_jit_type * type 480 | const char * name 481 | 482 | gcc_jit_object * 483 | gcc_jit_location_as_object(loc) 484 | gcc_jit_location * loc 485 | 486 | gcc_jit_lvalue * 487 | gcc_jit_lvalue_access_field(struct_or_union, loc, field) 488 | gcc_jit_lvalue * struct_or_union 489 | gcc_jit_location * loc 490 | gcc_jit_field * field 491 | 492 | gcc_jit_object * 493 | gcc_jit_lvalue_as_object(lvalue) 494 | gcc_jit_lvalue * lvalue 495 | 496 | gcc_jit_rvalue * 497 | gcc_jit_lvalue_as_rvalue(lvalue) 498 | gcc_jit_lvalue * lvalue 499 | 500 | gcc_jit_rvalue * 501 | gcc_jit_lvalue_get_address(lvalue, loc) 502 | gcc_jit_lvalue * lvalue 503 | gcc_jit_location * loc 504 | 505 | gcc_jit_context * 506 | gcc_jit_object_get_context(obj) 507 | gcc_jit_object * obj 508 | 509 | const char * 510 | gcc_jit_object_get_debug_string(obj) 511 | gcc_jit_object * obj 512 | 513 | gcc_jit_lvalue * 514 | gcc_jit_param_as_lvalue(param) 515 | gcc_jit_param * param 516 | 517 | gcc_jit_object * 518 | gcc_jit_param_as_object(param) 519 | gcc_jit_param * param 520 | 521 | gcc_jit_rvalue * 522 | gcc_jit_param_as_rvalue(param) 523 | gcc_jit_param * param 524 | 525 | void * 526 | gcc_jit_result_get_code(result, funcname) 527 | gcc_jit_result * result 528 | const char * funcname 529 | 530 | void * 531 | gcc_jit_result_get_global(result, name) 532 | gcc_jit_result * result 533 | const char * name 534 | 535 | void 536 | gcc_jit_result_release(result) 537 | gcc_jit_result * result 538 | 539 | gcc_jit_rvalue * 540 | gcc_jit_rvalue_access_field(struct_or_union, loc, field) 541 | gcc_jit_rvalue * struct_or_union 542 | gcc_jit_location * loc 543 | gcc_jit_field * field 544 | 545 | gcc_jit_object * 546 | gcc_jit_rvalue_as_object(rvalue) 547 | gcc_jit_rvalue * rvalue 548 | 549 | gcc_jit_lvalue * 550 | gcc_jit_rvalue_dereference(rvalue, loc) 551 | gcc_jit_rvalue * rvalue 552 | gcc_jit_location * loc 553 | 554 | gcc_jit_lvalue * 555 | gcc_jit_rvalue_dereference_field(ptr, loc, field) 556 | gcc_jit_rvalue * ptr 557 | gcc_jit_location * loc 558 | gcc_jit_field * field 559 | 560 | gcc_jit_type * 561 | gcc_jit_rvalue_get_type(rvalue) 562 | gcc_jit_rvalue * rvalue 563 | 564 | gcc_jit_type * 565 | gcc_jit_struct_as_type(struct_type) 566 | gcc_jit_struct * struct_type 567 | 568 | void 569 | gcc_jit_struct_set_fields(struct_type, loc, fields) 570 | gcc_jit_struct * struct_type 571 | gcc_jit_location * loc 572 | AV * fields 573 | PREINIT: 574 | AVPP_PREINIT(fields, gcc_jit_field *); 575 | CODE: 576 | AVPP_CODE(fields, "gcc_jit_struct_set_fields", gcc_jit_field *, "gcc_jit_fieldPtr"); 577 | gcc_jit_struct_set_fields(struct_type, loc, num_fields, ptr_fields); 578 | CLEANUP: 579 | AVPP_CLEANUP(fields); 580 | 581 | gcc_jit_object * 582 | gcc_jit_type_as_object(type) 583 | gcc_jit_type * type 584 | 585 | gcc_jit_type * 586 | gcc_jit_type_get_const(type) 587 | gcc_jit_type * type 588 | 589 | gcc_jit_type * 590 | gcc_jit_type_get_pointer(type) 591 | gcc_jit_type * type 592 | 593 | gcc_jit_type * 594 | gcc_jit_type_get_volatile(type) 595 | gcc_jit_type * type 596 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | av_to_pp.h 2 | Changes 3 | fallback/const-c.inc 4 | fallback/const-xs.inc 5 | GCCJIT.xs 6 | lib/GCCJIT.pm 7 | lib/GCCJIT/Context.pm 8 | lib/GCCJIT/Wrapper.pm 9 | LICENSE 10 | Makefile.PL 11 | MANIFEST 12 | MANIFEST.SKIP 13 | ppport.h 14 | README 15 | t/01-constants.t 16 | t/02-simple.t 17 | t/03-gcd.t 18 | t/04-wrapper.t 19 | t/05-wrapper-gcd.t 20 | tools/make.sh 21 | tools/regen.pl 22 | tools/test.sh 23 | typemap 24 | Vagrantfile 25 | -------------------------------------------------------------------------------- /MANIFEST.SKIP: -------------------------------------------------------------------------------- 1 | ^GCCJIT\.(c|o|bs)$ 2 | ^\. 3 | ~$ 4 | \.old$ 5 | \.bak$ 6 | ^blib 7 | ^MYMETA 8 | ^Makefile$ 9 | ^const-(c|xs)\.inc$ 10 | pm_to_blib 11 | -------------------------------------------------------------------------------- /Makefile.PL: -------------------------------------------------------------------------------- 1 | use ExtUtils::MakeMaker; 2 | WriteMakefile( 3 | NAME => 'GCCJIT', 4 | VERSION_FROM => 'lib/GCCJIT.pm', 5 | ABSTRACT_FROM => 'lib/GCCJIT.pm', 6 | AUTHOR => 'Vickenty Fesunov ', 7 | LICENSE => 'gpl_3', 8 | LIBS => ['-lgccjit'], 9 | TEST_REQUIRES => { 10 | "FFI::Raw" => "0.30", 11 | "Test::Fatal" => 0, 12 | }, 13 | META_MERGE => { 14 | "meta-spec" => { version => 2 }, 15 | resources => { 16 | repository => { 17 | type => "git", 18 | url => "https://github.com/vickenty/gccjit-perl", 19 | web => "https://github.com/vickenty/gccjit-perl", 20 | }, 21 | bugtracker => { 22 | web => "https://github.com/vickenty/gccjit-perl/issues", 23 | }, 24 | }, 25 | }, 26 | ); 27 | if (eval {require ExtUtils::Constant; 1}) { 28 | # If you edit these definitions to change the constants used by this module, 29 | # you will need to use the generated const-c.inc and const-xs.inc 30 | # files to replace their "fallback" counterparts before distributing your 31 | # changes. 32 | my @names = (qw(), 33 | {name=>"GCC_JIT_BINARY_OP_BITWISE_AND", macro=>"1"}, 34 | {name=>"GCC_JIT_BINARY_OP_BITWISE_OR", macro=>"1"}, 35 | {name=>"GCC_JIT_BINARY_OP_BITWISE_XOR", macro=>"1"}, 36 | {name=>"GCC_JIT_BINARY_OP_DIVIDE", macro=>"1"}, 37 | {name=>"GCC_JIT_BINARY_OP_LOGICAL_AND", macro=>"1"}, 38 | {name=>"GCC_JIT_BINARY_OP_LOGICAL_OR", macro=>"1"}, 39 | {name=>"GCC_JIT_BINARY_OP_LSHIFT", macro=>"1"}, 40 | {name=>"GCC_JIT_BINARY_OP_MINUS", macro=>"1"}, 41 | {name=>"GCC_JIT_BINARY_OP_MODULO", macro=>"1"}, 42 | {name=>"GCC_JIT_BINARY_OP_MULT", macro=>"1"}, 43 | {name=>"GCC_JIT_BINARY_OP_PLUS", macro=>"1"}, 44 | {name=>"GCC_JIT_BINARY_OP_RSHIFT", macro=>"1"}, 45 | {name=>"GCC_JIT_BOOL_OPTION_DEBUGINFO", macro=>"1"}, 46 | {name=>"GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING", macro=>"1"}, 47 | {name=>"GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE", macro=>"1"}, 48 | {name=>"GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE", macro=>"1"}, 49 | {name=>"GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE", macro=>"1"}, 50 | {name=>"GCC_JIT_BOOL_OPTION_DUMP_SUMMARY", macro=>"1"}, 51 | {name=>"GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES", macro=>"1"}, 52 | {name=>"GCC_JIT_BOOL_OPTION_SELFCHECK_GC", macro=>"1"}, 53 | {name=>"GCC_JIT_COMPARISON_EQ", macro=>"1"}, 54 | {name=>"GCC_JIT_COMPARISON_GE", macro=>"1"}, 55 | {name=>"GCC_JIT_COMPARISON_GT", macro=>"1"}, 56 | {name=>"GCC_JIT_COMPARISON_LE", macro=>"1"}, 57 | {name=>"GCC_JIT_COMPARISON_LT", macro=>"1"}, 58 | {name=>"GCC_JIT_COMPARISON_NE", macro=>"1"}, 59 | {name=>"GCC_JIT_FUNCTION_ALWAYS_INLINE", macro=>"1"}, 60 | {name=>"GCC_JIT_FUNCTION_EXPORTED", macro=>"1"}, 61 | {name=>"GCC_JIT_FUNCTION_IMPORTED", macro=>"1"}, 62 | {name=>"GCC_JIT_FUNCTION_INTERNAL", macro=>"1"}, 63 | {name=>"GCC_JIT_GLOBAL_EXPORTED", macro=>"1"}, 64 | {name=>"GCC_JIT_GLOBAL_IMPORTED", macro=>"1"}, 65 | {name=>"GCC_JIT_GLOBAL_INTERNAL", macro=>"1"}, 66 | {name=>"GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL", macro=>"1"}, 67 | {name=>"GCC_JIT_NUM_BOOL_OPTIONS", macro=>"1"}, 68 | {name=>"GCC_JIT_NUM_INT_OPTIONS", macro=>"1"}, 69 | {name=>"GCC_JIT_NUM_STR_OPTIONS", macro=>"1"}, 70 | {name=>"GCC_JIT_OUTPUT_KIND_ASSEMBLER", macro=>"1"}, 71 | {name=>"GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY", macro=>"1"}, 72 | {name=>"GCC_JIT_OUTPUT_KIND_EXECUTABLE", macro=>"1"}, 73 | {name=>"GCC_JIT_OUTPUT_KIND_OBJECT_FILE", macro=>"1"}, 74 | {name=>"GCC_JIT_STR_OPTION_PROGNAME", macro=>"1"}, 75 | {name=>"GCC_JIT_TYPE_BOOL", macro=>"1"}, 76 | {name=>"GCC_JIT_TYPE_CHAR", macro=>"1"}, 77 | {name=>"GCC_JIT_TYPE_COMPLEX_DOUBLE", macro=>"1"}, 78 | {name=>"GCC_JIT_TYPE_COMPLEX_FLOAT", macro=>"1"}, 79 | {name=>"GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE", macro=>"1"}, 80 | {name=>"GCC_JIT_TYPE_CONST_CHAR_PTR", macro=>"1"}, 81 | {name=>"GCC_JIT_TYPE_DOUBLE", macro=>"1"}, 82 | {name=>"GCC_JIT_TYPE_FILE_PTR", macro=>"1"}, 83 | {name=>"GCC_JIT_TYPE_FLOAT", macro=>"1"}, 84 | {name=>"GCC_JIT_TYPE_INT", macro=>"1"}, 85 | {name=>"GCC_JIT_TYPE_LONG", macro=>"1"}, 86 | {name=>"GCC_JIT_TYPE_LONG_DOUBLE", macro=>"1"}, 87 | {name=>"GCC_JIT_TYPE_LONG_LONG", macro=>"1"}, 88 | {name=>"GCC_JIT_TYPE_SHORT", macro=>"1"}, 89 | {name=>"GCC_JIT_TYPE_SIGNED_CHAR", macro=>"1"}, 90 | {name=>"GCC_JIT_TYPE_SIZE_T", macro=>"1"}, 91 | {name=>"GCC_JIT_TYPE_UNSIGNED_CHAR", macro=>"1"}, 92 | {name=>"GCC_JIT_TYPE_UNSIGNED_INT", macro=>"1"}, 93 | {name=>"GCC_JIT_TYPE_UNSIGNED_LONG", macro=>"1"}, 94 | {name=>"GCC_JIT_TYPE_UNSIGNED_LONG_LONG", macro=>"1"}, 95 | {name=>"GCC_JIT_TYPE_UNSIGNED_SHORT", macro=>"1"}, 96 | {name=>"GCC_JIT_TYPE_VOID", macro=>"1"}, 97 | {name=>"GCC_JIT_TYPE_VOID_PTR", macro=>"1"}, 98 | {name=>"GCC_JIT_UNARY_OP_ABS", macro=>"1"}, 99 | {name=>"GCC_JIT_UNARY_OP_BITWISE_NEGATE", macro=>"1"}, 100 | {name=>"GCC_JIT_UNARY_OP_LOGICAL_NEGATE", macro=>"1"}, 101 | {name=>"GCC_JIT_UNARY_OP_MINUS", macro=>"1"}); 102 | ExtUtils::Constant::WriteConstants( 103 | NAME => 'GCCJIT', 104 | NAMES => \@names, 105 | DEFAULT_TYPE => 'IV', 106 | C_FILE => 'const-c.inc', 107 | XS_FILE => 'const-xs.inc', 108 | ); 109 | 110 | } 111 | else { 112 | use File::Copy; 113 | use File::Spec; 114 | foreach my $file ('const-c.inc', 'const-xs.inc') { 115 | my $fallback = File::Spec->catfile('fallback', $file); 116 | copy ($fallback, $file) or die "Can't copy $fallback to $file: $!"; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | GCCJIT version 0.02 2 | =================== 3 | 4 | Perl bindings for GCC JIT library (libgccjit). 5 | 6 | INSTALLATION 7 | 8 | To install this module type the following: 9 | 10 | perl Makefile.PL 11 | make 12 | make test 13 | make install 14 | 15 | DEPENDENCIES 16 | 17 | This module requires these other modules and libraries: 18 | 19 | GCC 5.1.0. 20 | Perl of decently recent version. 21 | 22 | COPYRIGHT AND LICENCE 23 | 24 | Copyright (C) 2015 by Vickenty Fesunov. 25 | 26 | The library is distributed under the terms of the GNU General Public License 27 | version 3 or later. See the LICENSE file for details. 28 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | RPM_PACKAGES="perl perl-devel cpan gcc make libgccjit-devel git" 2 | APT_PACKAGES="build-essential libperl-dev git libgccjit-5-dev" 3 | CPAN_PACKAGES="FFI::Raw Test::Fatal" 4 | 5 | TEMPLATES = { 6 | fedora: [ 7 | "dnf install -y #{RPM_PACKAGES}", 8 | "cpan install #{CPAN_PACKAGES}", 9 | ], 10 | 11 | debian: [ 12 | "echo deb http://ftp.debian.org/debian/ testing main contrib non-free > /etc/apt/sources.list.d/testing.list", 13 | "apt-get update", 14 | "apt-get -y install #{APT_PACKAGES}", 15 | "cpan install #{CPAN_PACKAGES}", 16 | ], 17 | } 18 | 19 | def prov(vm, kind, box) 20 | vm.vm.box = box 21 | vm.vm.box_check_update = false 22 | for script in TEMPLATES[kind] 23 | vm.vm.provision "shell", inline: script 24 | end 25 | end 26 | 27 | Vagrant.configure("2") do |config| 28 | config.vm.define "f22-64" do |vm| 29 | prov vm, :fedora, "boxcutter/fedora22" 30 | end 31 | config.vm.define "deb8-64" do |vm| 32 | prov vm, :debian, "boxcutter/debian80" 33 | end 34 | config.vm.define "deb8-32" do |vm| 35 | prov vm, :debian, "boxcutter/debian80-i386" 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /av_to_pp.h: -------------------------------------------------------------------------------- 1 | void **av_to_pp(pTHX_ AV* av, char *ctx, char *avname, char *typename) 2 | { 3 | void **ptr; 4 | SSize_t idx, size = av_len(av) + 1; 5 | if (size == 0) 6 | return NULL; 7 | 8 | ptr = malloc(size * sizeof(void*)); 9 | for (idx = 0; idx < size; idx++) { 10 | SV **val = av_fetch(av, idx, 0); 11 | if (!val) 12 | Perl_croak(aTHX_ "%s: %s[%d] is missing", ctx, avname, idx); 13 | if (SvROK(*val) && sv_derived_from(*val, typename)) { 14 | IV tmp = SvIV((SV*) SvRV(*val)); 15 | ptr[idx] = INT2PTR(void*, tmp); 16 | } else { 17 | Perl_croak(aTHX_ "%s: %s[%d] is not %s", ctx, avname, idx, typename); 18 | } 19 | } 20 | return ptr; 21 | } 22 | 23 | #define AVPP_PREINIT(av, type) \ 24 | type* ptr_##av; \ 25 | int num_##av; 26 | 27 | #define AVPP_CODE(av, ctx, type, typename) { \ 28 | num_##av = av_len(av) + 1; \ 29 | ptr_##av = (type*) av_to_pp(aTHX_ av, ctx, #av, typename); \ 30 | } 31 | 32 | #define AVPP_CLEANUP(av) \ 33 | if(ptr_##av) free(ptr_##av); 34 | -------------------------------------------------------------------------------- /fallback/const-c.inc: -------------------------------------------------------------------------------- 1 | #define PERL_constant_NOTFOUND 1 2 | #define PERL_constant_NOTDEF 2 3 | #define PERL_constant_ISIV 3 4 | #define PERL_constant_ISNO 4 5 | #define PERL_constant_ISNV 5 6 | #define PERL_constant_ISPV 6 7 | #define PERL_constant_ISPVN 7 8 | #define PERL_constant_ISSV 8 9 | #define PERL_constant_ISUNDEF 9 10 | #define PERL_constant_ISUV 10 11 | #define PERL_constant_ISYES 11 12 | 13 | #ifndef NVTYPE 14 | typedef double NV; /* 5.6 and later define NVTYPE, and typedef NV to it. */ 15 | #endif 16 | #ifndef aTHX_ 17 | #define aTHX_ /* 5.6 or later define this for threading support. */ 18 | #endif 19 | #ifndef pTHX_ 20 | #define pTHX_ /* 5.6 or later define this for threading support. */ 21 | #endif 22 | 23 | static int 24 | constant_17 (pTHX_ const char *name, IV *iv_return) { 25 | /* When generated this function returned values for the list of names given 26 | here. However, subsequent manual editing may have added or removed some. 27 | GCC_JIT_TYPE_BOOL GCC_JIT_TYPE_CHAR GCC_JIT_TYPE_LONG GCC_JIT_TYPE_VOID */ 28 | /* Offset 16 gives the best switch position. */ 29 | switch (name[16]) { 30 | case 'D': 31 | if (memEQ(name, "GCC_JIT_TYPE_VOI", 16)) { 32 | /* D */ 33 | *iv_return = GCC_JIT_TYPE_VOID; 34 | return PERL_constant_ISIV; 35 | } 36 | break; 37 | case 'G': 38 | if (memEQ(name, "GCC_JIT_TYPE_LON", 16)) { 39 | /* G */ 40 | *iv_return = GCC_JIT_TYPE_LONG; 41 | return PERL_constant_ISIV; 42 | } 43 | break; 44 | case 'L': 45 | if (memEQ(name, "GCC_JIT_TYPE_BOO", 16)) { 46 | /* L */ 47 | *iv_return = GCC_JIT_TYPE_BOOL; 48 | return PERL_constant_ISIV; 49 | } 50 | break; 51 | case 'R': 52 | if (memEQ(name, "GCC_JIT_TYPE_CHA", 16)) { 53 | /* R */ 54 | *iv_return = GCC_JIT_TYPE_CHAR; 55 | return PERL_constant_ISIV; 56 | } 57 | break; 58 | } 59 | return PERL_constant_NOTFOUND; 60 | } 61 | 62 | static int 63 | constant_21 (pTHX_ const char *name, IV *iv_return) { 64 | /* When generated this function returned values for the list of names given 65 | here. However, subsequent manual editing may have added or removed some. 66 | GCC_JIT_COMPARISON_EQ GCC_JIT_COMPARISON_GE GCC_JIT_COMPARISON_GT 67 | GCC_JIT_COMPARISON_LE GCC_JIT_COMPARISON_LT GCC_JIT_COMPARISON_NE 68 | GCC_JIT_TYPE_FILE_PTR GCC_JIT_TYPE_VOID_PTR */ 69 | /* Offset 19 gives the best switch position. */ 70 | switch (name[19]) { 71 | case 'E': 72 | if (memEQ(name, "GCC_JIT_COMPARISON_EQ", 21)) { 73 | /* ^ */ 74 | *iv_return = GCC_JIT_COMPARISON_EQ; 75 | return PERL_constant_ISIV; 76 | } 77 | break; 78 | case 'G': 79 | if (memEQ(name, "GCC_JIT_COMPARISON_GE", 21)) { 80 | /* ^ */ 81 | *iv_return = GCC_JIT_COMPARISON_GE; 82 | return PERL_constant_ISIV; 83 | } 84 | if (memEQ(name, "GCC_JIT_COMPARISON_GT", 21)) { 85 | /* ^ */ 86 | *iv_return = GCC_JIT_COMPARISON_GT; 87 | return PERL_constant_ISIV; 88 | } 89 | break; 90 | case 'L': 91 | if (memEQ(name, "GCC_JIT_COMPARISON_LE", 21)) { 92 | /* ^ */ 93 | *iv_return = GCC_JIT_COMPARISON_LE; 94 | return PERL_constant_ISIV; 95 | } 96 | if (memEQ(name, "GCC_JIT_COMPARISON_LT", 21)) { 97 | /* ^ */ 98 | *iv_return = GCC_JIT_COMPARISON_LT; 99 | return PERL_constant_ISIV; 100 | } 101 | break; 102 | case 'N': 103 | if (memEQ(name, "GCC_JIT_COMPARISON_NE", 21)) { 104 | /* ^ */ 105 | *iv_return = GCC_JIT_COMPARISON_NE; 106 | return PERL_constant_ISIV; 107 | } 108 | break; 109 | case 'T': 110 | if (memEQ(name, "GCC_JIT_TYPE_FILE_PTR", 21)) { 111 | /* ^ */ 112 | *iv_return = GCC_JIT_TYPE_FILE_PTR; 113 | return PERL_constant_ISIV; 114 | } 115 | if (memEQ(name, "GCC_JIT_TYPE_VOID_PTR", 21)) { 116 | /* ^ */ 117 | *iv_return = GCC_JIT_TYPE_VOID_PTR; 118 | return PERL_constant_ISIV; 119 | } 120 | break; 121 | } 122 | return PERL_constant_NOTFOUND; 123 | } 124 | 125 | static int 126 | constant_22 (pTHX_ const char *name, IV *iv_return) { 127 | /* When generated this function returned values for the list of names given 128 | here. However, subsequent manual editing may have added or removed some. 129 | GCC_JIT_BINARY_OP_MULT GCC_JIT_BINARY_OP_PLUS GCC_JIT_TYPE_LONG_LONG 130 | GCC_JIT_UNARY_OP_MINUS */ 131 | /* Offset 18 gives the best switch position. */ 132 | switch (name[18]) { 133 | case 'I': 134 | if (memEQ(name, "GCC_JIT_UNARY_OP_MINUS", 22)) { 135 | /* ^ */ 136 | *iv_return = GCC_JIT_UNARY_OP_MINUS; 137 | return PERL_constant_ISIV; 138 | } 139 | break; 140 | case 'L': 141 | if (memEQ(name, "GCC_JIT_TYPE_LONG_LONG", 22)) { 142 | /* ^ */ 143 | *iv_return = GCC_JIT_TYPE_LONG_LONG; 144 | return PERL_constant_ISIV; 145 | } 146 | break; 147 | case 'M': 148 | if (memEQ(name, "GCC_JIT_BINARY_OP_MULT", 22)) { 149 | /* ^ */ 150 | *iv_return = GCC_JIT_BINARY_OP_MULT; 151 | return PERL_constant_ISIV; 152 | } 153 | break; 154 | case 'P': 155 | if (memEQ(name, "GCC_JIT_BINARY_OP_PLUS", 22)) { 156 | /* ^ */ 157 | *iv_return = GCC_JIT_BINARY_OP_PLUS; 158 | return PERL_constant_ISIV; 159 | } 160 | break; 161 | } 162 | return PERL_constant_NOTFOUND; 163 | } 164 | 165 | static int 166 | constant_23 (pTHX_ const char *name, IV *iv_return) { 167 | /* When generated this function returned values for the list of names given 168 | here. However, subsequent manual editing may have added or removed some. 169 | GCC_JIT_BINARY_OP_MINUS GCC_JIT_GLOBAL_EXPORTED GCC_JIT_GLOBAL_IMPORTED 170 | GCC_JIT_GLOBAL_INTERNAL GCC_JIT_NUM_INT_OPTIONS GCC_JIT_NUM_STR_OPTIONS */ 171 | /* Offset 16 gives the best switch position. */ 172 | switch (name[16]) { 173 | case 'M': 174 | if (memEQ(name, "GCC_JIT_GLOBAL_IMPORTED", 23)) { 175 | /* ^ */ 176 | *iv_return = GCC_JIT_GLOBAL_IMPORTED; 177 | return PERL_constant_ISIV; 178 | } 179 | break; 180 | case 'N': 181 | if (memEQ(name, "GCC_JIT_GLOBAL_INTERNAL", 23)) { 182 | /* ^ */ 183 | *iv_return = GCC_JIT_GLOBAL_INTERNAL; 184 | return PERL_constant_ISIV; 185 | } 186 | break; 187 | case 'O': 188 | if (memEQ(name, "GCC_JIT_NUM_INT_OPTIONS", 23)) { 189 | /* ^ */ 190 | *iv_return = GCC_JIT_NUM_INT_OPTIONS; 191 | return PERL_constant_ISIV; 192 | } 193 | if (memEQ(name, "GCC_JIT_NUM_STR_OPTIONS", 23)) { 194 | /* ^ */ 195 | *iv_return = GCC_JIT_NUM_STR_OPTIONS; 196 | return PERL_constant_ISIV; 197 | } 198 | break; 199 | case 'P': 200 | if (memEQ(name, "GCC_JIT_BINARY_OP_MINUS", 23)) { 201 | /* ^ */ 202 | *iv_return = GCC_JIT_BINARY_OP_MINUS; 203 | return PERL_constant_ISIV; 204 | } 205 | break; 206 | case 'X': 207 | if (memEQ(name, "GCC_JIT_GLOBAL_EXPORTED", 23)) { 208 | /* ^ */ 209 | *iv_return = GCC_JIT_GLOBAL_EXPORTED; 210 | return PERL_constant_ISIV; 211 | } 212 | break; 213 | } 214 | return PERL_constant_NOTFOUND; 215 | } 216 | 217 | static int 218 | constant_24 (pTHX_ const char *name, IV *iv_return) { 219 | /* When generated this function returned values for the list of names given 220 | here. However, subsequent manual editing may have added or removed some. 221 | GCC_JIT_BINARY_OP_DIVIDE GCC_JIT_BINARY_OP_LSHIFT GCC_JIT_BINARY_OP_MODULO 222 | GCC_JIT_BINARY_OP_RSHIFT GCC_JIT_NUM_BOOL_OPTIONS GCC_JIT_TYPE_LONG_DOUBLE 223 | GCC_JIT_TYPE_SIGNED_CHAR */ 224 | /* Offset 20 gives the best switch position. */ 225 | switch (name[20]) { 226 | case 'C': 227 | if (memEQ(name, "GCC_JIT_TYPE_SIGNED_CHAR", 24)) { 228 | /* ^ */ 229 | *iv_return = GCC_JIT_TYPE_SIGNED_CHAR; 230 | return PERL_constant_ISIV; 231 | } 232 | break; 233 | case 'D': 234 | if (memEQ(name, "GCC_JIT_BINARY_OP_MODULO", 24)) { 235 | /* ^ */ 236 | *iv_return = GCC_JIT_BINARY_OP_MODULO; 237 | return PERL_constant_ISIV; 238 | } 239 | break; 240 | case 'H': 241 | if (memEQ(name, "GCC_JIT_BINARY_OP_LSHIFT", 24)) { 242 | /* ^ */ 243 | *iv_return = GCC_JIT_BINARY_OP_LSHIFT; 244 | return PERL_constant_ISIV; 245 | } 246 | if (memEQ(name, "GCC_JIT_BINARY_OP_RSHIFT", 24)) { 247 | /* ^ */ 248 | *iv_return = GCC_JIT_BINARY_OP_RSHIFT; 249 | return PERL_constant_ISIV; 250 | } 251 | break; 252 | case 'I': 253 | if (memEQ(name, "GCC_JIT_NUM_BOOL_OPTIONS", 24)) { 254 | /* ^ */ 255 | *iv_return = GCC_JIT_NUM_BOOL_OPTIONS; 256 | return PERL_constant_ISIV; 257 | } 258 | break; 259 | case 'U': 260 | if (memEQ(name, "GCC_JIT_TYPE_LONG_DOUBLE", 24)) { 261 | /* ^ */ 262 | *iv_return = GCC_JIT_TYPE_LONG_DOUBLE; 263 | return PERL_constant_ISIV; 264 | } 265 | break; 266 | case 'V': 267 | if (memEQ(name, "GCC_JIT_BINARY_OP_DIVIDE", 24)) { 268 | /* ^ */ 269 | *iv_return = GCC_JIT_BINARY_OP_DIVIDE; 270 | return PERL_constant_ISIV; 271 | } 272 | break; 273 | } 274 | return PERL_constant_NOTFOUND; 275 | } 276 | 277 | static int 278 | constant_25 (pTHX_ const char *name, IV *iv_return) { 279 | /* When generated this function returned values for the list of names given 280 | here. However, subsequent manual editing may have added or removed some. 281 | GCC_JIT_FUNCTION_EXPORTED GCC_JIT_FUNCTION_IMPORTED 282 | GCC_JIT_FUNCTION_INTERNAL GCC_JIT_TYPE_UNSIGNED_INT */ 283 | /* Offset 17 gives the best switch position. */ 284 | switch (name[17]) { 285 | case 'E': 286 | if (memEQ(name, "GCC_JIT_FUNCTION_EXPORTED", 25)) { 287 | /* ^ */ 288 | *iv_return = GCC_JIT_FUNCTION_EXPORTED; 289 | return PERL_constant_ISIV; 290 | } 291 | break; 292 | case 'G': 293 | if (memEQ(name, "GCC_JIT_TYPE_UNSIGNED_INT", 25)) { 294 | /* ^ */ 295 | *iv_return = GCC_JIT_TYPE_UNSIGNED_INT; 296 | return PERL_constant_ISIV; 297 | } 298 | break; 299 | case 'I': 300 | if (memEQ(name, "GCC_JIT_FUNCTION_IMPORTED", 25)) { 301 | /* ^ */ 302 | *iv_return = GCC_JIT_FUNCTION_IMPORTED; 303 | return PERL_constant_ISIV; 304 | } 305 | if (memEQ(name, "GCC_JIT_FUNCTION_INTERNAL", 25)) { 306 | /* ^ */ 307 | *iv_return = GCC_JIT_FUNCTION_INTERNAL; 308 | return PERL_constant_ISIV; 309 | } 310 | break; 311 | } 312 | return PERL_constant_NOTFOUND; 313 | } 314 | 315 | static int 316 | constant_26 (pTHX_ const char *name, IV *iv_return) { 317 | /* When generated this function returned values for the list of names given 318 | here. However, subsequent manual editing may have added or removed some. 319 | GCC_JIT_TYPE_COMPLEX_FLOAT GCC_JIT_TYPE_UNSIGNED_CHAR 320 | GCC_JIT_TYPE_UNSIGNED_LONG */ 321 | /* Offset 25 gives the best switch position. */ 322 | switch (name[25]) { 323 | case 'G': 324 | if (memEQ(name, "GCC_JIT_TYPE_UNSIGNED_LON", 25)) { 325 | /* G */ 326 | *iv_return = GCC_JIT_TYPE_UNSIGNED_LONG; 327 | return PERL_constant_ISIV; 328 | } 329 | break; 330 | case 'R': 331 | if (memEQ(name, "GCC_JIT_TYPE_UNSIGNED_CHA", 25)) { 332 | /* R */ 333 | *iv_return = GCC_JIT_TYPE_UNSIGNED_CHAR; 334 | return PERL_constant_ISIV; 335 | } 336 | break; 337 | case 'T': 338 | if (memEQ(name, "GCC_JIT_TYPE_COMPLEX_FLOA", 25)) { 339 | /* T */ 340 | *iv_return = GCC_JIT_TYPE_COMPLEX_FLOAT; 341 | return PERL_constant_ISIV; 342 | } 343 | break; 344 | } 345 | return PERL_constant_NOTFOUND; 346 | } 347 | 348 | static int 349 | constant_27 (pTHX_ const char *name, IV *iv_return) { 350 | /* When generated this function returned values for the list of names given 351 | here. However, subsequent manual editing may have added or removed some. 352 | GCC_JIT_STR_OPTION_PROGNAME GCC_JIT_TYPE_COMPLEX_DOUBLE 353 | GCC_JIT_TYPE_CONST_CHAR_PTR GCC_JIT_TYPE_UNSIGNED_SHORT */ 354 | /* Offset 25 gives the best switch position. */ 355 | switch (name[25]) { 356 | case 'L': 357 | if (memEQ(name, "GCC_JIT_TYPE_COMPLEX_DOUBLE", 27)) { 358 | /* ^ */ 359 | *iv_return = GCC_JIT_TYPE_COMPLEX_DOUBLE; 360 | return PERL_constant_ISIV; 361 | } 362 | break; 363 | case 'M': 364 | if (memEQ(name, "GCC_JIT_STR_OPTION_PROGNAME", 27)) { 365 | /* ^ */ 366 | *iv_return = GCC_JIT_STR_OPTION_PROGNAME; 367 | return PERL_constant_ISIV; 368 | } 369 | break; 370 | case 'R': 371 | if (memEQ(name, "GCC_JIT_TYPE_UNSIGNED_SHORT", 27)) { 372 | /* ^ */ 373 | *iv_return = GCC_JIT_TYPE_UNSIGNED_SHORT; 374 | return PERL_constant_ISIV; 375 | } 376 | break; 377 | case 'T': 378 | if (memEQ(name, "GCC_JIT_TYPE_CONST_CHAR_PTR", 27)) { 379 | /* ^ */ 380 | *iv_return = GCC_JIT_TYPE_CONST_CHAR_PTR; 381 | return PERL_constant_ISIV; 382 | } 383 | break; 384 | } 385 | return PERL_constant_NOTFOUND; 386 | } 387 | 388 | static int 389 | constant_29 (pTHX_ const char *name, IV *iv_return) { 390 | /* When generated this function returned values for the list of names given 391 | here. However, subsequent manual editing may have added or removed some. 392 | GCC_JIT_BINARY_OP_BITWISE_AND GCC_JIT_BINARY_OP_BITWISE_XOR 393 | GCC_JIT_BINARY_OP_LOGICAL_AND GCC_JIT_BOOL_OPTION_DEBUGINFO 394 | GCC_JIT_OUTPUT_KIND_ASSEMBLER */ 395 | /* Offset 24 gives the best switch position. */ 396 | switch (name[24]) { 397 | case 'E': 398 | if (memEQ(name, "GCC_JIT_BINARY_OP_BITWISE_AND", 29)) { 399 | /* ^ */ 400 | *iv_return = GCC_JIT_BINARY_OP_BITWISE_AND; 401 | return PERL_constant_ISIV; 402 | } 403 | if (memEQ(name, "GCC_JIT_BINARY_OP_BITWISE_XOR", 29)) { 404 | /* ^ */ 405 | *iv_return = GCC_JIT_BINARY_OP_BITWISE_XOR; 406 | return PERL_constant_ISIV; 407 | } 408 | break; 409 | case 'G': 410 | if (memEQ(name, "GCC_JIT_BOOL_OPTION_DEBUGINFO", 29)) { 411 | /* ^ */ 412 | *iv_return = GCC_JIT_BOOL_OPTION_DEBUGINFO; 413 | return PERL_constant_ISIV; 414 | } 415 | break; 416 | case 'L': 417 | if (memEQ(name, "GCC_JIT_BINARY_OP_LOGICAL_AND", 29)) { 418 | /* ^ */ 419 | *iv_return = GCC_JIT_BINARY_OP_LOGICAL_AND; 420 | return PERL_constant_ISIV; 421 | } 422 | break; 423 | case 'M': 424 | if (memEQ(name, "GCC_JIT_OUTPUT_KIND_ASSEMBLER", 29)) { 425 | /* ^ */ 426 | *iv_return = GCC_JIT_OUTPUT_KIND_ASSEMBLER; 427 | return PERL_constant_ISIV; 428 | } 429 | break; 430 | } 431 | return PERL_constant_NOTFOUND; 432 | } 433 | 434 | static int 435 | constant_31 (pTHX_ const char *name, IV *iv_return) { 436 | /* When generated this function returned values for the list of names given 437 | here. However, subsequent manual editing may have added or removed some. 438 | GCC_JIT_OUTPUT_KIND_OBJECT_FILE GCC_JIT_TYPE_UNSIGNED_LONG_LONG 439 | GCC_JIT_UNARY_OP_BITWISE_NEGATE GCC_JIT_UNARY_OP_LOGICAL_NEGATE */ 440 | /* Offset 18 gives the best switch position. */ 441 | switch (name[18]) { 442 | case 'D': 443 | if (memEQ(name, "GCC_JIT_OUTPUT_KIND_OBJECT_FILE", 31)) { 444 | /* ^ */ 445 | *iv_return = GCC_JIT_OUTPUT_KIND_OBJECT_FILE; 446 | return PERL_constant_ISIV; 447 | } 448 | break; 449 | case 'I': 450 | if (memEQ(name, "GCC_JIT_UNARY_OP_BITWISE_NEGATE", 31)) { 451 | /* ^ */ 452 | *iv_return = GCC_JIT_UNARY_OP_BITWISE_NEGATE; 453 | return PERL_constant_ISIV; 454 | } 455 | break; 456 | case 'N': 457 | if (memEQ(name, "GCC_JIT_TYPE_UNSIGNED_LONG_LONG", 31)) { 458 | /* ^ */ 459 | *iv_return = GCC_JIT_TYPE_UNSIGNED_LONG_LONG; 460 | return PERL_constant_ISIV; 461 | } 462 | break; 463 | case 'O': 464 | if (memEQ(name, "GCC_JIT_UNARY_OP_LOGICAL_NEGATE", 31)) { 465 | /* ^ */ 466 | *iv_return = GCC_JIT_UNARY_OP_LOGICAL_NEGATE; 467 | return PERL_constant_ISIV; 468 | } 469 | break; 470 | } 471 | return PERL_constant_NOTFOUND; 472 | } 473 | 474 | static int 475 | constant_32 (pTHX_ const char *name, IV *iv_return) { 476 | /* When generated this function returned values for the list of names given 477 | here. However, subsequent manual editing may have added or removed some. 478 | GCC_JIT_BOOL_OPTION_DUMP_SUMMARY GCC_JIT_BOOL_OPTION_SELFCHECK_GC 479 | GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */ 480 | /* Offset 22 gives the best switch position. */ 481 | switch (name[22]) { 482 | case 'L': 483 | if (memEQ(name, "GCC_JIT_BOOL_OPTION_SELFCHECK_GC", 32)) { 484 | /* ^ */ 485 | *iv_return = GCC_JIT_BOOL_OPTION_SELFCHECK_GC; 486 | return PERL_constant_ISIV; 487 | } 488 | break; 489 | case 'M': 490 | if (memEQ(name, "GCC_JIT_BOOL_OPTION_DUMP_SUMMARY", 32)) { 491 | /* ^ */ 492 | *iv_return = GCC_JIT_BOOL_OPTION_DUMP_SUMMARY; 493 | return PERL_constant_ISIV; 494 | } 495 | break; 496 | case 'O': 497 | if (memEQ(name, "GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE", 32)) { 498 | /* ^ */ 499 | *iv_return = GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE; 500 | return PERL_constant_ISIV; 501 | } 502 | break; 503 | } 504 | return PERL_constant_NOTFOUND; 505 | } 506 | 507 | static int 508 | constant (pTHX_ const char *name, STRLEN len, IV *iv_return) { 509 | /* Initially switch on the length of the name. */ 510 | /* When generated this function returned values for the list of names given 511 | in this section of perl code. Rather than manually editing these functions 512 | to add or remove constants, which would result in this comment and section 513 | of code becoming inaccurate, we recommend that you edit this section of 514 | code, and use it to regenerate a new set of constant functions which you 515 | then use to replace the originals. 516 | 517 | Regenerate these constant functions by feeding this entire source file to 518 | perl -x 519 | 520 | #!/usr/bin/perl -w 521 | use ExtUtils::Constant qw (constant_types C_constant XS_constant); 522 | 523 | my $types = {map {($_, 1)} qw(IV)}; 524 | my @names = (qw(), 525 | {name=>"GCC_JIT_BINARY_OP_BITWISE_AND", type=>"IV", macro=>"1"}, 526 | {name=>"GCC_JIT_BINARY_OP_BITWISE_OR", type=>"IV", macro=>"1"}, 527 | {name=>"GCC_JIT_BINARY_OP_BITWISE_XOR", type=>"IV", macro=>"1"}, 528 | {name=>"GCC_JIT_BINARY_OP_DIVIDE", type=>"IV", macro=>"1"}, 529 | {name=>"GCC_JIT_BINARY_OP_LOGICAL_AND", type=>"IV", macro=>"1"}, 530 | {name=>"GCC_JIT_BINARY_OP_LOGICAL_OR", type=>"IV", macro=>"1"}, 531 | {name=>"GCC_JIT_BINARY_OP_LSHIFT", type=>"IV", macro=>"1"}, 532 | {name=>"GCC_JIT_BINARY_OP_MINUS", type=>"IV", macro=>"1"}, 533 | {name=>"GCC_JIT_BINARY_OP_MODULO", type=>"IV", macro=>"1"}, 534 | {name=>"GCC_JIT_BINARY_OP_MULT", type=>"IV", macro=>"1"}, 535 | {name=>"GCC_JIT_BINARY_OP_PLUS", type=>"IV", macro=>"1"}, 536 | {name=>"GCC_JIT_BINARY_OP_RSHIFT", type=>"IV", macro=>"1"}, 537 | {name=>"GCC_JIT_BOOL_OPTION_DEBUGINFO", type=>"IV", macro=>"1"}, 538 | {name=>"GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING", type=>"IV", macro=>"1"}, 539 | {name=>"GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE", type=>"IV", macro=>"1"}, 540 | {name=>"GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE", type=>"IV", macro=>"1"}, 541 | {name=>"GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE", type=>"IV", macro=>"1"}, 542 | {name=>"GCC_JIT_BOOL_OPTION_DUMP_SUMMARY", type=>"IV", macro=>"1"}, 543 | {name=>"GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES", type=>"IV", macro=>"1"}, 544 | {name=>"GCC_JIT_BOOL_OPTION_SELFCHECK_GC", type=>"IV", macro=>"1"}, 545 | {name=>"GCC_JIT_COMPARISON_EQ", type=>"IV", macro=>"1"}, 546 | {name=>"GCC_JIT_COMPARISON_GE", type=>"IV", macro=>"1"}, 547 | {name=>"GCC_JIT_COMPARISON_GT", type=>"IV", macro=>"1"}, 548 | {name=>"GCC_JIT_COMPARISON_LE", type=>"IV", macro=>"1"}, 549 | {name=>"GCC_JIT_COMPARISON_LT", type=>"IV", macro=>"1"}, 550 | {name=>"GCC_JIT_COMPARISON_NE", type=>"IV", macro=>"1"}, 551 | {name=>"GCC_JIT_FUNCTION_ALWAYS_INLINE", type=>"IV", macro=>"1"}, 552 | {name=>"GCC_JIT_FUNCTION_EXPORTED", type=>"IV", macro=>"1"}, 553 | {name=>"GCC_JIT_FUNCTION_IMPORTED", type=>"IV", macro=>"1"}, 554 | {name=>"GCC_JIT_FUNCTION_INTERNAL", type=>"IV", macro=>"1"}, 555 | {name=>"GCC_JIT_GLOBAL_EXPORTED", type=>"IV", macro=>"1"}, 556 | {name=>"GCC_JIT_GLOBAL_IMPORTED", type=>"IV", macro=>"1"}, 557 | {name=>"GCC_JIT_GLOBAL_INTERNAL", type=>"IV", macro=>"1"}, 558 | {name=>"GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL", type=>"IV", macro=>"1"}, 559 | {name=>"GCC_JIT_NUM_BOOL_OPTIONS", type=>"IV", macro=>"1"}, 560 | {name=>"GCC_JIT_NUM_INT_OPTIONS", type=>"IV", macro=>"1"}, 561 | {name=>"GCC_JIT_NUM_STR_OPTIONS", type=>"IV", macro=>"1"}, 562 | {name=>"GCC_JIT_OUTPUT_KIND_ASSEMBLER", type=>"IV", macro=>"1"}, 563 | {name=>"GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY", type=>"IV", macro=>"1"}, 564 | {name=>"GCC_JIT_OUTPUT_KIND_EXECUTABLE", type=>"IV", macro=>"1"}, 565 | {name=>"GCC_JIT_OUTPUT_KIND_OBJECT_FILE", type=>"IV", macro=>"1"}, 566 | {name=>"GCC_JIT_STR_OPTION_PROGNAME", type=>"IV", macro=>"1"}, 567 | {name=>"GCC_JIT_TYPE_BOOL", type=>"IV", macro=>"1"}, 568 | {name=>"GCC_JIT_TYPE_CHAR", type=>"IV", macro=>"1"}, 569 | {name=>"GCC_JIT_TYPE_COMPLEX_DOUBLE", type=>"IV", macro=>"1"}, 570 | {name=>"GCC_JIT_TYPE_COMPLEX_FLOAT", type=>"IV", macro=>"1"}, 571 | {name=>"GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE", type=>"IV", macro=>"1"}, 572 | {name=>"GCC_JIT_TYPE_CONST_CHAR_PTR", type=>"IV", macro=>"1"}, 573 | {name=>"GCC_JIT_TYPE_DOUBLE", type=>"IV", macro=>"1"}, 574 | {name=>"GCC_JIT_TYPE_FILE_PTR", type=>"IV", macro=>"1"}, 575 | {name=>"GCC_JIT_TYPE_FLOAT", type=>"IV", macro=>"1"}, 576 | {name=>"GCC_JIT_TYPE_INT", type=>"IV", macro=>"1"}, 577 | {name=>"GCC_JIT_TYPE_LONG", type=>"IV", macro=>"1"}, 578 | {name=>"GCC_JIT_TYPE_LONG_DOUBLE", type=>"IV", macro=>"1"}, 579 | {name=>"GCC_JIT_TYPE_LONG_LONG", type=>"IV", macro=>"1"}, 580 | {name=>"GCC_JIT_TYPE_SHORT", type=>"IV", macro=>"1"}, 581 | {name=>"GCC_JIT_TYPE_SIGNED_CHAR", type=>"IV", macro=>"1"}, 582 | {name=>"GCC_JIT_TYPE_SIZE_T", type=>"IV", macro=>"1"}, 583 | {name=>"GCC_JIT_TYPE_UNSIGNED_CHAR", type=>"IV", macro=>"1"}, 584 | {name=>"GCC_JIT_TYPE_UNSIGNED_INT", type=>"IV", macro=>"1"}, 585 | {name=>"GCC_JIT_TYPE_UNSIGNED_LONG", type=>"IV", macro=>"1"}, 586 | {name=>"GCC_JIT_TYPE_UNSIGNED_LONG_LONG", type=>"IV", macro=>"1"}, 587 | {name=>"GCC_JIT_TYPE_UNSIGNED_SHORT", type=>"IV", macro=>"1"}, 588 | {name=>"GCC_JIT_TYPE_VOID", type=>"IV", macro=>"1"}, 589 | {name=>"GCC_JIT_TYPE_VOID_PTR", type=>"IV", macro=>"1"}, 590 | {name=>"GCC_JIT_UNARY_OP_ABS", type=>"IV", macro=>"1"}, 591 | {name=>"GCC_JIT_UNARY_OP_BITWISE_NEGATE", type=>"IV", macro=>"1"}, 592 | {name=>"GCC_JIT_UNARY_OP_LOGICAL_NEGATE", type=>"IV", macro=>"1"}, 593 | {name=>"GCC_JIT_UNARY_OP_MINUS", type=>"IV", macro=>"1"}); 594 | 595 | print constant_types(), "\n"; # macro defs 596 | foreach (C_constant ("GCCJIT", 'constant', 'IV', $types, undef, 3, @names) ) { 597 | print $_, "\n"; # C constant subs 598 | } 599 | print "\n#### XS Section:\n"; 600 | print XS_constant ("GCCJIT", $types); 601 | __END__ 602 | */ 603 | 604 | switch (len) { 605 | case 16: 606 | if (memEQ(name, "GCC_JIT_TYPE_INT", 16)) { 607 | *iv_return = GCC_JIT_TYPE_INT; 608 | return PERL_constant_ISIV; 609 | } 610 | break; 611 | case 17: 612 | return constant_17 (aTHX_ name, iv_return); 613 | break; 614 | case 18: 615 | /* Names all of length 18. */ 616 | /* GCC_JIT_TYPE_FLOAT GCC_JIT_TYPE_SHORT */ 617 | /* Offset 14 gives the best switch position. */ 618 | switch (name[14]) { 619 | case 'H': 620 | if (memEQ(name, "GCC_JIT_TYPE_SHORT", 18)) { 621 | /* ^ */ 622 | *iv_return = GCC_JIT_TYPE_SHORT; 623 | return PERL_constant_ISIV; 624 | } 625 | break; 626 | case 'L': 627 | if (memEQ(name, "GCC_JIT_TYPE_FLOAT", 18)) { 628 | /* ^ */ 629 | *iv_return = GCC_JIT_TYPE_FLOAT; 630 | return PERL_constant_ISIV; 631 | } 632 | break; 633 | } 634 | break; 635 | case 19: 636 | /* Names all of length 19. */ 637 | /* GCC_JIT_TYPE_DOUBLE GCC_JIT_TYPE_SIZE_T */ 638 | /* Offset 16 gives the best switch position. */ 639 | switch (name[16]) { 640 | case 'B': 641 | if (memEQ(name, "GCC_JIT_TYPE_DOUBLE", 19)) { 642 | /* ^ */ 643 | *iv_return = GCC_JIT_TYPE_DOUBLE; 644 | return PERL_constant_ISIV; 645 | } 646 | break; 647 | case 'E': 648 | if (memEQ(name, "GCC_JIT_TYPE_SIZE_T", 19)) { 649 | /* ^ */ 650 | *iv_return = GCC_JIT_TYPE_SIZE_T; 651 | return PERL_constant_ISIV; 652 | } 653 | break; 654 | } 655 | break; 656 | case 20: 657 | if (memEQ(name, "GCC_JIT_UNARY_OP_ABS", 20)) { 658 | *iv_return = GCC_JIT_UNARY_OP_ABS; 659 | return PERL_constant_ISIV; 660 | } 661 | break; 662 | case 21: 663 | return constant_21 (aTHX_ name, iv_return); 664 | break; 665 | case 22: 666 | return constant_22 (aTHX_ name, iv_return); 667 | break; 668 | case 23: 669 | return constant_23 (aTHX_ name, iv_return); 670 | break; 671 | case 24: 672 | return constant_24 (aTHX_ name, iv_return); 673 | break; 674 | case 25: 675 | return constant_25 (aTHX_ name, iv_return); 676 | break; 677 | case 26: 678 | return constant_26 (aTHX_ name, iv_return); 679 | break; 680 | case 27: 681 | return constant_27 (aTHX_ name, iv_return); 682 | break; 683 | case 28: 684 | /* Names all of length 28. */ 685 | /* GCC_JIT_BINARY_OP_BITWISE_OR GCC_JIT_BINARY_OP_LOGICAL_OR */ 686 | /* Offset 19 gives the best switch position. */ 687 | switch (name[19]) { 688 | case 'I': 689 | if (memEQ(name, "GCC_JIT_BINARY_OP_BITWISE_OR", 28)) { 690 | /* ^ */ 691 | *iv_return = GCC_JIT_BINARY_OP_BITWISE_OR; 692 | return PERL_constant_ISIV; 693 | } 694 | break; 695 | case 'O': 696 | if (memEQ(name, "GCC_JIT_BINARY_OP_LOGICAL_OR", 28)) { 697 | /* ^ */ 698 | *iv_return = GCC_JIT_BINARY_OP_LOGICAL_OR; 699 | return PERL_constant_ISIV; 700 | } 701 | break; 702 | } 703 | break; 704 | case 29: 705 | return constant_29 (aTHX_ name, iv_return); 706 | break; 707 | case 30: 708 | /* Names all of length 30. */ 709 | /* GCC_JIT_FUNCTION_ALWAYS_INLINE GCC_JIT_OUTPUT_KIND_EXECUTABLE */ 710 | /* Offset 12 gives the best switch position. */ 711 | switch (name[12]) { 712 | case 'T': 713 | if (memEQ(name, "GCC_JIT_FUNCTION_ALWAYS_INLINE", 30)) { 714 | /* ^ */ 715 | *iv_return = GCC_JIT_FUNCTION_ALWAYS_INLINE; 716 | return PERL_constant_ISIV; 717 | } 718 | break; 719 | case 'U': 720 | if (memEQ(name, "GCC_JIT_OUTPUT_KIND_EXECUTABLE", 30)) { 721 | /* ^ */ 722 | *iv_return = GCC_JIT_OUTPUT_KIND_EXECUTABLE; 723 | return PERL_constant_ISIV; 724 | } 725 | break; 726 | } 727 | break; 728 | case 31: 729 | return constant_31 (aTHX_ name, iv_return); 730 | break; 731 | case 32: 732 | return constant_32 (aTHX_ name, iv_return); 733 | break; 734 | case 35: 735 | /* Names all of length 35. */ 736 | /* GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY 737 | */ 738 | /* Offset 17 gives the best switch position. */ 739 | switch (name[17]) { 740 | case 'N': 741 | if (memEQ(name, "GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY", 35)) { 742 | /* ^ */ 743 | *iv_return = GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY; 744 | return PERL_constant_ISIV; 745 | } 746 | break; 747 | case 'O': 748 | if (memEQ(name, "GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING", 35)) { 749 | /* ^ */ 750 | *iv_return = GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING; 751 | return PERL_constant_ISIV; 752 | } 753 | break; 754 | } 755 | break; 756 | case 37: 757 | /* Names all of length 37. */ 758 | /* GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE 759 | GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL */ 760 | /* Offset 9 gives the best switch position. */ 761 | switch (name[9]) { 762 | case 'N': 763 | if (memEQ(name, "GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL", 37)) { 764 | /* ^ */ 765 | *iv_return = GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL; 766 | return PERL_constant_ISIV; 767 | } 768 | break; 769 | case 'O': 770 | if (memEQ(name, "GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE", 37)) { 771 | /* ^ */ 772 | *iv_return = GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE; 773 | return PERL_constant_ISIV; 774 | } 775 | break; 776 | } 777 | break; 778 | case 38: 779 | if (memEQ(name, "GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES", 38)) { 780 | *iv_return = GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES; 781 | return PERL_constant_ISIV; 782 | } 783 | break; 784 | case 39: 785 | /* Names all of length 39. */ 786 | /* GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE 787 | GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE */ 788 | /* Offset 36 gives the best switch position. */ 789 | switch (name[36]) { 790 | case 'O': 791 | if (memEQ(name, "GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE", 39)) { 792 | /* ^ */ 793 | *iv_return = GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE; 794 | return PERL_constant_ISIV; 795 | } 796 | break; 797 | case 'P': 798 | if (memEQ(name, "GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE", 39)) { 799 | /* ^ */ 800 | *iv_return = GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE; 801 | return PERL_constant_ISIV; 802 | } 803 | break; 804 | } 805 | break; 806 | } 807 | return PERL_constant_NOTFOUND; 808 | } 809 | 810 | -------------------------------------------------------------------------------- /fallback/const-xs.inc: -------------------------------------------------------------------------------- 1 | void 2 | constant(sv) 3 | PREINIT: 4 | #ifdef dXSTARG 5 | dXSTARG; /* Faster if we have it. */ 6 | #else 7 | dTARGET; 8 | #endif 9 | STRLEN len; 10 | int type; 11 | IV iv; 12 | /* NV nv; Uncomment this if you need to return NVs */ 13 | /* const char *pv; Uncomment this if you need to return PVs */ 14 | INPUT: 15 | SV * sv; 16 | const char * s = SvPV(sv, len); 17 | PPCODE: 18 | /* Change this to constant(aTHX_ s, len, &iv, &nv); 19 | if you need to return both NVs and IVs */ 20 | type = constant(aTHX_ s, len, &iv); 21 | /* Return 1 or 2 items. First is error message, or undef if no error. 22 | Second, if present, is found value */ 23 | switch (type) { 24 | case PERL_constant_NOTFOUND: 25 | sv = 26 | sv_2mortal(newSVpvf("%s is not a valid GCCJIT macro", s)); 27 | PUSHs(sv); 28 | break; 29 | case PERL_constant_NOTDEF: 30 | sv = sv_2mortal(newSVpvf( 31 | "Your vendor has not defined GCCJIT macro %s, used", 32 | s)); 33 | PUSHs(sv); 34 | break; 35 | case PERL_constant_ISIV: 36 | EXTEND(SP, 1); 37 | PUSHs(&PL_sv_undef); 38 | PUSHi(iv); 39 | break; 40 | /* Uncomment this if you need to return NOs 41 | case PERL_constant_ISNO: 42 | EXTEND(SP, 1); 43 | PUSHs(&PL_sv_undef); 44 | PUSHs(&PL_sv_no); 45 | break; */ 46 | /* Uncomment this if you need to return NVs 47 | case PERL_constant_ISNV: 48 | EXTEND(SP, 1); 49 | PUSHs(&PL_sv_undef); 50 | PUSHn(nv); 51 | break; */ 52 | /* Uncomment this if you need to return PVs 53 | case PERL_constant_ISPV: 54 | EXTEND(SP, 1); 55 | PUSHs(&PL_sv_undef); 56 | PUSHp(pv, strlen(pv)); 57 | break; */ 58 | /* Uncomment this if you need to return PVNs 59 | case PERL_constant_ISPVN: 60 | EXTEND(SP, 1); 61 | PUSHs(&PL_sv_undef); 62 | PUSHp(pv, iv); 63 | break; */ 64 | /* Uncomment this if you need to return SVs 65 | case PERL_constant_ISSV: 66 | EXTEND(SP, 1); 67 | PUSHs(&PL_sv_undef); 68 | PUSHs(sv); 69 | break; */ 70 | /* Uncomment this if you need to return UNDEFs 71 | case PERL_constant_ISUNDEF: 72 | break; */ 73 | /* Uncomment this if you need to return UVs 74 | case PERL_constant_ISUV: 75 | EXTEND(SP, 1); 76 | PUSHs(&PL_sv_undef); 77 | PUSHu((UV)iv); 78 | break; */ 79 | /* Uncomment this if you need to return YESs 80 | case PERL_constant_ISYES: 81 | EXTEND(SP, 1); 82 | PUSHs(&PL_sv_undef); 83 | PUSHs(&PL_sv_yes); 84 | break; */ 85 | default: 86 | sv = sv_2mortal(newSVpvf( 87 | "Unexpected return type %d while processing GCCJIT macro %s, used", 88 | type, s)); 89 | PUSHs(sv); 90 | } 91 | -------------------------------------------------------------------------------- /lib/GCCJIT.pm: -------------------------------------------------------------------------------- 1 | package GCCJIT; 2 | 3 | use strict; 4 | use warnings; 5 | use Carp; 6 | 7 | require Exporter; 8 | use AutoLoader; 9 | 10 | our @ISA = qw(Exporter); 11 | 12 | our %EXPORT_TAGS; 13 | $EXPORT_TAGS{constants} = [ qw( 14 | GCC_JIT_BINARY_OP_BITWISE_AND 15 | GCC_JIT_BINARY_OP_BITWISE_OR 16 | GCC_JIT_BINARY_OP_BITWISE_XOR 17 | GCC_JIT_BINARY_OP_DIVIDE 18 | GCC_JIT_BINARY_OP_LOGICAL_AND 19 | GCC_JIT_BINARY_OP_LOGICAL_OR 20 | GCC_JIT_BINARY_OP_LSHIFT 21 | GCC_JIT_BINARY_OP_MINUS 22 | GCC_JIT_BINARY_OP_MODULO 23 | GCC_JIT_BINARY_OP_MULT 24 | GCC_JIT_BINARY_OP_PLUS 25 | GCC_JIT_BINARY_OP_RSHIFT 26 | GCC_JIT_BOOL_OPTION_DEBUGINFO 27 | GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING 28 | GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE 29 | GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE 30 | GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE 31 | GCC_JIT_BOOL_OPTION_DUMP_SUMMARY 32 | GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES 33 | GCC_JIT_BOOL_OPTION_SELFCHECK_GC 34 | GCC_JIT_COMPARISON_EQ 35 | GCC_JIT_COMPARISON_GE 36 | GCC_JIT_COMPARISON_GT 37 | GCC_JIT_COMPARISON_LE 38 | GCC_JIT_COMPARISON_LT 39 | GCC_JIT_COMPARISON_NE 40 | GCC_JIT_FUNCTION_ALWAYS_INLINE 41 | GCC_JIT_FUNCTION_EXPORTED 42 | GCC_JIT_FUNCTION_IMPORTED 43 | GCC_JIT_FUNCTION_INTERNAL 44 | GCC_JIT_GLOBAL_EXPORTED 45 | GCC_JIT_GLOBAL_IMPORTED 46 | GCC_JIT_GLOBAL_INTERNAL 47 | GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL 48 | GCC_JIT_NUM_BOOL_OPTIONS 49 | GCC_JIT_NUM_INT_OPTIONS 50 | GCC_JIT_NUM_STR_OPTIONS 51 | GCC_JIT_OUTPUT_KIND_ASSEMBLER 52 | GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY 53 | GCC_JIT_OUTPUT_KIND_EXECUTABLE 54 | GCC_JIT_OUTPUT_KIND_OBJECT_FILE 55 | GCC_JIT_STR_OPTION_PROGNAME 56 | GCC_JIT_TYPE_BOOL 57 | GCC_JIT_TYPE_CHAR 58 | GCC_JIT_TYPE_COMPLEX_DOUBLE 59 | GCC_JIT_TYPE_COMPLEX_FLOAT 60 | GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE 61 | GCC_JIT_TYPE_CONST_CHAR_PTR 62 | GCC_JIT_TYPE_DOUBLE 63 | GCC_JIT_TYPE_FILE_PTR 64 | GCC_JIT_TYPE_FLOAT 65 | GCC_JIT_TYPE_INT 66 | GCC_JIT_TYPE_LONG 67 | GCC_JIT_TYPE_LONG_DOUBLE 68 | GCC_JIT_TYPE_LONG_LONG 69 | GCC_JIT_TYPE_SHORT 70 | GCC_JIT_TYPE_SIGNED_CHAR 71 | GCC_JIT_TYPE_SIZE_T 72 | GCC_JIT_TYPE_UNSIGNED_CHAR 73 | GCC_JIT_TYPE_UNSIGNED_INT 74 | GCC_JIT_TYPE_UNSIGNED_LONG 75 | GCC_JIT_TYPE_UNSIGNED_LONG_LONG 76 | GCC_JIT_TYPE_UNSIGNED_SHORT 77 | GCC_JIT_TYPE_VOID 78 | GCC_JIT_TYPE_VOID_PTR 79 | GCC_JIT_UNARY_OP_ABS 80 | GCC_JIT_UNARY_OP_BITWISE_NEGATE 81 | GCC_JIT_UNARY_OP_LOGICAL_NEGATE 82 | GCC_JIT_UNARY_OP_MINUS 83 | )]; 84 | 85 | $EXPORT_TAGS{raw_api} = [ qw( 86 | gcc_jit_block_add_assignment 87 | gcc_jit_block_add_assignment_op 88 | gcc_jit_block_add_comment 89 | gcc_jit_block_add_eval 90 | gcc_jit_block_as_object 91 | gcc_jit_block_end_with_conditional 92 | gcc_jit_block_end_with_jump 93 | gcc_jit_block_end_with_return 94 | gcc_jit_block_end_with_switch 95 | gcc_jit_block_end_with_void_return 96 | gcc_jit_block_get_function 97 | gcc_jit_case_as_object 98 | gcc_jit_context_acquire 99 | gcc_jit_context_add_command_line_option 100 | gcc_jit_context_compile 101 | gcc_jit_context_compile_to_file 102 | gcc_jit_context_dump_reproducer_to_file 103 | gcc_jit_context_dump_to_file 104 | gcc_jit_context_enable_dump 105 | gcc_jit_context_get_builtin_function 106 | gcc_jit_context_get_first_error 107 | gcc_jit_context_get_int_type 108 | gcc_jit_context_get_last_error 109 | gcc_jit_context_get_type 110 | gcc_jit_context_new_array_access 111 | gcc_jit_context_new_array_type 112 | gcc_jit_context_new_binary_op 113 | gcc_jit_context_new_call 114 | gcc_jit_context_new_call_through_ptr 115 | gcc_jit_context_new_case 116 | gcc_jit_context_new_cast 117 | gcc_jit_context_new_child_context 118 | gcc_jit_context_new_comparison 119 | gcc_jit_context_new_field 120 | gcc_jit_context_new_function 121 | gcc_jit_context_new_function_ptr_type 122 | gcc_jit_context_new_global 123 | gcc_jit_context_new_location 124 | gcc_jit_context_new_opaque_struct 125 | gcc_jit_context_new_param 126 | gcc_jit_context_new_rvalue_from_double 127 | gcc_jit_context_new_rvalue_from_int 128 | gcc_jit_context_new_rvalue_from_long 129 | gcc_jit_context_new_rvalue_from_ptr 130 | gcc_jit_context_new_string_literal 131 | gcc_jit_context_new_struct_type 132 | gcc_jit_context_new_unary_op 133 | gcc_jit_context_new_union_type 134 | gcc_jit_context_null 135 | gcc_jit_context_one 136 | gcc_jit_context_release 137 | gcc_jit_context_set_bool_allow_unreachable_blocks 138 | gcc_jit_context_set_bool_option 139 | gcc_jit_context_set_int_option 140 | gcc_jit_context_set_logfile 141 | gcc_jit_context_set_str_option 142 | gcc_jit_context_zero 143 | gcc_jit_field_as_object 144 | gcc_jit_function_as_object 145 | gcc_jit_function_dump_to_dot 146 | gcc_jit_function_get_param 147 | gcc_jit_function_new_block 148 | gcc_jit_function_new_local 149 | gcc_jit_location_as_object 150 | gcc_jit_lvalue_access_field 151 | gcc_jit_lvalue_as_object 152 | gcc_jit_lvalue_as_rvalue 153 | gcc_jit_lvalue_get_address 154 | gcc_jit_object_get_context 155 | gcc_jit_object_get_debug_string 156 | gcc_jit_param_as_lvalue 157 | gcc_jit_param_as_object 158 | gcc_jit_param_as_rvalue 159 | gcc_jit_result_get_code 160 | gcc_jit_result_get_global 161 | gcc_jit_result_release 162 | gcc_jit_rvalue_access_field 163 | gcc_jit_rvalue_as_object 164 | gcc_jit_rvalue_dereference 165 | gcc_jit_rvalue_dereference_field 166 | gcc_jit_rvalue_get_type 167 | gcc_jit_struct_as_type 168 | gcc_jit_struct_set_fields 169 | gcc_jit_type_as_object 170 | gcc_jit_type_get_const 171 | gcc_jit_type_get_pointer 172 | gcc_jit_type_get_volatile 173 | )]; 174 | 175 | $EXPORT_TAGS{all} = [ 176 | @{$EXPORT_TAGS{constants}}, 177 | @{$EXPORT_TAGS{raw_api}}, 178 | ]; 179 | 180 | our @EXPORT_OK = @{$EXPORT_TAGS{'all'}}; 181 | 182 | our $VERSION = '0.03'; 183 | 184 | sub AUTOLOAD { 185 | my $constname; 186 | our $AUTOLOAD; 187 | ($constname = $AUTOLOAD) =~ s/.*:://; 188 | croak "&GCCJIT::constant not defined" if $constname eq 'constant'; 189 | my ($error, $val) = constant($constname); 190 | if ($error) { croak $error; } 191 | { 192 | no strict 'refs'; 193 | *$AUTOLOAD = sub { $val }; 194 | } 195 | goto &$AUTOLOAD; 196 | } 197 | 198 | require XSLoader; 199 | XSLoader::load('GCCJIT', $VERSION); 200 | 201 | 1; 202 | __END__ 203 | 204 | =head1 NAME 205 | 206 | GCCJIT - Perl bindings for GCCJIT library 207 | 208 | =head1 SYNOPSIS 209 | 210 | use GCCJIT qw/:constants/; 211 | use GCCJIT::Context; 212 | 213 | my $ctxt = GCCJIT::Context->acquire(); 214 | my $int_type = $ctxt->get_type(GCC_JIT_TYPE_INT); 215 | 216 | my $param_i = $ctxt->new_param(undef, $int_type, "i"); 217 | my $func = $ctxt->new_function(undef, GCC_JIT_FUNCTION_EXPORTED, 218 | $int_type, "square", [ $param_i ], 0); 219 | 220 | my $block = $func->new_block("my new block"); 221 | 222 | my $expr = $ctxt->new_binary_op(undef, GCC_JIT_BINARY_OP_MULT, 223 | $int_type, $param_i->as_rvalue(), $param_i->as_rvalue()); 224 | 225 | $block->end_with_return(undef, $expr); 226 | 227 | my $result = $ctxt->compile(); 228 | my $raw_ptr = $result->get_code("square"); 229 | 230 | use FFI::Raw; 231 | my $ffi = FFI::Raw->new_from_ptr($raw_ptr, FFI::Raw::int, FFI::Raw::int); 232 | say $ffi->(4); 233 | 234 | =head1 DESCRIPTION 235 | 236 | This package provides bindings for libgccjit, an embeddable compiler backend 237 | based on GCC. There are two packages in this distribution: 238 | 239 | C, this package, provides direct bindings to the C API of libgccjit. 240 | 241 | L provides a more succinct, object-oriented view of the same API. 242 | 243 | Where gccjit functions expects an array and its length as two arguments, GCCJIT 244 | variant takes a single array reference instead. 245 | 246 | =head1 EXPORTS 247 | 248 | This package does not export anything by default. Exportable are all gccjit 249 | constants and functions, and following tags: 250 | 251 | =over 252 | 253 | =item :constants 254 | 255 | Exports all libgccjit constants. 256 | 257 | =item :raw_api 258 | 259 | Exports raw libgccjit functions (use L wrappers instead). 260 | 261 | =item :all 262 | 263 | Exports everything. 264 | 265 | =back 266 | 267 | =head1 SEE ALSO 268 | 269 | Online documentation for GCCJIT library: L 270 | 271 | GCCJIT project wiki page: L 272 | 273 | =head1 AUTHOR 274 | 275 | Vickenty Fesunov Ecpan-gccjit@setattr.netE 276 | 277 | =head1 COPYRIGHT AND LICENSE 278 | 279 | Copyright (C) 2015 by Vickenty Fesunov. 280 | 281 | This program is free software: you can redistribute it and/or modify it under 282 | the terms of the GNU General Public License as published by the Free Software 283 | Foundation, either version 3 of the License, or (at your option) any later 284 | version. 285 | 286 | This program is distributed in the hope that it will be useful, but WITHOUT ANY 287 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 288 | PARTICULAR PURPOSE. See the GNU General Public License for more details. 289 | 290 | You should have received a copy of the GNU General Public License along with 291 | this program. If not, see . 292 | 293 | =cut 294 | -------------------------------------------------------------------------------- /lib/GCCJIT/Context.pm: -------------------------------------------------------------------------------- 1 | package GCCJIT::Context; 2 | use strict; 3 | use warnings; 4 | 5 | require GCCJIT::Wrapper; 6 | 7 | sub acquire { 8 | gcc_jit_contextPtr::acquire(); 9 | } 10 | 11 | =head1 NAME 12 | 13 | GCCJIT::Context - object-oriented wrapper around libgccjit bindings. 14 | 15 | =head1 SYNOPSYS 16 | 17 | use GCCJIT qw/:constants/; 18 | use GCCJIT::Context; 19 | 20 | my $ctxt = GCCJIT::Context->acquire(); 21 | $ctxt->get_type(GCC_JIT_TYPE_INT); 22 | 23 | =head1 DESCRIPTION 24 | 25 | This package provides an object-oriented wrapper around libgccjit. In addition 26 | to shorter method names, these wrappers handle the memory management tasks 27 | remained from libgccjit (which already is very simple). 28 | 29 | =head2 Shorter names 30 | 31 | All libgccjit functions are available as methods on corresponding object 32 | references. 33 | 34 | gcc_jit_context_get_type($ctxt, ...) 35 | 36 | becomes: 37 | 38 | $ctxt->get_type(...) 39 | 40 | =head2 Memory management 41 | 42 | In libgccjit context objects own all allocated memory: developer needs only to 43 | release context to free all allocated memory, and until then all pointers 44 | produced by the library are valid. 45 | 46 | When using this wrapper context and result objects will be freed automatically 47 | when last reference to it is gone as usual. 48 | 49 | Other objects, like types, functions and blocks will become invalid once context 50 | owning them is destroyed. If any methods are called on a invalidated object, 51 | a perl exception is thrown. 52 | 53 | =head1 METHODS 54 | 55 | This package contain only one method: 56 | 57 | GCCJIT::Context->acquire() 58 | 59 | creates new top-level libgccjit context. 60 | 61 | =head1 SEE ALSO 62 | 63 | Online documentation for GCCJIT library: L 64 | 65 | GCCJIT project wiki page: L 66 | 67 | =head1 AUTHOR 68 | 69 | Vickenty Fesunov Ecpan-gccjit@setattr.netE 70 | 71 | =head1 COPYRIGHT AND LICENSE 72 | 73 | Copyright (C) 2015 by Vickenty Fesunov. 74 | 75 | This program is free software: you can redistribute it and/or modify it under 76 | the terms of the GNU General Public License as published by the Free Software 77 | Foundation, either version 3 of the License, or (at your option) any later 78 | version. 79 | 80 | This program is distributed in the hope that it will be useful, but WITHOUT ANY 81 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 82 | PARTICULAR PURPOSE. See the GNU General Public License for more details. 83 | 84 | You should have received a copy of the GNU General Public License along with 85 | this program. If not, see . 86 | 87 | =cut 88 | 1; 89 | -------------------------------------------------------------------------------- /lib/GCCJIT/Wrapper.pm: -------------------------------------------------------------------------------- 1 | # DO NOT EDIT - this file is autogenerated by tools/regen.pl 2 | package GCCJIT::Wrapper; 3 | use strict; 4 | use warnings; 5 | use Scalar::Util qw/weaken/; 6 | use GCCJIT; 7 | 8 | my %stash; 9 | sub gcc_jit_blockPtr::add_assignment { 10 | die "this block is no longer usable because parent context was destroyed" 11 | unless defined $stash{"gcc_jit_blockPtr"}{$_[0]}; 12 | GCCJIT::gcc_jit_block_add_assignment(@_); 13 | } 14 | 15 | sub gcc_jit_blockPtr::add_assignment_op { 16 | die "this block is no longer usable because parent context was destroyed" 17 | unless defined $stash{"gcc_jit_blockPtr"}{$_[0]}; 18 | GCCJIT::gcc_jit_block_add_assignment_op(@_); 19 | } 20 | 21 | sub gcc_jit_blockPtr::add_comment { 22 | die "this block is no longer usable because parent context was destroyed" 23 | unless defined $stash{"gcc_jit_blockPtr"}{$_[0]}; 24 | GCCJIT::gcc_jit_block_add_comment(@_); 25 | } 26 | 27 | sub gcc_jit_blockPtr::add_eval { 28 | die "this block is no longer usable because parent context was destroyed" 29 | unless defined $stash{"gcc_jit_blockPtr"}{$_[0]}; 30 | GCCJIT::gcc_jit_block_add_eval(@_); 31 | } 32 | 33 | sub gcc_jit_blockPtr::as_object { 34 | die "this block is no longer usable because parent context was destroyed" 35 | unless defined $stash{"gcc_jit_blockPtr"}{$_[0]}; 36 | my $obj = GCCJIT::gcc_jit_block_as_object(@_); 37 | if (defined $obj) { 38 | $stash{"gcc_jit_objectPtr"}{$obj} = $stash{"gcc_jit_blockPtr"}{$_[0]}; 39 | weaken $stash{"gcc_jit_objectPtr"}{$obj}; 40 | } 41 | $obj; 42 | } 43 | 44 | sub gcc_jit_blockPtr::end_with_conditional { 45 | die "this block is no longer usable because parent context was destroyed" 46 | unless defined $stash{"gcc_jit_blockPtr"}{$_[0]}; 47 | GCCJIT::gcc_jit_block_end_with_conditional(@_); 48 | } 49 | 50 | sub gcc_jit_blockPtr::end_with_jump { 51 | die "this block is no longer usable because parent context was destroyed" 52 | unless defined $stash{"gcc_jit_blockPtr"}{$_[0]}; 53 | GCCJIT::gcc_jit_block_end_with_jump(@_); 54 | } 55 | 56 | sub gcc_jit_blockPtr::end_with_return { 57 | die "this block is no longer usable because parent context was destroyed" 58 | unless defined $stash{"gcc_jit_blockPtr"}{$_[0]}; 59 | GCCJIT::gcc_jit_block_end_with_return(@_); 60 | } 61 | 62 | sub gcc_jit_blockPtr::end_with_switch { 63 | die "this block is no longer usable because parent context was destroyed" 64 | unless defined $stash{"gcc_jit_blockPtr"}{$_[0]}; 65 | GCCJIT::gcc_jit_block_end_with_switch(@_); 66 | } 67 | 68 | sub gcc_jit_blockPtr::end_with_void_return { 69 | die "this block is no longer usable because parent context was destroyed" 70 | unless defined $stash{"gcc_jit_blockPtr"}{$_[0]}; 71 | GCCJIT::gcc_jit_block_end_with_void_return(@_); 72 | } 73 | 74 | sub gcc_jit_blockPtr::get_function { 75 | die "this block is no longer usable because parent context was destroyed" 76 | unless defined $stash{"gcc_jit_blockPtr"}{$_[0]}; 77 | my $obj = GCCJIT::gcc_jit_block_get_function(@_); 78 | if (defined $obj) { 79 | $stash{"gcc_jit_functionPtr"}{$obj} = $stash{"gcc_jit_blockPtr"}{$_[0]}; 80 | weaken $stash{"gcc_jit_functionPtr"}{$obj}; 81 | } 82 | $obj; 83 | } 84 | 85 | sub gcc_jit_casePtr::as_object { 86 | die "this case is no longer usable because parent context was destroyed" 87 | unless defined $stash{"gcc_jit_casePtr"}{$_[0]}; 88 | my $obj = GCCJIT::gcc_jit_case_as_object(@_); 89 | if (defined $obj) { 90 | $stash{"gcc_jit_objectPtr"}{$obj} = $stash{"gcc_jit_casePtr"}{$_[0]}; 91 | weaken $stash{"gcc_jit_objectPtr"}{$obj}; 92 | } 93 | $obj; 94 | } 95 | 96 | sub gcc_jit_contextPtr::acquire { 97 | my $obj = GCCJIT::gcc_jit_context_acquire(@_); 98 | if (defined $obj) { 99 | $stash{"gcc_jit_contextPtr"}{$obj} = $_[0]; 100 | } 101 | $obj; 102 | } 103 | 104 | *gcc_jit_contextPtr::add_command_line_option = \&GCCJIT::gcc_jit_context_add_command_line_option; 105 | 106 | *gcc_jit_contextPtr::compile = \&GCCJIT::gcc_jit_context_compile; 107 | 108 | *gcc_jit_contextPtr::compile_to_file = \&GCCJIT::gcc_jit_context_compile_to_file; 109 | 110 | *gcc_jit_contextPtr::dump_reproducer_to_file = \&GCCJIT::gcc_jit_context_dump_reproducer_to_file; 111 | 112 | *gcc_jit_contextPtr::dump_to_file = \&GCCJIT::gcc_jit_context_dump_to_file; 113 | 114 | sub gcc_jit_contextPtr::get_builtin_function { 115 | my $obj = GCCJIT::gcc_jit_context_get_builtin_function(@_); 116 | if (defined $obj) { 117 | $stash{"gcc_jit_functionPtr"}{$obj} = $_[0]; 118 | weaken $stash{"gcc_jit_functionPtr"}{$obj}; 119 | } 120 | $obj; 121 | } 122 | 123 | *gcc_jit_contextPtr::get_first_error = \&GCCJIT::gcc_jit_context_get_first_error; 124 | 125 | sub gcc_jit_contextPtr::get_int_type { 126 | my $obj = GCCJIT::gcc_jit_context_get_int_type(@_); 127 | if (defined $obj) { 128 | $stash{"gcc_jit_typePtr"}{$obj} = $_[0]; 129 | weaken $stash{"gcc_jit_typePtr"}{$obj}; 130 | } 131 | $obj; 132 | } 133 | 134 | *gcc_jit_contextPtr::get_last_error = \&GCCJIT::gcc_jit_context_get_last_error; 135 | 136 | sub gcc_jit_contextPtr::get_type { 137 | my $obj = GCCJIT::gcc_jit_context_get_type(@_); 138 | if (defined $obj) { 139 | $stash{"gcc_jit_typePtr"}{$obj} = $_[0]; 140 | weaken $stash{"gcc_jit_typePtr"}{$obj}; 141 | } 142 | $obj; 143 | } 144 | 145 | sub gcc_jit_contextPtr::new_array_access { 146 | my $obj = GCCJIT::gcc_jit_context_new_array_access(@_); 147 | if (defined $obj) { 148 | $stash{"gcc_jit_lvaluePtr"}{$obj} = $_[0]; 149 | weaken $stash{"gcc_jit_lvaluePtr"}{$obj}; 150 | } 151 | $obj; 152 | } 153 | 154 | sub gcc_jit_contextPtr::new_array_type { 155 | my $obj = GCCJIT::gcc_jit_context_new_array_type(@_); 156 | if (defined $obj) { 157 | $stash{"gcc_jit_typePtr"}{$obj} = $_[0]; 158 | weaken $stash{"gcc_jit_typePtr"}{$obj}; 159 | } 160 | $obj; 161 | } 162 | 163 | sub gcc_jit_contextPtr::new_binary_op { 164 | my $obj = GCCJIT::gcc_jit_context_new_binary_op(@_); 165 | if (defined $obj) { 166 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 167 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 168 | } 169 | $obj; 170 | } 171 | 172 | sub gcc_jit_contextPtr::new_call { 173 | my $obj = GCCJIT::gcc_jit_context_new_call(@_); 174 | if (defined $obj) { 175 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 176 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 177 | } 178 | $obj; 179 | } 180 | 181 | sub gcc_jit_contextPtr::new_call_through_ptr { 182 | my $obj = GCCJIT::gcc_jit_context_new_call_through_ptr(@_); 183 | if (defined $obj) { 184 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 185 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 186 | } 187 | $obj; 188 | } 189 | 190 | sub gcc_jit_contextPtr::new_case { 191 | my $obj = GCCJIT::gcc_jit_context_new_case(@_); 192 | if (defined $obj) { 193 | $stash{"gcc_jit_casePtr"}{$obj} = $_[0]; 194 | weaken $stash{"gcc_jit_casePtr"}{$obj}; 195 | } 196 | $obj; 197 | } 198 | 199 | sub gcc_jit_contextPtr::new_cast { 200 | my $obj = GCCJIT::gcc_jit_context_new_cast(@_); 201 | if (defined $obj) { 202 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 203 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 204 | } 205 | $obj; 206 | } 207 | 208 | sub gcc_jit_contextPtr::new_child_context { 209 | my $obj = GCCJIT::gcc_jit_context_new_child_context(@_); 210 | if (defined $obj) { 211 | $stash{"gcc_jit_contextPtr"}{$obj} = $_[0]; 212 | } 213 | $obj; 214 | } 215 | 216 | sub gcc_jit_contextPtr::new_comparison { 217 | my $obj = GCCJIT::gcc_jit_context_new_comparison(@_); 218 | if (defined $obj) { 219 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 220 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 221 | } 222 | $obj; 223 | } 224 | 225 | sub gcc_jit_contextPtr::new_field { 226 | my $obj = GCCJIT::gcc_jit_context_new_field(@_); 227 | if (defined $obj) { 228 | $stash{"gcc_jit_fieldPtr"}{$obj} = $_[0]; 229 | weaken $stash{"gcc_jit_fieldPtr"}{$obj}; 230 | } 231 | $obj; 232 | } 233 | 234 | sub gcc_jit_contextPtr::new_function { 235 | my $obj = GCCJIT::gcc_jit_context_new_function(@_); 236 | if (defined $obj) { 237 | $stash{"gcc_jit_functionPtr"}{$obj} = $_[0]; 238 | weaken $stash{"gcc_jit_functionPtr"}{$obj}; 239 | } 240 | $obj; 241 | } 242 | 243 | sub gcc_jit_contextPtr::new_function_ptr_type { 244 | my $obj = GCCJIT::gcc_jit_context_new_function_ptr_type(@_); 245 | if (defined $obj) { 246 | $stash{"gcc_jit_typePtr"}{$obj} = $_[0]; 247 | weaken $stash{"gcc_jit_typePtr"}{$obj}; 248 | } 249 | $obj; 250 | } 251 | 252 | sub gcc_jit_contextPtr::new_global { 253 | my $obj = GCCJIT::gcc_jit_context_new_global(@_); 254 | if (defined $obj) { 255 | $stash{"gcc_jit_lvaluePtr"}{$obj} = $_[0]; 256 | weaken $stash{"gcc_jit_lvaluePtr"}{$obj}; 257 | } 258 | $obj; 259 | } 260 | 261 | sub gcc_jit_contextPtr::new_location { 262 | my $obj = GCCJIT::gcc_jit_context_new_location(@_); 263 | if (defined $obj) { 264 | $stash{"gcc_jit_locationPtr"}{$obj} = $_[0]; 265 | weaken $stash{"gcc_jit_locationPtr"}{$obj}; 266 | } 267 | $obj; 268 | } 269 | 270 | sub gcc_jit_contextPtr::new_opaque_struct { 271 | my $obj = GCCJIT::gcc_jit_context_new_opaque_struct(@_); 272 | if (defined $obj) { 273 | $stash{"gcc_jit_structPtr"}{$obj} = $_[0]; 274 | weaken $stash{"gcc_jit_structPtr"}{$obj}; 275 | } 276 | $obj; 277 | } 278 | 279 | sub gcc_jit_contextPtr::new_param { 280 | my $obj = GCCJIT::gcc_jit_context_new_param(@_); 281 | if (defined $obj) { 282 | $stash{"gcc_jit_paramPtr"}{$obj} = $_[0]; 283 | weaken $stash{"gcc_jit_paramPtr"}{$obj}; 284 | } 285 | $obj; 286 | } 287 | 288 | sub gcc_jit_contextPtr::new_rvalue_from_double { 289 | my $obj = GCCJIT::gcc_jit_context_new_rvalue_from_double(@_); 290 | if (defined $obj) { 291 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 292 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 293 | } 294 | $obj; 295 | } 296 | 297 | sub gcc_jit_contextPtr::new_rvalue_from_int { 298 | my $obj = GCCJIT::gcc_jit_context_new_rvalue_from_int(@_); 299 | if (defined $obj) { 300 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 301 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 302 | } 303 | $obj; 304 | } 305 | 306 | sub gcc_jit_contextPtr::new_rvalue_from_long { 307 | my $obj = GCCJIT::gcc_jit_context_new_rvalue_from_long(@_); 308 | if (defined $obj) { 309 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 310 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 311 | } 312 | $obj; 313 | } 314 | 315 | sub gcc_jit_contextPtr::new_rvalue_from_ptr { 316 | my $obj = GCCJIT::gcc_jit_context_new_rvalue_from_ptr(@_); 317 | if (defined $obj) { 318 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 319 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 320 | } 321 | $obj; 322 | } 323 | 324 | sub gcc_jit_contextPtr::new_string_literal { 325 | my $obj = GCCJIT::gcc_jit_context_new_string_literal(@_); 326 | if (defined $obj) { 327 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 328 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 329 | } 330 | $obj; 331 | } 332 | 333 | sub gcc_jit_contextPtr::new_struct_type { 334 | my $obj = GCCJIT::gcc_jit_context_new_struct_type(@_); 335 | if (defined $obj) { 336 | $stash{"gcc_jit_structPtr"}{$obj} = $_[0]; 337 | weaken $stash{"gcc_jit_structPtr"}{$obj}; 338 | } 339 | $obj; 340 | } 341 | 342 | sub gcc_jit_contextPtr::new_unary_op { 343 | my $obj = GCCJIT::gcc_jit_context_new_unary_op(@_); 344 | if (defined $obj) { 345 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 346 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 347 | } 348 | $obj; 349 | } 350 | 351 | sub gcc_jit_contextPtr::new_union_type { 352 | my $obj = GCCJIT::gcc_jit_context_new_union_type(@_); 353 | if (defined $obj) { 354 | $stash{"gcc_jit_typePtr"}{$obj} = $_[0]; 355 | weaken $stash{"gcc_jit_typePtr"}{$obj}; 356 | } 357 | $obj; 358 | } 359 | 360 | sub gcc_jit_contextPtr::null { 361 | my $obj = GCCJIT::gcc_jit_context_null(@_); 362 | if (defined $obj) { 363 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 364 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 365 | } 366 | $obj; 367 | } 368 | 369 | sub gcc_jit_contextPtr::one { 370 | my $obj = GCCJIT::gcc_jit_context_one(@_); 371 | if (defined $obj) { 372 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 373 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 374 | } 375 | $obj; 376 | } 377 | 378 | *gcc_jit_contextPtr::set_bool_allow_unreachable_blocks = \&GCCJIT::gcc_jit_context_set_bool_allow_unreachable_blocks; 379 | 380 | *gcc_jit_contextPtr::set_bool_option = \&GCCJIT::gcc_jit_context_set_bool_option; 381 | 382 | *gcc_jit_contextPtr::set_int_option = \&GCCJIT::gcc_jit_context_set_int_option; 383 | 384 | *gcc_jit_contextPtr::set_logfile = \&GCCJIT::gcc_jit_context_set_logfile; 385 | 386 | *gcc_jit_contextPtr::set_str_option = \&GCCJIT::gcc_jit_context_set_str_option; 387 | 388 | sub gcc_jit_contextPtr::zero { 389 | my $obj = GCCJIT::gcc_jit_context_zero(@_); 390 | if (defined $obj) { 391 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $_[0]; 392 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 393 | } 394 | $obj; 395 | } 396 | 397 | sub gcc_jit_fieldPtr::as_object { 398 | die "this field is no longer usable because parent context was destroyed" 399 | unless defined $stash{"gcc_jit_fieldPtr"}{$_[0]}; 400 | my $obj = GCCJIT::gcc_jit_field_as_object(@_); 401 | if (defined $obj) { 402 | $stash{"gcc_jit_objectPtr"}{$obj} = $stash{"gcc_jit_fieldPtr"}{$_[0]}; 403 | weaken $stash{"gcc_jit_objectPtr"}{$obj}; 404 | } 405 | $obj; 406 | } 407 | 408 | sub gcc_jit_functionPtr::as_object { 409 | die "this function is no longer usable because parent context was destroyed" 410 | unless defined $stash{"gcc_jit_functionPtr"}{$_[0]}; 411 | my $obj = GCCJIT::gcc_jit_function_as_object(@_); 412 | if (defined $obj) { 413 | $stash{"gcc_jit_objectPtr"}{$obj} = $stash{"gcc_jit_functionPtr"}{$_[0]}; 414 | weaken $stash{"gcc_jit_objectPtr"}{$obj}; 415 | } 416 | $obj; 417 | } 418 | 419 | sub gcc_jit_functionPtr::dump_to_dot { 420 | die "this function is no longer usable because parent context was destroyed" 421 | unless defined $stash{"gcc_jit_functionPtr"}{$_[0]}; 422 | GCCJIT::gcc_jit_function_dump_to_dot(@_); 423 | } 424 | 425 | sub gcc_jit_functionPtr::get_param { 426 | die "this function is no longer usable because parent context was destroyed" 427 | unless defined $stash{"gcc_jit_functionPtr"}{$_[0]}; 428 | my $obj = GCCJIT::gcc_jit_function_get_param(@_); 429 | if (defined $obj) { 430 | $stash{"gcc_jit_paramPtr"}{$obj} = $stash{"gcc_jit_functionPtr"}{$_[0]}; 431 | weaken $stash{"gcc_jit_paramPtr"}{$obj}; 432 | } 433 | $obj; 434 | } 435 | 436 | sub gcc_jit_functionPtr::new_block { 437 | die "this function is no longer usable because parent context was destroyed" 438 | unless defined $stash{"gcc_jit_functionPtr"}{$_[0]}; 439 | my $obj = GCCJIT::gcc_jit_function_new_block(@_); 440 | if (defined $obj) { 441 | $stash{"gcc_jit_blockPtr"}{$obj} = $stash{"gcc_jit_functionPtr"}{$_[0]}; 442 | weaken $stash{"gcc_jit_blockPtr"}{$obj}; 443 | } 444 | $obj; 445 | } 446 | 447 | sub gcc_jit_functionPtr::new_local { 448 | die "this function is no longer usable because parent context was destroyed" 449 | unless defined $stash{"gcc_jit_functionPtr"}{$_[0]}; 450 | my $obj = GCCJIT::gcc_jit_function_new_local(@_); 451 | if (defined $obj) { 452 | $stash{"gcc_jit_lvaluePtr"}{$obj} = $stash{"gcc_jit_functionPtr"}{$_[0]}; 453 | weaken $stash{"gcc_jit_lvaluePtr"}{$obj}; 454 | } 455 | $obj; 456 | } 457 | 458 | sub gcc_jit_locationPtr::as_object { 459 | die "this location is no longer usable because parent context was destroyed" 460 | unless defined $stash{"gcc_jit_locationPtr"}{$_[0]}; 461 | my $obj = GCCJIT::gcc_jit_location_as_object(@_); 462 | if (defined $obj) { 463 | $stash{"gcc_jit_objectPtr"}{$obj} = $stash{"gcc_jit_locationPtr"}{$_[0]}; 464 | weaken $stash{"gcc_jit_objectPtr"}{$obj}; 465 | } 466 | $obj; 467 | } 468 | 469 | sub gcc_jit_lvaluePtr::access_field { 470 | die "this lvalue is no longer usable because parent context was destroyed" 471 | unless defined $stash{"gcc_jit_lvaluePtr"}{$_[0]}; 472 | my $obj = GCCJIT::gcc_jit_lvalue_access_field(@_); 473 | if (defined $obj) { 474 | $stash{"gcc_jit_lvaluePtr"}{$obj} = $stash{"gcc_jit_lvaluePtr"}{$_[0]}; 475 | weaken $stash{"gcc_jit_lvaluePtr"}{$obj}; 476 | } 477 | $obj; 478 | } 479 | 480 | sub gcc_jit_lvaluePtr::as_object { 481 | die "this lvalue is no longer usable because parent context was destroyed" 482 | unless defined $stash{"gcc_jit_lvaluePtr"}{$_[0]}; 483 | my $obj = GCCJIT::gcc_jit_lvalue_as_object(@_); 484 | if (defined $obj) { 485 | $stash{"gcc_jit_objectPtr"}{$obj} = $stash{"gcc_jit_lvaluePtr"}{$_[0]}; 486 | weaken $stash{"gcc_jit_objectPtr"}{$obj}; 487 | } 488 | $obj; 489 | } 490 | 491 | sub gcc_jit_lvaluePtr::as_rvalue { 492 | die "this lvalue is no longer usable because parent context was destroyed" 493 | unless defined $stash{"gcc_jit_lvaluePtr"}{$_[0]}; 494 | my $obj = GCCJIT::gcc_jit_lvalue_as_rvalue(@_); 495 | if (defined $obj) { 496 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $stash{"gcc_jit_lvaluePtr"}{$_[0]}; 497 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 498 | } 499 | $obj; 500 | } 501 | 502 | sub gcc_jit_lvaluePtr::get_address { 503 | die "this lvalue is no longer usable because parent context was destroyed" 504 | unless defined $stash{"gcc_jit_lvaluePtr"}{$_[0]}; 505 | my $obj = GCCJIT::gcc_jit_lvalue_get_address(@_); 506 | if (defined $obj) { 507 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $stash{"gcc_jit_lvaluePtr"}{$_[0]}; 508 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 509 | } 510 | $obj; 511 | } 512 | 513 | sub gcc_jit_objectPtr::get_context { 514 | $stash{"gcc_jit_objectPtr"}{$_[0]} 515 | } 516 | 517 | sub gcc_jit_objectPtr::get_debug_string { 518 | die "this object is no longer usable because parent context was destroyed" 519 | unless defined $stash{"gcc_jit_objectPtr"}{$_[0]}; 520 | GCCJIT::gcc_jit_object_get_debug_string(@_); 521 | } 522 | 523 | sub gcc_jit_paramPtr::as_lvalue { 524 | die "this param is no longer usable because parent context was destroyed" 525 | unless defined $stash{"gcc_jit_paramPtr"}{$_[0]}; 526 | my $obj = GCCJIT::gcc_jit_param_as_lvalue(@_); 527 | if (defined $obj) { 528 | $stash{"gcc_jit_lvaluePtr"}{$obj} = $stash{"gcc_jit_paramPtr"}{$_[0]}; 529 | weaken $stash{"gcc_jit_lvaluePtr"}{$obj}; 530 | } 531 | $obj; 532 | } 533 | 534 | sub gcc_jit_paramPtr::as_object { 535 | die "this param is no longer usable because parent context was destroyed" 536 | unless defined $stash{"gcc_jit_paramPtr"}{$_[0]}; 537 | my $obj = GCCJIT::gcc_jit_param_as_object(@_); 538 | if (defined $obj) { 539 | $stash{"gcc_jit_objectPtr"}{$obj} = $stash{"gcc_jit_paramPtr"}{$_[0]}; 540 | weaken $stash{"gcc_jit_objectPtr"}{$obj}; 541 | } 542 | $obj; 543 | } 544 | 545 | sub gcc_jit_paramPtr::as_rvalue { 546 | die "this param is no longer usable because parent context was destroyed" 547 | unless defined $stash{"gcc_jit_paramPtr"}{$_[0]}; 548 | my $obj = GCCJIT::gcc_jit_param_as_rvalue(@_); 549 | if (defined $obj) { 550 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $stash{"gcc_jit_paramPtr"}{$_[0]}; 551 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 552 | } 553 | $obj; 554 | } 555 | 556 | *gcc_jit_resultPtr::get_code = \&GCCJIT::gcc_jit_result_get_code; 557 | 558 | *gcc_jit_resultPtr::get_global = \&GCCJIT::gcc_jit_result_get_global; 559 | 560 | sub gcc_jit_rvaluePtr::access_field { 561 | die "this rvalue is no longer usable because parent context was destroyed" 562 | unless defined $stash{"gcc_jit_rvaluePtr"}{$_[0]}; 563 | my $obj = GCCJIT::gcc_jit_rvalue_access_field(@_); 564 | if (defined $obj) { 565 | $stash{"gcc_jit_rvaluePtr"}{$obj} = $stash{"gcc_jit_rvaluePtr"}{$_[0]}; 566 | weaken $stash{"gcc_jit_rvaluePtr"}{$obj}; 567 | } 568 | $obj; 569 | } 570 | 571 | sub gcc_jit_rvaluePtr::as_object { 572 | die "this rvalue is no longer usable because parent context was destroyed" 573 | unless defined $stash{"gcc_jit_rvaluePtr"}{$_[0]}; 574 | my $obj = GCCJIT::gcc_jit_rvalue_as_object(@_); 575 | if (defined $obj) { 576 | $stash{"gcc_jit_objectPtr"}{$obj} = $stash{"gcc_jit_rvaluePtr"}{$_[0]}; 577 | weaken $stash{"gcc_jit_objectPtr"}{$obj}; 578 | } 579 | $obj; 580 | } 581 | 582 | sub gcc_jit_rvaluePtr::dereference { 583 | die "this rvalue is no longer usable because parent context was destroyed" 584 | unless defined $stash{"gcc_jit_rvaluePtr"}{$_[0]}; 585 | my $obj = GCCJIT::gcc_jit_rvalue_dereference(@_); 586 | if (defined $obj) { 587 | $stash{"gcc_jit_lvaluePtr"}{$obj} = $stash{"gcc_jit_rvaluePtr"}{$_[0]}; 588 | weaken $stash{"gcc_jit_lvaluePtr"}{$obj}; 589 | } 590 | $obj; 591 | } 592 | 593 | sub gcc_jit_rvaluePtr::dereference_field { 594 | die "this rvalue is no longer usable because parent context was destroyed" 595 | unless defined $stash{"gcc_jit_rvaluePtr"}{$_[0]}; 596 | my $obj = GCCJIT::gcc_jit_rvalue_dereference_field(@_); 597 | if (defined $obj) { 598 | $stash{"gcc_jit_lvaluePtr"}{$obj} = $stash{"gcc_jit_rvaluePtr"}{$_[0]}; 599 | weaken $stash{"gcc_jit_lvaluePtr"}{$obj}; 600 | } 601 | $obj; 602 | } 603 | 604 | sub gcc_jit_rvaluePtr::get_type { 605 | die "this rvalue is no longer usable because parent context was destroyed" 606 | unless defined $stash{"gcc_jit_rvaluePtr"}{$_[0]}; 607 | my $obj = GCCJIT::gcc_jit_rvalue_get_type(@_); 608 | if (defined $obj) { 609 | $stash{"gcc_jit_typePtr"}{$obj} = $stash{"gcc_jit_rvaluePtr"}{$_[0]}; 610 | weaken $stash{"gcc_jit_typePtr"}{$obj}; 611 | } 612 | $obj; 613 | } 614 | 615 | sub gcc_jit_structPtr::as_type { 616 | die "this struct is no longer usable because parent context was destroyed" 617 | unless defined $stash{"gcc_jit_structPtr"}{$_[0]}; 618 | my $obj = GCCJIT::gcc_jit_struct_as_type(@_); 619 | if (defined $obj) { 620 | $stash{"gcc_jit_typePtr"}{$obj} = $stash{"gcc_jit_structPtr"}{$_[0]}; 621 | weaken $stash{"gcc_jit_typePtr"}{$obj}; 622 | } 623 | $obj; 624 | } 625 | 626 | sub gcc_jit_structPtr::set_fields { 627 | die "this struct is no longer usable because parent context was destroyed" 628 | unless defined $stash{"gcc_jit_structPtr"}{$_[0]}; 629 | GCCJIT::gcc_jit_struct_set_fields(@_); 630 | } 631 | 632 | sub gcc_jit_typePtr::as_object { 633 | die "this type is no longer usable because parent context was destroyed" 634 | unless defined $stash{"gcc_jit_typePtr"}{$_[0]}; 635 | my $obj = GCCJIT::gcc_jit_type_as_object(@_); 636 | if (defined $obj) { 637 | $stash{"gcc_jit_objectPtr"}{$obj} = $stash{"gcc_jit_typePtr"}{$_[0]}; 638 | weaken $stash{"gcc_jit_objectPtr"}{$obj}; 639 | } 640 | $obj; 641 | } 642 | 643 | sub gcc_jit_typePtr::get_const { 644 | die "this type is no longer usable because parent context was destroyed" 645 | unless defined $stash{"gcc_jit_typePtr"}{$_[0]}; 646 | my $obj = GCCJIT::gcc_jit_type_get_const(@_); 647 | if (defined $obj) { 648 | $stash{"gcc_jit_typePtr"}{$obj} = $stash{"gcc_jit_typePtr"}{$_[0]}; 649 | weaken $stash{"gcc_jit_typePtr"}{$obj}; 650 | } 651 | $obj; 652 | } 653 | 654 | sub gcc_jit_typePtr::get_pointer { 655 | die "this type is no longer usable because parent context was destroyed" 656 | unless defined $stash{"gcc_jit_typePtr"}{$_[0]}; 657 | my $obj = GCCJIT::gcc_jit_type_get_pointer(@_); 658 | if (defined $obj) { 659 | $stash{"gcc_jit_typePtr"}{$obj} = $stash{"gcc_jit_typePtr"}{$_[0]}; 660 | weaken $stash{"gcc_jit_typePtr"}{$obj}; 661 | } 662 | $obj; 663 | } 664 | 665 | sub gcc_jit_typePtr::get_volatile { 666 | die "this type is no longer usable because parent context was destroyed" 667 | unless defined $stash{"gcc_jit_typePtr"}{$_[0]}; 668 | my $obj = GCCJIT::gcc_jit_type_get_volatile(@_); 669 | if (defined $obj) { 670 | $stash{"gcc_jit_typePtr"}{$obj} = $stash{"gcc_jit_typePtr"}{$_[0]}; 671 | weaken $stash{"gcc_jit_typePtr"}{$obj}; 672 | } 673 | $obj; 674 | } 675 | 676 | sub gcc_jit_blockPtr::DESTROY { 677 | delete $stash{"gcc_jit_blockPtr"}{$_[0]}; 678 | } 679 | 680 | sub gcc_jit_casePtr::DESTROY { 681 | delete $stash{"gcc_jit_casePtr"}{$_[0]}; 682 | } 683 | 684 | sub gcc_jit_contextPtr::DESTROY { 685 | delete $stash{"gcc_jit_contextPtr"}{$_[0]}; 686 | GCCJIT::gcc_jit_context_release($_[0]); 687 | } 688 | 689 | sub gcc_jit_fieldPtr::DESTROY { 690 | delete $stash{"gcc_jit_fieldPtr"}{$_[0]}; 691 | } 692 | 693 | sub gcc_jit_functionPtr::DESTROY { 694 | delete $stash{"gcc_jit_functionPtr"}{$_[0]}; 695 | } 696 | 697 | sub gcc_jit_locationPtr::DESTROY { 698 | delete $stash{"gcc_jit_locationPtr"}{$_[0]}; 699 | } 700 | 701 | sub gcc_jit_lvaluePtr::DESTROY { 702 | delete $stash{"gcc_jit_lvaluePtr"}{$_[0]}; 703 | } 704 | 705 | sub gcc_jit_objectPtr::DESTROY { 706 | delete $stash{"gcc_jit_objectPtr"}{$_[0]}; 707 | } 708 | 709 | sub gcc_jit_paramPtr::DESTROY { 710 | delete $stash{"gcc_jit_paramPtr"}{$_[0]}; 711 | } 712 | 713 | sub gcc_jit_resultPtr::DESTROY { 714 | GCCJIT::gcc_jit_result_release($_[0]); 715 | } 716 | 717 | sub gcc_jit_rvaluePtr::DESTROY { 718 | delete $stash{"gcc_jit_rvaluePtr"}{$_[0]}; 719 | } 720 | 721 | sub gcc_jit_structPtr::DESTROY { 722 | delete $stash{"gcc_jit_structPtr"}{$_[0]}; 723 | } 724 | 725 | sub gcc_jit_typePtr::DESTROY { 726 | delete $stash{"gcc_jit_typePtr"}{$_[0]}; 727 | } 728 | 729 | 1; 730 | __END__ 731 | =head1 NAME 732 | 733 | GCCJIT::Wrapper - object oriented wrapper for GCCJIT. 734 | 735 | =head1 DESCRIPTION 736 | 737 | Do not use this package directly. Instead, use L. 738 | 739 | =head1 AUTHOR 740 | 741 | Vickenty Fesunov Ecpan-gccjit@setattr.netE 742 | 743 | =head1 COPYRIGHT AND LICENSE 744 | 745 | Copyright (C) 2015 by Vickenty Fesunov. 746 | 747 | This program is free software: you can redistribute it and/or modify it under 748 | the terms of the GNU General Public License as published by the Free Software 749 | Foundation, either version 3 of the License, or (at your option) any later 750 | version. 751 | 752 | This program is distributed in the hope that it will be useful, but WITHOUT ANY 753 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 754 | PARTICULAR PURPOSE. See the GNU General Public License for more details. 755 | 756 | You should have received a copy of the GNU General Public License along with 757 | this program. If not, see . 758 | 759 | =cut 760 | -------------------------------------------------------------------------------- /t/01-constants.t: -------------------------------------------------------------------------------- 1 | # Before 'make install' is performed this script should be runnable with 2 | # 'make test'. After 'make install' it should work as 'perl GCCJIT.t' 3 | 4 | ######################### 5 | 6 | # change 'tests => 2' to 'tests => last_test_to_print'; 7 | 8 | use strict; 9 | use warnings; 10 | 11 | use Test::More tests => 2; 12 | BEGIN { use_ok('GCCJIT', ':all') }; 13 | 14 | 15 | my $fail = 0; 16 | foreach my $constname (qw( 17 | GCC_JIT_BINARY_OP_BITWISE_AND GCC_JIT_BINARY_OP_BITWISE_OR 18 | GCC_JIT_BINARY_OP_BITWISE_XOR GCC_JIT_BINARY_OP_DIVIDE 19 | GCC_JIT_BINARY_OP_LOGICAL_AND GCC_JIT_BINARY_OP_LOGICAL_OR 20 | GCC_JIT_BINARY_OP_LSHIFT GCC_JIT_BINARY_OP_MINUS 21 | GCC_JIT_BINARY_OP_MODULO GCC_JIT_BINARY_OP_MULT GCC_JIT_BINARY_OP_PLUS 22 | GCC_JIT_BINARY_OP_RSHIFT GCC_JIT_BOOL_OPTION_DEBUGINFO 23 | GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING 24 | GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE 25 | GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE 26 | GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE GCC_JIT_BOOL_OPTION_DUMP_SUMMARY 27 | GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES GCC_JIT_BOOL_OPTION_SELFCHECK_GC 28 | GCC_JIT_COMPARISON_EQ GCC_JIT_COMPARISON_GE GCC_JIT_COMPARISON_GT 29 | GCC_JIT_COMPARISON_LE GCC_JIT_COMPARISON_LT GCC_JIT_COMPARISON_NE 30 | GCC_JIT_FUNCTION_ALWAYS_INLINE GCC_JIT_FUNCTION_EXPORTED 31 | GCC_JIT_FUNCTION_IMPORTED GCC_JIT_FUNCTION_INTERNAL 32 | GCC_JIT_GLOBAL_EXPORTED GCC_JIT_GLOBAL_IMPORTED GCC_JIT_GLOBAL_INTERNAL 33 | GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL GCC_JIT_NUM_BOOL_OPTIONS 34 | GCC_JIT_NUM_INT_OPTIONS GCC_JIT_NUM_STR_OPTIONS 35 | GCC_JIT_OUTPUT_KIND_ASSEMBLER GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY 36 | GCC_JIT_OUTPUT_KIND_EXECUTABLE GCC_JIT_OUTPUT_KIND_OBJECT_FILE 37 | GCC_JIT_STR_OPTION_PROGNAME GCC_JIT_TYPE_BOOL GCC_JIT_TYPE_CHAR 38 | GCC_JIT_TYPE_COMPLEX_DOUBLE GCC_JIT_TYPE_COMPLEX_FLOAT 39 | GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE GCC_JIT_TYPE_CONST_CHAR_PTR 40 | GCC_JIT_TYPE_DOUBLE GCC_JIT_TYPE_FILE_PTR GCC_JIT_TYPE_FLOAT 41 | GCC_JIT_TYPE_INT GCC_JIT_TYPE_LONG GCC_JIT_TYPE_LONG_DOUBLE 42 | GCC_JIT_TYPE_LONG_LONG GCC_JIT_TYPE_SHORT GCC_JIT_TYPE_SIGNED_CHAR 43 | GCC_JIT_TYPE_SIZE_T GCC_JIT_TYPE_UNSIGNED_CHAR 44 | GCC_JIT_TYPE_UNSIGNED_INT GCC_JIT_TYPE_UNSIGNED_LONG 45 | GCC_JIT_TYPE_UNSIGNED_LONG_LONG GCC_JIT_TYPE_UNSIGNED_SHORT 46 | GCC_JIT_TYPE_VOID GCC_JIT_TYPE_VOID_PTR GCC_JIT_UNARY_OP_ABS 47 | GCC_JIT_UNARY_OP_BITWISE_NEGATE GCC_JIT_UNARY_OP_LOGICAL_NEGATE 48 | GCC_JIT_UNARY_OP_MINUS)) { 49 | next if (eval "my \$a = $constname; 1"); 50 | if ($@ =~ /^Your vendor has not defined GCCJIT macro $constname/) { 51 | print "# pass: $@"; 52 | } else { 53 | print "# fail: $@"; 54 | $fail = 1; 55 | } 56 | 57 | } 58 | 59 | ok( $fail == 0 , 'Constants' ); 60 | ######################### 61 | 62 | # Insert your test code below, the Test::More module is use()ed here so read 63 | # its man page ( perldoc Test::More ) for help writing this test script. 64 | 65 | -------------------------------------------------------------------------------- /t/02-simple.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | 4 | use Test::More; 5 | use FFI::Raw; 6 | 7 | BEGIN { 8 | use_ok("GCCJIT", ":all"); 9 | } 10 | 11 | my $ctx = gcc_jit_context_acquire; 12 | my $int = gcc_jit_context_get_type $ctx, GCC_JIT_TYPE_INT; 13 | my $arg = gcc_jit_context_new_param $ctx, undef, $int, "i"; 14 | my $fun = gcc_jit_context_new_function $ctx, undef, GCC_JIT_FUNCTION_EXPORTED, $int, "square", [ $arg ], 0; 15 | my $blk = gcc_jit_function_new_block $fun, "entry"; 16 | my $rvl = gcc_jit_param_as_rvalue $arg; 17 | my $tmp = gcc_jit_context_new_binary_op $ctx, undef, GCC_JIT_BINARY_OP_MULT, $int, $rvl, $rvl; 18 | gcc_jit_block_end_with_return $blk, undef, $tmp; 19 | 20 | my $res = gcc_jit_context_compile $ctx; 21 | my $ptr = gcc_jit_result_get_code $res, "square"; 22 | 23 | my $ffi = FFI::Raw->new_from_ptr($ptr, FFI::Raw::int, FFI::Raw::int); 24 | 25 | is $ffi->(4), 16; 26 | is $ffi->(6), 36; 27 | is $ffi->(-2), 4; 28 | 29 | done_testing; 30 | -------------------------------------------------------------------------------- /t/03-gcd.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | 4 | use Test::More; 5 | use FFI::Raw; 6 | 7 | BEGIN { 8 | use_ok("GCCJIT", ":all"); 9 | } 10 | 11 | my $ctx = gcc_jit_context_acquire; 12 | my $int = gcc_jit_context_get_type $ctx, GCC_JIT_TYPE_INT; 13 | my ($u, $v) = my @arg = map gcc_jit_context_new_param($ctx, undef, $int, $_), qw/u v/; 14 | my $fun = gcc_jit_context_new_function $ctx, undef, GCC_JIT_FUNCTION_EXPORTED, $int, "gcd", \@arg, 0; 15 | 16 | my %b = map { $_ => gcc_jit_function_new_block($fun, $_) } qw/init cond loop loop_end ret retneg/; 17 | 18 | my $t = gcc_jit_function_new_local $fun, undef, $int, "t"; 19 | my $z = gcc_jit_context_zero $ctx, $int; 20 | gcc_jit_block_end_with_jump $b{init}, undef, $b{cond}; 21 | 22 | my $vz = gcc_jit_context_new_comparison $ctx, undef, GCC_JIT_COMPARISON_GT, gcc_jit_param_as_rvalue($v), $z; 23 | gcc_jit_block_end_with_conditional $b{cond}, undef, $vz, $b{loop}, $b{loop_end}; 24 | 25 | gcc_jit_block_add_assignment $b{loop}, undef, $t, gcc_jit_param_as_rvalue($u); 26 | gcc_jit_block_add_assignment $b{loop}, undef, gcc_jit_param_as_lvalue($u), gcc_jit_param_as_rvalue($v); 27 | 28 | my $r = gcc_jit_context_new_binary_op $ctx, undef, GCC_JIT_BINARY_OP_MODULO, $int, gcc_jit_lvalue_as_rvalue($t), gcc_jit_param_as_rvalue($v); 29 | gcc_jit_block_add_assignment $b{loop}, undef, gcc_jit_param_as_lvalue($v), $r; 30 | gcc_jit_block_end_with_jump $b{loop}, undef, $b{cond}; 31 | 32 | my $uz = gcc_jit_context_new_comparison $ctx, undef, GCC_JIT_COMPARISON_GT, gcc_jit_param_as_rvalue($u), $z; 33 | gcc_jit_block_end_with_conditional $b{loop_end}, undef, $uz, $b{ret}, $b{retneg}; 34 | 35 | gcc_jit_block_end_with_return $b{ret}, undef, gcc_jit_param_as_rvalue($u); 36 | 37 | gcc_jit_block_end_with_return $b{retneg}, undef, 38 | gcc_jit_context_new_unary_op $ctx, undef, GCC_JIT_UNARY_OP_MINUS, $int, gcc_jit_param_as_rvalue($u); 39 | 40 | my $res = gcc_jit_context_compile $ctx; 41 | my $ptr = gcc_jit_result_get_code $res, "gcd"; 42 | my $ffi = FFI::Raw->new_from_ptr($ptr, FFI::Raw::int, FFI::Raw::int, FFI::Raw::int); 43 | 44 | is $ffi->(8, 12), 4; 45 | 46 | done_testing; 47 | -------------------------------------------------------------------------------- /t/04-wrapper.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | 4 | use Test::More; 5 | use Test::Fatal; 6 | 7 | use GCCJIT qw/:all/; 8 | 9 | require_ok("GCCJIT::Context"); 10 | 11 | my $ctx = GCCJIT::Context->acquire; 12 | can_ok($ctx, qw/get_type new_child_context/); 13 | 14 | my $int = $ctx->get_type(GCC_JIT_TYPE_INT); 15 | can_ok($int, qw/as_object/); 16 | 17 | my $obj = $int->as_object; 18 | can_ok($obj, qw/get_context get_debug_string/); 19 | is $obj->get_context, $ctx, "derived child's get_context still returns correct perl object"; 20 | is $obj->get_debug_string, "int", "get_debug_string works"; 21 | 22 | my $const = $int->get_const; 23 | is $const->as_object->get_debug_string(), "const int", "const ok"; 24 | 25 | my $volatile = $const->get_volatile; 26 | is $volatile->as_object->get_debug_string(), "volatile const int", "volatile ok"; 27 | 28 | my $sub = $ctx->new_child_context(); 29 | can_ok($sub, qw/get_type new_child_context/); 30 | 31 | $ctx = undef; 32 | 33 | is exception { $sub->get_type(GCC_JIT_TYPE_INT) }, undef, "subcontext is alive when parent is out of scope"; 34 | is exception { $volatile->as_object }, undef, "subcontext keeps parent's objects alive"; 35 | 36 | $sub = undef; 37 | 38 | like exception { $volatile->as_object }, qr/this type is no longer usable/, "when all contexts are destroyed, objects become invalid"; 39 | 40 | done_testing; 41 | -------------------------------------------------------------------------------- /t/05-wrapper-gcd.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | 4 | use Test::More; 5 | use FFI::Raw; 6 | 7 | BEGIN { 8 | use_ok("GCCJIT", ":all"); 9 | require_ok("GCCJIT::Context"); 10 | } 11 | 12 | my $ctx = GCCJIT::Context->acquire(); 13 | my $int = $ctx->get_type(GCC_JIT_TYPE_INT); 14 | my ($u, $v) = my @arg = map $ctx->new_param(undef, $int, $_), qw/u v/; 15 | my $fun = $ctx->new_function(undef, GCC_JIT_FUNCTION_EXPORTED, $int, "gcd", \@arg, 0); 16 | 17 | my %b = map { $_ => $fun->new_block($_) } qw/init cond loop loop_end ret retneg/; 18 | 19 | my $t = $fun->new_local(undef, $int, "t"); 20 | my $z = $ctx->zero($int); 21 | $b{init}->end_with_jump(undef, $b{cond}); 22 | 23 | my $vz = $ctx->new_comparison(undef, GCC_JIT_COMPARISON_GT, $v->as_rvalue(), $z); 24 | $b{cond}->end_with_conditional(undef, $vz, $b{loop}, $b{loop_end}); 25 | 26 | $b{loop}->add_assignment(undef, $t, $u->as_rvalue()); 27 | $b{loop}->add_assignment(undef, $u->as_lvalue(), $v->as_rvalue()); 28 | 29 | my $r = $ctx->new_binary_op(undef, GCC_JIT_BINARY_OP_MODULO, $int, $t->as_rvalue(), $v->as_rvalue()); 30 | $b{loop}->add_assignment(undef, $v->as_lvalue(), $r); 31 | $b{loop}->end_with_jump(undef, $b{cond}); 32 | 33 | my $uz = $ctx->new_comparison(undef, GCC_JIT_COMPARISON_GT, $u->as_rvalue(), $z); 34 | $b{loop_end}->end_with_conditional(undef, $uz, $b{ret}, $b{retneg}); 35 | 36 | $b{ret}->end_with_return(undef, $u->as_rvalue()); 37 | 38 | $b{retneg}->end_with_return(undef, $ctx->new_unary_op(undef, GCC_JIT_UNARY_OP_MINUS, $int, $u->as_rvalue())); 39 | 40 | my $res = $ctx->compile(); 41 | my $ptr = $res->get_code("gcd"); 42 | my $ffi = FFI::Raw->new_from_ptr($ptr, FFI::Raw::int, FFI::Raw::int, FFI::Raw::int); 43 | 44 | is $ffi->(8, 12), 4; 45 | 46 | done_testing; 47 | -------------------------------------------------------------------------------- /tools/make.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Helper to build using GCC installed under non-standard prefix. 3 | GCC_ROOT="$1" 4 | PERL_MM_OPT="$PERL_MM_OPT INC=-I$GCC_ROOT/include LIBS=\"-L$GCC_ROOT/lib -lgccjit\"" perl Makefile.PL 5 | -------------------------------------------------------------------------------- /tools/regen.pl: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use autodie; 4 | use List::MoreUtils qw/uniq/; 5 | 6 | sub read_xs_decl { 7 | my ($path) = @_; 8 | 9 | open my $xs, "<", $path; 10 | 11 | my (@decl, @temp); 12 | my ($module, $package); 13 | 14 | while (<$xs>) { 15 | chomp; 16 | # skip lines that start with whitespace, comments and XS directives. 17 | next if /^(\s|#|$|[A-Z]+:)/; 18 | if (/^MODULE\s*=\s*([^\s]+)\s+PACKAGE\s*=\s*([^\s]+)/) { 19 | $module = $1; 20 | $package = $2; 21 | next; 22 | } 23 | 24 | if (/^=/) { 25 | while (<$xs> !~ /^=cut/) {}; 26 | next; 27 | } 28 | push @temp, $_; 29 | if (@temp == 2) { 30 | my ($name, $args) = $temp[1] =~ /^([^(]+)(.*)/; 31 | push @decl, { 32 | module => $module, 33 | package => $package, 34 | type => $temp[0], 35 | name => $name, 36 | args => $args, 37 | }; 38 | @temp = (); 39 | } 40 | } 41 | 42 | return \@decl; 43 | } 44 | 45 | my $xs_decls = read_xs_decl("GCCJIT.xs"); 46 | 47 | print "# DO NOT EDIT - this file is autogenerated by tools/regen.pl\n"; 48 | print "package GCCJIT::Wrapper;\n"; 49 | print "use strict;\n"; 50 | print "use warnings;\n"; 51 | print "use Scalar::Util qw/weaken/;\n"; 52 | print "use $_;\n" foreach (uniq sort map $_->{package}, @$xs_decls); 53 | 54 | print "\nmy %stash;\n"; 55 | 56 | my %destructor_code; 57 | 58 | sub is_memory_owner { 59 | shift() =~ /^gcc_jit_(context|result)Ptr$/; 60 | } 61 | 62 | sub is_managed_type { 63 | my $type = shift; 64 | $type =~ /^gcc_jit_/ && !is_memory_owner($type) 65 | } 66 | 67 | foreach my $decl (sort { $a->{name} cmp $b->{name} } @$xs_decls) { 68 | my ($class, $method) = $decl->{name} =~ /gcc_jit_([a-z]+)_(.*)/; 69 | 70 | my $objpkg = "gcc_jit_${class}Ptr"; 71 | my $retpkg = $decl->{type} =~ s/\s*\*/Ptr/r; 72 | 73 | if ($method eq "get_context") { 74 | print "sub ${objpkg}::${method} {\n"; 75 | print " \$stash{\"$objpkg\"}{\$_[0]}\n"; 76 | print "}\n\n"; 77 | next; 78 | } 79 | if ($method eq "release") { 80 | $destructor_code{$objpkg}{release} = "$decl->{package}::$decl->{name}(\$_[0])"; 81 | next; 82 | } 83 | 84 | my $need_check = is_managed_type($objpkg); 85 | my $need_stash = is_managed_type($retpkg) || $objpkg eq $retpkg; 86 | my $need_weaken = is_managed_type($retpkg); 87 | 88 | if ($need_stash) { 89 | $destructor_code{$retpkg}{unstash} = "delete \$stash{\"$retpkg\"}{\$_[0]}"; 90 | } 91 | 92 | unless ($need_check || $need_stash) { 93 | print "*${objpkg}::${method} = \\&$decl->{package}::$decl->{name};\n\n"; 94 | } else { 95 | print "sub ${objpkg}::${method} {\n"; 96 | 97 | if ($need_check) { 98 | print " die \"this $class is no longer usable because parent context was destroyed\"\n"; 99 | print " unless defined \$stash{\"$objpkg\"}{\$_[0]};\n"; 100 | } 101 | 102 | print " "; 103 | print "my \$obj = " if ($need_stash); 104 | print "$decl->{package}::$decl->{name}(\@_);\n"; 105 | 106 | if ($need_stash) { 107 | print " if (defined \$obj) {\n"; 108 | if ($objpkg eq "gcc_jit_contextPtr") { 109 | print " \$stash{\"$retpkg\"}{\$obj} = \$_[0];\n"; 110 | } 111 | else { 112 | print " \$stash{\"$retpkg\"}{\$obj} = \$stash{\"$objpkg\"}{\$_[0]};\n"; 113 | } 114 | if ($need_weaken) { 115 | print " weaken \$stash{\"$retpkg\"}{\$obj};\n"; 116 | } 117 | 118 | print " }\n"; 119 | print " \$obj;\n"; 120 | } 121 | print "}\n\n"; 122 | } 123 | } 124 | 125 | foreach my $pkg (sort keys %destructor_code) { 126 | my $code = $destructor_code{$pkg}; 127 | print "sub ${pkg}::DESTROY {\n"; 128 | print " $_;\n" foreach (values %$code); 129 | print "}\n\n"; 130 | } 131 | 132 | print "1;\n"; 133 | print ; 134 | __DATA__ 135 | __END__ 136 | =head1 NAME 137 | 138 | GCCJIT::Wrapper - object oriented wrapper for GCCJIT. 139 | 140 | =head1 DESCRIPTION 141 | 142 | Do not use this package directly. Instead, use L. 143 | 144 | =head1 AUTHOR 145 | 146 | Vickenty Fesunov Ecpan-gccjit@setattr.netE 147 | 148 | =head1 COPYRIGHT AND LICENSE 149 | 150 | Copyright (C) 2015 by Vickenty Fesunov. 151 | 152 | This program is free software: you can redistribute it and/or modify it under 153 | the terms of the GNU General Public License as published by the Free Software 154 | Foundation, either version 3 of the License, or (at your option) any later 155 | version. 156 | 157 | This program is distributed in the hope that it will be useful, but WITHOUT ANY 158 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 159 | PARTICULAR PURPOSE. See the GNU General Public License for more details. 160 | 161 | You should have received a copy of the GNU General Public License along with 162 | this program. If not, see . 163 | 164 | =cut 165 | -------------------------------------------------------------------------------- /tools/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SRCDIR="/vagrant" 4 | TESTDIR="/home/vagrant/gccjit-test" 5 | VMS="f22-64 deb8-32 deb8-64" 6 | 7 | export LC_ALL=C 8 | 9 | if [ "$1" = "vagrant-run" ]; then 10 | set -e 11 | test -d $SRCDIR 12 | rm -rf $TESTDIR 13 | git clone $SRCDIR $TESTDIR 14 | cd $TESTDIR 15 | perl Makefile.PL 16 | make 17 | make test 18 | else 19 | for vm in $VMS; do 20 | echo "Running tests in $vm" 21 | vagrant ssh $vm -- "$SRCDIR/tools/test.sh" vagrant-run 22 | done 23 | fi 24 | -------------------------------------------------------------------------------- /typemap: -------------------------------------------------------------------------------- 1 | const char * T_PV 2 | enum gcc_jit_binary_op T_ENUM 3 | enum gcc_jit_bool_option T_ENUM 4 | enum gcc_jit_comparison T_ENUM 5 | enum gcc_jit_function_kind T_ENUM 6 | enum gcc_jit_global_kind T_ENUM 7 | enum gcc_jit_int_option T_ENUM 8 | enum gcc_jit_output_kind T_ENUM 9 | enum gcc_jit_str_option T_ENUM 10 | enum gcc_jit_types T_ENUM 11 | enum gcc_jit_unary_op T_ENUM 12 | gcc_jit_block * T_PTROBJ 13 | gcc_jit_case * T_PTROBJ 14 | gcc_jit_context * T_PTROBJ 15 | gcc_jit_field * T_PTROBJ 16 | gcc_jit_function * T_PTROBJ 17 | gcc_jit_location * T_NULLABLE_PTROBJ 18 | gcc_jit_lvalue * T_PTROBJ 19 | gcc_jit_object * T_PTROBJ 20 | gcc_jit_param * T_PTROBJ 21 | gcc_jit_result * T_PTROBJ 22 | gcc_jit_rvalue * T_PTROBJ 23 | gcc_jit_struct * T_PTROBJ 24 | gcc_jit_type * T_PTROBJ 25 | ## 26 | INPUT 27 | T_NULLABLE_PTROBJ 28 | if (SvROK($arg) && sv_derived_from($arg, \"${ntype}\")) { 29 | IV tmp = SvIV((SV*)SvRV($arg)); 30 | $var = INT2PTR($type,tmp); 31 | } 32 | else if (!SvOK($arg)) { 33 | $var = NULL; 34 | } else 35 | Perl_croak(aTHX_ \"%s: %s is not of type %s\", 36 | ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]}, 37 | \"$var\", \"$ntype\") 38 | ## 39 | OUTPUT 40 | T_NULLABLE_PTROBJ 41 | sv_setref_pv($arg, \"${ntype}\", (void*)$var); 42 | --------------------------------------------------------------------------------