Check-in [d611cc5908]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Alignment constraints on coroutine intrinsics must be actual integer constants, not just constant expressions of integer type.
Timelines: family | ancestors | descendants | both | notworking | kbk-nre
Files: files | file ages | folders
SHA3-256: d611cc590870ce747748509a66eeb335e89b9d4f2e8971654b7fb2d8c9dad2dd
User & Date: kbk 2018-04-18 23:03:32.873
Context
2018-04-20
02:26
Add NRE test that throws error check-in: fcf84a8631 user: kbk tags: notworking, kbk-nre
2018-04-18
23:03
Alignment constraints on coroutine intrinsics must be actual integer constants, not just constant expressions of integer type. check-in: d611cc5908 user: kbk tags: notworking, kbk-nre
2018-04-17
21:53
Added debugging types for NRE callbacks. check-in: 11236a5639 user: dkf tags: notworking, kbk-nre
Changes
Unified Diff Ignore Whitespace Patch
Changes to codegen/coro.tcl.
72
73
74
75
76
77
78
79

80

81
82
83
84
85
86
87
88
89
	$api Tcl_NRAddCallback $interp ${tcl.coro.runner} ${coro.handle} \
	    [my null char*] [my null char*] [my null char*]
    
	# Transfer the interpreter status into the coroutine promise
	# so that the body of the coroutine can see it.

	set llvm.coro.promise [$m intrinsic coro.promise]
	set promise.addr.raw [my call ${llvm.coro.promise} \

				  [list ${coro.handle} [Const 4 int32] \

				       [Const false bool]] \
				  "promise.addr.raw"]
	set promise.addr [my cast(ptr) ${promise.addr.raw} int32 "promise.addr"]
	my store $result ${promise.addr}

	# Resume the coroutine, and return to the trampoline to await
	# further developments

	set llvm.coro.resume [$m intrinsic coro.resume]







|
>
|
>
|
|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
	$api Tcl_NRAddCallback $interp ${tcl.coro.runner} ${coro.handle} \
	    [my null char*] [my null char*] [my null char*]
    
	# Transfer the interpreter status into the coroutine promise
	# so that the body of the coroutine can see it.

	set llvm.coro.promise [$m intrinsic coro.promise]
	set promise.addr.raw \
	    [my call ${llvm.coro.promise} \
		 [list ${coro.handle} \
		      [Const $::tcl_platform(pointerSize) int32] \
		      [Const false bool]] \
		 "promise.addr.raw"]
	set promise.addr [my cast(ptr) ${promise.addr.raw} int32 "promise.addr"]
	my store $result ${promise.addr}

	# Resume the coroutine, and return to the trampoline to await
	# further developments

	set llvm.coro.resume [$m intrinsic coro.resume]
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

oo::define TclCompiler method returnedFromCoro {rettype callee corohandle} {

    # Retrieve the coroutine promise from the coroutine handle

    set handle [my LoadOrLiteral $corohandle]
    set ptype [my CoroPromiseType $rettype $callee]
    set alignment [$b cast(int) [AlignOf $ptype] "alignment"]
    set paddr_raw [$b call [$m intrinsic coro.promise] \
		       [list $handle $alignment [Const false bool]] \
		       "promise.addr.raw"]
    set paddr [$b cast(ptr) $paddr_raw $ptype "promise.addr"]

    # Retrieve the return code and return value of the called procedure








|







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373

oo::define TclCompiler method returnedFromCoro {rettype callee corohandle} {

    # Retrieve the coroutine promise from the coroutine handle

    set handle [my LoadOrLiteral $corohandle]
    set ptype [my CoroPromiseType $rettype $callee]
    set alignment [Const $::tcl_platform(pointerSize) int32]
    set paddr_raw [$b call [$m intrinsic coro.promise] \
		       [list $handle $alignment [Const false bool]] \
		       "promise.addr.raw"]
    set paddr [$b cast(ptr) $paddr_raw $ptype "promise.addr"]

    # Retrieve the return code and return value of the called procedure

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
# Results:
#	Returns the LLVM value reference to the result of the wrapped function

oo::define Builder method NRReturnToThunk {handle resType} {
    set llvm.coro.promise [$m intrinsic coro.promise]
    set promiseAddrRaw [my call ${llvm.coro.promise} \
			    [list $handle \
				 [my cast(int) [AlignOf [Type STRING]]] \
				 [Const false bool]] "promise.addr.raw"]
    set promiseType named{$resType.promise,int32,$resType}
    set promiseAddr [my cast(ptr) $promiseAddrRaw $promiseType]
    set value [my load [my gep $promiseAddr 0 1] "value"]
    set llvm.coro.destroy [$m intrinsic coro.destroy]
    my call ${llvm.coro.destroy} $handle
    return $value







|







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
# Results:
#	Returns the LLVM value reference to the result of the wrapped function

oo::define Builder method NRReturnToThunk {handle resType} {
    set llvm.coro.promise [$m intrinsic coro.promise]
    set promiseAddrRaw [my call ${llvm.coro.promise} \
			    [list $handle \
				 [Const $::tcl_platform(pointerSize) int32] \
				 [Const false bool]] "promise.addr.raw"]
    set promiseType named{$resType.promise,int32,$resType}
    set promiseAddr [my cast(ptr) $promiseAddrRaw $promiseType]
    set value [my load [my gep $promiseAddr 0 1] "value"]
    set llvm.coro.destroy [$m intrinsic coro.destroy]
    my call ${llvm.coro.destroy} $handle
    return $value
Changes to codegen/stdlib.tcl.
583
584
585
586
587
588
589

590




591

592
593
594
595
596
597
598
	    set memcpy [$m intrinsic memcpy $vt $vt [TypeOf $length]]
	    if {[TypeOf $target] ne $vt} {
		set target [my cast(ptr) $target void]
	    }
	    if {[TypeOf $source] ne $vt} {
		set source [my cast(ptr) $source void]
	    }

	    my Call memcpy $target $source $length \




		    [Const 0] [Const false bool]

	    return
	}

	##### Closure Build:bzero #####
	#
	# Type signature: memoryBlock:[?]* * length:int[?] -> void
	#







>
|
>
>
>
>

>







583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
	    set memcpy [$m intrinsic memcpy $vt $vt [TypeOf $length]]
	    if {[TypeOf $target] ne $vt} {
		set target [my cast(ptr) $target void]
	    }
	    if {[TypeOf $source] ne $vt} {
		set source [my cast(ptr) $source void]
	    }
	    if {[catch {
		my Call memcpy $target $source $length \
		    [Const false bool]
	    }]} {
		# Pre-LLVM7 - alignment must be specified
		my Call memcpy $target $source $length \
		    [Const 0] [Const false bool]
	    }
	    return
	}

	##### Closure Build:bzero #####
	#
	# Type signature: memoryBlock:[?]* * length:int[?] -> void
	#
606
607
608
609
610
611
612

613




614


615
616
617
618
619
620
621
		set alignment $::tcl_platform(wordSize)
	    }
	    set vt [Type void*]
	    set memset [$m intrinsic memset $vt [TypeOf $length]]
	    if {[TypeOf $target] ne $vt} {
		set target [my cast(ptr) $target void]
	    }

	    my Call memset $target [Const 0 int8] $length \




		[Const $alignment] [Const false bool]


	    return
	}

	##### Closure Build:memcmp #####
	#
	# Type signature: a:[?]* * b:[?]* * length:int[?] -> int
	#







>
|
>
>
>
>
|
>
>







612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
		set alignment $::tcl_platform(wordSize)
	    }
	    set vt [Type void*]
	    set memset [$m intrinsic memset $vt [TypeOf $length]]
	    if {[TypeOf $target] ne $vt} {
		set target [my cast(ptr) $target void]
	    }
	    if {[catch {
		my Call memset $target [Const 0 int8] $length \
		    [Const false bool]
	    }]} {
		# Pre-LLVM 7: alignment must be specified
		my Call memset $target [Const 0 int8] $length \
		    [Const $alignment] [Const false bool]
	    }
		
	    return
	}

	##### Closure Build:memcmp #####
	#
	# Type signature: a:[?]* * b:[?]* * length:int[?] -> int
	#