Annotation of parser3/src/main/execute.C, revision 1.40
1.1 paf 1: /*
1.40 ! paf 2: $Id: execute.C,v 1.39 2001/02/25 08:50:14 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));
1.39 paf 111: printf(" \"%s\"", vclass->name()->cstr());
1.38 paf 112: PUSH(vclass);
113: break;
114: }
1.32 paf 115:
116: // OP_WITH
1.37 paf 117: case OP_WITH_SELF:
118: {
119: PUSH(self);
120: break;
121: }
122: case OP_WITH_ROOT:
1.11 paf 123: {
1.37 paf 124: PUSH(root);
1.13 paf 125: break;
1.11 paf 126: }
1.15 paf 127: case OP_WITH_READ:
128: {
1.24 paf 129: PUSH(rcontext);
1.20 paf 130: break;
131: }
1.37 paf 132: case OP_WITH_WRITE:
1.20 paf 133: {
1.37 paf 134: PUSH(wcontext);
1.20 paf 135: break;
136: }
1.37 paf 137:
138: // ...
139: case OP_CONSTRUCT:
1.20 paf 140: {
1.37 paf 141: Value *value=POP();
142: String& name=POP_NAME();
143: Value *ncontext=POP();
144: value->set_name(name);
145: ncontext->put_element(name, value);
1.15 paf 146: break;
147: }
1.37 paf 148: // TODO: OP_EXPRESSION_EVAL, OP_MODIFY_EVAL,
1.18 paf 149: case OP_WRITE:
1.13 paf 150: {
1.24 paf 151: Value *value=POP();
1.14 paf 152: wcontext->write(value);
1.13 paf 153: break;
1.14 paf 154: }
1.13 paf 155:
1.15 paf 156: case OP_GET_ELEMENT:
1.11 paf 157: {
1.17 paf 158: Value *value=get_element();
1.24 paf 159: PUSH(value);
1.17 paf 160: break;
161: }
162:
1.18 paf 163: case OP_GET_ELEMENT__WRITE:
1.17 paf 164: {
165: Value *value=get_element();
166: wcontext->write(value);
167: break;
168: }
169:
1.32 paf 170:
1.17 paf 171: case OP_CREATE_EWPOOL:
172: {
1.24 paf 173: PUSH(wcontext);
1.29 paf 174: wcontext=NEW WWrapper(pool(), 0 /* empty */);
1.17 paf 175: break;
176: }
177: case OP_REDUCE_EWPOOL:
178: {
1.36 paf 179: Value *value=wcontext->result();
1.25 paf 180: wcontext=static_cast<WContext *>(POP());
1.24 paf 181: PUSH(value);
1.13 paf 182: break;
1.15 paf 183: }
1.13 paf 184:
1.26 paf 185: case OP_CREATE_RWPOOL:
186: {
187: Value *ncontext=POP();
188: PUSH(rcontext);
189: rcontext=ncontext;
190: PUSH(wcontext);
1.29 paf 191: wcontext=NEW WWrapper(pool(), ncontext);
1.26 paf 192: break;
193: }
194: case OP_REDUCE_RWPOOL:
195: {
196: String *string=wcontext->get_string();
197: Value *value=NEW VString(string);
198: wcontext=static_cast<WContext *>(POP());
199: rcontext=POP();
200: PUSH(value);
201: break;
202: }
203:
1.37 paf 204: // CALL
1.28 paf 205: case OP_GET_METHOD_FRAME:
206: {
1.32 paf 207: Value *value=POP();
1.28 paf 208: // [self/class?;params;local;code/native_code](name)
1.32 paf 209: Junction *junction=value->get_junction();
1.31 paf 210: if(!junction)
1.28 paf 211: THROW(0,0,
1.32 paf 212: value->name(),
1.39 paf 213: "type is '%s', can not call it (must be method or junction)",
1.38 paf 214: value->type());
1.28 paf 215: //unless(method) method=operators.get_method[...;code/native_code](name)
1.34 paf 216: VMethodFrame *frame=NEW VMethodFrame(pool(), *junction);
1.28 paf 217: PUSH(frame);
218: break;
219: }
220: case OP_STORE_PARAM:
221: {
222: Value *value=POP();
1.34 paf 223: VMethodFrame *frame=static_cast<VMethodFrame *>(stack[0]);
1.28 paf 224: frame->store_param(value);
1.29 paf 225: break;
226: }
227:
228: case OP_CALL:
229: {
230: printf("->\n");
1.34 paf 231: VMethodFrame *frame=static_cast<VMethodFrame *>(POP());
232: frame->fill_unspecified_params();
233: PUSH(self); PUSH(root); PUSH(rcontext); PUSH(wcontext);
1.38 paf 234:
235: VClass *called_class=frame->junction.self.get_class();
1.40 ! paf 236: // variable already constructed?
! 237: if(wcontext->get_class()) { // yes
! 238: VClass *read_class=rcontext->get_class();
1.38 paf 239: // is it me or one of my parents?
1.40 ! paf 240: if(read_class->is_or_derived_from(*called_class)) // yes
1.38 paf 241: self=&frame->junction.self; // dynamic call
242: else // no
243: self=called_class; // static call
244: } else { // no, we have constructor call here: $some(^class:method(..))
245: self=NEW VObject(pool(), *called_class);
246: frame->write(self);
247: }
1.29 paf 248: frame->set_self(self);
1.38 paf 249:
1.29 paf 250: root=rcontext=wcontext=frame;
1.31 paf 251: execute(frame->junction.method->code);
1.36 paf 252: Value *value=wcontext->result();
1.32 paf 253: wcontext=static_cast<WContext *>(POP()); rcontext=POP(); root=POP(); self=POP();
1.29 paf 254: wcontext->write(value);
255: printf("<-returned");
1.28 paf 256: break;
257: }
258:
1.11 paf 259: default:
1.16 paf 260: printf("\tTODO");
1.11 paf 261: break;
262: }
1.16 paf 263: printf("\n");
1.11 paf 264: }
1.1 paf 265: }
1.17 paf 266:
267: Value *Request::get_element() {
1.32 paf 268: String& name=POP_NAME();
1.24 paf 269: Value *ncontext=POP();
1.32 paf 270: Value *value=ncontext->get_element(name);
1.21 paf 271:
1.32 paf 272: if(value) {
273: Junction *junction=value->get_junction();
1.36 paf 274: if(junction && junction->code) { // is it a code-junction?
1.32 paf 275: // autocalc it
276: printf("ja->\n");
277: PUSH(self); PUSH(root); PUSH(rcontext); PUSH(wcontext);
1.34 paf 278: // almost plain wwrapper about junction wcontext,
279: // BUT intercepts string writes
280: VCodeFrame frame(pool(), *junction->wcontext); wcontext=&frame;
281: self=&junction->self;
1.32 paf 282: root=junction->root;
283: rcontext=junction->rcontext;
284: execute(*junction->code);
1.35 paf 285: // CodeFrame soul:
1.36 paf 286: // string writes were intercepted
287: // returning them as the result of getting code-junction
1.35 paf 288: value=NEW VString(frame.get_string());
1.32 paf 289: wcontext=static_cast<WContext *>(POP()); rcontext=POP(); root=POP(); self=POP();
290: printf("<-ja returned");
291: }
292: } else {
1.23 paf 293: value=NEW VUnknown(pool());
1.25 paf 294: value->set_name(name);
1.22 paf 295: }
1.17 paf 296: return value;
1.34 paf 297: }
E-mail: