| ... | @@ -35,6 +35,18 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont | ... | @@ -35,6 +35,18 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont |
| 35 | LValPurpose lval); | 35 | LValPurpose lval); |
| 36 | static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); | 36 | static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); |
| 37 | | 37 | |
| | 38 | ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) { |
| | 39 | ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr; |
| | 40 | size_t index = const_val->data.x_ptr.index; |
| | 41 | |
| | 42 | if (index == SIZE_MAX) { |
| | 43 | return base_ptr; |
| | 44 | } else { |
| | 45 | assert(index < base_ptr->data.x_array.size); |
| | 46 | return &base_ptr->data.x_array.elements[index]; |
| | 47 | } |
| | 48 | } |
| | 49 | |
| 38 | static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) { | 50 | static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) { |
| 39 | assert(basic_block); | 51 | assert(basic_block); |
| 40 | assert(instruction); | 52 | assert(instruction); |
| ... | @@ -237,7 +249,7 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, AstNode *source_node, IrI | ... | @@ -237,7 +249,7 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, AstNode *source_node, IrI |
| 237 | { | 249 | { |
| 238 | IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, source_node); | 250 | IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, source_node); |
| 239 | cond_br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; | 251 | cond_br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; |
| 240 | cond_br_instruction->base.static_value.ok = true; | 252 | cond_br_instruction->base.static_value.special = ConstValSpecialStatic; |
| 241 | cond_br_instruction->condition = condition; | 253 | cond_br_instruction->condition = condition; |
| 242 | cond_br_instruction->then_block = then_block; | 254 | cond_br_instruction->then_block = then_block; |
| 243 | cond_br_instruction->else_block = else_block; | 255 | cond_br_instruction->else_block = else_block; |
| ... | @@ -262,7 +274,7 @@ static IrInstruction *ir_build_cond_br_from(IrBuilder *irb, IrInstruction *old_i | ... | @@ -262,7 +274,7 @@ static IrInstruction *ir_build_cond_br_from(IrBuilder *irb, IrInstruction *old_i |
| 262 | static IrInstruction *ir_build_return(IrBuilder *irb, AstNode *source_node, IrInstruction *return_value) { | 274 | static IrInstruction *ir_build_return(IrBuilder *irb, AstNode *source_node, IrInstruction *return_value) { |
| 263 | IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, source_node); | 275 | IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, source_node); |
| 264 | return_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; | 276 | return_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; |
| 265 | return_instruction->base.static_value.ok = true; | 277 | return_instruction->base.static_value.special = ConstValSpecialStatic; |
| 266 | return_instruction->value = return_value; | 278 | return_instruction->value = return_value; |
| 267 | | 279 | |
| 268 | ir_ref_instruction(return_value); | 280 | ir_ref_instruction(return_value); |
| ... | @@ -281,20 +293,19 @@ static IrInstruction *ir_build_return_from(IrBuilder *irb, IrInstruction *old_in | ... | @@ -281,20 +293,19 @@ static IrInstruction *ir_build_return_from(IrBuilder *irb, IrInstruction *old_in |
| 281 | static IrInstruction *ir_create_const(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) { | 293 | static IrInstruction *ir_create_const(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) { |
| 282 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, source_node); | 294 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, source_node); |
| 283 | const_instruction->base.type_entry = type_entry; | 295 | const_instruction->base.type_entry = type_entry; |
| 284 | const_instruction->base.static_value.ok = true; | 296 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| 285 | return &const_instruction->base; | 297 | return &const_instruction->base; |
| 286 | } | 298 | } |
| 287 | | 299 | |
| 288 | static IrInstruction *ir_build_const_void(IrBuilder *irb, AstNode *source_node) { | 300 | static IrInstruction *ir_build_const_void(IrBuilder *irb, AstNode *source_node) { |
| 289 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | 301 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); |
| 290 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_void; | 302 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_void; |
| 291 | const_instruction->base.static_value.ok = true; | 303 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| 292 | return &const_instruction->base; | 304 | return &const_instruction->base; |
| 293 | } | 305 | } |
| 294 | | 306 | |
| 295 | static IrInstruction *ir_build_const_undefined(IrBuilder *irb, AstNode *source_node) { | 307 | static IrInstruction *ir_build_const_undefined(IrBuilder *irb, AstNode *source_node) { |
| 296 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | 308 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); |
| 297 | const_instruction->base.static_value.ok = true; | | |
| 298 | const_instruction->base.static_value.special = ConstValSpecialUndef; | 309 | const_instruction->base.static_value.special = ConstValSpecialUndef; |
| 299 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_undef; | 310 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_undef; |
| 300 | return &const_instruction->base; | 311 | return &const_instruction->base; |
| ... | @@ -304,7 +315,7 @@ static IrInstruction *ir_build_const_bignum(IrBuilder *irb, AstNode *source_node | ... | @@ -304,7 +315,7 @@ static IrInstruction *ir_build_const_bignum(IrBuilder *irb, AstNode *source_node |
| 304 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | 315 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); |
| 305 | const_instruction->base.type_entry = (bignum->kind == BigNumKindInt) ? | 316 | const_instruction->base.type_entry = (bignum->kind == BigNumKindInt) ? |
| 306 | irb->codegen->builtin_types.entry_num_lit_int : irb->codegen->builtin_types.entry_num_lit_float; | 317 | irb->codegen->builtin_types.entry_num_lit_int : irb->codegen->builtin_types.entry_num_lit_float; |
| 307 | const_instruction->base.static_value.ok = true; | 318 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| 308 | const_instruction->base.static_value.data.x_bignum = *bignum; | 319 | const_instruction->base.static_value.data.x_bignum = *bignum; |
| 309 | return &const_instruction->base; | 320 | return &const_instruction->base; |
| 310 | } | 321 | } |
| ... | @@ -312,7 +323,7 @@ static IrInstruction *ir_build_const_bignum(IrBuilder *irb, AstNode *source_node | ... | @@ -312,7 +323,7 @@ static IrInstruction *ir_build_const_bignum(IrBuilder *irb, AstNode *source_node |
| 312 | static IrInstruction *ir_build_const_usize(IrBuilder *irb, AstNode *source_node, uint64_t value) { | 323 | static IrInstruction *ir_build_const_usize(IrBuilder *irb, AstNode *source_node, uint64_t value) { |
| 313 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | 324 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); |
| 314 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_usize; | 325 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_usize; |
| 315 | const_instruction->base.static_value.ok = true; | 326 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| 316 | bignum_init_unsigned(&const_instruction->base.static_value.data.x_bignum, value); | 327 | bignum_init_unsigned(&const_instruction->base.static_value.data.x_bignum, value); |
| 317 | return &const_instruction->base; | 328 | return &const_instruction->base; |
| 318 | } | 329 | } |
| ... | @@ -320,7 +331,7 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, AstNode *source_node, | ... | @@ -320,7 +331,7 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, AstNode *source_node, |
| 320 | static IrInstruction *ir_create_const_type(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) { | 331 | static IrInstruction *ir_create_const_type(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) { |
| 321 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, source_node); | 332 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, source_node); |
| 322 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_type; | 333 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_type; |
| 323 | const_instruction->base.static_value.ok = true; | 334 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| 324 | const_instruction->base.static_value.data.x_type = type_entry; | 335 | const_instruction->base.static_value.data.x_type = type_entry; |
| 325 | return &const_instruction->base; | 336 | return &const_instruction->base; |
| 326 | } | 337 | } |
| ... | @@ -334,7 +345,7 @@ static IrInstruction *ir_build_const_type(IrBuilder *irb, AstNode *source_node, | ... | @@ -334,7 +345,7 @@ static IrInstruction *ir_build_const_type(IrBuilder *irb, AstNode *source_node, |
| 334 | static IrInstruction *ir_build_const_fn(IrBuilder *irb, AstNode *source_node, FnTableEntry *fn_entry) { | 345 | static IrInstruction *ir_build_const_fn(IrBuilder *irb, AstNode *source_node, FnTableEntry *fn_entry) { |
| 335 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | 346 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); |
| 336 | const_instruction->base.type_entry = fn_entry->type_entry; | 347 | const_instruction->base.type_entry = fn_entry->type_entry; |
| 337 | const_instruction->base.static_value.ok = true; | 348 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| 338 | const_instruction->base.static_value.data.x_fn = fn_entry; | 349 | const_instruction->base.static_value.data.x_fn = fn_entry; |
| 339 | return &const_instruction->base; | 350 | return &const_instruction->base; |
| 340 | } | 351 | } |
| ... | @@ -342,7 +353,7 @@ static IrInstruction *ir_build_const_fn(IrBuilder *irb, AstNode *source_node, Fn | ... | @@ -342,7 +353,7 @@ static IrInstruction *ir_build_const_fn(IrBuilder *irb, AstNode *source_node, Fn |
| 342 | static IrInstruction *ir_build_const_generic_fn(IrBuilder *irb, AstNode *source_node, TypeTableEntry *fn_type) { | 353 | static IrInstruction *ir_build_const_generic_fn(IrBuilder *irb, AstNode *source_node, TypeTableEntry *fn_type) { |
| 343 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | 354 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); |
| 344 | const_instruction->base.type_entry = fn_type; | 355 | const_instruction->base.type_entry = fn_type; |
| 345 | const_instruction->base.static_value.ok = true; | 356 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| 346 | const_instruction->base.static_value.data.x_type = fn_type; | 357 | const_instruction->base.static_value.data.x_type = fn_type; |
| 347 | return &const_instruction->base; | 358 | return &const_instruction->base; |
| 348 | } | 359 | } |
| ... | @@ -350,7 +361,7 @@ static IrInstruction *ir_build_const_generic_fn(IrBuilder *irb, AstNode *source_ | ... | @@ -350,7 +361,7 @@ static IrInstruction *ir_build_const_generic_fn(IrBuilder *irb, AstNode *source_ |
| 350 | static IrInstruction *ir_build_const_import(IrBuilder *irb, AstNode *source_node, ImportTableEntry *import) { | 361 | static IrInstruction *ir_build_const_import(IrBuilder *irb, AstNode *source_node, ImportTableEntry *import) { |
| 351 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | 362 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); |
| 352 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_namespace; | 363 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_namespace; |
| 353 | const_instruction->base.static_value.ok = true; | 364 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| 354 | const_instruction->base.static_value.data.x_import = import; | 365 | const_instruction->base.static_value.data.x_import = import; |
| 355 | return &const_instruction->base; | 366 | return &const_instruction->base; |
| 356 | } | 367 | } |
| ... | @@ -358,7 +369,7 @@ static IrInstruction *ir_build_const_import(IrBuilder *irb, AstNode *source_node | ... | @@ -358,7 +369,7 @@ static IrInstruction *ir_build_const_import(IrBuilder *irb, AstNode *source_node |
| 358 | static IrInstruction *ir_build_const_scope(IrBuilder *irb, AstNode *source_node, BlockContext *scope) { | 369 | static IrInstruction *ir_build_const_scope(IrBuilder *irb, AstNode *source_node, BlockContext *scope) { |
| 359 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | 370 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); |
| 360 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_block; | 371 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_block; |
| 361 | const_instruction->base.static_value.ok = true; | 372 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| 362 | const_instruction->base.static_value.data.x_block = scope; | 373 | const_instruction->base.static_value.data.x_block = scope; |
| 363 | return &const_instruction->base; | 374 | return &const_instruction->base; |
| 364 | } | 375 | } |
| ... | @@ -366,7 +377,7 @@ static IrInstruction *ir_build_const_scope(IrBuilder *irb, AstNode *source_node, | ... | @@ -366,7 +377,7 @@ static IrInstruction *ir_build_const_scope(IrBuilder *irb, AstNode *source_node, |
| 366 | static IrInstruction *ir_build_const_bool(IrBuilder *irb, AstNode *source_node, bool value) { | 377 | static IrInstruction *ir_build_const_bool(IrBuilder *irb, AstNode *source_node, bool value) { |
| 367 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | 378 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); |
| 368 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_bool; | 379 | const_instruction->base.type_entry = irb->codegen->builtin_types.entry_bool; |
| 369 | const_instruction->base.static_value.ok = true; | 380 | const_instruction->base.static_value.special = ConstValSpecialStatic; |
| 370 | const_instruction->base.static_value.data.x_bool = value; | 381 | const_instruction->base.static_value.data.x_bool = value; |
| 371 | return &const_instruction->base; | 382 | return &const_instruction->base; |
| 372 | } | 383 | } |
| ... | @@ -377,45 +388,45 @@ static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, AstNode *source_nod | ... | @@ -377,45 +388,45 @@ static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, AstNode *source_nod |
| 377 | TypeTableEntry *type_entry = get_array_type(irb->codegen, u8_type, buf_len(str)); | 388 | TypeTableEntry *type_entry = get_array_type(irb->codegen, u8_type, buf_len(str)); |
| 378 | const_instruction->base.type_entry = type_entry; | 389 | const_instruction->base.type_entry = type_entry; |
| 379 | ConstExprValue *const_val = &const_instruction->base.static_value; | 390 | ConstExprValue *const_val = &const_instruction->base.static_value; |
| 380 | const_val->ok = true; | 391 | const_val->special = ConstValSpecialStatic; |
| 381 | const_val->data.x_array.fields = allocate<ConstExprValue*>(buf_len(str)); | 392 | const_val->data.x_array.elements = allocate<ConstExprValue>(buf_len(str)); |
| | 393 | const_val->data.x_array.size = buf_len(str); |
| 382 | | 394 | |
| 383 | ConstExprValue *all_chars = allocate<ConstExprValue>(buf_len(str)); | | |
| 384 | for (size_t i = 0; i < buf_len(str); i += 1) { | 395 | for (size_t i = 0; i < buf_len(str); i += 1) { |
| 385 | ConstExprValue *this_char = &all_chars[i]; | 396 | ConstExprValue *this_char = &const_val->data.x_array.elements[i]; |
| 386 | this_char->ok = true; | 397 | this_char->special = ConstValSpecialStatic; |
| 387 | bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]); | 398 | bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]); |
| 388 | const_val->data.x_array.fields[i] = this_char; | | |
| 389 | } | 399 | } |
| 390 | | 400 | |
| 391 | return &const_instruction->base; | 401 | return &const_instruction->base; |
| 392 | } | 402 | } |
| 393 | | 403 | |
| 394 | static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, AstNode *source_node, Buf *str) { | 404 | static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, AstNode *source_node, Buf *str) { |
| 395 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); | 405 | // first we build the underlying array |
| 396 | TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8; | | |
| 397 | TypeTableEntry *type_entry = get_pointer_to_type(irb->codegen, u8_type, true); | | |
| 398 | const_instruction->base.type_entry = type_entry; | | |
| 399 | ConstExprValue *const_val = &const_instruction->base.static_value; | | |
| 400 | const_val->ok = true; | | |
| 401 | | | |
| 402 | size_t len_with_null = buf_len(str) + 1; | 406 | size_t len_with_null = buf_len(str) + 1; |
| 403 | const_val->data.x_ptr.ptr = allocate<ConstExprValue*>(len_with_null); | 407 | ConstExprValue *array_val = allocate<ConstExprValue>(1); |
| 404 | const_val->data.x_ptr.len = len_with_null; | 408 | array_val->special = ConstValSpecialStatic; |
| 405 | const_val->data.x_ptr.is_c_str = true; | 409 | array_val->data.x_array.elements = allocate<ConstExprValue>(len_with_null); |
| 406 | | 410 | array_val->data.x_array.size = len_with_null; |
| 407 | ConstExprValue *all_chars = allocate<ConstExprValue>(len_with_null); | | |
| 408 | for (size_t i = 0; i < buf_len(str); i += 1) { | 411 | for (size_t i = 0; i < buf_len(str); i += 1) { |
| 409 | ConstExprValue *this_char = &all_chars[i]; | 412 | ConstExprValue *this_char = &array_val->data.x_array.elements[i]; |
| 410 | this_char->ok = true; | 413 | this_char->special = ConstValSpecialStatic; |
| 411 | bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]); | 414 | bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]); |
| 412 | const_val->data.x_ptr.ptr[i] = this_char; | | |
| 413 | } | 415 | } |
| 414 | | 416 | ConstExprValue *null_char = &array_val->data.x_array.elements[len_with_null - 1]; |
| 415 | ConstExprValue *null_char = &all_chars[len_with_null - 1]; | 417 | null_char->special = ConstValSpecialStatic; |
| 416 | null_char->ok = true; | | |
| 417 | bignum_init_unsigned(&null_char->data.x_bignum, 0); | 418 | bignum_init_unsigned(&null_char->data.x_bignum, 0); |
| 418 | const_val->data.x_ptr.ptr[len_with_null - 1] = null_char; | 419 | |
| | 420 | // then make the pointer point to it |
| | 421 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node); |
| | 422 | TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8; |
| | 423 | TypeTableEntry *type_entry = get_pointer_to_type(irb->codegen, u8_type, true); |
| | 424 | const_instruction->base.type_entry = type_entry; |
| | 425 | ConstExprValue *ptr_val = &const_instruction->base.static_value; |
| | 426 | ptr_val->special = ConstValSpecialStatic; |
| | 427 | ptr_val->data.x_ptr.base_ptr = array_val; |
| | 428 | ptr_val->data.x_ptr.index = 0; |
| | 429 | ptr_val->data.x_ptr.is_c_str = true; |
| 419 | | 430 | |
| 420 | return &const_instruction->base; | 431 | return &const_instruction->base; |
| 421 | } | 432 | } |
| ... | @@ -591,7 +602,7 @@ static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instr | ... | @@ -591,7 +602,7 @@ static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instr |
| 591 | static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block, bool is_inline) { | 602 | static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block, bool is_inline) { |
| 592 | IrInstructionBr *br_instruction = ir_build_instruction<IrInstructionBr>(irb, source_node); | 603 | IrInstructionBr *br_instruction = ir_build_instruction<IrInstructionBr>(irb, source_node); |
| 593 | br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; | 604 | br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; |
| 594 | br_instruction->base.static_value.ok = true; | 605 | br_instruction->base.static_value.special = ConstValSpecialStatic; |
| 595 | br_instruction->dest_block = dest_block; | 606 | br_instruction->dest_block = dest_block; |
| 596 | br_instruction->is_inline = is_inline; | 607 | br_instruction->is_inline = is_inline; |
| 597 | | 608 | |
| ... | @@ -662,7 +673,7 @@ static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, AstNode *so | ... | @@ -662,7 +673,7 @@ static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, AstNode *so |
| 662 | static IrInstruction *ir_build_unreachable(IrBuilder *irb, AstNode *source_node) { | 673 | static IrInstruction *ir_build_unreachable(IrBuilder *irb, AstNode *source_node) { |
| 663 | IrInstructionUnreachable *unreachable_instruction = | 674 | IrInstructionUnreachable *unreachable_instruction = |
| 664 | ir_build_instruction<IrInstructionUnreachable>(irb, source_node); | 675 | ir_build_instruction<IrInstructionUnreachable>(irb, source_node); |
| 665 | unreachable_instruction->base.static_value.ok = true; | 676 | unreachable_instruction->base.static_value.special = ConstValSpecialStatic; |
| 666 | unreachable_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; | 677 | unreachable_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; |
| 667 | return &unreachable_instruction->base; | 678 | return &unreachable_instruction->base; |
| 668 | } | 679 | } |
| ... | @@ -677,7 +688,7 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, AstNode *source_node, | ... | @@ -677,7 +688,7 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, AstNode *source_node, |
| 677 | IrInstruction *ptr, IrInstruction *value) | 688 | IrInstruction *ptr, IrInstruction *value) |
| 678 | { | 689 | { |
| 679 | IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, source_node); | 690 | IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, source_node); |
| 680 | instruction->base.static_value.ok = true; | 691 | instruction->base.static_value.special = ConstValSpecialStatic; |
| 681 | instruction->base.type_entry = irb->codegen->builtin_types.entry_void; | 692 | instruction->base.type_entry = irb->codegen->builtin_types.entry_void; |
| 682 | instruction->ptr = ptr; | 693 | instruction->ptr = ptr; |
| 683 | instruction->value = value; | 694 | instruction->value = value; |
| ... | @@ -700,7 +711,7 @@ static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node, | ... | @@ -700,7 +711,7 @@ static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node, |
| 700 | VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value) | 711 | VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value) |
| 701 | { | 712 | { |
| 702 | IrInstructionDeclVar *decl_var_instruction = ir_build_instruction<IrInstructionDeclVar>(irb, source_node); | 713 | IrInstructionDeclVar *decl_var_instruction = ir_build_instruction<IrInstructionDeclVar>(irb, source_node); |
| 703 | decl_var_instruction->base.static_value.ok = true; | 714 | decl_var_instruction->base.static_value.special = ConstValSpecialStatic; |
| 704 | decl_var_instruction->base.type_entry = irb->codegen->builtin_types.entry_void; | 715 | decl_var_instruction->base.type_entry = irb->codegen->builtin_types.entry_void; |
| 705 | decl_var_instruction->var = var; | 716 | decl_var_instruction->var = var; |
| 706 | decl_var_instruction->var_type = var_type; | 717 | decl_var_instruction->var_type = var_type; |
| ... | @@ -1900,7 +1911,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -1900,7 +1911,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 1900 | } | 1911 | } |
| 1901 | | 1912 | |
| 1902 | ConstExprValue *const_val = &instruction->static_value; | 1913 | ConstExprValue *const_val = &instruction->static_value; |
| 1903 | assert(const_val->ok); | 1914 | assert(const_val->special != ConstValSpecialRuntime); |
| 1904 | if (other_type_underlying->id == TypeTableEntryIdFloat) { | 1915 | if (other_type_underlying->id == TypeTableEntryIdFloat) { |
| 1905 | return true; | 1916 | return true; |
| 1906 | } else if (other_type_underlying->id == TypeTableEntryIdInt && | 1917 | } else if (other_type_underlying->id == TypeTableEntryIdInt && |
| ... | @@ -2110,10 +2121,10 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -2110,10 +2121,10 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 2110 | IrInstruction *dest_type, CastOp cast_op, bool need_alloca) | 2121 | IrInstruction *dest_type, CastOp cast_op, bool need_alloca) |
| 2111 | { | 2122 | { |
| 2112 | assert(dest_type->type_entry->id == TypeTableEntryIdMetaType); | 2123 | assert(dest_type->type_entry->id == TypeTableEntryIdMetaType); |
| 2113 | assert(dest_type->static_value.ok); | 2124 | assert(dest_type->static_value.special != ConstValSpecialRuntime); |
| 2114 | TypeTableEntry *wanted_type = dest_type->static_value.data.x_type; | 2125 | TypeTableEntry *wanted_type = dest_type->static_value.data.x_type; |
| 2115 | | 2126 | |
| 2116 | if (value->static_value.ok) { | 2127 | if (value->static_value.special != ConstValSpecialRuntime) { |
| 2117 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->source_node, wanted_type); | 2128 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->source_node, wanted_type); |
| 2118 | eval_const_expr_implicit_cast(cast_op, &value->static_value, value->type_entry, | 2129 | eval_const_expr_implicit_cast(cast_op, &value->static_value, value->type_entry, |
| 2119 | &result->static_value, wanted_type); | 2130 | &result->static_value, wanted_type); |
| ... | @@ -2194,7 +2205,7 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in | ... | @@ -2194,7 +2205,7 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in |
| 2194 | } | 2205 | } |
| 2195 | ir_link_new_instruction(new_instruction, old_instruction); | 2206 | ir_link_new_instruction(new_instruction, old_instruction); |
| 2196 | ConstExprValue *const_val = &new_instruction->static_value; | 2207 | ConstExprValue *const_val = &new_instruction->static_value; |
| 2197 | const_val->ok = true; | 2208 | const_val->special = ConstValSpecialStatic; |
| 2198 | const_val->depends_on_compile_var = depends_on_compile_var; | 2209 | const_val->depends_on_compile_var = depends_on_compile_var; |
| 2199 | return const_val; | 2210 | return const_val; |
| 2200 | } | 2211 | } |
| ... | @@ -2226,7 +2237,7 @@ static TypeTableEntry *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value | ... | @@ -2226,7 +2237,7 @@ static TypeTableEntry *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value |
| 2226 | } | 2237 | } |
| 2227 | | 2238 | |
| 2228 | ConstExprValue *const_val = &type_value->static_value; | 2239 | ConstExprValue *const_val = &type_value->static_value; |
| 2229 | if (!const_val->ok) { | 2240 | if (const_val->special == ConstValSpecialRuntime) { |
| 2230 | add_node_error(ira->codegen, type_value->source_node, | 2241 | add_node_error(ira->codegen, type_value->source_node, |
| 2231 | buf_sprintf("unable to evaluate constant expression")); | 2242 | buf_sprintf("unable to evaluate constant expression")); |
| 2232 | return ira->codegen->builtin_types.entry_invalid; | 2243 | return ira->codegen->builtin_types.entry_invalid; |
| ... | @@ -2249,7 +2260,7 @@ static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *bool_value, bool *out | ... | @@ -2249,7 +2260,7 @@ static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *bool_value, bool *out |
| 2249 | } | 2260 | } |
| 2250 | | 2261 | |
| 2251 | ConstExprValue *const_val = &bool_value->static_value; | 2262 | ConstExprValue *const_val = &bool_value->static_value; |
| 2252 | if (!const_val->ok) { | 2263 | if (const_val->special == ConstValSpecialRuntime) { |
| 2253 | add_node_error(ira->codegen, bool_value->source_node, | 2264 | add_node_error(ira->codegen, bool_value->source_node, |
| 2254 | buf_sprintf("unable to evaluate constant expression")); | 2265 | buf_sprintf("unable to evaluate constant expression")); |
| 2255 | return false; | 2266 | return false; |
| ... | @@ -2273,7 +2284,7 @@ static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { | ... | @@ -2273,7 +2284,7 @@ static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { |
| 2273 | } | 2284 | } |
| 2274 | | 2285 | |
| 2275 | ConstExprValue *const_val = &fn_value->static_value; | 2286 | ConstExprValue *const_val = &fn_value->static_value; |
| 2276 | if (!const_val->ok) { | 2287 | if (const_val->special == ConstValSpecialRuntime) { |
| 2277 | add_node_error(ira->codegen, fn_value->source_node, | 2288 | add_node_error(ira->codegen, fn_value->source_node, |
| 2278 | buf_sprintf("unable to evaluate constant expression")); | 2289 | buf_sprintf("unable to evaluate constant expression")); |
| 2279 | return nullptr; | 2290 | return nullptr; |
| ... | @@ -2286,7 +2297,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -2286,7 +2297,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 2286 | IrInstruction *dest_type, IrInstruction *value) | 2297 | IrInstruction *dest_type, IrInstruction *value) |
| 2287 | { | 2298 | { |
| 2288 | assert(dest_type->type_entry->id == TypeTableEntryIdMetaType); | 2299 | assert(dest_type->type_entry->id == TypeTableEntryIdMetaType); |
| 2289 | assert(dest_type->static_value.ok); | 2300 | assert(dest_type->static_value.special != ConstValSpecialRuntime); |
| 2290 | | 2301 | |
| 2291 | TypeTableEntry *wanted_type = dest_type->static_value.data.x_type; | 2302 | TypeTableEntry *wanted_type = dest_type->static_value.data.x_type; |
| 2292 | TypeTableEntry *actual_type = value->type_entry; | 2303 | TypeTableEntry *actual_type = value->type_entry; |
| ... | @@ -2618,7 +2629,7 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -2618,7 +2629,7 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp |
| 2618 | | 2629 | |
| 2619 | ConstExprValue *op1_val = &casted_op1->static_value; | 2630 | ConstExprValue *op1_val = &casted_op1->static_value; |
| 2620 | ConstExprValue *op2_val = &casted_op2->static_value; | 2631 | ConstExprValue *op2_val = &casted_op2->static_value; |
| 2621 | if (op1_val->ok && op2_val->ok) { | 2632 | if (op1_val->special != ConstValSpecialRuntime && op2_val->special != ConstValSpecialRuntime) { |
| 2622 | bool depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var; | 2633 | bool depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var; |
| 2623 | ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base, depends_on_compile_var); | 2634 | ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base, depends_on_compile_var); |
| 2624 | | 2635 | |
| ... | @@ -2710,7 +2721,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -2710,7 +2721,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp |
| 2710 | | 2721 | |
| 2711 | ConstExprValue *op1_val = &casted_op1->static_value; | 2722 | ConstExprValue *op1_val = &casted_op1->static_value; |
| 2712 | ConstExprValue *op2_val = &casted_op2->static_value; | 2723 | ConstExprValue *op2_val = &casted_op2->static_value; |
| 2713 | if (op1_val->ok && op2_val->ok) { | 2724 | if (op1_val->special != ConstValSpecialRuntime && op2_val->special != ConstValSpecialRuntime) { |
| 2714 | bool type_can_gt_lt_cmp = (resolved_type->id == TypeTableEntryIdNumLitFloat || | 2725 | bool type_can_gt_lt_cmp = (resolved_type->id == TypeTableEntryIdNumLitFloat || |
| 2715 | resolved_type->id == TypeTableEntryIdNumLitInt || | 2726 | resolved_type->id == TypeTableEntryIdNumLitInt || |
| 2716 | resolved_type->id == TypeTableEntryIdFloat || | 2727 | resolved_type->id == TypeTableEntryIdFloat || |
| ... | @@ -2799,7 +2810,7 @@ static int ir_eval_bignum(ConstExprValue *op1_val, ConstExprValue *op2_val, | ... | @@ -2799,7 +2810,7 @@ static int ir_eval_bignum(ConstExprValue *op1_val, ConstExprValue *op2_val, |
| 2799 | } | 2810 | } |
| 2800 | } | 2811 | } |
| 2801 | | 2812 | |
| 2802 | out_val->ok = true; | 2813 | out_val->special = ConstValSpecialStatic; |
| 2803 | out_val->depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var; | 2814 | out_val->depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var; |
| 2804 | return 0; | 2815 | return 0; |
| 2805 | } | 2816 | } |
| ... | @@ -2892,7 +2903,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -2892,7 +2903,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 2892 | return ira->codegen->builtin_types.entry_invalid; | 2903 | return ira->codegen->builtin_types.entry_invalid; |
| 2893 | | 2904 | |
| 2894 | | 2905 | |
| 2895 | if (casted_op1->static_value.ok && casted_op2->static_value.ok) { | 2906 | if (casted_op1->static_value.special != ConstValSpecialRuntime && casted_op2->static_value.special != ConstValSpecialRuntime) { |
| 2896 | ConstExprValue *op1_val = &casted_op1->static_value; | 2907 | ConstExprValue *op1_val = &casted_op1->static_value; |
| 2897 | ConstExprValue *op2_val = &casted_op2->static_value; | 2908 | ConstExprValue *op2_val = &casted_op2->static_value; |
| 2898 | ConstExprValue *out_val = &bin_op_instruction->base.static_value; | 2909 | ConstExprValue *out_val = &bin_op_instruction->base.static_value; |
| ... | @@ -2992,7 +3003,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -2992,7 +3003,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 2992 | break; | 3003 | break; |
| 2993 | case TypeTableEntryIdNumLitFloat: | 3004 | case TypeTableEntryIdNumLitFloat: |
| 2994 | case TypeTableEntryIdNumLitInt: | 3005 | case TypeTableEntryIdNumLitInt: |
| 2995 | if (is_export || is_extern || !casted_init_value->static_value.ok) { | 3006 | if (is_export || is_extern || casted_init_value->static_value.special == ConstValSpecialRuntime) { |
| 2996 | add_node_error(ira->codegen, var_type->source_node, buf_sprintf("unable to infer variable type")); | 3007 | add_node_error(ira->codegen, var_type->source_node, buf_sprintf("unable to infer variable type")); |
| 2997 | result_type = ira->codegen->builtin_types.entry_invalid; | 3008 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 2998 | } | 3009 | } |
| ... | @@ -3006,7 +3017,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -3006,7 +3017,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 3006 | break; | 3017 | break; |
| 3007 | case TypeTableEntryIdMetaType: | 3018 | case TypeTableEntryIdMetaType: |
| 3008 | case TypeTableEntryIdNamespace: | 3019 | case TypeTableEntryIdNamespace: |
| 3009 | if (!casted_init_value->static_value.ok) { | 3020 | if (casted_init_value->static_value.special == ConstValSpecialRuntime) { |
| 3010 | add_node_error(ira->codegen, var_type->source_node, | 3021 | add_node_error(ira->codegen, var_type->source_node, |
| 3011 | buf_sprintf("variable of type '%s' must be constant", buf_ptr(&result_type->name))); | 3022 | buf_sprintf("variable of type '%s' must be constant", buf_ptr(&result_type->name))); |
| 3012 | result_type = ira->codegen->builtin_types.entry_invalid; | 3023 | result_type = ira->codegen->builtin_types.entry_invalid; |
| ... | @@ -3052,7 +3063,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction | ... | @@ -3052,7 +3063,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction |
| 3052 | if (fn_ref->type_entry->id == TypeTableEntryIdInvalid) | 3063 | if (fn_ref->type_entry->id == TypeTableEntryIdInvalid) |
| 3053 | return ira->codegen->builtin_types.entry_invalid; | 3064 | return ira->codegen->builtin_types.entry_invalid; |
| 3054 | | 3065 | |
| 3055 | if (fn_ref->static_value.ok) { | 3066 | if (fn_ref->static_value.special != ConstValSpecialRuntime) { |
| 3056 | if (fn_ref->type_entry->id == TypeTableEntryIdMetaType) { | 3067 | if (fn_ref->type_entry->id == TypeTableEntryIdMetaType) { |
| 3057 | size_t actual_param_count = call_instruction->arg_count; | 3068 | size_t actual_param_count = call_instruction->arg_count; |
| 3058 | | 3069 | |
| ... | @@ -3106,9 +3117,9 @@ static TypeTableEntry *ir_analyze_unary_bool_not(IrAnalyze *ira, IrInstructionUn | ... | @@ -3106,9 +3117,9 @@ static TypeTableEntry *ir_analyze_unary_bool_not(IrAnalyze *ira, IrInstructionUn |
| 3106 | return ira->codegen->builtin_types.entry_invalid; | 3117 | return ira->codegen->builtin_types.entry_invalid; |
| 3107 | | 3118 | |
| 3108 | ConstExprValue *operand_val = &casted_value->static_value; | 3119 | ConstExprValue *operand_val = &casted_value->static_value; |
| 3109 | if (operand_val->ok) { | 3120 | if (operand_val->special != ConstValSpecialRuntime) { |
| 3110 | ConstExprValue *result_val = &un_op_instruction->base.static_value; | 3121 | ConstExprValue *result_val = &un_op_instruction->base.static_value; |
| 3111 | result_val->ok = true; | 3122 | result_val->special = ConstValSpecialStatic; |
| 3112 | result_val->depends_on_compile_var = operand_val->depends_on_compile_var; | 3123 | result_val->depends_on_compile_var = operand_val->depends_on_compile_var; |
| 3113 | result_val->data.x_bool = !operand_val->data.x_bool; | 3124 | result_val->data.x_bool = !operand_val->data.x_bool; |
| 3114 | return bool_type; | 3125 | return bool_type; |
| ... | @@ -3204,7 +3215,7 @@ static TypeTableEntry *ir_analyze_unary_address_of(IrAnalyze *ira, IrInstruction | ... | @@ -3204,7 +3215,7 @@ static TypeTableEntry *ir_analyze_unary_address_of(IrAnalyze *ira, IrInstruction |
| 3204 | { | 3215 | { |
| 3205 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base, | 3216 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base, |
| 3206 | value->static_value.depends_on_compile_var); | 3217 | value->static_value.depends_on_compile_var); |
| 3207 | assert(value->static_value.ok); | 3218 | assert(value->static_value.special != ConstValSpecialRuntime); |
| 3208 | TypeTableEntry *child_type = value->static_value.data.x_type; | 3219 | TypeTableEntry *child_type = value->static_value.data.x_type; |
| 3209 | out_val->data.x_type = get_pointer_to_type(ira->codegen, child_type, is_const); | 3220 | out_val->data.x_type = get_pointer_to_type(ira->codegen, child_type, is_const); |
| 3210 | return ira->codegen->builtin_types.entry_type; | 3221 | return ira->codegen->builtin_types.entry_type; |
| ... | @@ -3252,9 +3263,10 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp | ... | @@ -3252,9 +3263,10 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp |
| 3252 | // this dereference is always an rvalue because in the IR gen we identify lvalue and emit | 3263 | // this dereference is always an rvalue because in the IR gen we identify lvalue and emit |
| 3253 | // one of the ptr instructions | 3264 | // one of the ptr instructions |
| 3254 | | 3265 | |
| 3255 | if (value->static_value.ok) { | 3266 | if (value->static_value.special != ConstValSpecialRuntime) { |
| 3256 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base, false); | 3267 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base, false); |
| 3257 | *out_val = *value->static_value.data.x_ptr.ptr[0]; | 3268 | ConstExprValue *pointee = const_ptr_pointee(&value->static_value); |
| | 3269 | *out_val = *pointee; |
| 3258 | return child_type; | 3270 | return child_type; |
| 3259 | } | 3271 | } |
| 3260 | | 3272 | |
| ... | @@ -3428,7 +3440,7 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct | ... | @@ -3428,7 +3440,7 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct |
| 3428 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); | 3440 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 3429 | | 3441 | |
| 3430 | // TODO detect backward jumps | 3442 | // TODO detect backward jumps |
| 3431 | if (condition->static_value.ok) { | 3443 | if (condition->static_value.special != ConstValSpecialRuntime) { |
| 3432 | IrBasicBlock *old_dest_block = condition->static_value.data.x_bool ? | 3444 | IrBasicBlock *old_dest_block = condition->static_value.data.x_bool ? |
| 3433 | cond_br_instruction->then_block : cond_br_instruction->else_block; | 3445 | cond_br_instruction->then_block : cond_br_instruction->else_block; |
| 3434 | | 3446 | |
| ... | @@ -3463,7 +3475,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP | ... | @@ -3463,7 +3475,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP |
| 3463 | continue; | 3475 | continue; |
| 3464 | IrInstruction *value = phi_instruction->incoming_values[i]->other; | 3476 | IrInstruction *value = phi_instruction->incoming_values[i]->other; |
| 3465 | assert(value->type_entry); | 3477 | assert(value->type_entry); |
| 3466 | if (value->static_value.ok) { | 3478 | if (value->static_value.special != ConstValSpecialRuntime) { |
| 3467 | ConstExprValue *out_val = ir_build_const_from(ira, &phi_instruction->base, | 3479 | ConstExprValue *out_val = ir_build_const_from(ira, &phi_instruction->base, |
| 3468 | value->static_value.depends_on_compile_var); | 3480 | value->static_value.depends_on_compile_var); |
| 3469 | *out_val = value->static_value; | 3481 | *out_val = value->static_value; |
| ... | @@ -3523,17 +3535,16 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -3523,17 +3535,16 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct |
| 3523 | } else if (var->src_is_const) { | 3535 | } else if (var->src_is_const) { |
| 3524 | AstNode *var_decl_node = var->decl_node; | 3536 | AstNode *var_decl_node = var->decl_node; |
| 3525 | assert(var_decl_node->type == NodeTypeVariableDeclaration); | 3537 | assert(var_decl_node->type == NodeTypeVariableDeclaration); |
| 3526 | mem_slot = &get_resolved_expr(var_decl_node->data.variable_declaration.expr)->const_val; | 3538 | mem_slot = &get_resolved_expr(var_decl_node->data.variable_declaration.expr)->instruction->static_value; |
| 3527 | assert(mem_slot->ok); | 3539 | assert(mem_slot->special != ConstValSpecialRuntime); |
| 3528 | } | 3540 | } |
| 3529 | | 3541 | |
| 3530 | if (mem_slot && mem_slot->ok) { | 3542 | if (mem_slot && mem_slot->special != ConstValSpecialRuntime) { |
| 3531 | ConstExprValue *out_val = ir_build_const_from(ira, &var_ptr_instruction->base, | 3543 | ConstExprValue *out_val = ir_build_const_from(ira, &var_ptr_instruction->base, |
| 3532 | mem_slot->depends_on_compile_var); | 3544 | mem_slot->depends_on_compile_var); |
| 3533 | | 3545 | |
| 3534 | out_val->data.x_ptr.len = 1; | 3546 | out_val->data.x_ptr.base_ptr = mem_slot; |
| 3535 | out_val->data.x_ptr.ptr = allocate<ConstExprValue *>(1); | 3547 | out_val->data.x_ptr.index = SIZE_MAX; |
| 3536 | out_val->data.x_ptr.ptr[0] = mem_slot; | | |
| 3537 | return ptr_type; | 3548 | return ptr_type; |
| 3538 | } else { | 3549 | } else { |
| 3539 | ir_build_var_ptr_from(&ira->new_irb, &var_ptr_instruction->base, var); | 3550 | ir_build_var_ptr_from(&ira->new_irb, &var_ptr_instruction->base, var); |
| ... | @@ -3577,7 +3588,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -3577,7 +3588,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3577 | if (casted_elem_index == ira->codegen->invalid_instruction) | 3588 | if (casted_elem_index == ira->codegen->invalid_instruction) |
| 3578 | return ira->codegen->builtin_types.entry_invalid; | 3589 | return ira->codegen->builtin_types.entry_invalid; |
| 3579 | | 3590 | |
| 3580 | if (casted_elem_index->static_value.ok) { | 3591 | if (casted_elem_index->static_value.special != ConstValSpecialRuntime) { |
| 3581 | uint64_t index = casted_elem_index->static_value.data.x_bignum.data.x_uint; | 3592 | uint64_t index = casted_elem_index->static_value.data.x_bignum.data.x_uint; |
| 3582 | if (array_type->id == TypeTableEntryIdArray) { | 3593 | if (array_type->id == TypeTableEntryIdArray) { |
| 3583 | uint64_t array_len = array_type->data.array.len; | 3594 | uint64_t array_len = array_type->data.array.len; |
| ... | @@ -3589,24 +3600,34 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -3589,24 +3600,34 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3589 | } | 3600 | } |
| 3590 | } | 3601 | } |
| 3591 | | 3602 | |
| 3592 | if (array_ptr->static_value.ok) { | 3603 | if (array_ptr->static_value.special != ConstValSpecialRuntime) { |
| 3593 | bool depends_on_compile_var = array_ptr->static_value.depends_on_compile_var || | 3604 | bool depends_on_compile_var = array_ptr->static_value.depends_on_compile_var || |
| 3594 | casted_elem_index->static_value.depends_on_compile_var; | 3605 | casted_elem_index->static_value.depends_on_compile_var; |
| 3595 | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base, depends_on_compile_var); | 3606 | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base, depends_on_compile_var); |
| 3596 | out_val->data.x_ptr.len = 1; | | |
| 3597 | out_val->data.x_ptr.ptr = allocate<ConstExprValue *>(1); | | |
| 3598 | if (array_type->id == TypeTableEntryIdPointer) { | 3607 | if (array_type->id == TypeTableEntryIdPointer) { |
| 3599 | uint64_t pointer_len = array_ptr->static_value.data.x_ptr.len; | 3608 | size_t offset = array_ptr->static_value.data.x_ptr.index; |
| 3600 | if (index >= pointer_len) { | 3609 | size_t new_index; |
| | 3610 | size_t mem_size; |
| | 3611 | size_t old_size; |
| | 3612 | if (offset == SIZE_MAX) { |
| | 3613 | new_index = SIZE_MAX; |
| | 3614 | mem_size = 1; |
| | 3615 | old_size = 1; |
| | 3616 | } else { |
| | 3617 | new_index = offset + index; |
| | 3618 | mem_size = array_ptr->static_value.data.x_ptr.base_ptr->data.x_array.size; |
| | 3619 | old_size = mem_size - offset; |
| | 3620 | } |
| | 3621 | if (new_index >= mem_size) { |
| 3601 | add_node_error(ira->codegen, elem_ptr_instruction->base.source_node, | 3622 | add_node_error(ira->codegen, elem_ptr_instruction->base.source_node, |
| 3602 | buf_sprintf("index %" PRIu64 " outside pointer of size %" PRIu64, | 3623 | buf_sprintf("index %" PRIu64 " outside pointer of size %" PRIu64, index, old_size)); |
| 3603 | index, pointer_len)); | | |
| 3604 | return ira->codegen->builtin_types.entry_invalid; | 3624 | return ira->codegen->builtin_types.entry_invalid; |
| 3605 | } | 3625 | } |
| 3606 | out_val->data.x_ptr.ptr[0] = array_ptr->static_value.data.x_ptr.ptr[index]; | 3626 | out_val->data.x_ptr.base_ptr = array_ptr->static_value.data.x_ptr.base_ptr; |
| | 3627 | out_val->data.x_ptr.index = new_index; |
| 3607 | } else if (is_slice(array_type)) { | 3628 | } else if (is_slice(array_type)) { |
| 3608 | ConstExprValue *ptr_field = array_ptr->static_value.data.x_struct.fields[0]; | 3629 | ConstExprValue *ptr_field = &array_ptr->static_value.data.x_struct.fields[slice_ptr_index]; |
| 3609 | ConstExprValue *len_field = array_ptr->static_value.data.x_struct.fields[1]; | 3630 | ConstExprValue *len_field = &array_ptr->static_value.data.x_struct.fields[slice_len_index]; |
| 3610 | uint64_t slice_len = len_field->data.x_bignum.data.x_uint; | 3631 | uint64_t slice_len = len_field->data.x_bignum.data.x_uint; |
| 3611 | if (index >= slice_len) { | 3632 | if (index >= slice_len) { |
| 3612 | add_node_error(ira->codegen, elem_ptr_instruction->base.source_node, | 3633 | add_node_error(ira->codegen, elem_ptr_instruction->base.source_node, |
| ... | @@ -3614,10 +3635,18 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -3614,10 +3635,18 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3614 | index, slice_len)); | 3635 | index, slice_len)); |
| 3615 | return ira->codegen->builtin_types.entry_invalid; | 3636 | return ira->codegen->builtin_types.entry_invalid; |
| 3616 | } | 3637 | } |
| 3617 | assert(index < ptr_field->data.x_ptr.len); | 3638 | out_val->data.x_ptr.base_ptr = ptr_field->data.x_ptr.base_ptr; |
| 3618 | out_val->data.x_ptr.ptr[0] = ptr_field->data.x_ptr.ptr[index]; | 3639 | size_t offset = ptr_field->data.x_ptr.index; |
| | 3640 | if (offset == SIZE_MAX) { |
| | 3641 | out_val->data.x_ptr.index = SIZE_MAX; |
| | 3642 | } else { |
| | 3643 | uint64_t new_index = offset + index; |
| | 3644 | assert(new_index < ptr_field->data.x_ptr.base_ptr->data.x_array.size); |
| | 3645 | out_val->data.x_ptr.index = new_index; |
| | 3646 | } |
| 3619 | } else if (array_type->id == TypeTableEntryIdArray) { | 3647 | } else if (array_type->id == TypeTableEntryIdArray) { |
| 3620 | out_val->data.x_ptr.ptr[0] = array_ptr->static_value.data.x_array.fields[index]; | 3648 | out_val->data.x_ptr.base_ptr = &array_ptr->static_value; |
| | 3649 | out_val->data.x_ptr.index = index; |
| 3621 | } else { | 3650 | } else { |
| 3622 | zig_unreachable(); | 3651 | zig_unreachable(); |
| 3623 | } | 3652 | } |
| ... | @@ -3790,9 +3819,9 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -3790,9 +3819,9 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc |
| 3790 | return type_entry; | 3819 | return type_entry; |
| 3791 | } else if (type_entry->id == TypeTableEntryIdPointer) { | 3820 | } else if (type_entry->id == TypeTableEntryIdPointer) { |
| 3792 | TypeTableEntry *child_type = type_entry->data.pointer.child_type; | 3821 | TypeTableEntry *child_type = type_entry->data.pointer.child_type; |
| 3793 | if (ptr->static_value.ok) { | 3822 | if (ptr->static_value.special != ConstValSpecialRuntime) { |
| 3794 | ConstExprValue *pointee = ptr->static_value.data.x_ptr.ptr[0]; | 3823 | ConstExprValue *pointee = const_ptr_pointee(&ptr->static_value); |
| 3795 | if (pointee->ok) { | 3824 | if (pointee->special != ConstValSpecialRuntime) { |
| 3796 | ConstExprValue *out_val = ir_build_const_from(ira, &load_ptr_instruction->base, | 3825 | ConstExprValue *out_val = ir_build_const_from(ira, &load_ptr_instruction->base, |
| 3797 | pointee->depends_on_compile_var); | 3826 | pointee->depends_on_compile_var); |
| 3798 | *out_val = *pointee; | 3827 | *out_val = *pointee; |
| ... | @@ -3823,18 +3852,20 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru | ... | @@ -3823,18 +3852,20 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru |
| 3823 | if (casted_value == ira->codegen->invalid_instruction) | 3852 | if (casted_value == ira->codegen->invalid_instruction) |
| 3824 | return ira->codegen->builtin_types.entry_invalid; | 3853 | return ira->codegen->builtin_types.entry_invalid; |
| 3825 | | 3854 | |
| 3826 | if (ptr->static_value.ok && casted_value->static_value.ok) { | 3855 | if (ptr->static_value.special != ConstValSpecialRuntime && |
| 3827 | ConstExprValue *dest_val = ptr->static_value.data.x_ptr.ptr[0]; | 3856 | casted_value->static_value.special != ConstValSpecialRuntime) |
| 3828 | if (dest_val->ok) { | 3857 | { |
| | 3858 | ConstExprValue *dest_val = const_ptr_pointee(&ptr->static_value); |
| | 3859 | if (dest_val->special != ConstValSpecialRuntime) { |
| 3829 | *dest_val = casted_value->static_value; | 3860 | *dest_val = casted_value->static_value; |
| 3830 | return ir_analyze_void(ira, &store_ptr_instruction->base); | 3861 | return ir_analyze_void(ira, &store_ptr_instruction->base); |
| 3831 | } | 3862 | } |
| 3832 | } | 3863 | } |
| 3833 | | 3864 | |
| 3834 | if (ptr->static_value.ok) { | 3865 | if (ptr->static_value.special != ConstValSpecialRuntime) { |
| 3835 | // This memory location is transforming from known at compile time to known at runtime. | 3866 | // This memory location is transforming from known at compile time to known at runtime. |
| 3836 | // We must emit our own var ptr instruction. | 3867 | // We must emit our own var ptr instruction. |
| 3837 | ptr->static_value.ok = false; | 3868 | ptr->static_value.special = ConstValSpecialRuntime; |
| 3838 | IrInstruction *new_ptr_inst; | 3869 | IrInstruction *new_ptr_inst; |
| 3839 | if (ptr->id == IrInstructionIdVarPtr) { | 3870 | if (ptr->id == IrInstructionIdVarPtr) { |
| 3840 | IrInstructionVarPtr *var_ptr_inst = (IrInstructionVarPtr *)ptr; | 3871 | IrInstructionVarPtr *var_ptr_inst = (IrInstructionVarPtr *)ptr; |
| ... | @@ -3842,7 +3873,7 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru | ... | @@ -3842,7 +3873,7 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru |
| 3842 | new_ptr_inst = ir_build_var_ptr(&ira->new_irb, store_ptr_instruction->base.source_node, var); | 3873 | new_ptr_inst = ir_build_var_ptr(&ira->new_irb, store_ptr_instruction->base.source_node, var); |
| 3843 | assert(var->mem_slot_index != SIZE_MAX); | 3874 | assert(var->mem_slot_index != SIZE_MAX); |
| 3844 | ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; | 3875 | ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; |
| 3845 | mem_slot->ok = false; | 3876 | mem_slot->special = ConstValSpecialRuntime; |
| 3846 | } else if (ptr->id == IrInstructionIdFieldPtr) { | 3877 | } else if (ptr->id == IrInstructionIdFieldPtr) { |
| 3847 | zig_panic("TODO"); | 3878 | zig_panic("TODO"); |
| 3848 | } else if (ptr->id == IrInstructionIdElemPtr) { | 3879 | } else if (ptr->id == IrInstructionIdElemPtr) { |
| ... | @@ -4236,7 +4267,7 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -4236,7 +4267,7 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 4236 | | 4267 | |
| 4237 | IrInstructionReturn *ret_inst = (IrInstructionReturn *)only_inst; | 4268 | IrInstructionReturn *ret_inst = (IrInstructionReturn *)only_inst; |
| 4238 | IrInstruction *value = ret_inst->value; | 4269 | IrInstruction *value = ret_inst->value; |
| 4239 | assert(value->static_value.ok); | 4270 | assert(value->static_value.special != ConstValSpecialRuntime); |
| 4240 | return value; | 4271 | return value; |
| 4241 | } | 4272 | } |
| 4242 | | 4273 | |