CXXR (C++ R)
ByteCode.hpp
Go to the documentation of this file.
1 /*CXXR $Id: ByteCode.hpp 1348 2013-02-25 17:49:03Z arr $
2  *CXXR
3  *CXXR This file is part of CXXR, a project to refactor the R interpreter
4  *CXXR into C++. It may consist in whole or in part of program code and
5  *CXXR documentation taken from the R project itself, incorporated into
6  *CXXR CXXR (and possibly MODIFIED) under the terms of the GNU General Public
7  *CXXR Licence.
8  *CXXR
9  *CXXR CXXR is Copyright (C) 2008-13 Andrew R. Runnalls, subject to such other
10  *CXXR copyrights and copyright restrictions as may be stated below.
11  *CXXR
12  *CXXR CXXR is not part of the R project, and bugs and other issues should
13  *CXXR not be reported via r-bugs or other R project channels; instead refer
14  *CXXR to the CXXR website.
15  *CXXR */
16 
17 /*
18  * R : A Computer Language for Statistical Data Analysis
19  * Copyright (C) 1995, 1996 Robert Gentleman and Ross Ihaka
20  * Copyright (C) 1999-2006 The R Development Core Team.
21  *
22  * This program is free software; you can redistribute it and/or modify
23  * it under the terms of the GNU General Public License as published by
24  * the Free Software Foundation; either version 2.1 of the License, or
25  * (at your option) any later version.
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  *
32  * You should have received a copy of the GNU General Public License
33  * along with this program; if not, a copy is available at
34  * http://www.r-project.org/Licenses/
35  */
36 
41 #ifndef BYTECODE_HPP
42 #define BYTECODE_HPP
43 
44 #include "CXXR/ConsCell.h"
45 // Just to pick up define of BYTECODE:
46 #include "CXXR/Evaluator.h"
47 #include "CXXR/IntVector.h"
48 #include "CXXR/ListVector.h"
49 #include "CXXR/NodeStack.hpp"
50 
51 extern "C" {
52 #ifdef BYTECODE
53 
54 // In CXXR for the time being:
55 #define NO_THREADED_CODE
56 
57 #if defined(__GNUC__) && ! defined(BC_PROFILING) && (! defined(NO_THREADED_CODE))
58 # define THREADED_CODE
59 #endif
60 
61 #endif
62 
63 #define TOKEN_THREADING
64 }
65 
66 namespace CXXR {
69  class ByteCode : public RObject {
70  public:
79  : RObject(BCODESXP), m_code(code), m_constants(constants)
80  {
81 #ifdef THREADED_CODE
82 #ifndef TOKEN_THREADING
83  thread();
84 #endif
85 #endif
86  }
87 
88  // Interim accessor functions. Try to get rid of these:
89 
93  {
94  return m_code;
95  }
96 
100  {
101  return m_constants;
102  }
103 
109  static void initialize();
110 
116  static void protectAll();
117 
122  static const char* staticTypeName()
123  {
124  return "bytecode";
125  }
126 
134  static void visitRoots(GCNode::const_visitor* v);
135 
136  // Virtual functions of RObject:
138  const char* typeName() const;
139 
140  // Virtual functions of GCNode:
141  void detachReferents();
142  void visitReferents(const_visitor* v) const;
143 
144  // Make this private in due course:
145 #ifdef THREADED_CODE
146 #ifndef TOKEN_THREADING
147 #define ENCODED_BCODE
148 #endif
149 #endif
150 
151 #ifdef ENCODED_BCODE
152  typedef union { void *v; int i; } BCODE;
153 #else
154  typedef int BCODE;
155 #endif
156  private:
157  // Object whose constructor saves, and destructor restores,
158  // the states of s_nodestack and s_loopvar_stack:
159  class Scope {
160  public:
161  Scope()
162  : m_nodestack_scope(ByteCode::s_nodestack),
163  m_loopvar_stack_size(ByteCode::s_loopvar_stack->size())
164  {}
165 
166  ~Scope()
167  {
168  ByteCode::s_loopvar_stack->resize(m_loopvar_stack_size);
169  }
170  private:
171  NodeStack::Scope m_nodestack_scope;
172  size_t m_loopvar_stack_size;
173  };
174 
175  static NodeStack* s_nodestack;
176 
177  // Stack of pointers to the bindings of loop variables, which
178  // CXXR manipulates alongside s_nodestack. (In CR, these
179  // bindings are put directly on s_nodestack, with type coercion.)
180  static std::vector<Frame::Binding*>* s_loopvar_stack;
181 #ifdef THREADED_CODE
182  static void* s_op_address[];
183 #ifndef TOKEN_THREADING
184  static int s_op_arity[];
185 #endif
186 #endif
187 
188  GCEdge<IntVector> m_code;
189  GCEdge<ListVector> m_constants;
190 #ifdef THREADED_CODE
191  std::vector<BCODE> m_threaded_code;
192 #endif
193 
194  // Declared private to ensure that ByteCode objects are
195  // allocated only using 'new':
196  ~ByteCode() {}
197 
198  // Not implemented yet. Declared to prevent
199  // compiler-generated versions:
200  ByteCode(const ByteCode&);
201  ByteCode& operator=(const ByteCode&);
202 
203  // Normally this implements evaluate() by evaluating bcode in
204  // the environment env. However, if called with a null
205  // pointer for bcode, it initialises the opcode despatch
206  // table(s).
207  static RObject* interpret(ByteCode* bcode, Environment* env);
208 
209 #ifdef ENCODED_BCODE
210  // Initialize the m_threaded_code field by creating a threaded
211  // form of the code.
212  void thread();
213 #endif
214 
215  // Helper functions from CR which need to be inside the
216  // ByteCode class in CXXR:
217  static void DO_MATSUBSET(SEXP rho);
218  static void DO_SETVECSUBSET(SEXP rho);
219  static void DO_SETMATSUBSET(SEXP rho);
220  };
221 } // namespace CXXR
222 
223 // Bytecode related stuff from Defn.h. Try to get rid of these in due
224 // course:
225 
226 typedef SEXP R_bcstack_t;
227 
228 #endif /* BYTECODE_HPP */