Annotation of parser3/src/main/execute.C, revision 1.38
1.1 paf 1: /*
1.38 ! paf 2: $Id: execute.C,v 1.37 2001/02/24 14:20:51 paf Exp $
1.1 paf 3: */
4:
1.8 paf 5: #include "pa_array.h"
1.1 paf 6: #include "code.h"
1.11 paf 7: #include "pa_request.h"
1.15 paf 8: #include "pa_vstring.h"
1.22 paf 9: #include "pa_vhash.h"
1.23 paf 10: #include "pa_vunknown.h"
1.34 paf 11: #include "pa_vcframe.h"
12: #include "pa_vmframe.h"
1.38 ! paf 13: #include "pa_vobject.h"
1.1 paf 14:
15: #include <stdio.h>
16:
1.24 paf 17: #define PUSH(value) stack.push(value)
18: #define POP() static_cast<Value *>(stack.pop())
1.32 paf 19: #define POP_NAME() static_cast<Value *>(stack.pop())->as_string()
1.24 paf 20:
1.11 paf 21:
1.1 paf 22: char *opcode_name[]={
1.38 ! paf 23: "STRING", "CODE", "CLASS",
1.1 paf 24: "WITH_ROOT", "WITH_SELF", "WITH_READ", "WITH_WRITE",
25: "CONSTRUCT",
26: "EXPRESSION_EVAL", "MODIFY_EVAL",
1.18 paf 27: "WRITE",
28: "GET_ELEMENT", "GET_ELEMENT__WRITE",
1.1 paf 29: "CREATE_EWPOOL", "REDUCE_EWPOOL",
30: "CREATE_RWPOOL", "REDUCE_RWPOOL",
31: "GET_METHOD_FRAME",
32: "STORE_PARAM",
33: "CALL"
34: };
35:
1.9 paf 36: void dump(int level, const Array& ops) {
1.23 paf 37: if(0){
38: int size=ops.size();
1.27 paf 39: //printf("size=%d\n", size);
1.23 paf 40: for(int i=0; i<size; i++) {
41: Operation op;
42: op.cast=ops.quick_get(i);
43: printf("%8X\n", op.cast);
44: }
45: }
46:
1.9 paf 47: int size=ops.size();
1.27 paf 48: //printf("size=%d\n", size);
1.1 paf 49: for(int i=0; i<size; i++) {
1.23 paf 50: Operation op;
51: op.cast=ops.quick_get(i);
52: printf("%*s%s", level*4, "", opcode_name[op.code]);
1.1 paf 53:
1.23 paf 54: if(op.code==OP_STRING) {
1.19 paf 55: VString *vstring=static_cast<VString *>(ops.quick_get(++i));
56: printf(" \"%s\"", vstring->get_string()->cstr());
1.15 paf 57: }
1.38 ! paf 58: if(op.code==OP_CLASS) {
! 59: VClass *vclass=static_cast<VClass *>(ops.quick_get(++i));
! 60: printf(" \"%s\"", vclass->name()->cstr());
! 61: }
1.1 paf 62: printf("\n");
63:
1.32 paf 64: if(op.code==OP_CODE) {
1.10 paf 65: const Array *local_ops=reinterpret_cast<const Array *>(ops.quick_get(++i));
1.9 paf 66: dump(level+1, *local_ops);
1.1 paf 67: }
68: }
69: }
70:
1.32 paf 71: void Request::execute(const Array& ops) {
1.30 paf 72: if(1) {
1.32 paf 73: puts("source----------------------------");
1.12 paf 74: dump(0, ops);
1.32 paf 75: puts("execution-------------------------");
1.12 paf 76: }
77:
1.11 paf 78: int size=ops.size();
1.27 paf 79: //printf("size=%d\n", size);
1.11 paf 80: for(int i=0; i<size; i++) {
1.23 paf 81: Operation op;
82: op.cast=ops.quick_get(i);
83: printf("%d:%s", stack.top(), opcode_name[op.code]);
1.11 paf 84:
1.23 paf 85: switch(op.code) {
1.32 paf 86: // param in next instruction
87: case OP_STRING:
88: {
89: VString *vstring=static_cast<VString *>(ops.quick_get(++i));
90: printf(" \"%s\"", vstring->get_string()->cstr());
91: PUSH(vstring);
92: break;
93: }
94: case OP_CODE:
95: {
96: const Array *local_ops=reinterpret_cast<const Array *>(ops.quick_get(++i));
1.38 ! paf 97: printf(" (%d)\n", local_ops->size());
! 98: dump(1, *local_ops);
1.32 paf 99: Junction& j=*NEW Junction(pool(),
1.34 paf 100: *self,
1.32 paf 101: 0,
1.34 paf 102: root,rcontext,wcontext,local_ops);
1.32 paf 103:
104: Value *value=NEW VJunction(j);
105: PUSH(value);
106: break;
107: }
1.38 ! paf 108: case OP_CLASS:
! 109: {
! 110: VClass *vclass=static_cast<VClass *>(ops.quick_get(++i));
! 111: PUSH(vclass);
! 112: break;
! 113: }
1.32 paf 114:
115: // OP_WITH
1.37 paf 116: case OP_WITH_SELF:
117: {
118: PUSH(self);
119: break;
120: }
121: case OP_WITH_ROOT:
1.11 paf 122: {
1.37 paf 123: PUSH(root);
1.13 paf 124: break;
1.11 paf 125: }
1.15 paf 126: case OP_WITH_READ:
127: {
1.24 paf 128: PUSH(rcontext);
1.20 paf 129: break;
130: }
1.37 paf 131: case OP_WITH_WRITE:
1.20 paf 132: {
1.37 paf 133: PUSH(wcontext);
1.20 paf 134: break;
135: }
1.37 paf 136:
137: // ...
138: case OP_CONSTRUCT:
1.20 paf 139: {
1.37 paf 140: Value *value=POP();
141: String& name=POP_NAME();
142: Value *ncontext=POP();
143: value->set_name(name);
144: ncontext->put_element(name, value);
1.15 paf 145: break;
146: }
1.37 paf 147: // TODO: OP_EXPRESSION_EVAL, OP_MODIFY_EVAL,
1.18 paf 148: case OP_WRITE:
1.13 paf 149: {
1.24 paf 150: Value *value=POP();
1.14 paf 151: wcontext->write(value);
1.13 paf 152: break;
1.14 paf 153: }
1.13 paf 154:
1.15 paf 155: case OP_GET_ELEMENT:
1.11 paf 156: {
1.17 paf 157: Value *value=get_element();
1.24 paf 158: PUSH(value);
1.17 paf 159: break;
160: }
161:
1.18 paf 162: case OP_GET_ELEMENT__WRITE:
1.17 paf 163: {
164: Value *value=get_element();
165: wcontext->write(value);
166: break;
167: }
168:
1.32 paf 169:
1.17 paf 170: case OP_CREATE_EWPOOL:
171: {
1.24 paf 172: PUSH(wcontext);
1.29 paf 173: wcontext=NEW WWrapper(pool(), 0 /* empty */);
1.17 paf 174: break;
175: }
176: case OP_REDUCE_EWPOOL:
177: {
1.36 paf 178: Value *value=wcontext->result();
1.25 paf 179: wcontext=static_cast<WContext *>(POP());
1.24 paf 180: PUSH(value);
1.13 paf 181: break;
1.15 paf 182: }
1.13 paf 183:
1.26 paf 184: case OP_CREATE_RWPOOL:
185: {
186: Value *ncontext=POP();
187: PUSH(rcontext);
188: rcontext=ncontext;
189: PUSH(wcontext);
1.29 paf 190: wcontext=NEW WWrapper(pool(), ncontext);
1.26 paf 191: break;
192: }
193: case OP_REDUCE_RWPOOL:
194: {
195: String *string=wcontext->get_string();
196: Value *value=NEW VString(string);
197: wcontext=static_cast<WContext *>(POP());
198: rcontext=POP();
199: PUSH(value);
200: break;
201: }
202:
1.37 paf 203: // CALL
1.28 paf 204: case OP_GET_METHOD_FRAME:
205: {
1.32 paf 206: Value *value=POP();
1.28 paf 207: // [self/class?;params;local;code/native_code](name)
1.32 paf 208: Junction *junction=value->get_junction();
1.31 paf 209: if(!junction)
1.28 paf 210: THROW(0,0,
1.32 paf 211: value->name(),
212: "is not a method or a junction (it is '%s'), can not call it",
1.38 ! paf 213: value->type());
1.28 paf 214: //unless(method) method=operators.get_method[...;code/native_code](name)
1.34 paf 215: VMethodFrame *frame=NEW VMethodFrame(pool(), *junction);
1.28 paf 216: PUSH(frame);
217: break;
218: }
219: case OP_STORE_PARAM:
220: {
221: Value *value=POP();
1.34 paf 222: VMethodFrame *frame=static_cast<VMethodFrame *>(stack[0]);
1.28 paf 223: frame->store_param(value);
1.29 paf 224: break;
225: }
226:
227: case OP_CALL:
228: {
229: printf("->\n");
1.34 paf 230: VMethodFrame *frame=static_cast<VMethodFrame *>(POP());
231: frame->fill_unspecified_params();
232: PUSH(self); PUSH(root); PUSH(rcontext); PUSH(wcontext);
1.38 ! paf 233:
! 234: VClass *context_class=wcontext->get_class();
! 235: VClass *called_class=frame->junction.self.get_class();
! 236: // context is some class? [variable already constructed?]
! 237: if(context_class) { // yes
! 238: // is it me or one of my parents?
! 239: if(context_class->is_or_derived_from(*called_class)) // yes
! 240: self=&frame->junction.self; // dynamic call
! 241: else // no
! 242: self=called_class; // static call
! 243: } else { // no, we have constructor call here: $some(^class:method(..))
! 244: self=NEW VObject(pool(), *called_class);
! 245: frame->write(self);
! 246: }
1.29 paf 247: frame->set_self(self);
1.38 ! paf 248:
1.29 paf 249: root=rcontext=wcontext=frame;
1.31 paf 250: execute(frame->junction.method->code);
1.36 paf 251: Value *value=wcontext->result();
1.32 paf 252: wcontext=static_cast<WContext *>(POP()); rcontext=POP(); root=POP(); self=POP();
1.29 paf 253: wcontext->write(value);
254: printf("<-returned");
1.28 paf 255: break;
256: }
257:
1.11 paf 258: default:
1.16 paf 259: printf("\tTODO");
1.11 paf 260: break;
261: }
1.16 paf 262: printf("\n");
1.11 paf 263: }
1.1 paf 264: }
1.17 paf 265:
266: Value *Request::get_element() {
1.32 paf 267: String& name=POP_NAME();
1.24 paf 268: Value *ncontext=POP();
1.32 paf 269: Value *value=ncontext->get_element(name);
1.21 paf 270:
1.32 paf 271: if(value) {
272: Junction *junction=value->get_junction();
1.36 paf 273: if(junction && junction->code) { // is it a code-junction?
1.32 paf 274: // autocalc it
275: printf("ja->\n");
276: PUSH(self); PUSH(root); PUSH(rcontext); PUSH(wcontext);
1.34 paf 277: // almost plain wwrapper about junction wcontext,
278: // BUT intercepts string writes
279: VCodeFrame frame(pool(), *junction->wcontext); wcontext=&frame;
280: self=&junction->self;
1.32 paf 281: root=junction->root;
282: rcontext=junction->rcontext;
283: execute(*junction->code);
1.35 paf 284: // CodeFrame soul:
1.36 paf 285: // string writes were intercepted
286: // returning them as the result of getting code-junction
1.35 paf 287: value=NEW VString(frame.get_string());
1.32 paf 288: wcontext=static_cast<WContext *>(POP()); rcontext=POP(); root=POP(); self=POP();
289: printf("<-ja returned");
290: }
291: } else {
1.23 paf 292: value=NEW VUnknown(pool());
1.25 paf 293: value->set_name(name);
1.22 paf 294: }
1.17 paf 295: return value;
1.34 paf 296: }
E-mail: