value_locals.h

Go to the documentation of this file.
00001 
00002 #pragma once
00003 
00004 #include "..\kernel\MAXScript_TLS.h"
00005 #include "..\..\assert1.h"
00006 // forward declarations
00007 class Value;
00008 
00009 /* value local macros - for managing C local variable references to Value*'s for the collector - see Collectable.cpp */
00010 
00011 #define one_value_local(n1)                                         \
00012     struct { int count; Value** link; Value* n1; } vl =             \
00013         { 1, NULL, NULL };                                          \
00014     vl.link = thread_local(current_locals_frame);                   \
00015     thread_local(current_locals_frame) = (Value**)&vl;
00016     
00017 #define one_typed_value_local(n1)                                   \
00018     struct { int count; Value** link; n1; } vl =                    \
00019         { 1, NULL, NULL };                                          \
00020     vl.link = thread_local(current_locals_frame);                   \
00021     thread_local(current_locals_frame) = (Value**)&vl;
00022     
00023 #define two_value_locals(n1, n2)                                    \
00024     struct { int count; Value** link; Value *n1, *n2; } vl =        \
00025         { 2, NULL, NULL, NULL };                                    \
00026     vl.link = thread_local(current_locals_frame);                   \
00027     thread_local(current_locals_frame) = (Value**)&vl;
00028     
00029 #define two_typed_value_locals(n1, n2)                              \
00030     struct { int count; Value** link; n1; n2; } vl =                \
00031         { 2, NULL, NULL, NULL };                                    \
00032     vl.link = thread_local(current_locals_frame);                   \
00033     thread_local(current_locals_frame) = (Value**)&vl;
00034     
00035 #define three_value_locals(n1, n2, n3)                              \
00036     struct { int count; Value** link; Value *n1, *n2, *n3; } vl =   \
00037         { 3, NULL, NULL, NULL, NULL };                              \
00038     vl.link = thread_local(current_locals_frame);                   \
00039     thread_local(current_locals_frame) = (Value**)&vl;
00040     
00041 #define three_typed_value_locals(n1, n2, n3)                        \
00042     struct { int count; Value** link; n1; n2; n3; } vl =            \
00043         { 3, NULL, NULL, NULL, NULL };                              \
00044     vl.link = thread_local(current_locals_frame);                   \
00045     thread_local(current_locals_frame) = (Value**)&vl;
00046     
00047 #define four_value_locals(n1, n2, n3, n4)                               \
00048     struct { int count; Value** link; Value *n1, *n2, *n3, *n4; } vl =  \
00049         { 4, NULL, NULL, NULL, NULL, NULL };                            \
00050     vl.link = thread_local(current_locals_frame);                       \
00051     thread_local(current_locals_frame) = (Value**)&vl;
00052     
00053 #define four_typed_value_locals(n1, n2, n3, n4)                     \
00054     struct { int count; Value** link; n1; n2; n3; n4; } vl =        \
00055         { 4, NULL, NULL, NULL, NULL, NULL };                        \
00056     vl.link = thread_local(current_locals_frame);                   \
00057     thread_local(current_locals_frame) = (Value**)&vl;
00058     
00059 #define five_value_locals(n1, n2, n3, n4, n5)                               \
00060     struct { int count; Value** link; Value *n1, *n2, *n3, *n4, *n5; } vl = \
00061         { 5, NULL, NULL, NULL, NULL, NULL, NULL };                          \
00062     vl.link = thread_local(current_locals_frame);                           \
00063     thread_local(current_locals_frame) = (Value**)&vl;
00064     
00065 #define five_typed_value_locals(n1, n2, n3, n4, n5)                         \
00066     struct { int count; Value** link; n1; n2; n3; n4; n5; } vl =            \
00067         { 5, NULL, NULL, NULL, NULL, NULL, NULL };                          \
00068     vl.link = thread_local(current_locals_frame);                           \
00069     thread_local(current_locals_frame) = (Value**)&vl;
00070     
00071 #define six_value_locals(n1, n2, n3, n4, n5, n6)                                 \
00072     struct { int count; Value** link; Value *n1, *n2, *n3, *n4, *n5, *n6; } vl = \
00073         { 6, NULL, NULL, NULL, NULL, NULL, NULL, NULL };                         \
00074     vl.link = thread_local(current_locals_frame);                                \
00075     thread_local(current_locals_frame) = (Value**)&vl;
00076     
00077 #define six_typed_value_locals(n1, n2, n3, n4, n5, n6)                      \
00078     struct { int count; Value** link; n1; n2; n3; n4; n5; n6; } vl =        \
00079         { 6, NULL, NULL, NULL, NULL, NULL, NULL, NULL };                    \
00080     vl.link = thread_local(current_locals_frame);                           \
00081     thread_local(current_locals_frame) = (Value**)&vl;
00082     
00083 #define seven_value_locals(n1, n2, n3, n4, n5, n6, n7)                                \
00084     struct { int count; Value** link; Value *n1, *n2, *n3, *n4, *n5, *n6, *n7; } vl = \
00085         { 7, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };                        \
00086     vl.link = thread_local(current_locals_frame);                                     \
00087     thread_local(current_locals_frame) = (Value**)&vl;
00088     
00089 #define seven_typed_value_locals(n1, n2, n3, n4, n5, n6, n7)                \
00090     struct { int count; Value** link; n1; n2; n3; n4; n5; n6; n7; } vl =    \
00091         { 7, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };              \
00092     vl.link = thread_local(current_locals_frame);                           \
00093     thread_local(current_locals_frame) = (Value**)&vl;
00094     
00095 #define eight_value_locals(n1, n2, n3, n4, n5, n6, n7, n8)                                 \
00096     struct { int count; Value** link; Value *n1, *n2, *n3, *n4, *n5, *n6, *n7, *n8; } vl = \
00097         { 8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };                       \
00098     vl.link = thread_local(current_locals_frame);                                          \
00099     thread_local(current_locals_frame) = (Value**)&vl;
00100     
00101 #define eight_typed_value_locals(n1, n2, n3, n4, n5, n6, n7, n8)                \
00102     struct { int count; Value** link; n1; n2; n3; n4; n5; n6; n7; n8; } vl =    \
00103         { 8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };            \
00104     vl.link = thread_local(current_locals_frame);                               \
00105     thread_local(current_locals_frame) = (Value**)&vl;
00106 
00107 // LAM - 6/07/02 - added new defines - no SDK impact    
00108 #define nine_value_locals(n1, n2, n3, n4, n5, n6, n7, n8, n9)                                   \
00109     struct { int count; Value** link; Value *n1, *n2, *n3, *n4, *n5, *n6, *n7, *n8, *n9; } vl = \
00110         { 9, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };                      \
00111     vl.link = thread_local(current_locals_frame);                                               \
00112     thread_local(current_locals_frame) = (Value**)&vl;
00113     
00114 #define nine_typed_value_locals(n1, n2, n3, n4, n5, n6, n7, n8, n9)                 \
00115     struct { int count; Value** link; n1; n2; n3; n4; n5; n6; n7; n8; n9; } vl =    \
00116         { 9, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };          \
00117     vl.link = thread_local(current_locals_frame);                                   \
00118     thread_local(current_locals_frame) = (Value**)&vl;
00119     
00120 #define ten_value_locals(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10)                                   \
00121 struct { int count; Value** link; Value *n1, *n2, *n3, *n4, *n5, *n6, *n7, *n8, *n9, *n10; } vl =   \
00122         { 10, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };                   \
00123         vl.link = thread_local(current_locals_frame);                                               \
00124         thread_local(current_locals_frame) = (Value**)&vl;
00125 
00126 #define ten_typed_value_locals(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10)             \
00127 struct { int count; Value** link; n1; n2; n3; n4; n5; n6; n7; n8; n9; n10; } vl =   \
00128         { 10, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };   \
00129         vl.link = thread_local(current_locals_frame);                               \
00130         thread_local(current_locals_frame) = (Value**)&vl;
00131 
00132 #define eleven_value_locals(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11)                               \
00133 struct { int count; Value** link; Value *n1, *n2, *n3, *n4, *n5, *n6, *n7, *n8, *n9, *n10, *n11; } vl = \
00134         { 11, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };                 \
00135         vl.link = thread_local(current_locals_frame);                                                   \
00136         thread_local(current_locals_frame) = (Value**)&vl;
00137 
00138 #define eleven_typed_value_locals(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11)         \
00139 struct { int count; Value** link; n1; n2; n3; n4; n5; n6; n7; n8; n9; n10; n11; } vl =  \
00140         { 11, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; \
00141         vl.link = thread_local(current_locals_frame);                                   \
00142         thread_local(current_locals_frame) = (Value**)&vl;
00143 
00144 #define value_local_array(var, count) {                             \
00145     var = &((Value**)_alloca(((count) + 2) * sizeof(Value*)))[2];   \
00146     memset(var, 0, (count) * sizeof(Value*));                       \
00147    var[-2] = (Value*)(static_cast<INT_PTR>(count));            \
00148     var[-1] = (Value*)thread_local(current_locals_frame);           \
00149     thread_local(current_locals_frame) = &var[-2]; }
00150 
00151 #define pop_value_local_array(var)                                  \
00152     thread_local(current_locals_frame) = (Value**)var[-1];
00153     
00154 #define value_temp_array(var, count)    {                           \
00155     var = &((Value**)ms_malloc(((count) + 2) * sizeof(Value*)))[2]; \
00156     memset(var, 0, (count) * sizeof(Value*));                       \
00157    var[-2] = (Value*)(static_cast<INT_PTR>(count));            \
00158    var[-1] = (Value*)thread_local(current_locals_frame);       \
00159    thread_local(current_locals_frame) = &var[-2];}
00160 
00161 // SR NOTE64: If your 'count' is the constant zero, then use this version instead otherwise
00162 // you may end up with "warning C4318: passing constant zero as the length to memset"
00163 // ie: value_temp_array(var, 0) should be value_temp_array0(var)
00164 #define value_temp_array0(var)   {                              \
00165    var = &((Value**)ms_malloc(2 * sizeof(Value*)))[2];   \
00166    var[-2] = 0; \
00167     var[-1] = (Value*)thread_local(current_locals_frame);           \
00168     thread_local(current_locals_frame) = &var[-2];}
00169 
00170 // LAM - 6/07/02 - fix for when multiple value_temp_arrays in same frame
00171 #define realloc_value_temp_array(var, count, old_count) {                       \
00172     Value **oldPointer = &var[-2];                                              \
00173     Value **sframe = thread_local(current_locals_frame);                        \
00174     var = &((Value**)ms_realloc(&var[-2], ((count) + 2) * sizeof(Value*)))[2];      \
00175     if ((count) > (old_count))                                                  \
00176         memset(&var[(old_count)], 0, ((count) - (old_count)) * sizeof(Value*)); \
00177    var[-2] = (Value*)(static_cast<INT_PTR>(count));               \
00178     Value **newPointer = &var[-2];                                              \
00179     if (sframe == oldPointer)                                                   \
00180     {   thread_local(current_locals_frame) = newPointer;                        \
00181         DbgAssert( newPointer != (Value**)newPointer[1] );                      \
00182     }                                                                           \
00183     else                                                                        \
00184     {   Value **frame;                                                          \
00185         for (frame = sframe; frame && (Value**)frame[1] != oldPointer && frame != (Value**)frame[1]; frame = (Value**)frame[1]);    \
00186         if (frame) {                                                            \
00187             DbgAssert( frame != (Value**)frame[1] );                            \
00188             frame[1] = (Value*)newPointer;                                      \
00189         }                                                                       \
00190     }                                                                           \
00191     }
00192 
00193 // LAM - 6/07/02 - fix for when multiple value_temp_arrays in same frame
00194 #define pop_value_temp_array(var)   {                           \
00195     Value **oldPointer = &var[-2];                              \
00196 /*  Value **sframe = thread_local(current_locals_frame); */     \
00197     Value **head = (Value**)var[-1];                            \
00198     thread_local(current_locals_frame) = head;                  \
00199     ms_free(oldPointer);                                            \
00200     }
00201     
00202 #define return_value(r) {                                       \
00203     thread_local(current_result) = r;                           \
00204     thread_local(current_locals_frame) = vl.link;               \
00205     return r; }
00206      
00207 #define return_value_no_pop(r) {                                \
00208     thread_local(current_result) = r;                           \
00209     return r; }
00210 
00211 #define return_protected(r) {                                   \
00212     thread_local(current_result) = r;                           \
00213     return r; }
00214 
00215 #define pop_value_locals()                                      \
00216     thread_local(current_locals_frame) = vl.link;
00217 
00218 #define reset_locals_frame()                                    \
00219     thread_local(current_locals_frame) = (Value**)&vl;
00220 
00221 #define reset_locals_array_frame(var)                           \
00222     thread_local(current_locals_frame) = &var[-2]; 
00223 
00224 #define clear_current_frames() {                                \
00225     thread_local(current_locals_frame) = NULL;                  \
00226     thread_local(current_frame) = NULL;}
00227 
00228 #define save_current_frames()                                   \
00229     Value** _sclf = thread_local(current_locals_frame);         \
00230     Value** _scsf = thread_local(current_scan_frame);           \
00231     Value** _scf = thread_local(current_frame);
00232     
00233 #define restore_current_frames() {                              \
00234     thread_local(current_locals_frame) = _sclf;                 \
00235     thread_local(current_scan_frame) = _scsf;                   \
00236     thread_local(current_frame) = _scf;}
00237 
00238 #define save_current_source()                                   \
00239     Value* _save_source = thread_local(source_file);            \
00240     MSZipPackage* _save_pkg = thread_local(current_pkg);        \
00241     unsigned int  _save_pos = thread_local(source_pos);         \
00242     unsigned int _save_line = thread_local(source_line);        \
00243     DWORD _save_flags = thread_local(source_flags);
00244 
00245 #define restore_current_source() {                              \
00246     thread_local(source_file) = _save_source;                   \
00247     thread_local(current_pkg) = _save_pkg;                      \
00248     thread_local(source_pos) = _save_pos;                       \
00249     thread_local(source_line) = _save_line;                     \
00250     thread_local(source_flags) = _save_flags;}
00251 
00252 #define save_current_source_no_pos()                            \
00253     Value* _save_source = thread_local(source_file);            \
00254     MSZipPackage* _save_pkg = thread_local(current_pkg);        \
00255     DWORD _save_flags = thread_local(source_flags);
00256 
00257 #define restore_current_source_no_pos() {                       \
00258     thread_local(source_file) = _save_source;                   \
00259     thread_local(current_pkg) = _save_pkg;                      \
00260     thread_local(source_flags) = _save_flags;}
00261 
00262 #define save_current_source_pos()                               \
00263     unsigned int  _save_pos = thread_local(source_pos);         \
00264     unsigned int _save_line = thread_local(source_line);        \
00265     DWORD _save_flags = thread_local(source_flags);
00266 
00267 #define restore_current_source_pos() {                          \
00268     thread_local(source_pos) = _save_pos;                       \
00269     thread_local(source_line) = _save_line;                     \
00270     thread_local(source_flags) = _save_flags;}
00271 
00272 #define save_current_source_to_frame() {                        \
00273     Value** _frame = thread_local(current_scan_frame);          \
00274     if (_frame) _frame[3] = thread_local(source_file);          \
00275     if (_frame) _frame[4] = (Value*)thread_local(source_pos);   \
00276     if (_frame) _frame[8] = (Value*)thread_local(source_line);  \
00277     if (_frame) _frame[7] = (Value*)static_cast<DWORD_PTR>(thread_local(source_flags));}
00278 
00279 #define save_current_source_to_frame_no_pos() {                 \
00280     Value** _frame = thread_local(current_scan_frame);          \
00281     if (_frame) _frame[3] = thread_local(source_file);          \
00282     if (_frame) _frame[7] = (Value*)static_cast<DWORD_PTR>(thread_local(source_flags));}
00283 
00284 #define save_current_source_to_frame_pos() {                    \
00285     Value** _frame = thread_local(current_scan_frame);          \
00286     if (_frame) _frame[4] = (Value*)thread_local(source_pos);   \
00287     if (_frame) _frame[8] = (Value*)thread_local(source_line);}
00288 
00289 #define save_current_source_to_frame_no_file() {                \
00290     Value** _frame = thread_local(current_scan_frame);          \
00291     if (_frame) _frame[4] = (Value*)thread_local(source_pos);   \
00292     if (_frame) _frame[8] = (Value*)thread_local(source_line);}
00293 
00294 #define push_control(_c)                                        \
00295     Control* _save_cc = thread_local(current_controller);       \
00296     thread_local(current_controller) = _c;
00297 
00298 #define pop_control()                                           \
00299     thread_local(current_controller) = _save_cc;
00300 
00301 // When an exception occurs, mxs stores data regarding source
00302 // code location corresponding to the code generating the error.
00303 // This data is used by the debugger and to display the source code
00304 // in the editor
00305 // Following macro stores this data in the thread local variables
00306 #define save_error_source_data() {                              \
00307     thread_local(err_source_file) = thread_local(source_file);  \
00308     thread_local(err_source_pos) = thread_local(source_pos);    \
00309     thread_local(err_source_line)= thread_local(source_line);   \
00310     thread_local(err_source_flags) = thread_local(source_flags);\
00311     thread_local(err_occurred) = TRUE;}
00312 
00313 // The following macro clears the data associated with errors.
00314 // This macro must be used if a catch "eats" an mxs runtime exception.
00315 // A catch statement "eats" an exception if it does not either
00316 // call show_source_pos() nor rethrow the exception.
00317 #define clear_error_source_data() {                             \
00318     thread_local(err_source_file) = NULL;                       \
00319     thread_local(err_source_pos) = 0;                           \
00320     thread_local(err_source_flags) = 0;                         \
00321     thread_local(err_source_line) = 0;                          \
00322     thread_local(err_occurred) = FALSE;}