Check-in [d611cc5908]
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

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
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

Changes to codegen/coro.tcl.

72
73
74
75
76
77
78

79
80

81
82
83
84
85
86
87
88
89
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
	$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]
................................................................................

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

................................................................................
# 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






>
|
|
>
|
|







 







|







 







|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
	$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]
................................................................................

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

................................................................................
# 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
...
606
607
608
609
610
611
612

613




614


615
616
617
618
619
620
621
	    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
	#
................................................................................
		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
	#






>
|
>
>
>
>

>







 







>
|
>
>
>
>
|
>
>







583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
...
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
	    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
	#
................................................................................
		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
	#