| 2155 | } |
| 2156 | |
| 2157 | func (ls *LState) Resume(th *LState, fn *LFunction, args ...LValue) (ResumeState, error, []LValue) { |
| 2158 | isstarted := th.isStarted() |
| 2159 | if !isstarted { |
| 2160 | base := 0 |
| 2161 | th.stack.Push(callFrame{ |
| 2162 | Fn: fn, |
| 2163 | Pc: 0, |
| 2164 | Base: base, |
| 2165 | LocalBase: base + 1, |
| 2166 | ReturnBase: base, |
| 2167 | NArgs: 0, |
| 2168 | NRet: MultRet, |
| 2169 | Parent: nil, |
| 2170 | TailCall: 0, |
| 2171 | }) |
| 2172 | } |
| 2173 | |
| 2174 | if ls.G.CurrentThread == th { |
| 2175 | return ResumeError, newApiErrorS(ApiErrorRun, "can not resume a running thread"), nil |
| 2176 | } |
| 2177 | if th.Dead { |
| 2178 | return ResumeError, newApiErrorS(ApiErrorRun, "can not resume a dead thread"), nil |
| 2179 | } |
| 2180 | th.Parent = ls |
| 2181 | ls.G.CurrentThread = th |
| 2182 | if !isstarted { |
| 2183 | cf := th.stack.Last() |
| 2184 | th.currentFrame = cf |
| 2185 | th.SetTop(0) |
| 2186 | for _, arg := range args { |
| 2187 | th.Push(arg) |
| 2188 | } |
| 2189 | cf.NArgs = len(args) |
| 2190 | th.initCallFrame(cf) |
| 2191 | th.Panic = panicWithoutTraceback |
| 2192 | } else { |
| 2193 | for _, arg := range args { |
| 2194 | th.Push(arg) |
| 2195 | } |
| 2196 | } |
| 2197 | top := ls.GetTop() |
| 2198 | threadRun(th) |
| 2199 | haserror := LVIsFalse(ls.Get(top + 1)) |
| 2200 | ret := make([]LValue, 0, ls.GetTop()) |
| 2201 | for idx := top + 2; idx <= ls.GetTop(); idx++ { |
| 2202 | ret = append(ret, ls.Get(idx)) |
| 2203 | } |
| 2204 | if len(ret) == 0 { |
| 2205 | ret = append(ret, LNil) |
| 2206 | } |
| 2207 | ls.SetTop(top) |
| 2208 | |
| 2209 | if haserror { |
| 2210 | return ResumeError, newApiError(ApiErrorRun, ret[0]), nil |
| 2211 | } else if th.stack.IsEmpty() { |
| 2212 | return ResumeOK, nil, ret |
| 2213 | } |
| 2214 | return ResumeYield, nil, ret |