{"action":"created","comment":{"url":"https://api.github.com/repos/solson/miri/pulls/comments/66379530","id":66379530,"diff_hunk":"@@ -0,0 +1,214 @@\n+use super::{\n+    CachedMir,\n+    TerminatorTarget,\n+    ConstantId\n+};\n+use interpreter::function::FnEvalContext;\n+use interpreter::global::GlobalEvalContext;\n+use interpreter::frame::{FrameInterpreter, Frame};\n+use error::EvalResult;\n+use rustc::mir::repr as mir;\n+use rustc::ty::subst::{self, Subst};\n+use rustc::hir::def_id::DefId;\n+use rustc::mir::visit::{Visitor, LvalueContext};\n+use syntax::codemap::Span;\n+use std::rc::Rc;\n+\n+pub enum Event {\n+    Constant,\n+    Assignment,\n+    Terminator,\n+    Done,\n+}\n+\n+pub struct Stepper<'fncx, 'a: 'fncx, 'b: 'a + 'mir, 'mir: 'fncx, 'tcx: 'b>{\n+    fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>,\n+    mir: CachedMir<'mir, 'tcx>,\n+    process: fn (&mut Stepper<'fncx, 'a, 'b, 'mir, 'tcx>) -> EvalResult<()>,\n+}\n+\n+impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx> {\n+    pub(super) fn new(fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>) -> Self {\n+        Stepper {\n+            mir: fncx.mir(),\n+            fncx: fncx,\n+            process: Self::dummy,\n+        }\n+    }\n+\n+    fn dummy(&mut self) -> EvalResult<()> { Ok(()) }\n+\n+    fn statement(&mut self) -> EvalResult<()> {\n+        let result = FrameInterpreter {\n+            frame: self.fncx.stack.last_mut().unwrap(),\n+            gecx: self.fncx.gecx,\n+        }.eval_next_assignment();\n+        self.fncx.maybe_report(result)\n+    }\n+\n+    fn terminator(&mut self) -> EvalResult<()> {\n+        // after a terminator we go to a new block\n+        self.fncx.frame_mut().stmt = 0;\n+        let term = {\n+            let block_data = self.mir.basic_block_data(self.fncx.frame().next_block);\n+            let terminator = block_data.terminator();\n+            let result = self.fncx.eval_terminator(terminator);\n+            self.fncx.maybe_report(result)?\n+        };\n+        match term {\n+            TerminatorTarget::Block => {},\n+            TerminatorTarget::Return => {\n+                assert!(self.fncx.frame().constants.is_empty());\n+                self.fncx.pop_stack_frame();\n+                if !self.fncx.stack.is_empty() {\n+                    self.mir = self.fncx.mir();\n+                }\n+            },\n+            TerminatorTarget::Call => {\n+                self.mir = self.fncx.mir();\n+            },\n+        }\n+        Ok(())\n+    }\n+\n+    fn constant(&mut self) -> EvalResult<()> {\n+        let (cid, span, return_ptr, mir) = self.fncx.frame_mut().constants.pop().expect(\"state machine broken\");\n+        let def_id = cid.def_id();\n+        let substs = cid.substs();\n+        self.fncx.push_stack_frame(def_id, span, mir, substs, Some(return_ptr));\n+        self.mir = self.fncx.mir();\n+        Ok(())\n+    }\n+\n+    pub fn step(&mut self) -> EvalResult<Event> {\n+        (self.process)(self)?;\n+\n+        if self.fncx.stack.is_empty() {\n+            // fuse the iterator\n+            self.process = Self::dummy;\n+            return Ok(Event::Done);\n+        }\n+\n+        if !self.fncx.frame().constants.is_empty() {\n+            self.process = Self::constant;\n+            return Ok(Event::Constant);\n+        }\n+\n+        let block = self.fncx.frame().next_block;\n+        let stmt = self.fncx.frame().stmt;\n+        let basic_block = self.mir.basic_block_data(block);\n+\n+        if let Some(ref stmt) = basic_block.statements.get(stmt) {\n+            assert!(self.fncx.frame().constants.is_empty());\n+            ConstantExtractor {\n+                span: stmt.span,\n+                mir: &self.mir,\n+                gecx: self.fncx.gecx,\n+                frame: self.fncx.stack.last_mut().expect(\"stack empty\"),\n+            }.visit_statement(block, stmt);\n+            if self.fncx.frame().constants.is_empty() {\n+                self.process = Self::statement;\n+                return Ok(Event::Assignment);\n+            } else {\n+                self.process = Self::constant;\n+                return Ok(Event::Constant);\n+            }\n+        }\n+\n+        let terminator = basic_block.terminator();\n+        assert!(self.fncx.frame().constants.is_empty());\n+        ConstantExtractor {\n+            span: terminator.span,\n+            mir: &self.mir,\n+            gecx: self.fncx.gecx,\n+            frame: self.fncx.stack.last_mut().expect(\"stack empty\"),\n+        }.visit_terminator(block, terminator);\n+        if self.fncx.frame().constants.is_empty() {\n+            self.process = Self::terminator;\n+            Ok(Event::Terminator)\n+        } else {\n+            self.process = Self::constant;\n+            Ok(Event::Constant)\n+        }\n+    }\n+\n+    /// returns the statement that will be processed next\n+    pub fn stmt(&self) -> &mir::Statement {\n+        &self.fncx.basic_block().statements[self.fncx.frame().stmt]\n+    }\n+\n+    /// returns the terminator of the current block\n+    pub fn term(&self) -> &mir::Terminator {\n+        self.fncx.basic_block().terminator()\n+    }\n+\n+    pub fn block(&self) -> mir::BasicBlock {\n+        self.fncx.frame().next_block\n+    }\n+}\n+\n+struct ConstantExtractor<'a, 'b: 'mir, 'mir: 'a, 'tcx: 'b> {\n+    span: Span,\n+    mir: &'a CachedMir<'mir, 'tcx>,\n+    frame: &'a mut Frame<'mir, 'tcx>,\n+    gecx: &'a mut GlobalEvalContext<'b, 'tcx>,\n+}\n+\n+impl<'a, 'b, 'mir, 'tcx> ConstantExtractor<'a, 'b, 'mir, 'tcx> {\n+    fn static_item(&mut self, def_id: DefId, substs: &'tcx subst::Substs<'tcx>, span: Span) {\n+        let cid = ConstantId::Static {\n+            def_id: def_id,\n+            substs: substs,\n+        };\n+        if self.gecx.statics.contains_key(&cid) {\n+            return;\n+        }\n+        let mir = self.gecx.load_mir(def_id);\n+        let ptr = self.gecx.alloc_ret_ptr(mir.return_ty, substs).expect(\"there's no such thing as an unreachable static\");\n+        self.gecx.statics.insert(cid.clone(), ptr);\n+        self.frame.constants.push((cid, span, ptr, mir));\n+    }\n+}\n+\n+impl<'a, 'b, 'mir, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'mir, 'tcx> {\n+    fn visit_constant(&mut self, constant: &mir::Constant<'tcx>) {\n+        self.super_constant(constant);\n+        match constant.literal {\n+            // already computed by rustc\n+            mir::Literal::Value { .. } => {}\n+            mir::Literal::Item { def_id, substs } => {\n+                let item_ty = self.gecx.tcx.lookup_item_type(def_id).subst(self.gecx.tcx, substs);","path":"src/interpreter/stepper.rs","position":162,"original_position":180,"commit_id":"cbbf58bbaaafb9cdd9cb837bc3570a8b04bc734a","original_commit_id":"068302e0458ad7791acd4d839df0cfa02e3df4e8","user":{"login":"solson","id":26806,"avatar_url":"https://avatars.githubusercontent.com/u/26806?v=3","gravatar_id":"","url":"https://api.github.com/users/solson","html_url":"https://github.com/solson","followers_url":"https://api.github.com/users/solson/followers","following_url":"https://api.github.com/users/solson/following{/other_user}","gists_url":"https://api.github.com/users/solson/gists{/gist_id}","starred_url":"https://api.github.com/users/solson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/solson/subscriptions","organizations_url":"https://api.github.com/users/solson/orgs","repos_url":"https://api.github.com/users/solson/repos","events_url":"https://api.github.com/users/solson/events{/privacy}","received_events_url":"https://api.github.com/users/solson/received_events","type":"User","site_admin":false},"body":"Weird. Can you add `// FIXME: Should probably use self.gecx.monomorphize; currently hits an ICE` so I can find it later?","created_at":"2016-06-09T03:58:23Z","updated_at":"2016-06-09T03:58:23Z","html_url":"https://github.com/solson/miri/pull/18#discussion_r66379530","pull_request_url":"https://api.github.com/repos/solson/miri/pulls/18","_links":{"self":{"href":"https://api.github.com/repos/solson/miri/pulls/comments/66379530"},"html":{"href":"https://github.com/solson/miri/pull/18#discussion_r66379530"},"pull_request":{"href":"https://api.github.com/repos/solson/miri/pulls/18"}}},"pull_request":{"url":"https://api.github.com/repos/solson/miri/pulls/18","id":72215995,"html_url":"https://github.com/solson/miri/pull/18","diff_url":"https://github.com/solson/miri/pull/18.diff","patch_url":"https://github.com/solson/miri/pull/18.patch","issue_url":"https://api.github.com/repos/solson/miri/issues/18","number":18,"state":"open","locked":false,"title":"Hold the state","user":{"login":"oli-obk","id":332036,"avatar_url":"https://avatars.githubusercontent.com/u/332036?v=3","gravatar_id":"","url":"https://api.github.com/users/oli-obk","html_url":"https://github.com/oli-obk","followers_url":"https://api.github.com/users/oli-obk/followers","following_url":"https://api.github.com/users/oli-obk/following{/other_user}","gists_url":"https://api.github.com/users/oli-obk/gists{/gist_id}","starred_url":"https://api.github.com/users/oli-obk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oli-obk/subscriptions","organizations_url":"https://api.github.com/users/oli-obk/orgs","repos_url":"https://api.github.com/users/oli-obk/repos","events_url":"https://api.github.com/users/oli-obk/events{/privacy}","received_events_url":"https://api.github.com/users/oli-obk/received_events","type":"User","site_admin":false},"body":"precursor to #14\r\n\r\nok... iterator style was much easier than anticipated... The current design would require streaming iterators though...\r\n\r\nBasically it returns the statement or the terminator that is going to be interpreted *next*. Then it actually interprets that at the next `step` call and returns the statement after that.","created_at":"2016-06-01T16:57:16Z","updated_at":"2016-06-09T03:58:23Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2da367215aa2731040b659e5409edb8b84817c02","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/solson/miri/pulls/18/commits","review_comments_url":"https://api.github.com/repos/solson/miri/pulls/18/comments","review_comment_url":"https://api.github.com/repos/solson/miri/pulls/comments{/number}","comments_url":"https://api.github.com/repos/solson/miri/issues/18/comments","statuses_url":"https://api.github.com/repos/solson/miri/statuses/cbbf58bbaaafb9cdd9cb837bc3570a8b04bc734a","head":{"label":"oli-obk:hold_the_state","ref":"hold_the_state","sha":"cbbf58bbaaafb9cdd9cb837bc3570a8b04bc734a","user":{"login":"oli-obk","id":332036,"avatar_url":"https://avatars.githubusercontent.com/u/332036?v=3","gravatar_id":"","url":"https://api.github.com/users/oli-obk","html_url":"https://github.com/oli-obk","followers_url":"https://api.github.com/users/oli-obk/followers","following_url":"https://api.github.com/users/oli-obk/following{/other_user}","gists_url":"https://api.github.com/users/oli-obk/gists{/gist_id}","starred_url":"https://api.github.com/users/oli-obk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oli-obk/subscriptions","organizations_url":"https://api.github.com/users/oli-obk/orgs","repos_url":"https://api.github.com/users/oli-obk/repos","events_url":"https://api.github.com/users/oli-obk/events{/privacy}","received_events_url":"https://api.github.com/users/oli-obk/received_events","type":"User","site_admin":false},"repo":{"id":51430710,"name":"miri","full_name":"oli-obk/miri","owner":{"login":"oli-obk","id":332036,"avatar_url":"https://avatars.githubusercontent.com/u/332036?v=3","gravatar_id":"","url":"https://api.github.com/users/oli-obk","html_url":"https://github.com/oli-obk","followers_url":"https://api.github.com/users/oli-obk/followers","following_url":"https://api.github.com/users/oli-obk/following{/other_user}","gists_url":"https://api.github.com/users/oli-obk/gists{/gist_id}","starred_url":"https://api.github.com/users/oli-obk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oli-obk/subscriptions","organizations_url":"https://api.github.com/users/oli-obk/orgs","repos_url":"https://api.github.com/users/oli-obk/repos","events_url":"https://api.github.com/users/oli-obk/events{/privacy}","received_events_url":"https://api.github.com/users/oli-obk/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/oli-obk/miri","description":"An experimental interpreter for Rust MIR","fork":true,"url":"https://api.github.com/repos/oli-obk/miri","forks_url":"https://api.github.com/repos/oli-obk/miri/forks","keys_url":"https://api.github.com/repos/oli-obk/miri/keys{/key_id}","collaborators_url":"https://api.github.com/repos/oli-obk/miri/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/oli-obk/miri/teams","hooks_url":"https://api.github.com/repos/oli-obk/miri/hooks","issue_events_url":"https://api.github.com/repos/oli-obk/miri/issues/events{/number}","events_url":"https://api.github.com/repos/oli-obk/miri/events","assignees_url":"https://api.github.com/repos/oli-obk/miri/assignees{/user}","branches_url":"https://api.github.com/repos/oli-obk/miri/branches{/branch}","tags_url":"https://api.github.com/repos/oli-obk/miri/tags","blobs_url":"https://api.github.com/repos/oli-obk/miri/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/oli-obk/miri/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/oli-obk/miri/git/refs{/sha}","trees_url":"https://api.github.com/repos/oli-obk/miri/git/trees{/sha}","statuses_url":"https://api.github.com/repos/oli-obk/miri/statuses/{sha}","languages_url":"https://api.github.com/repos/oli-obk/miri/languages","stargazers_url":"https://api.github.com/repos/oli-obk/miri/stargazers","contributors_url":"https://api.github.com/repos/oli-obk/miri/contributors","subscribers_url":"https://api.github.com/repos/oli-obk/miri/subscribers","subscription_url":"https://api.github.com/repos/oli-obk/miri/subscription","commits_url":"https://api.github.com/repos/oli-obk/miri/commits{/sha}","git_commits_url":"https://api.github.com/repos/oli-obk/miri/git/commits{/sha}","comments_url":"https://api.github.com/repos/oli-obk/miri/comments{/number}","issue_comment_url":"https://api.github.com/repos/oli-obk/miri/issues/comments{/number}","contents_url":"https://api.github.com/repos/oli-obk/miri/contents/{+path}","compare_url":"https://api.github.com/repos/oli-obk/miri/compare/{base}...{head}","merges_url":"https://api.github.com/repos/oli-obk/miri/merges","archive_url":"https://api.github.com/repos/oli-obk/miri/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/oli-obk/miri/downloads","issues_url":"https://api.github.com/repos/oli-obk/miri/issues{/number}","pulls_url":"https://api.github.com/repos/oli-obk/miri/pulls{/number}","milestones_url":"https://api.github.com/repos/oli-obk/miri/milestones{/number}","notifications_url":"https://api.github.com/repos/oli-obk/miri/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/oli-obk/miri/labels{/name}","releases_url":"https://api.github.com/repos/oli-obk/miri/releases{/id}","deployments_url":"https://api.github.com/repos/oli-obk/miri/deployments","created_at":"2016-02-10T09:10:02Z","updated_at":"2016-02-10T09:10:02Z","pushed_at":"2016-06-08T11:44:23Z","git_url":"git://github.com/oli-obk/miri.git","ssh_url":"git@github.com:oli-obk/miri.git","clone_url":"https://github.com/oli-obk/miri.git","svn_url":"https://github.com/oli-obk/miri","homepage":null,"size":499,"stargazers_count":0,"watchers_count":0,"language":"Rust","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"solson:master","ref":"master","sha":"66a812f3e133400f269f2e2beea2c67c8ba7d181","user":{"login":"solson","id":26806,"avatar_url":"https://avatars.githubusercontent.com/u/26806?v=3","gravatar_id":"","url":"https://api.github.com/users/solson","html_url":"https://github.com/solson","followers_url":"https://api.github.com/users/solson/followers","following_url":"https://api.github.com/users/solson/following{/other_user}","gists_url":"https://api.github.com/users/solson/gists{/gist_id}","starred_url":"https://api.github.com/users/solson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/solson/subscriptions","organizations_url":"https://api.github.com/users/solson/orgs","repos_url":"https://api.github.com/users/solson/repos","events_url":"https://api.github.com/users/solson/events{/privacy}","received_events_url":"https://api.github.com/users/solson/received_events","type":"User","site_admin":false},"repo":{"id":46083140,"name":"miri","full_name":"solson/miri","owner":{"login":"solson","id":26806,"avatar_url":"https://avatars.githubusercontent.com/u/26806?v=3","gravatar_id":"","url":"https://api.github.com/users/solson","html_url":"https://github.com/solson","followers_url":"https://api.github.com/users/solson/followers","following_url":"https://api.github.com/users/solson/following{/other_user}","gists_url":"https://api.github.com/users/solson/gists{/gist_id}","starred_url":"https://api.github.com/users/solson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/solson/subscriptions","organizations_url":"https://api.github.com/users/solson/orgs","repos_url":"https://api.github.com/users/solson/repos","events_url":"https://api.github.com/users/solson/events{/privacy}","received_events_url":"https://api.github.com/users/solson/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/solson/miri","description":"An experimental interpreter for Rust MIR","fork":false,"url":"https://api.github.com/repos/solson/miri","forks_url":"https://api.github.com/repos/solson/miri/forks","keys_url":"https://api.github.com/repos/solson/miri/keys{/key_id}","collaborators_url":"https://api.github.com/repos/solson/miri/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/solson/miri/teams","hooks_url":"https://api.github.com/repos/solson/miri/hooks","issue_events_url":"https://api.github.com/repos/solson/miri/issues/events{/number}","events_url":"https://api.github.com/repos/solson/miri/events","assignees_url":"https://api.github.com/repos/solson/miri/assignees{/user}","branches_url":"https://api.github.com/repos/solson/miri/branches{/branch}","tags_url":"https://api.github.com/repos/solson/miri/tags","blobs_url":"https://api.github.com/repos/solson/miri/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/solson/miri/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/solson/miri/git/refs{/sha}","trees_url":"https://api.github.com/repos/solson/miri/git/trees{/sha}","statuses_url":"https://api.github.com/repos/solson/miri/statuses/{sha}","languages_url":"https://api.github.com/repos/solson/miri/languages","stargazers_url":"https://api.github.com/repos/solson/miri/stargazers","contributors_url":"https://api.github.com/repos/solson/miri/contributors","subscribers_url":"https://api.github.com/repos/solson/miri/subscribers","subscription_url":"https://api.github.com/repos/solson/miri/subscription","commits_url":"https://api.github.com/repos/solson/miri/commits{/sha}","git_commits_url":"https://api.github.com/repos/solson/miri/git/commits{/sha}","comments_url":"https://api.github.com/repos/solson/miri/comments{/number}","issue_comment_url":"https://api.github.com/repos/solson/miri/issues/comments{/number}","contents_url":"https://api.github.com/repos/solson/miri/contents/{+path}","compare_url":"https://api.github.com/repos/solson/miri/compare/{base}...{head}","merges_url":"https://api.github.com/repos/solson/miri/merges","archive_url":"https://api.github.com/repos/solson/miri/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/solson/miri/downloads","issues_url":"https://api.github.com/repos/solson/miri/issues{/number}","pulls_url":"https://api.github.com/repos/solson/miri/pulls{/number}","milestones_url":"https://api.github.com/repos/solson/miri/milestones{/number}","notifications_url":"https://api.github.com/repos/solson/miri/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/solson/miri/labels{/name}","releases_url":"https://api.github.com/repos/solson/miri/releases{/id}","deployments_url":"https://api.github.com/repos/solson/miri/deployments","created_at":"2015-11-12T21:51:25Z","updated_at":"2016-06-08T02:58:48Z","pushed_at":"2016-06-08T10:47:32Z","git_url":"git://github.com/solson/miri.git","ssh_url":"git@github.com:solson/miri.git","clone_url":"https://github.com/solson/miri.git","svn_url":"https://github.com/solson/miri","homepage":null,"size":450,"stargazers_count":68,"watchers_count":68,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":12,"mirror_url":null,"open_issues_count":5,"forks":12,"open_issues":5,"watchers":68,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/solson/miri/pulls/18"},"html":{"href":"https://github.com/solson/miri/pull/18"},"issue":{"href":"https://api.github.com/repos/solson/miri/issues/18"},"comments":{"href":"https://api.github.com/repos/solson/miri/issues/18/comments"},"review_comments":{"href":"https://api.github.com/repos/solson/miri/pulls/18/comments"},"review_comment":{"href":"https://api.github.com/repos/solson/miri/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/solson/miri/pulls/18/commits"},"statuses":{"href":"https://api.github.com/repos/solson/miri/statuses/cbbf58bbaaafb9cdd9cb837bc3570a8b04bc734a"}}}}
{"actor":{"display_login":"solson"}}