mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-11 19:24:10 +01:00
1e78cc7a30
git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2364 ebee16cc-31ac-478f-84a7-5cbb03baadba
258 lines
7.3 KiB
C
258 lines
7.3 KiB
C
/*
|
|
# This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
|
|
#
|
|
# This file is part of the PyMite VM.
|
|
# The PyMite VM is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
|
|
#
|
|
# The PyMite VM is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
# A copy of the GNU GENERAL PUBLIC LICENSE Version 2
|
|
# is seen in the file COPYING in this directory.
|
|
*/
|
|
|
|
|
|
#undef __FILE_ID__
|
|
#define __FILE_ID__ 0x05
|
|
|
|
|
|
/**
|
|
* \file
|
|
* \brief VM Globals
|
|
*
|
|
* VM globals operations.
|
|
* PyMite's global struct def and initial values.
|
|
*/
|
|
|
|
|
|
#include "pm.h"
|
|
|
|
|
|
extern unsigned char const *stdlib_img;
|
|
|
|
static uint8_t const *bistr = (uint8_t const *)"__bi";
|
|
|
|
|
|
/** Most PyMite globals all in one convenient place */
|
|
volatile PmVmGlobal_t gVmGlobal;
|
|
|
|
|
|
PmReturn_t
|
|
global_init(void)
|
|
{
|
|
PmReturn_t retval;
|
|
uint8_t *codestr = (uint8_t *)"code";
|
|
uint8_t *pchunk;
|
|
pPmObj_t pobj;
|
|
#ifdef HAVE_CLASSES
|
|
uint8_t const *initstr = (uint8_t const *)"__init__";
|
|
#endif /* HAVE_CLASSES */
|
|
#ifdef HAVE_GENERATORS
|
|
uint8_t const *genstr = (uint8_t const *)"Generator";
|
|
uint8_t const *nextstr = (uint8_t const *)"next";
|
|
#endif /* HAVE_GENERATORS */
|
|
#ifdef HAVE_ASSERT
|
|
uint8_t const *exnstr = (uint8_t const *)"Exception";
|
|
#endif /* HAVE_ASSERT */
|
|
#ifdef HAVE_BYTEARRAY
|
|
uint8_t const *pbastr = (uint8_t const *)"bytearray";
|
|
#endif /* HAVE_BYTEARRAY */
|
|
|
|
/* Clear the global struct */
|
|
sli_memset((uint8_t *)&gVmGlobal, '\0', sizeof(PmVmGlobal_t));
|
|
|
|
/* Set the PyMite release num (for debug and post mortem) */
|
|
gVmGlobal.errVmRelease = PM_RELEASE;
|
|
|
|
/* Init zero */
|
|
retval = heap_getChunk(sizeof(PmInt_t), &pchunk);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
pobj = (pPmObj_t)pchunk;
|
|
OBJ_SET_TYPE(pobj, OBJ_TYPE_INT);
|
|
((pPmInt_t)pobj)->val = (int32_t)0;
|
|
gVmGlobal.pzero = (pPmInt_t)pobj;
|
|
|
|
/* Init one */
|
|
retval = heap_getChunk(sizeof(PmInt_t), &pchunk);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
pobj = (pPmObj_t)pchunk;
|
|
OBJ_SET_TYPE(pobj, OBJ_TYPE_INT);
|
|
((pPmInt_t)pobj)->val = (int32_t)1;
|
|
gVmGlobal.pone = (pPmInt_t)pobj;
|
|
|
|
/* Init negone */
|
|
retval = heap_getChunk(sizeof(PmInt_t), &pchunk);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
pobj = (pPmObj_t)pchunk;
|
|
OBJ_SET_TYPE(pobj, OBJ_TYPE_INT);
|
|
((pPmInt_t)pobj)->val = (int32_t)-1;
|
|
gVmGlobal.pnegone = (pPmInt_t)pobj;
|
|
|
|
/* Init False */
|
|
retval = heap_getChunk(sizeof(PmBoolean_t), &pchunk);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
pobj = (pPmObj_t)pchunk;
|
|
OBJ_SET_TYPE(pobj, OBJ_TYPE_BOOL);
|
|
((pPmBoolean_t) pobj)->val = (int32_t)C_FALSE;
|
|
gVmGlobal.pfalse = (pPmInt_t)pobj;
|
|
|
|
/* Init True */
|
|
retval = heap_getChunk(sizeof(PmBoolean_t), &pchunk);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
pobj = (pPmObj_t)pchunk;
|
|
OBJ_SET_TYPE(pobj, OBJ_TYPE_BOOL);
|
|
((pPmBoolean_t) pobj)->val = (int32_t)C_TRUE;
|
|
gVmGlobal.ptrue = (pPmInt_t)pobj;
|
|
|
|
/* Init None */
|
|
retval = heap_getChunk(sizeof(PmObj_t), &pchunk);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
pobj = (pPmObj_t)pchunk;
|
|
OBJ_SET_TYPE(pobj, OBJ_TYPE_NON);
|
|
gVmGlobal.pnone = pobj;
|
|
|
|
/* Init "code" string obj */
|
|
retval = string_new((uint8_t const **)&codestr, &pobj);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
gVmGlobal.pcodeStr = (pPmString_t)pobj;
|
|
|
|
#ifdef HAVE_CLASSES
|
|
/* Init "__init__" string obj */
|
|
retval = string_new((uint8_t const **)&initstr, &pobj);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
gVmGlobal.pinitStr = (pPmString_t)pobj;
|
|
#endif /* HAVE_CLASSES */
|
|
|
|
#ifdef HAVE_GENERATORS
|
|
/* Init "Generator" string obj */
|
|
retval = string_new((uint8_t const **)&genstr, &pobj);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
gVmGlobal.pgenStr = (pPmString_t)pobj;
|
|
|
|
/* Init "next" string obj */
|
|
retval = string_new((uint8_t const **)&nextstr, &pobj);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
gVmGlobal.pnextStr = (pPmString_t)pobj;
|
|
#endif /* HAVE_GENERATORS */
|
|
|
|
#ifdef HAVE_ASSERT
|
|
/* Init "Exception" string obj */
|
|
retval = string_new((uint8_t const **)&exnstr, &pobj);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
gVmGlobal.pexnStr = (pPmString_t)pobj;
|
|
#endif /* HAVE_ASSERT */
|
|
|
|
#ifdef HAVE_BYTEARRAY
|
|
/* Init "bytearray" string obj */
|
|
retval = string_new((uint8_t const **)&pbastr, &pobj);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
gVmGlobal.pbaStr = (pPmString_t)pobj;
|
|
#endif /* HAVE_BYTEARRAY */
|
|
|
|
/* Init empty builtins */
|
|
gVmGlobal.builtins = C_NULL;
|
|
|
|
/* Init native frame */
|
|
OBJ_SET_SIZE(&gVmGlobal.nativeframe, sizeof(PmNativeFrame_t));
|
|
OBJ_SET_TYPE(&gVmGlobal.nativeframe, OBJ_TYPE_NFM);
|
|
gVmGlobal.nativeframe.nf_func = C_NULL;
|
|
gVmGlobal.nativeframe.nf_stack = C_NULL;
|
|
gVmGlobal.nativeframe.nf_active = C_FALSE;
|
|
gVmGlobal.nativeframe.nf_numlocals = 0;
|
|
|
|
/* Create empty threadList */
|
|
retval = list_new(&pobj);
|
|
gVmGlobal.threadList = (pPmList_t)pobj;
|
|
|
|
/* Init the PmImgPaths with std image info */
|
|
gVmGlobal.imgPaths.memspace[0] = MEMSPACE_PROG;
|
|
gVmGlobal.imgPaths.pimg[0] = (uint8_t *)&stdlib_img;
|
|
gVmGlobal.imgPaths.pathcount = 1;
|
|
|
|
#ifdef HAVE_PRINT
|
|
gVmGlobal.needSoftSpace = C_FALSE;
|
|
gVmGlobal.somethingPrinted = C_FALSE;
|
|
#endif /* HAVE_PRINT */
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
PmReturn_t
|
|
global_setBuiltins(pPmFunc_t pmod)
|
|
{
|
|
PmReturn_t retval = PM_RET_OK;
|
|
pPmObj_t pkey = C_NULL;
|
|
uint8_t const *pbistr = bistr;
|
|
uint8_t objid;
|
|
|
|
if (PM_PBUILTINS == C_NULL)
|
|
{
|
|
/* Need to load builtins first */
|
|
global_loadBuiltins();
|
|
}
|
|
|
|
/* Put builtins module in the module's attrs dict */
|
|
retval = string_new(&pbistr, &pkey);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
|
|
heap_gcPushTempRoot(pkey, &objid);
|
|
retval = dict_setItem((pPmObj_t)pmod->f_attrs, pkey, PM_PBUILTINS);
|
|
heap_gcPopTempRoot(objid);
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
PmReturn_t
|
|
global_loadBuiltins(void)
|
|
{
|
|
PmReturn_t retval = PM_RET_OK;
|
|
pPmObj_t pkey = C_NULL;
|
|
uint8_t const *nonestr = (uint8_t const *)"None";
|
|
uint8_t const *falsestr = (uint8_t const *)"False";
|
|
uint8_t const *truestr = (uint8_t const *)"True";
|
|
pPmObj_t pstr = C_NULL;
|
|
pPmObj_t pbimod;
|
|
uint8_t const *pbistr = bistr;
|
|
|
|
/* Import the builtins */
|
|
retval = string_new(&pbistr, &pstr);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
retval = mod_import(pstr, &pbimod);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
|
|
/* Must interpret builtins' root code to set the attrs */
|
|
C_ASSERT(gVmGlobal.threadList->length == 0);
|
|
interp_addThread((pPmFunc_t)pbimod);
|
|
retval = interpret(INTERP_RETURN_ON_NO_THREADS);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
|
|
/* Builtins points to the builtins module's attrs dict */
|
|
gVmGlobal.builtins = ((pPmFunc_t)pbimod)->f_attrs;
|
|
|
|
/* Set None manually */
|
|
retval = string_new(&nonestr, &pkey);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
retval = dict_setItem(PM_PBUILTINS, pkey, PM_NONE);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
|
|
/* Set False manually */
|
|
retval = string_new(&falsestr, &pkey);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
retval = dict_setItem(PM_PBUILTINS, pkey, PM_FALSE);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
|
|
/* Set True manually */
|
|
retval = string_new(&truestr, &pkey);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
retval = dict_setItem(PM_PBUILTINS, pkey, PM_TRUE);
|
|
PM_RETURN_IF_ERROR(retval);
|
|
|
|
/* Deallocate builtins module */
|
|
retval = heap_freeChunk((pPmObj_t)pbimod);
|
|
|
|
return retval;
|
|
}
|