2009-05-26 12:18:42 -06:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
2009-10-19 20:59:39 -06:00
|
|
|
|
|
|
|
#include "runtime.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
There are two bits of magic:
|
|
|
|
- The signature of the compiler generated function uses two stack frames
|
|
|
|
as arguments (callerpc separates these frames)
|
|
|
|
- size determines how many arguments runtime.closure actually has
|
|
|
|
starting at arg0.
|
|
|
|
|
|
|
|
Example closure with 3 captured variables:
|
|
|
|
func closure(siz int32,
|
|
|
|
fn func(arg0, arg1, arg2 *ptr, callerpc uintptr, xxx) yyy,
|
|
|
|
arg0, arg1, arg2 *ptr) (func(xxx) yyy)
|
|
|
|
|
|
|
|
Code generated:
|
|
|
|
src R0
|
|
|
|
dst R1
|
|
|
|
end R3
|
|
|
|
tmp R4
|
|
|
|
frame = siz+4
|
|
|
|
|
|
|
|
//skip loop for 0 size closures
|
|
|
|
MOVW.W R14,-frame(R13)
|
|
|
|
|
|
|
|
MOVW $vars(PC), R0
|
|
|
|
MOVW $4(SP), R1
|
|
|
|
MOVW $siz(R0), R3
|
|
|
|
loop: MOVW.P 4(R0), R4
|
|
|
|
MOVW.P R4, 4(R1)
|
|
|
|
CMP R0, R3
|
|
|
|
BNE loop
|
|
|
|
|
|
|
|
MOVW 8(PC), R0
|
|
|
|
BL (R0) // 2 words
|
|
|
|
MOVW.P frame(R13),R15
|
|
|
|
fptr: WORD *fn
|
|
|
|
vars: WORD arg0
|
|
|
|
WORD arg1
|
|
|
|
WORD arg2
|
|
|
|
*/
|
|
|
|
|
2011-05-21 22:59:25 -06:00
|
|
|
extern void runtime·cacheflush(byte* start, byte* end);
|
2009-11-12 00:23:11 -07:00
|
|
|
|
2009-10-19 20:59:39 -06:00
|
|
|
#pragma textflag 7
|
|
|
|
void
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·closure(int32 siz, byte *fn, byte *arg0)
|
2009-10-19 20:59:39 -06:00
|
|
|
{
|
|
|
|
byte *p, *q, **ret;
|
|
|
|
uint32 *pc;
|
|
|
|
int32 n;
|
|
|
|
|
|
|
|
if(siz < 0 || siz%4 != 0)
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·throw("bad closure size");
|
2009-10-19 20:59:39 -06:00
|
|
|
|
|
|
|
ret = (byte**)((byte*)&arg0 + siz);
|
|
|
|
|
|
|
|
if(siz > 100) {
|
|
|
|
// TODO(kaib): implement stack growth preamble?
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·throw("closure too big");
|
2009-10-19 20:59:39 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// size of new fn.
|
|
|
|
// must match code laid out below.
|
|
|
|
if (siz > 0)
|
|
|
|
n = 6 * 4 + 7 * 4;
|
|
|
|
else
|
|
|
|
n = 6 * 4;
|
|
|
|
|
|
|
|
// store args aligned after code, so gc can find them.
|
|
|
|
n += siz;
|
|
|
|
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
p = runtime·mal(n);
|
2009-10-19 20:59:39 -06:00
|
|
|
*ret = p;
|
|
|
|
q = p + n - siz;
|
|
|
|
|
|
|
|
pc = (uint32*)p;
|
|
|
|
|
|
|
|
// MOVW.W R14,-frame(R13)
|
|
|
|
*pc++ = 0xe52de000 | (siz + 4);
|
|
|
|
|
|
|
|
if(siz > 0) {
|
2011-07-12 18:30:40 -06:00
|
|
|
runtime·memmove(q, (byte*)&arg0, siz);
|
2009-10-19 20:59:39 -06:00
|
|
|
|
|
|
|
// MOVW $vars(PC), R0
|
|
|
|
*pc = 0xe28f0000 | (int32)(q - (byte*)pc - 8);
|
|
|
|
pc++;
|
|
|
|
|
|
|
|
// MOVW $4(SP), R1
|
|
|
|
*pc++ = 0xe28d1004;
|
|
|
|
|
|
|
|
// MOVW $siz(R0), R3
|
|
|
|
*pc++ = 0xe2803000 | siz;
|
|
|
|
|
|
|
|
// MOVW.P 4(R0), R4
|
|
|
|
*pc++ = 0xe4904004;
|
|
|
|
// MOVW.P R4, 4(R1)
|
|
|
|
*pc++ = 0xe4814004;
|
|
|
|
// CMP R0, R3
|
|
|
|
*pc++ = 0xe1530000;
|
|
|
|
// BNE loop
|
|
|
|
*pc++ = 0x1afffffb;
|
|
|
|
}
|
|
|
|
|
|
|
|
// MOVW fptr(PC), R0
|
|
|
|
*pc = 0xe59f0008 | (int32)((q - 4) -(byte*) pc - 8);
|
|
|
|
pc++;
|
|
|
|
|
|
|
|
// BL (R0)
|
|
|
|
*pc++ = 0xe28fe000;
|
|
|
|
*pc++ = 0xe280f000;
|
|
|
|
|
|
|
|
// MOVW.P frame(R13),R15
|
|
|
|
*pc++ = 0xe49df000 | (siz + 4);
|
|
|
|
|
|
|
|
// WORD *fn
|
|
|
|
*pc++ = (uint32)fn;
|
|
|
|
|
|
|
|
p = (byte*)pc;
|
|
|
|
|
|
|
|
if(p > q)
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·throw("bad math in sys.closure");
|
2009-11-12 00:23:11 -07:00
|
|
|
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·cacheflush(*ret, q+siz);
|
2009-10-19 20:59:39 -06:00
|
|
|
}
|
|
|
|
|