Annotation of parser3/src/main/execute.C, revision 1.87
1.1 paf 1: /*
1.87 ! paf 2: $Id: execute.C,v 1.86 2001/03/10 15:17:47 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.49 paf 14: #include "pa_vdouble.h"
1.54 paf 15: #include "pa_vbool.h"
1.1 paf 16:
17: #include <stdio.h>
18:
1.24 paf 19: #define PUSH(value) stack.push(value)
20: #define POP() static_cast<Value *>(stack.pop())
1.32 paf 21: #define POP_NAME() static_cast<Value *>(stack.pop())->as_string()
1.24 paf 22:
1.11 paf 23:
1.1 paf 24: char *opcode_name[]={
1.49 paf 25: // literals
1.66 paf 26: "VALUE", "CODE__STORE_PARAM",
1.49 paf 27:
28: // actions
1.51 paf 29: "WITH_SELF", "WITH_ROOT", "WITH_READ", "WITH_WRITE",
1.66 paf 30: "GET_CLASS",
1.80 paf 31: "CONSTRUCT_VALUE", "CONSTRUCT_DOUBLE",
1.86 paf 32: "WRITE", "STRING__WRITE",
1.18 paf 33: "GET_ELEMENT", "GET_ELEMENT__WRITE",
1.1 paf 34: "CREATE_EWPOOL", "REDUCE_EWPOOL",
35: "CREATE_RWPOOL", "REDUCE_RWPOOL",
1.49 paf 36: "CREATE_SWPOOL", "REDUCE_SWPOOL",
1.1 paf 37: "GET_METHOD_FRAME",
38: "STORE_PARAM",
1.51 paf 39: "CALL",
1.49 paf 40:
41: // expression ops: unary
42: "NEG", "INV", "NOT", "DEF", "IN", "FEXISTS",
43: // expression ops: binary
44: "SUB", "ADD", "MUL", "DIV", "MOD",
1.56 paf 45: "BIN_AND", "BIN_OR", "BIN_XOR",
46: "LOG_AND", "LOG_OR", "LOG_XOR",
1.49 paf 47: "NUM_LT", "NUM_GT", "NUM_LE", "NUM_GE", "NUM_EQ", "NUM_NE",
1.55 paf 48: "STR_LT", "STR_GT", "STR_LE", "STR_GE", "STR_EQ", "STR_NE"
1.1 paf 49: };
50:
1.9 paf 51: void dump(int level, const Array& ops) {
1.23 paf 52: if(0){
53: int size=ops.size();
1.46 paf 54: //fprintf(stderr, "size=%d\n", size);
1.23 paf 55: for(int i=0; i<size; i++) {
56: Operation op;
57: op.cast=ops.quick_get(i);
1.46 paf 58: fprintf(stderr, "%8X\n", op.cast);
1.23 paf 59: }
60: }
61:
1.9 paf 62: int size=ops.size();
1.46 paf 63: //fprintf(stderr, "size=%d\n", size);
1.1 paf 64: for(int i=0; i<size; i++) {
1.23 paf 65: Operation op;
66: op.cast=ops.quick_get(i);
1.46 paf 67: fprintf(stderr, "%*s%s", level*4, "", opcode_name[op.code]);
1.1 paf 68:
1.86 paf 69: if(op.code==OP_VALUE || op.code==OP_STRING__WRITE) {
1.52 paf 70: Value *value=static_cast<Value *>(ops.quick_get(++i));
71: fprintf(stderr, " \"%s\" %s", value->get_string()->cstr(), value->type());
1.15 paf 72: }
1.46 paf 73: fprintf(stderr, "\n");
1.1 paf 74:
1.65 paf 75: if(op.code==OP_CODE__STORE_PARAM) {
1.10 paf 76: const Array *local_ops=reinterpret_cast<const Array *>(ops.quick_get(++i));
1.9 paf 77: dump(level+1, *local_ops);
1.1 paf 78: }
79: }
1.60 paf 80: fflush(stderr);
1.1 paf 81: }
82:
1.32 paf 83: void Request::execute(const Array& ops) {
1.30 paf 84: if(1) {
1.51 paf 85: fputs("source----------------------------\n", stderr);
1.12 paf 86: dump(0, ops);
1.51 paf 87: fputs("execution-------------------------\n", stderr);
1.12 paf 88: }
89:
1.11 paf 90: int size=ops.size();
1.46 paf 91: //fprintf(stderr, "size=%d\n", size);
1.11 paf 92: for(int i=0; i<size; i++) {
1.23 paf 93: Operation op;
94: op.cast=ops.quick_get(i);
1.80 paf 95: fprintf(stderr, "%d:%s", stack.top_index()+1, opcode_name[op.code]); fflush(stderr);
1.11 paf 96:
1.23 paf 97: switch(op.code) {
1.51 paf 98: // param in next instruction
1.52 paf 99: case OP_VALUE:
1.32 paf 100: {
1.52 paf 101: Value *value=static_cast<Value *>(ops.quick_get(++i));
102: fprintf(stderr, " \"%s\" %s", value->get_string()->cstr(), value->type());
103: PUSH(value);
1.32 paf 104: break;
105: }
1.65 paf 106: case OP_CODE__STORE_PARAM:
1.32 paf 107: {
1.73 paf 108: VMethodFrame *frame=static_cast<VMethodFrame *>(stack.top_value());
1.65 paf 109: // code
1.32 paf 110: const Array *local_ops=reinterpret_cast<const Array *>(ops.quick_get(++i));
1.46 paf 111: fprintf(stderr, " (%d)\n", local_ops->size());
1.38 paf 112: dump(1, *local_ops);
1.63 paf 113:
1.32 paf 114: Junction& j=*NEW Junction(pool(),
1.45 paf 115: *self, 0, 0,
1.64 paf 116: root, frame, frame, local_ops);
1.32 paf 117:
118: Value *value=NEW VJunction(j);
1.65 paf 119:
120: // store param
121: frame->store_param(value);
1.32 paf 122: break;
123: }
1.66 paf 124: case OP_GET_CLASS:
1.38 paf 125: {
1.82 paf 126: const String& name=POP_NAME();
1.66 paf 127: VClass *vclass=static_cast<VClass *>(classes().get(name));
128: if(!vclass)
129: THROW(0,0,
130: &name,
131: ": undefined class");
132:
133: PUSH(vclass);
1.38 paf 134: break;
135: }
1.32 paf 136:
1.51 paf 137: // OP_WITH
1.37 paf 138: case OP_WITH_SELF:
139: {
140: PUSH(self);
141: break;
142: }
143: case OP_WITH_ROOT:
1.11 paf 144: {
1.37 paf 145: PUSH(root);
1.13 paf 146: break;
1.11 paf 147: }
1.15 paf 148: case OP_WITH_READ:
149: {
1.24 paf 150: PUSH(rcontext);
1.20 paf 151: break;
152: }
1.37 paf 153: case OP_WITH_WRITE:
1.20 paf 154: {
1.37 paf 155: PUSH(wcontext);
1.20 paf 156: break;
157: }
1.37 paf 158:
1.51 paf 159: // OTHER ACTIONS BUT WITHs
1.80 paf 160: case OP_CONSTRUCT_VALUE:
1.20 paf 161: {
1.37 paf 162: Value *value=POP();
1.82 paf 163: const String& name=POP_NAME();
1.37 paf 164: Value *ncontext=POP();
1.81 paf 165: ncontext->put_element(name, value);
1.37 paf 166: value->set_name(name);
1.15 paf 167: break;
168: }
1.80 paf 169: case OP_CONSTRUCT_EXPR:
170: {
171: Value *value=POP();
1.82 paf 172: const String& name=POP_NAME();
1.80 paf 173: Value *ncontext=POP();
1.81 paf 174: ncontext->put_element(name, value->get_expr_result());
1.80 paf 175: value->set_name(name);
176: break;
177: }
1.18 paf 178: case OP_WRITE:
1.13 paf 179: {
1.24 paf 180: Value *value=POP();
1.83 paf 181: write(*value);
1.86 paf 182: break;
183: }
184: case OP_STRING__WRITE:
185: {
186: VString *vstring=static_cast<VString *>(ops.quick_get(++i));
187: fprintf(stderr, " \"%s\"", vstring->value().cstr());
188: write(vstring->value());
1.13 paf 189: break;
1.14 paf 190: }
1.13 paf 191:
1.15 paf 192: case OP_GET_ELEMENT:
1.11 paf 193: {
1.17 paf 194: Value *value=get_element();
1.24 paf 195: PUSH(value);
1.17 paf 196: break;
197: }
198:
1.18 paf 199: case OP_GET_ELEMENT__WRITE:
1.17 paf 200: {
201: Value *value=get_element();
1.83 paf 202: write(*value);
1.17 paf 203: break;
204: }
205:
1.32 paf 206:
1.17 paf 207: case OP_CREATE_EWPOOL:
208: {
1.24 paf 209: PUSH(wcontext);
1.43 paf 210: wcontext=NEW WWrapper(pool(), 0 /* empty */, true /* constructing */);
1.17 paf 211: break;
212: }
213: case OP_REDUCE_EWPOOL:
214: {
1.36 paf 215: Value *value=wcontext->result();
1.25 paf 216: wcontext=static_cast<WContext *>(POP());
1.24 paf 217: PUSH(value);
1.13 paf 218: break;
1.15 paf 219: }
1.13 paf 220:
1.26 paf 221: case OP_CREATE_RWPOOL:
222: {
223: Value *ncontext=POP();
224: PUSH(rcontext);
225: rcontext=ncontext;
226: PUSH(wcontext);
1.43 paf 227: wcontext=NEW WWrapper(pool(), ncontext, false /* not constructing */);
1.26 paf 228: break;
229: }
230: case OP_REDUCE_RWPOOL:
231: {
1.82 paf 232: const String *string=wcontext->get_string();
1.80 paf 233: Value *value;
234: if(string)
235: value=NEW VString(*string);
236: else
237: value=NEW VUnknown(pool());
1.26 paf 238: wcontext=static_cast<WContext *>(POP());
239: rcontext=POP();
240: PUSH(value);
241: break;
242: }
1.49 paf 243: case OP_CREATE_SWPOOL:
244: {
245: PUSH(wcontext);
1.50 paf 246: wcontext=NEW WWrapper(pool(), 0 /* empty */, false /* not constructing */);
1.49 paf 247: break;
248: }
249: case OP_REDUCE_SWPOOL:
250: {
251: // from "$a $b" part of expression taking only string value,
252: // ignoring any other content of wcontext
1.82 paf 253: const String *string=wcontext->get_string();
1.80 paf 254: Value *value;
255: if(string)
256: value=NEW VString(*string);
257: else
258: NEW VUnknown(pool());
1.50 paf 259: wcontext=static_cast<WContext *>(POP());
1.49 paf 260: PUSH(value);
261: break;
262: }
263:
1.51 paf 264: // CALL
1.28 paf 265: case OP_GET_METHOD_FRAME:
266: {
1.32 paf 267: Value *value=POP();
1.70 paf 268: // info: this one's always method-junction, not a code-junction
1.32 paf 269: Junction *junction=value->get_junction();
1.31 paf 270: if(!junction)
1.28 paf 271: THROW(0,0,
1.42 paf 272: &value->name(),
1.39 paf 273: "type is '%s', can not call it (must be method or junction)",
1.38 paf 274: value->type());
1.70 paf 275:
1.34 paf 276: VMethodFrame *frame=NEW VMethodFrame(pool(), *junction);
1.63 paf 277: frame->set_name(junction->self.name());
1.28 paf 278: PUSH(frame);
279: break;
280: }
281: case OP_STORE_PARAM:
282: {
283: Value *value=POP();
1.73 paf 284: VMethodFrame *frame=static_cast<VMethodFrame *>(stack.top_value());
1.28 paf 285: frame->store_param(value);
1.29 paf 286: break;
287: }
288:
289: case OP_CALL:
290: {
1.46 paf 291: fprintf(stderr, "->\n");
1.34 paf 292: VMethodFrame *frame=static_cast<VMethodFrame *>(POP());
293: frame->fill_unspecified_params();
1.45 paf 294: PUSH(self);
295: PUSH(root);
296: PUSH(rcontext);
297: PUSH(wcontext);
298:
1.38 paf 299: VClass *called_class=frame->junction.self.get_class();
1.74 paf 300: // is context object or class & is it my class or my parent's class?
301: VClass *read_class=rcontext->get_class();
302: if(read_class && read_class->is_or_derived_from(*called_class)) // yes
303: self=rcontext; // class dynamic call
1.75 paf 304: else // no, not me or relative of mine (total stranger)
305: if(wcontext->constructing()) { // constructing?
306: // yes, constructor call: $some(^class:method(..))
1.80 paf 307: self=NEW VObject(pool(), *called_class);
1.83 paf 308: frame->write(*self,
309: String::Untaint_lang::NO // not used, always an object, not string
310: );
1.75 paf 311: } else
312: self=&frame->junction.self; // no, static or simple dynamic call
313:
1.45 paf 314: frame->set_self(*self);
1.29 paf 315: root=rcontext=wcontext=frame;
1.47 paf 316: {
1.48 paf 317: // take object or class from any wrappers
318: VAliased *aliased=self->get_aliased();
319: // substitute class alias to the class they are called AS
1.47 paf 320: Temp_alias temp_alias(*aliased, *frame->junction.vclass);
1.68 paf 321:
1.69 paf 322: Method& method=*frame->junction.method;
1.80 paf 323: if(method.native_code) { // native code?
324: method.check_actual_numbered_params(frame->numbered_params());
1.70 paf 325: (*method.native_code)(*this, frame->numbered_params()); // execute it
1.80 paf 326: } else // parser code
1.69 paf 327: execute(*method.parser_code); // execute it
1.47 paf 328: }
1.36 paf 329: Value *value=wcontext->result();
1.45 paf 330:
331: wcontext=static_cast<WContext *>(POP());
332: rcontext=POP();
333: root=POP();
334: self=static_cast<VAliased *>(POP());
1.62 paf 335:
1.61 paf 336: PUSH(value);
1.46 paf 337: fprintf(stderr, "<-returned");
1.49 paf 338: break;
339: }
340:
1.55 paf 341: // expression ops: unary
342: case OP_NEG:
343: {
344: Value *operand=POP();
1.80 paf 345: Value *value=NEW VDouble(pool(), -operand->get_double());
1.55 paf 346: PUSH(value);
347: break;
348: }
349: case OP_INV:
350: {
351: Value *operand=POP();
1.80 paf 352: Value *value=NEW VDouble(pool(), ~static_cast<int>(operand->get_double()));
1.55 paf 353: PUSH(value);
354: break;
355: }
356: case OP_NOT:
357: {
358: Value *operand=POP();
1.78 paf 359: Value *value=NEW VBool(pool(), !operand->get_bool());
1.55 paf 360: PUSH(value);
361: break;
362: }
1.62 paf 363: case OP_DEF:
364: {
365: Value *operand=POP();
1.78 paf 366: Value *value=NEW VBool(pool(), operand->get_defined());
1.62 paf 367: PUSH(value);
368: break;
369: }
370: case OP_IN:
371: {
372: Value *operand=POP();
1.78 paf 373: Value *value=NEW VBool(pool(), true/*TODO*/);
1.62 paf 374: PUSH(value);
375: break;
376: }
377: case OP_FEXISTS:
378: {
379: Value *operand=POP();
1.78 paf 380: Value *value=NEW VBool(pool(), true/*TODO*/);
1.62 paf 381: PUSH(value);
382: break;
383: }
1.55 paf 384:
385: // expression ops: binary
386: case OP_SUB:
1.53 paf 387: {
1.61 paf 388: Value *b=POP(); Value *a=POP();
1.80 paf 389: Value *value=NEW VDouble(pool(), a->get_double() - b->get_double());
1.53 paf 390: PUSH(value);
391: break;
392: }
1.55 paf 393: case OP_ADD:
1.53 paf 394: {
1.61 paf 395: Value *b=POP(); Value *a=POP();
1.80 paf 396: Value *value=NEW VDouble(pool(), a->get_double() + b->get_double());
1.53 paf 397: PUSH(value);
398: break;
399: }
1.49 paf 400: case OP_MUL:
401: {
1.61 paf 402: Value *b=POP(); Value *a=POP();
1.80 paf 403: Value *value=NEW VDouble(pool(), a->get_double() * b->get_double());
1.53 paf 404: PUSH(value);
405: break;
406: }
407: case OP_DIV:
408: {
1.61 paf 409: Value *b=POP(); Value *a=POP();
1.80 paf 410: Value *value=NEW VDouble(pool(), a->get_double() / b->get_double());
1.54 paf 411: PUSH(value);
412: break;
413: }
1.55 paf 414: case OP_MOD:
415: {
1.61 paf 416: Value *b=POP(); Value *a=POP();
1.78 paf 417: Value *value=NEW VDouble(pool(),
1.55 paf 418: static_cast<int>(a->get_double()) %
1.78 paf 419: static_cast<int>(b->get_double()));
1.55 paf 420: PUSH(value);
421: break;
422: }
423: case OP_BIN_AND:
1.54 paf 424: {
1.61 paf 425: Value *b=POP(); Value *a=POP();
1.78 paf 426: Value *value=NEW VDouble(pool(),
1.55 paf 427: static_cast<int>(a->get_double()) &
1.78 paf 428: static_cast<int>(b->get_double()));
1.54 paf 429: PUSH(value);
430: break;
431: }
1.55 paf 432: case OP_BIN_OR:
1.54 paf 433: {
1.61 paf 434: Value *b=POP(); Value *a=POP();
1.78 paf 435: Value *value=NEW VDouble(pool(),
1.55 paf 436: static_cast<int>(a->get_double()) |
1.78 paf 437: static_cast<int>(b->get_double()));
1.55 paf 438: PUSH(value);
439: break;
440: }
1.56 paf 441: case OP_BIN_XOR:
442: {
1.61 paf 443: Value *b=POP(); Value *a=POP();
1.78 paf 444: Value *value=NEW VDouble(pool(),
1.56 paf 445: static_cast<int>(a->get_double()) ^
1.78 paf 446: static_cast<int>(b->get_double()));
1.56 paf 447: PUSH(value);
448: break;
449: }
1.55 paf 450: case OP_LOG_AND:
451: {
1.61 paf 452: Value *b=POP(); Value *a=POP();
1.78 paf 453: Value *value=NEW VBool(pool(), a->get_bool() && b->get_bool());
1.55 paf 454: PUSH(value);
455: break;
456: }
457: case OP_LOG_OR:
458: {
1.61 paf 459: Value *b=POP(); Value *a=POP();
1.78 paf 460: Value *value=NEW VBool(pool(), a->get_bool() || b->get_bool());
1.56 paf 461: PUSH(value);
462: break;
463: }
464: case OP_LOG_XOR:
465: {
1.61 paf 466: Value *b=POP(); Value *a=POP();
1.78 paf 467: Value *value=NEW VBool(pool(), a->get_bool() ^ b->get_bool());
1.55 paf 468: PUSH(value);
469: break;
470: }
471: case OP_NUM_LT:
472: {
1.61 paf 473: Value *b=POP(); Value *a=POP();
1.78 paf 474: Value *value=NEW VBool(pool(), a->get_double() < b->get_double());
1.55 paf 475: PUSH(value);
476: break;
477: }
478: case OP_NUM_GT:
479: {
1.61 paf 480: Value *b=POP(); Value *a=POP();
1.78 paf 481: Value *value=NEW VBool(pool(), a->get_double() > b->get_double());
1.55 paf 482: PUSH(value);
483: break;
484: }
485: case OP_NUM_LE:
486: {
1.61 paf 487: Value *b=POP(); Value *a=POP();
1.78 paf 488: Value *value=NEW VBool(pool(), a->get_double() <= b->get_double());
1.55 paf 489: PUSH(value);
490: break;
491: }
492: case OP_NUM_GE:
493: {
1.61 paf 494: Value *b=POP(); Value *a=POP();
1.78 paf 495: Value *value=NEW VBool(pool(), a->get_double() >= b->get_double());
1.55 paf 496: PUSH(value);
497: break;
498: }
499: case OP_NUM_EQ:
500: {
1.61 paf 501: Value *b=POP(); Value *a=POP();
1.78 paf 502: Value *value=NEW VBool(pool(), a->get_double() == b->get_double());
1.55 paf 503: PUSH(value);
504: break;
505: }
506: case OP_NUM_NE:
507: {
1.61 paf 508: Value *b=POP(); Value *a=POP();
1.78 paf 509: Value *value=NEW VBool(pool(), a->get_double() != b->get_double());
1.54 paf 510: PUSH(value);
511: break;
512: }
1.58 paf 513: case OP_STR_LT:
514: {
1.61 paf 515: Value *b=POP(); Value *a=POP();
1.78 paf 516: Value *value=NEW VBool(pool(), a->as_string() < b->as_string());
1.58 paf 517: PUSH(value);
518: break;
519: }
520: case OP_STR_GT:
521: {
1.61 paf 522: Value *b=POP(); Value *a=POP();
1.78 paf 523: Value *value=NEW VBool(pool(), a->as_string() > b->as_string());
1.58 paf 524: PUSH(value);
525: break;
526: }
1.55 paf 527: case OP_STR_LE:
1.58 paf 528: {
1.61 paf 529: Value *b=POP(); Value *a=POP();
1.78 paf 530: Value *value=NEW VBool(pool(), a->as_string() <= b->as_string());
1.58 paf 531: PUSH(value);
532: break;
533: }
1.55 paf 534: case OP_STR_GE:
1.54 paf 535: {
1.61 paf 536: Value *b=POP(); Value *a=POP();
1.78 paf 537: Value *value=NEW VBool(pool(), a->as_string() >= b->as_string());
1.58 paf 538: PUSH(value);
539: break;
540: }
541: case OP_STR_EQ:
542: {
1.61 paf 543: Value *b=POP(); Value *a=POP();
1.78 paf 544: Value *value=NEW VBool(pool(), a->as_string() == b->as_string());
1.58 paf 545: PUSH(value);
546: break;
547: }
548: case OP_STR_NE:
549: {
1.61 paf 550: Value *b=POP(); Value *a=POP();
1.78 paf 551: Value *value=NEW VBool(pool(), a->as_string() != b->as_string());
1.49 paf 552: PUSH(value);
1.28 paf 553: break;
554: }
555:
1.11 paf 556: default:
1.67 paf 557: THROW(0,0,
558: 0,
559: "unhandled '%s' opcode", opcode_name[op.code]);
1.11 paf 560: }
1.46 paf 561: fprintf(stderr, "\n");
1.11 paf 562: }
1.1 paf 563: }
1.17 paf 564:
565: Value *Request::get_element() {
1.82 paf 566: const String& name=POP_NAME();
1.24 paf 567: Value *ncontext=POP();
1.32 paf 568: Value *value=ncontext->get_element(name);
1.21 paf 569:
1.76 paf 570: if(value)
1.84 paf 571: value=&autocalc(*value, &name); // autocalc possible code-junction
1.76 paf 572: else {
573: value=NEW VUnknown(pool());
574: value->set_name(name);
575: }
1.63 paf 576:
1.17 paf 577: return value;
1.34 paf 578: }
1.70 paf 579:
1.84 paf 580: Value& Request::autocalc(Value& value, const String *name, bool make_string) {
1.70 paf 581: Junction *junction=value.get_junction();
582: if(junction && junction->code) { // is it a code-junction?
583: // autocalc it
584: fprintf(stderr, "ja->\n");
585: PUSH(self);
586: PUSH(root);
587: PUSH(rcontext);
588: PUSH(wcontext);
589:
1.71 paf 590: WContext *frame;
591: if(make_string) {
592: // almost plain wwrapper about junction wcontext,
593: // BUT intercepts string writes
594: frame=NEW VCodeFrame(pool(), *junction->wcontext);
595: } else {
596: // plain wwrapper
597: frame=NEW WWrapper(pool(), 0 /* empty */, false /*not constructing*/);
598: }
599:
600: wcontext=frame;
1.70 paf 601: self=&junction->self;
602: root=junction->root;
603: rcontext=junction->rcontext;
604: execute(*junction->code);
1.71 paf 605: Value *result;
606: if(make_string) {
607: // CodeFrame soul:
608: // string writes were intercepted
609: // returning them as the result of getting code-junction
610: result=NEW VString(*frame->get_string());
611: } else
612: result=frame->result();
1.84 paf 613: if(name)
614: result->set_name(*name);
1.70 paf 615:
616: wcontext=static_cast<WContext *>(POP());
617: rcontext=POP();
618: root=POP();
619: self=static_cast<VAliased *>(POP());
620:
621: fprintf(stderr, "<-ja returned");
1.71 paf 622: return *result;
1.70 paf 623: } else
624: return value;
1.85 paf 625: }
626:
1.87 ! paf 627: char *Request::execute_static_method(VClass& vclass, String& method_name, bool return_cstr) {
1.85 paf 628: Value *value=vclass.get_element(method_name);
629: if(value) { // found some 'METHOD_NAME' element
630: Junction *junction=value->get_junction();
631: if(junction) {// it even has junction!
632: const Method *method=junction->method;
633: if(method) { // and junction is method-junction! call it
634: PUSH(self);
635: PUSH(root);
636: PUSH(rcontext);
637: PUSH(wcontext);
638:
639: // initialize contexts
640: root=rcontext=self=&vclass;
641: wcontext=NEW WWrapper(pool(), &vclass, false /* not constructing */);
642:
643: // execute!
644: execute(*method->parser_code);
645:
646: // result
647: char *result;
648: if(return_cstr)
649: result=wcontext->get_string()->cstr(); // chars
650: else
651: result=0; // ignore result
652:
653: wcontext=static_cast<WContext *>(POP());
654: rcontext=POP();
655: root=POP();
656: self=static_cast<VAliased *>(POP());
657:
658: // return
659: return result;
660: }
661: }
662: }
663: return 0;
1.70 paf 664: }
E-mail: