/usr/include/falcon/vmcontext.h is in falconpl-dev 0.9.6.9-git20120606-2.1+b1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | /*
FALCON - The Falcon Programming Language.
FILE: flc_vmcontext.h
Virtual Machine coroutine execution context.
-------------------------------------------------------------------
Author: Giancarlo Niccolai
Begin: mar nov 9 2004
-------------------------------------------------------------------
(C) Copyright 2004: the FALCON developers (see list in AUTHORS file)
See LICENSE file for licensing details.
*/
/** \file
Virtual Machine coroutine execution context.
*/
#ifndef flc_vmcontext_H
#define flc_vmcontext_H
#include <falcon/setup.h>
#include <falcon/types.h>
#include <falcon/genericvector.h>
#include <falcon/genericlist.h>
#include <falcon/basealloc.h>
#include <falcon/livemodule.h>
#include <falcon/stackframe.h>
namespace Falcon {
class Symbol;
class Item;
class VMSemaphore;
/** Class representing a coroutine execution context. */
class FALCON_DYN_CLASS VMContext: public BaseAlloc
{
Item m_regA;
Item m_regB;
//Item m_regS1;
Item m_regL1;
Item m_regL2;
Item m_regBind;
Item m_regBindP;
VMSemaphore *m_sleepingOn;
/** Currently executed symbol.
May be 0 if the startmodule has not a "__main__" symbol;
this should be impossible when things are set up properly.
*/
const Symbol* m_symbol;
/** Module that contains the currently being executed symbol. */
LiveModule *m_lmodule;
/** Point in time when this context is due to run again.
(this is an absolute measure).
*/
numeric m_schedule;
int32 m_priority;
/** Program counter register.
Current execution point in current code.
*/
uint32 m_pc;
/** Next program counter register.
This is the next instruction the VM has to execute.
Call returns and jumps can easily modify the VM execution flow by
changing this value, that is normally set just to m_pc + the length
of the current instruction.
*/
uint32 m_pc_next;
/** Topmost try frame handler.
Inside a frame, the m_prevTryFrame points to the previous try frame, and
m_tryPos points to the position in the stack of the current frame where
the try try is to be restored.
*/
StackFrame* m_tryFrame;
/** In atomic mode, the VM refuses to be kindly interrupted or to rotate contexts. */
bool m_atomicMode;
friend class VMSemaphore;
/** Stack of stack frames.
* The topmost stack frame is that indicated here.
*/
StackFrame *m_frames;
StackFrame *m_spareFrames;
public:
VMContext();
VMContext( const VMContext& other );
~VMContext();
/** Wakes up the context after a wait. */
void wakeup( bool signaled = false );
void priority( int32 value ) { m_priority = value; }
int32 priority() const { return m_priority; }
void schedule( numeric value ) { m_schedule = value; }
numeric schedule() const { return m_schedule; }
/** Schedule this context after some time from now.
This function add the current system time to secs and
prepares this context to be scheduled after that absolute
time.
@param secs Number of seconds and fraction after current time.
*/
void scheduleAfter( numeric secs );
/** Return true if this is waiting forever on a semaphore signal */
bool isWaitingForever() const { return m_sleepingOn != 0 && m_schedule < 0; }
VMSemaphore* waitingOn() const { return m_sleepingOn; }
void waitOn( VMSemaphore* sem, numeric value=-1 );
void signaled();
//===========================
uint32& pc() { return m_pc; }
const uint32& pc() const { return m_pc; }
uint32& pc_next() { return m_pc_next; }
const uint32& pc_next() const { return m_pc_next; }
StackFrame* tryFrame() const { return m_tryFrame; }
Item ®A() { return m_regA; }
const Item ®A() const { return m_regA; }
Item ®B() { return m_regB; }
const Item ®B() const { return m_regB; }
Item ®Bind() { return m_regBind; }
const Item ®Bind() const { return m_regBind; }
/*
Item ®Bind() { return currentFrame()->m_binding; }
const Item ®Bind() const { return currentFrame()->m_binding; }
*/
Item ®BindP() { return m_regBindP; }
const Item ®BindP() const { return m_regBindP; }
Item &self() { return currentFrame()->m_self; }
const Item &self() const { return currentFrame()->m_self; }
Item &fself() { return currentFrame()->m_fself; }
const Item &fself() const { return currentFrame()->m_fself; }
/** Latch item.
Generated on load property/vector instructions, it stores the accessed object.
*/
const Item &latch() const { return m_regL1; }
/** Latch item.
Generated on load property/vector instructions, it stores the accessed object.
*/
Item &latch() { return m_regL1; }
/** Latcher item.
Generated on load property/vector instructions, it stores the accessor item.
*/
const Item &latcher() const { return m_regL2; }
/** Latcher item.
Generated on load property/vector instructions, it stores the accessor item.
*/
Item &latcher() { return m_regL2; }
//===========================================
const ItemArray& stack() const { return m_frames->stack(); }
ItemArray& stack() { return m_frames->stack(); }
VMSemaphore *sleepingOn() const { return m_sleepingOn; }
void sleepOn( VMSemaphore *sl ) { m_sleepingOn = sl; }
/** Returns the current module global variables vector. */
ItemArray &globals() { return m_lmodule->globals(); }
/** Returns the current module global variables vector (const version). */
const ItemArray &globals() const { return m_lmodule->globals(); }
/** Returns the currently active live module. */
LiveModule *lmodule() const { return m_lmodule; }
/** Changes the currently active live module. */
void lmodule(LiveModule *lm) { m_lmodule = lm; }
/** Returns the currently active symbol. */
const Symbol *symbol() const { return m_symbol; }
/** Changes the currently active symbol. */
void symbol( const Symbol* s ) { m_symbol = s; }
/** Returns the current code. */
byte* code() const {
fassert( symbol()->isFunction() );
return symbol()->getFuncDef()->code();
}
/** The currently active frame in this context */
StackFrame* currentFrame() const
{
return m_frames;
}
void setFrames( StackFrame* newTop )
{
m_frames = newTop;
}
/** Creates a stack frame taking a certain number of parameters.
The stack is created so that it is ready to run the new context;
use addFrame to add it at a later moment, or prepareFrame to create
it and add it immediately.
\param paramCount number of parameters in the stack
\param frameEndFunc Callback function to be executed at frame end
\return The newly created or recycled stack frame.
*/
StackFrame* createFrame( uint32 pcount, ext_func_frame_t frameEndFunc = 0 );
/** Creates a stack frame and adds it immediately to the stack list.
This call is equivalent to addFrame( callFrame( pcount, frameEndFunc) ).
\param paramCount number of parameters in the stack
\param frameEndFunc Callback function to be executed at frame end
\return The newly created or recycled stack frame.
*/
inline StackFrame* prepareFrame( uint32 pcount, ext_func_frame_t frameEndFunc = 0 )
{
StackFrame* frame = createFrame( pcount, frameEndFunc );
addFrame( frame );
return frame;
}
/** Adds a prepared stack frame on top of the frame list.
*
*/
void addFrame( StackFrame* frame );
/** Removes the topmost frame.
* The frame can be deleted or disposed via disposeFrame for further recycling.
* \return The just removed topmost frame or 0 if the frame stack is empty.
*/
StackFrame* popFrame();
void pushTry( uint32 locationPC );
void popTry( bool bMoveTo );
/** Returns from the current stack frame.
Modifies context PC and PCNext, and reutrns true if this is a break context.
*/
bool callReturn();
bool atomicMode() const { return m_atomicMode; }
void atomicMode( bool b ) { m_atomicMode = b; }
/** Adds some space in the local stack for local variables. */
void addLocals( uint32 space )
{
if ( stack().length() < space )
stack().resize( space );
}
/** Returns the nth local item.
The first variable in the local context is numbered 0.
\note Fetched item pointers are valid while the stack doesn't change.
Pushes, addLocal(), item calls and VM operations may alter the
stack. Using this method again after such operations allows to
get a valid pointer to the desired item again. Items extracted with
this method can be also saved locally in an Item instance, at
the cost of a a flat item copy (a few bytes).
\param itemId the number of the local item accessed.
\return a valid pointer to the (dereferenced) local variable or 0 if itemId is invalid.
*/
const Item *local( uint32 itemId ) const
{
return stack()[ itemId ].dereference();
}
/** Returns the nth local item.
This is just the non-const version.
The first variable in the local context is numbered 0.
\param itemId the number of the local item accessed.
\return a valid pointer to the (dereferenced) local variable or 0 if itemId is invalid.
*/
Item *local( uint32 itemId )
{
return stack()[ itemId ].dereference();
}
/** Returns the parameter count for the current function.
\note If the method as not a current frame, you'll have a crash.
\return parameter count for the current function.
*/
int32 paramCount() const {
fassert( m_frames != 0 );
return m_frames->m_param_count;
}
/** Returns the nth paramter passed to the VM.
Const version of param(uint32).
*/
const Item *param( uint32 itemId ) const
{
if ( itemId >= m_frames->m_param_count ) return 0;
return m_frames->m_params[ itemId ].dereference();
}
/** Returns the nth paramter passed to the VM.
This is just the noncost version.
The count is 0 based (0 is the first parameter).
If the parameter exists, a pointer to the Item holding the
parameter will be returned. If the item is a reference,
the referenced item is returned instead (i.e. the parameter
is dereferenced before the return).
The pointer may be modified by the caller, but this will usually
have no effect in the calling program unless the parameter has been
passed by reference.
\note Fetched item pointers are valid while the stack doesn't change.
Pushes, addLocal(), item calls and VM operations may alter the
stack. Using this method again after such operations allows to
get a valid pointer to the desired item. Items extracted with
this method can be also saved locally in an Item instance, at
the cost of a a flat item copy (a few bytes).
\param itemId the number of the parameter accessed, 0 based.
\return a valid pointer to the (dereferenced) parameter or 0 if itemId is invalid.
\see isParamByRef
*/
Item *param( uint32 itemId )
{
if ( itemId >= m_frames->m_param_count ) return 0;
//return &m_frames->prev()->stack()[ m_frames->prev()->stack().length() - m_frames->m_param_count + itemId];
return m_frames->m_params[ itemId ].dereference();
}
/** Returns the nth pre-paramter passed to the VM.
Pre-parameters can be used to pass items to external functions.
They are numbered 0...n in reverse push order, and start at the first
push before the first real parameter.
For example;
\code
Item *p0, *p1, *callable;
...
vm->pushParameter( (int64) 0 ); // pre-parameter 1
vm->pushParameter( vm->self() ); // pre-parameter 0
vm->pushParameter( *p0 );
vm->pushParameter( *p1 );
vm->callFrame( *callable, 2 ); // 2 parameters
\endcode
*/
Item *preParam( uint32 itemId )
{
Item* params = m_frames->m_params;
params -= 1 + itemId;
return params->dereference();
}
/** Const version of preParam */
const Item *preParam( uint32 itemId ) const
{
Item* params = m_frames->m_params;
params -= 1 + itemId;
return params->dereference();
}
/** Returns true if the nth element of the current function has been passed by reference.
\param itemId the number of the parameter accessed, 0 based.
\return true if the parameter exists and has been passed by reference, false otherwise
*/
bool isParamByRef( uint32 itemId ) const
{
if ( itemId >= m_frames->m_param_count ) return 0;
return m_frames->m_params[ itemId ].type() == FLC_ITEM_REFERENCE;
}
/** Installs a post-processing return frame handler.
The function passed as a parmeter will receive a pointer to this VM.
The function <b>MUST</b> return true if it performs another frame item call. This will
tell the VM that the stack cannot be freed now, as a new call stack has been
prepared for immediate execution. When done, the function will be called again.
A frame handler willing to call another frame and not willing to be called anymore
must first unininstall itself by calling this method with parameters set at 0,
and then it <b>MUST return true</b>.
A frame handler not installing a new call frame <b>MUST return false</b>. This will
terminate the current stack frame and cause the VM to complete the return stack.
\param callbackFunct the return frame handler, or 0 to disinstall a previously set handler.
*/
void returnHandler( ext_func_frame_t callbackFunc )
{
currentFrame()->m_endFrameFunc = callbackFunc;
}
ext_func_frame_t returnHandler() const
{
return currentFrame()->m_endFrameFunc;
}
/** Pushes a parameter for the vm callItem and callFrame functions.
\see callItem
\see callFrame
\param item the item to be passes as a parameter to the next call.
*/
void pushParam( const Item &item ) { stack().append(item); }
StackFrame* allocFrame();
void disposeFrame( StackFrame* frame );
void disposeFrames( StackFrame* first, StackFrame* last );
void resetFrames();
void fillErrorTraceback( Error& err );
//! Gets a step in a traceback.
bool getTraceStep( uint32 level, const Symbol* &sym, uint32& line, uint32 &pc );
};
}
#endif
/* end of flc_vmcontext.h */
|