1
// Copyright 2009 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
8
// func closure(siz int32,
9
// fn func(arg0, arg1, arg2 *ptr, callerpc uintptr, xxx) yyy,
10
// arg0, arg1, arg2 *ptr) (func(xxx) yyy)
12
runtime·closure(int32 siz, byte *fn, byte *arg0)
18
if(siz < 0 || siz%8 != 0)
19
runtime·throw("bad closure size");
21
ret = (byte**)((byte*)&arg0 + siz);
24
// TODO(rsc): implement stack growth preamble?
25
runtime·throw("closure too big");
28
// compute size of new fn.
29
// must match code laid out below.
30
n = 7+10+3; // SUBQ MOVQ MOVQ
32
n += 2*siz/8; // MOVSQ MOVSQ...
34
n += 7+3; // MOVQ REP MOVSQ
35
n += 12; // CALL worst case; sometimes only 5
38
// store args aligned after code, so gc can find them.
48
runtime·memmove(q, (byte*)&arg0, siz);
69
for(i=0; i<siz; i+=8) {
75
// MOVQ $(siz/8), CX [32-bit immediate siz/8]
91
if((int32)pcrel == pcrel) {
92
// can use direct call with pc-relative offset
98
// MOVQ $fn, CX [64-bit immediate fn]
120
runtime·throw("bad math in sys.closure");