blob: f9a372dccee63d8eff9f289ab42f8b7c2fd75793 [file] [log] [blame]
Russ Cox8c195bd2015-02-13 14:40:36 -05001// 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.
4
5package gc
6
7import (
Dave Cheneyca397bb2016-04-08 19:30:41 +10008 "bufio"
Michael Pratta4e31d42016-03-12 14:07:40 -08009 "cmd/compile/internal/ssa"
Matthew Dempsky4b7e36c2016-04-06 21:45:29 -070010 "cmd/internal/bio"
Russ Cox8c195bd2015-02-13 14:40:36 -050011 "cmd/internal/obj"
Russ Cox8c195bd2015-02-13 14:40:36 -050012)
13
Russ Cox8c195bd2015-02-13 14:40:36 -050014const (
Rob Pike24a43e62015-03-05 10:39:23 -080015 UINF = 100
Rob Pike24a43e62015-03-05 10:39:23 -080016 BADWIDTH = -1000000000
17 MaxStackVarSize = 10 * 1024 * 1024
18)
19
Russ Cox8c195bd2015-02-13 14:40:36 -050020type Pkg struct {
David Chase8eec2bb2016-03-11 00:10:52 -050021 Name string // package name, e.g. "sys"
22 Path string // string literal used in import statement, e.g. "runtime/internal/sys"
David Crawshawf1209362016-03-31 10:02:10 -040023 Pathsym *obj.LSym
Russ Coxcdb7d7d2015-03-05 13:57:36 -050024 Prefix string // escaped path for use in symbol table
Marvin Stengere03c7892015-09-08 05:46:31 +020025 Imported bool // export data of this package was parsed
26 Exported bool // import line written in export data
27 Direct bool // imported directly
Russ Coxcdb7d7d2015-03-05 13:57:36 -050028 Safe bool // whether the package is marked as safe
Russ Coxd0b59de2015-03-02 16:21:15 -050029 Syms map[string]*Sym
Russ Cox8c195bd2015-02-13 14:40:36 -050030}
31
Matthew Dempskycca4ddb2016-04-05 12:48:49 -070032// Sym represents an object name. Most commonly, this is a Go identifier naming
33// an object declared within a package, but Syms are also used to name internal
34// synthesized objects.
35//
36// As a special exception, field and method names that are exported use the Sym
37// associated with localpkg instead of the package that declared them. This
38// allows using Sym pointer equality to test for Go identifier uniqueness when
39// handling selector expressions.
Russ Cox8c195bd2015-02-13 14:40:36 -050040type Sym struct {
Robert Griesemer37c29722016-03-01 16:37:20 -080041 Flags SymFlags
Matthew Dempsky071e43a2016-02-26 01:37:28 -080042 Link *Sym
Russ Coxcdb7d7d2015-03-05 13:57:36 -050043 Importdef *Pkg // where imported definition was found
44 Linkname string // link name
45
46 // saved and restored by dcopy
Russ Cox8c195bd2015-02-13 14:40:36 -050047 Pkg *Pkg
Russ Coxcdb7d7d2015-03-05 13:57:36 -050048 Name string // variable name
49 Def *Node // definition: ONAME OTYPE OPACK or OLITERAL
Russ Coxcdb7d7d2015-03-05 13:57:36 -050050 Block int32 // blocknumber to catch redeclaration
51 Lastlineno int32 // last declaration for diagnostic
Robert Griesemer157f0692016-03-10 15:07:08 -080052
53 Label *Label // corresponding label (ephemeral)
54 Origpkg *Pkg // original package for . import
55 Lsym *obj.LSym
56 Fsym *Sym // funcsym
Russ Cox8c195bd2015-02-13 14:40:36 -050057}
58
Russ Cox8c195bd2015-02-13 14:40:36 -050059type Label struct {
Robert Griesemerdef9c0b2016-03-10 20:35:27 -080060 Sym *Sym
61 Def *Node
62 Use []*Node
Russ Coxcdb7d7d2015-03-05 13:57:36 -050063
64 // for use during gen
65 Gotopc *obj.Prog // pointer to unresolved gotos
66 Labelpc *obj.Prog // pointer to code
67 Breakpc *obj.Prog // pointer to code
68 Continpc *obj.Prog // pointer to code
Dave Cheney8712e182015-09-07 11:11:14 +100069
70 Used bool
Russ Cox8c195bd2015-02-13 14:40:36 -050071}
72
Robert Griesemer37c29722016-03-01 16:37:20 -080073type SymFlags uint8
74
Russ Cox8c195bd2015-02-13 14:40:36 -050075const (
Robert Griesemer37c29722016-03-01 16:37:20 -080076 SymExport SymFlags = 1 << iota // to be exported
77 SymPackage
78 SymExported // already written out by export
79 SymUniq
80 SymSiggen
81 SymAsm
82 SymAlgGen
Russ Cox8c195bd2015-02-13 14:40:36 -050083)
84
Robert Griesemercd7d7382015-10-26 14:57:36 -070085// The Class of a variable/function describes the "storage class"
86// of a variable or function. During parsing, storage classes are
87// called declaration contexts.
88type Class uint8
89
Russ Cox8c195bd2015-02-13 14:40:36 -050090const (
Robert Griesemercd7d7382015-10-26 14:57:36 -070091 Pxxx Class = iota
92 PEXTERN // global variable
93 PAUTO // local variables
94 PPARAM // input arguments
95 PPARAMOUT // output results
96 PPARAMREF // closure variable reference
97 PFUNC // global function
Russ Coxcdb7d7d2015-03-05 13:57:36 -050098
99 PDISCARD // discard during parse of duplicate import
100
Robert Griesemercd7d7382015-10-26 14:57:36 -0700101 PHEAP = 1 << 7 // an extra bit to identify an escaped variable
Russ Cox8c195bd2015-02-13 14:40:36 -0500102)
103
Jeremy Jackins6327e8d2015-10-22 09:51:12 +0900104// note this is the runtime representation
105// of the compilers arrays.
106//
107// typedef struct
108// { // must not move anything
109// uchar array[8]; // pointer to data
110// uchar nel[4]; // number of elements
111// uchar cap[4]; // allocated number of elements
112// } Array;
Russ Cox8c195bd2015-02-13 14:40:36 -0500113var Array_array int // runtime offsetof(Array,array) - same for String
114
115var Array_nel int // runtime offsetof(Array,nel) - same for String
116
117var Array_cap int // runtime offsetof(Array,cap)
118
119var sizeof_Array int // runtime sizeof(Array)
120
Jeremy Jackins6327e8d2015-10-22 09:51:12 +0900121// note this is the runtime representation
122// of the compilers strings.
123//
124// typedef struct
125// { // must not move anything
126// uchar array[8]; // pointer to data
127// uchar nel[4]; // number of elements
128// } String;
Russ Cox8c195bd2015-02-13 14:40:36 -0500129var sizeof_String int // runtime sizeof(String)
130
Russ Cox8c195bd2015-02-13 14:40:36 -0500131var pragcgobuf string
132
133var infile string
134
135var outfile string
136
Dave Cheney8f2edf12016-04-08 19:14:03 +1000137var bout *bio.Writer
Russ Cox8c195bd2015-02-13 14:40:36 -0500138
139var nerrors int
140
141var nsavederrors int
142
143var nsyntaxerrors int
144
Josh Bleecher Snyder2b063bd2015-05-14 19:33:31 -0700145var decldepth int32
Russ Cox8c195bd2015-02-13 14:40:36 -0500146
Matthew Dempsky980ab122016-04-13 18:37:18 -0700147var safemode bool
Russ Cox8c195bd2015-02-13 14:40:36 -0500148
Matthew Dempsky980ab122016-04-13 18:37:18 -0700149var nolocalimports bool
Russ Cox8c195bd2015-02-13 14:40:36 -0500150
Russ Cox8c195bd2015-02-13 14:40:36 -0500151var Debug [256]int
152
153var debugstr string
154
155var Debug_checknil int
Russ Cox4224d812015-03-20 00:06:10 -0400156var Debug_typeassert int
Russ Cox8c195bd2015-02-13 14:40:36 -0500157
Russ Cox8c195bd2015-02-13 14:40:36 -0500158var localpkg *Pkg // package being compiled
159
160var importpkg *Pkg // package being imported
161
Michel Lespinasse859b63c2016-03-18 17:21:33 -0700162var itabpkg *Pkg // fake pkg for itab entries
Michel Lespinassef00bbd52016-03-17 06:18:13 -0700163
164var itablinkpkg *Pkg // fake package for runtime itab entries
165
Russ Cox8c195bd2015-02-13 14:40:36 -0500166var Runtimepkg *Pkg // package runtime
167
168var racepkg *Pkg // package runtime/race
169
Ian Lance Taylor0c69f132015-10-21 07:04:10 -0700170var msanpkg *Pkg // package runtime/msan
171
Russ Cox8c195bd2015-02-13 14:40:36 -0500172var typepkg *Pkg // fake package for runtime type info (headers)
173
Russ Cox8c195bd2015-02-13 14:40:36 -0500174var unsafepkg *Pkg // package unsafe
175
176var trackpkg *Pkg // fake package for field tracking
177
Keith Randall60fd32a2016-04-19 08:31:04 -0700178var mappkg *Pkg // fake package for map zero value
179var zerosize int64
180
Marvin Stenger8e7a3ea2015-09-24 23:21:18 +0200181var Tptr EType // either TPTR32 or TPTR64
Russ Cox8c195bd2015-02-13 14:40:36 -0500182
183var myimportpath string
184
Russ Cox8c195bd2015-02-13 14:40:36 -0500185var localimport string
186
187var asmhdr string
188
Marvin Stenger8e7a3ea2015-09-24 23:21:18 +0200189var Simtype [NTYPE]EType
Russ Cox8c195bd2015-02-13 14:40:36 -0500190
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +0000191var (
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +0000192 isforw [NTYPE]bool
193 Isint [NTYPE]bool
194 Isfloat [NTYPE]bool
195 Iscomplex [NTYPE]bool
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +0000196 issimple [NTYPE]bool
197)
Russ Cox8c195bd2015-02-13 14:40:36 -0500198
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +0000199var (
200 okforeq [NTYPE]bool
201 okforadd [NTYPE]bool
202 okforand [NTYPE]bool
203 okfornone [NTYPE]bool
204 okforcmp [NTYPE]bool
205 okforbool [NTYPE]bool
206 okforcap [NTYPE]bool
207 okforlen [NTYPE]bool
208 okforarith [NTYPE]bool
209 okforconst [NTYPE]bool
210)
Russ Cox8c195bd2015-02-13 14:40:36 -0500211
Josh Bleecher Snyder25da5942015-03-01 07:54:01 +0000212var (
213 okfor [OEND][]bool
214 iscmp [OEND]bool
215)
Russ Cox8c195bd2015-02-13 14:40:36 -0500216
217var Minintval [NTYPE]*Mpint
218
219var Maxintval [NTYPE]*Mpint
220
221var minfltval [NTYPE]*Mpflt
222
223var maxfltval [NTYPE]*Mpflt
224
Ian Lance Taylorf444b8a2016-03-09 20:29:21 -0800225var xtop []*Node
Russ Cox8c195bd2015-02-13 14:40:36 -0500226
Robert Griesemer3d3bc882015-08-12 14:29:50 -0700227var exportlist []*Node
Russ Cox8c195bd2015-02-13 14:40:36 -0500228
HÃ¥vard Haugen391cc542015-09-06 22:38:49 +0200229var importlist []*Node // imported functions and methods with inlinable bodies
Russ Cox8c195bd2015-02-13 14:40:36 -0500230
Robert Griesemera2119ac2015-10-05 16:33:53 -0700231var funcsyms []*Node
Russ Cox8c195bd2015-02-13 14:40:36 -0500232
Robert Griesemercd7d7382015-10-26 14:57:36 -0700233var dclcontext Class // PEXTERN/PAUTO
Russ Cox8c195bd2015-02-13 14:40:36 -0500234
235var incannedimport int
236
237var statuniqgen int // name generator for static temps
238
Russ Cox8c195bd2015-02-13 14:40:36 -0500239var iota_ int32
240
Ian Lance Taylorf444b8a2016-03-09 20:29:21 -0800241var lastconst []*Node
Russ Cox8c195bd2015-02-13 14:40:36 -0500242
243var lasttype *Node
244
245var Maxarg int64
246
247var Stksize int64 // stack size for current frame
248
249var stkptrsize int64 // prefix of stack containing pointers
250
HÃ¥vard Haugen25946642015-09-07 22:19:30 +0200251var hasdefer bool // flag that curfn has defer statement
Russ Cox8c195bd2015-02-13 14:40:36 -0500252
253var Curfn *Node
254
255var Widthptr int
256
257var Widthint int
258
259var Widthreg int
260
Russ Cox8c195bd2015-02-13 14:40:36 -0500261var nblank *Node
262
Dave Cheneye4981812015-03-10 09:58:01 +1100263var Funcdepth int32
Russ Cox8c195bd2015-02-13 14:40:36 -0500264
HÃ¥vard Haugendc3540d2015-08-30 23:56:40 +0200265var typecheckok bool
Russ Cox8c195bd2015-02-13 14:40:36 -0500266
Matthew Dempsky980ab122016-04-13 18:37:18 -0700267var compiling_runtime bool
Russ Cox8c195bd2015-02-13 14:40:36 -0500268
269var compiling_wrappers int
270
Matthew Dempsky980ab122016-04-13 18:37:18 -0700271var use_writebarrier bool
Russ Cox8c195bd2015-02-13 14:40:36 -0500272
Matthew Dempsky980ab122016-04-13 18:37:18 -0700273var pure_go bool
Russ Cox8c195bd2015-02-13 14:40:36 -0500274
275var flag_installsuffix string
276
Matthew Dempsky980ab122016-04-13 18:37:18 -0700277var flag_race bool
Russ Cox8c195bd2015-02-13 14:40:36 -0500278
Matthew Dempsky980ab122016-04-13 18:37:18 -0700279var flag_msan bool
Ian Lance Taylor0c69f132015-10-21 07:04:10 -0700280
Matthew Dempsky980ab122016-04-13 18:37:18 -0700281var flag_largemodel bool
Russ Cox8c195bd2015-02-13 14:40:36 -0500282
Ian Lance Taylor9e902f02015-10-20 10:00:07 -0700283// Whether we are adding any sort of code instrumentation, such as
284// when the race detector is enabled.
285var instrumenting bool
286
Russ Cox8c195bd2015-02-13 14:40:36 -0500287var debuglive int
288
289var Ctxt *obj.Link
290
Matthew Dempsky980ab122016-04-13 18:37:18 -0700291var writearchive bool
Russ Cox8c195bd2015-02-13 14:40:36 -0500292
Dave Cheneyca397bb2016-04-08 19:30:41 +1000293var bstdout *bufio.Writer
Russ Cox8c195bd2015-02-13 14:40:36 -0500294
295var Nacl bool
296
Russ Cox8c195bd2015-02-13 14:40:36 -0500297var continpc *obj.Prog
298
299var breakpc *obj.Prog
300
301var Pc *obj.Prog
302
Russ Cox8c195bd2015-02-13 14:40:36 -0500303var nodfp *Node
304
305var Disable_checknil int
306
Jeremy Jackins6327e8d2015-10-22 09:51:12 +0900307// interface to back end
Russ Cox8c195bd2015-02-13 14:40:36 -0500308
309const (
Russ Coxcdb7d7d2015-03-05 13:57:36 -0500310 // Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
311 Pseudo = 1 << 1
312
313 // There's nothing to say about the instruction,
314 // but it's still okay to see.
315 OK = 1 << 2
316
317 // Size of right-side write, or right-side read if no write.
318 SizeB = 1 << 3
319 SizeW = 1 << 4
320 SizeL = 1 << 5
321 SizeQ = 1 << 6
322 SizeF = 1 << 7
323 SizeD = 1 << 8
324
325 // Left side (Prog.from): address taken, read, write.
326 LeftAddr = 1 << 9
327 LeftRead = 1 << 10
328 LeftWrite = 1 << 11
329
330 // Register in middle (Prog.reg); only ever read. (arm, ppc64)
Russ Cox8c195bd2015-02-13 14:40:36 -0500331 RegRead = 1 << 12
332 CanRegRead = 1 << 13
Russ Coxcdb7d7d2015-03-05 13:57:36 -0500333
334 // Right side (Prog.to): address taken, read, write.
Russ Cox8c195bd2015-02-13 14:40:36 -0500335 RightAddr = 1 << 14
336 RightRead = 1 << 15
337 RightWrite = 1 << 16
Russ Coxcdb7d7d2015-03-05 13:57:36 -0500338
339 // Instruction kinds
340 Move = 1 << 17 // straight move
341 Conv = 1 << 18 // size conversion
342 Cjmp = 1 << 19 // conditional jump
343 Break = 1 << 20 // breaks control flow (no fallthrough)
344 Call = 1 << 21 // function call
345 Jump = 1 << 22 // jump
346 Skip = 1 << 23 // data instruction
347
348 // Set, use, or kill of carry bit.
349 // Kill means we never look at the carry bit after this kind of instruction.
David Chase8eec2bb2016-03-11 00:10:52 -0500350 // Originally for understanding ADC, RCR, and so on, but now also
351 // tracks set, use, and kill of the zero and overflow bits as well.
352 // TODO rename to {Set,Use,Kill}Flags
Russ Coxcdb7d7d2015-03-05 13:57:36 -0500353 SetCarry = 1 << 24
354 UseCarry = 1 << 25
355 KillCarry = 1 << 26
356
357 // Special cases for register use. (amd64, 386)
358 ShiftCX = 1 << 27 // possible shift by CX
359 ImulAXDX = 1 << 28 // possible multiply into DX:AX
360
361 // Instruction updates whichever of from/to is type D_OREG. (ppc64)
362 PostInc = 1 << 29
Russ Cox8c195bd2015-02-13 14:40:36 -0500363)
364
365type Arch struct {
Matthew Dempskyc6e11fe2016-04-06 12:01:40 -0700366 LinkArch *obj.LinkArch
367
Russ Coxb115c352015-03-18 17:26:36 -0400368 REGSP int
369 REGCTXT int
370 REGCALLX int // BX
371 REGCALLX2 int // AX
372 REGRETURN int // AX
373 REGMIN int
374 REGMAX int
Dave Cheney888d44d2015-04-09 21:25:48 +1000375 REGZERO int // architectural zero register, if available
Russ Coxb115c352015-03-18 17:26:36 -0400376 FREGMIN int
377 FREGMAX int
378 MAXWIDTH int64
379 ReservedRegs []int
380
Zhongwei Yao74a9bad2016-04-25 11:08:38 +0800381 AddIndex func(*Node, int64, *Node) bool // optional
382 Betypeinit func()
383 Bgen_float func(*Node, bool, int, *obj.Prog) // optional
384 Cgen64 func(*Node, *Node) // only on 32-bit systems
385 Cgenindex func(*Node, *Node, bool) *obj.Prog
386 Cgen_bmul func(Op, *Node, *Node, *Node) bool
387 Cgen_float func(*Node, *Node) // optional
388 Cgen_hmul func(*Node, *Node, *Node)
389 RightShiftWithCarry func(*Node, uint, *Node) // only on systems without RROTC instruction
390 AddSetCarry func(*Node, *Node, *Node) // only on systems when ADD does not update carry flag
391 Cgen_shift func(Op, bool, *Node, *Node, *Node)
392 Clearfat func(*Node)
393 Cmp64 func(*Node, *Node, Op, int, *obj.Prog) // only on 32-bit systems
394 Defframe func(*obj.Prog)
395 Dodiv func(Op, *Node, *Node, *Node)
396 Excise func(*Flow)
397 Expandchecks func(*obj.Prog)
398 Getg func(*Node)
399 Gins func(obj.As, *Node, *Node) *obj.Prog
Russ Coxf8d14fc2015-05-06 12:28:19 -0400400
401 // Ginscmp generates code comparing n1 to n2 and jumping away if op is satisfied.
402 // The returned prog should be Patch'ed with the jump target.
403 // If op is not satisfied, code falls through to the next emitted instruction.
404 // Likely is the branch prediction hint: +1 for likely, -1 for unlikely, 0 for no opinion.
405 //
406 // Ginscmp must be able to handle all kinds of arguments for n1 and n2,
407 // not just simple registers, although it can assume that there are no
Russ Cox6e8bcbb2015-05-15 16:11:25 -0400408 // function calls needed during the evaluation, and on 32-bit systems
409 // the values are guaranteed not to be 64-bit values, so no in-memory
410 // temporaries are necessary.
Marvin Stenger8e7a3ea2015-09-24 23:21:18 +0200411 Ginscmp func(op Op, t *Type, n1, n2 *Node, likely int) *obj.Prog
Russ Coxf8d14fc2015-05-06 12:28:19 -0400412
Josh Bleecher Snyder13cb62c2015-04-08 09:54:15 -0700413 // Ginsboolval inserts instructions to convert the result
414 // of a just-completed comparison to a boolean value.
415 // The first argument is the conditional jump instruction
416 // corresponding to the desired value.
417 // The second argument is the destination.
418 // If not present, Ginsboolval will be emulated with jumps.
Matthew Dempsky0d9258a2016-03-07 18:00:08 -0800419 Ginsboolval func(obj.As, *Node)
Russ Coxf8d14fc2015-05-06 12:28:19 -0400420
Matthew Dempsky0d9258a2016-03-07 18:00:08 -0800421 Ginscon func(obj.As, int64, *Node)
Russ Coxb115c352015-03-18 17:26:36 -0400422 Ginsnop func()
423 Gmove func(*Node, *Node)
424 Igenindex func(*Node, *Node, bool) *obj.Prog
Russ Coxb115c352015-03-18 17:26:36 -0400425 Peep func(*obj.Prog)
426 Proginfo func(*obj.Prog) // fills in Prog.Info
427 Regtyp func(*obj.Addr) bool
428 Sameaddr func(*obj.Addr, *obj.Addr) bool
429 Smallindir func(*obj.Addr, *obj.Addr) bool
430 Stackaddr func(*obj.Addr) bool
Shenghou Mae7dd2882015-04-08 13:34:42 -0400431 Blockcopy func(*Node, *Node, int64, int64, int64)
Matthew Dempsky0d9258a2016-03-07 18:00:08 -0800432 Sudoaddable func(obj.As, *Node, *obj.Addr) bool
Russ Coxb115c352015-03-18 17:26:36 -0400433 Sudoclean func()
434 Excludedregs func() uint64
435 RtoB func(int) uint64
436 FtoB func(int) uint64
437 BtoR func(uint64) int
438 BtoF func(uint64) int
Matthew Dempsky0d9258a2016-03-07 18:00:08 -0800439 Optoas func(Op, *Type) obj.As
Russ Coxb115c352015-03-18 17:26:36 -0400440 Doregbits func(int) uint64
441 Regnames func(*int) []string
Dave Cheney01d005c2015-03-25 09:17:09 +1100442 Use387 bool // should 8g use 387 FP instructions instead of sse2.
Michael Pratta4e31d42016-03-12 14:07:40 -0800443
444 // SSARegToReg maps ssa register numbers to obj register numbers.
445 SSARegToReg []int16
446
447 // SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
448 SSAMarkMoves func(*SSAGenState, *ssa.Block)
449
450 // SSAGenValue emits Prog(s) for the Value.
451 SSAGenValue func(*SSAGenState, *ssa.Value)
452
453 // SSAGenBlock emits end-of-block Progs. SSAGenValue should be called
454 // for all values in the block before SSAGenBlock.
455 SSAGenBlock func(s *SSAGenState, b, next *ssa.Block)
Russ Cox8c195bd2015-02-13 14:40:36 -0500456}
457
458var pcloc int32
459
460var Thearch Arch
461
462var Newproc *Node
463
464var Deferproc *Node
465
466var Deferreturn *Node
467
468var Panicindex *Node
469
470var panicslice *Node
471
David Chase18559e22015-10-28 13:55:46 -0400472var panicdivide *Node
473
Russ Cox8c195bd2015-02-13 14:40:36 -0500474var throwreturn *Node
Keith Randall8c5bfcc2015-09-18 15:11:30 -0700475
476var growslice *Node
477
Keith Randall5ba31942016-01-25 17:06:54 -0800478var writebarrierptr *Node
479var typedmemmove *Node
Keith Randall8c5bfcc2015-09-18 15:11:30 -0700480
481var panicdottype *Node