Annotation of parser3/src/main/execute.C, revision 1.48
1.1 paf 1: /*
1.48 ! paf 2: $Id: execute.C,v 1.47 2001/02/25 17:35:49 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.46 paf 39: //fprintf(stderr, "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);
1.46 paf 43: fprintf(stderr, "%8X\n", op.cast);
1.23 paf 44: }
45: }
46:
1.9 paf 47: int size=ops.size();
1.46 paf 48: //fprintf(stderr, "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);
1.46 paf 52: fprintf(stderr, "%*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));
1.46 paf 56: fprintf(stderr, " \"%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));
1.46 paf 60: fprintf(stderr, " \"%s\"", vclass->name().cstr());
1.38 paf 61: }
1.46 paf 62: fprintf(stderr, "\n");
1.1 paf 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.46 paf 73: fputs("source----------------------------", stderr);
1.12 paf 74: dump(0, ops);
1.46 paf 75: fputs("execution-------------------------", stderr);
1.12 paf 76: }
77:
1.11 paf 78: int size=ops.size();
1.46 paf 79: //fprintf(stderr, "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);
1.46 paf 83: fprintf(stderr, "%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));
1.46 paf 90: fprintf(stderr, " \"%s\"", vstring->get_string()->cstr());
1.32 paf 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.46 paf 97: fprintf(stderr, " (%d)\n", local_ops->size());
1.38 paf 98: dump(1, *local_ops);
1.32 paf 99: Junction& j=*NEW Junction(pool(),
1.45 paf 100: *self, 0, 0,
1.34 paf 101: root,rcontext,wcontext,local_ops);
1.32 paf 102:
103: Value *value=NEW VJunction(j);
104: PUSH(value);
105: break;
106: }
1.38 paf 107: case OP_CLASS:
108: {
109: VClass *vclass=static_cast<VClass *>(ops.quick_get(++i));
1.46 paf 110: fprintf(stderr, " \"%s\"", vclass->name().cstr());
1.38 paf 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.43 paf 173: wcontext=NEW WWrapper(pool(), 0 /* empty */, true /* constructing */);
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.43 paf 190: wcontext=NEW WWrapper(pool(), ncontext, false /* not constructing */);
1.26 paf 191: break;
192: }
193: case OP_REDUCE_RWPOOL:
194: {
195: String *string=wcontext->get_string();
1.42 paf 196: Value *value=NEW VString(*string);
1.26 paf 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.42 paf 211: &value->name(),
1.39 paf 212: "type is '%s', can not call it (must be method or junction)",
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: {
1.46 paf 229: fprintf(stderr, "->\n");
1.34 paf 230: VMethodFrame *frame=static_cast<VMethodFrame *>(POP());
231: frame->fill_unspecified_params();
1.45 paf 232: PUSH(self);
233: PUSH(root);
234: PUSH(rcontext);
235: PUSH(wcontext);
236:
1.38 paf 237: VClass *called_class=frame->junction.self.get_class();
1.43 paf 238: // constructing?
239: if(wcontext->constructing()) { // yes
1.41 paf 240: // constructor call: $some(^class:method(..))
1.38 paf 241: self=NEW VObject(pool(), *called_class);
1.42 paf 242: frame->write(self);
1.43 paf 243: } else { // no
1.47 paf 244: // context is object or class & is it my class or my parent's class?
1.44 paf 245: VClass *read_class=rcontext->get_class();
246: if(read_class && read_class->is_or_derived_from(*called_class)) // yes
1.46 paf 247: self=rcontext; // class dynamic call
1.44 paf 248: else // no
249: self=&frame->junction.self; // static or simple dynamic call
1.38 paf 250: }
1.45 paf 251: frame->set_self(*self);
1.29 paf 252: root=rcontext=wcontext=frame;
1.47 paf 253: {
1.48 ! paf 254: // take object or class from any wrappers
! 255: VAliased *aliased=self->get_aliased();
! 256: // substitute class alias to the class they are called AS
1.47 paf 257: Temp_alias temp_alias(*aliased, *frame->junction.vclass);
258: execute(frame->junction.method->code);
259: }
1.36 paf 260: Value *value=wcontext->result();
1.45 paf 261:
262: wcontext=static_cast<WContext *>(POP());
263: rcontext=POP();
264: root=POP();
265: self=static_cast<VAliased *>(POP());
1.29 paf 266: wcontext->write(value);
1.46 paf 267: fprintf(stderr, "<-returned");
1.28 paf 268: break;
269: }
270:
1.11 paf 271: default:
1.46 paf 272: fprintf(stderr, "\tTODO");
1.11 paf 273: break;
274: }
1.46 paf 275: fprintf(stderr, "\n");
1.11 paf 276: }
1.1 paf 277: }
1.17 paf 278:
279: Value *Request::get_element() {
1.32 paf 280: String& name=POP_NAME();
1.24 paf 281: Value *ncontext=POP();
1.32 paf 282: Value *value=ncontext->get_element(name);
1.21 paf 283:
1.32 paf 284: if(value) {
285: Junction *junction=value->get_junction();
1.36 paf 286: if(junction && junction->code) { // is it a code-junction?
1.32 paf 287: // autocalc it
1.46 paf 288: fprintf(stderr, "ja->\n");
1.45 paf 289: PUSH(self);
290: PUSH(root);
291: PUSH(rcontext);
292: PUSH(wcontext);
293:
1.34 paf 294: // almost plain wwrapper about junction wcontext,
295: // BUT intercepts string writes
296: VCodeFrame frame(pool(), *junction->wcontext); wcontext=&frame;
297: self=&junction->self;
1.32 paf 298: root=junction->root;
299: rcontext=junction->rcontext;
300: execute(*junction->code);
1.35 paf 301: // CodeFrame soul:
1.36 paf 302: // string writes were intercepted
303: // returning them as the result of getting code-junction
1.42 paf 304: value=NEW VString(*frame.get_string());
1.45 paf 305:
306: wcontext=static_cast<WContext *>(POP());
307: rcontext=POP();
308: root=POP();
309: self=static_cast<VAliased *>(POP());
1.46 paf 310: fprintf(stderr, "<-ja returned");
1.32 paf 311: }
312: } else {
1.23 paf 313: value=NEW VUnknown(pool());
1.25 paf 314: value->set_name(name);
1.22 paf 315: }
1.17 paf 316: return value;
1.34 paf 317: }
E-mail: