0001
0002
0003
0004 #include "pspcheader.h"
0005 #include "psvm.h"
0006 #include "psstring.h"
0007 #include "pstable.h"
0008 #include "psarray.h"
0009 #include "psfuncproto.h"
0010 #include "psclosure.h"
0011 #include "psclass.h"
0012 #include <stdlib.h>
0013 #include <stdarg.h>
0014 #include <ctype.h>
0015
0016 static bool str2num(const PSChar *s,PSObjectPtr &res,PSInteger base)
0017 {
0018 PSChar *end;
0019 const PSChar *e = s;
0020 bool iseintbase = base > 13;
0021 bool isfloat = false;
0022 PSChar c;
0023 while((c = *e) != _SC('\0'))
0024 {
0025 if (c == _SC('.') || (!iseintbase && (c == _SC('E') || c == _SC('e')))) {
0026 isfloat = true;
0027 break;
0028 }
0029 e++;
0030 }
0031 if(isfloat){
0032 PSFloat r = PSFloat(scstrtod(s,&end));
0033 if(s == end) return false;
0034 res = r;
0035 }
0036 else{
0037 PSInteger r = PSInteger(scstrtol(s,&end,(int)base));
0038 if(s == end) return false;
0039 res = r;
0040 }
0041 return true;
0042 }
0043
0044 static PSInteger base_dummy(HPSCRIPTVM PS_UNUSED_ARG(v))
0045 {
0046 return 0;
0047 }
0048
0049 #ifndef NO_GARBAGE_COLLECTOR
0050 static PSInteger base_collectgarbage(HPSCRIPTVM v)
0051 {
0052 ps_pushinteger(v, ps_collectgarbage(v));
0053 return 1;
0054 }
0055 static PSInteger base_resurectureachable(HPSCRIPTVM v)
0056 {
0057 ps_resurrectunreachable(v);
0058 return 1;
0059 }
0060 #endif
0061
0062 static PSInteger base_getroottable(HPSCRIPTVM v)
0063 {
0064 v->Push(v->_roottable);
0065 return 1;
0066 }
0067
0068 static PSInteger base_getconsttable(HPSCRIPTVM v)
0069 {
0070 v->Push(_ss(v)->_consts);
0071 return 1;
0072 }
0073
0074
0075 static PSInteger base_setroottable(HPSCRIPTVM v)
0076 {
0077 PSObjectPtr o = v->_roottable;
0078 if(PS_FAILED(ps_setroottable(v))) return PS_ERROR;
0079 v->Push(o);
0080 return 1;
0081 }
0082
0083 static PSInteger base_setconsttable(HPSCRIPTVM v)
0084 {
0085 PSObjectPtr o = _ss(v)->_consts;
0086 if(PS_FAILED(ps_setconsttable(v))) return PS_ERROR;
0087 v->Push(o);
0088 return 1;
0089 }
0090
0091 static PSInteger base_seterrorhandler(HPSCRIPTVM v)
0092 {
0093 ps_seterrorhandler(v);
0094 return 0;
0095 }
0096
0097 static PSInteger base_setdebughook(HPSCRIPTVM v)
0098 {
0099 ps_setdebughook(v);
0100 return 0;
0101 }
0102
0103 static PSInteger base_enabledebuginfo(HPSCRIPTVM v)
0104 {
0105 PSObjectPtr &o=stack_get(v,2);
0106
0107 ps_enabledebuginfo(v,PSVM::IsFalse(o)?PSFalse:PSTrue);
0108 return 0;
0109 }
0110
0111 static PSInteger __getcallstackinfos(HPSCRIPTVM v,PSInteger level)
0112 {
0113 PSStackInfos si;
0114 PSInteger seq = 0;
0115 const PSChar *name = NULL;
0116
0117 if (PS_SUCCEEDED(ps_stackinfos(v, level, &si)))
0118 {
0119 const PSChar *fn = _SC("unknown");
0120 const PSChar *src = _SC("unknown");
0121 if(si.funcname)fn = si.funcname;
0122 if(si.source)src = si.source;
0123 ps_newtable(v);
0124 ps_pushstring(v, _SC("func"), -1);
0125 ps_pushstring(v, fn, -1);
0126 ps_newslot(v, -3, PSFalse);
0127 ps_pushstring(v, _SC("src"), -1);
0128 ps_pushstring(v, src, -1);
0129 ps_newslot(v, -3, PSFalse);
0130 ps_pushstring(v, _SC("line"), -1);
0131 ps_pushinteger(v, si.line);
0132 ps_newslot(v, -3, PSFalse);
0133 ps_pushstring(v, _SC("locals"), -1);
0134 ps_newtable(v);
0135 seq=0;
0136 while ((name = ps_getlocal(v, level, seq))) {
0137 ps_pushstring(v, name, -1);
0138 ps_push(v, -2);
0139 ps_newslot(v, -4, PSFalse);
0140 ps_pop(v, 1);
0141 seq++;
0142 }
0143 ps_newslot(v, -3, PSFalse);
0144 return 1;
0145 }
0146
0147 return 0;
0148 }
0149 static PSInteger base_getstackinfos(HPSCRIPTVM v)
0150 {
0151 PSInteger level;
0152 ps_getinteger(v, -1, &level);
0153 return __getcallstackinfos(v,level);
0154 }
0155
0156 static PSInteger base_assert(HPSCRIPTVM v)
0157 {
0158 if(PSVM::IsFalse(stack_get(v,2))){
0159 return ps_throwerror(v,_SC("assertion failed"));
0160 }
0161 return 0;
0162 }
0163
0164 static PSInteger get_slice_params(HPSCRIPTVM v,PSInteger &sidx,PSInteger &eidx,PSObjectPtr &o)
0165 {
0166 PSInteger top = ps_gettop(v);
0167 sidx=0;
0168 eidx=0;
0169 o=stack_get(v,1);
0170 if(top>1){
0171 PSObjectPtr &start=stack_get(v,2);
0172 if(type(start)!=OT_NULL && ps_isnumeric(start)){
0173 sidx=tointeger(start);
0174 }
0175 }
0176 if(top>2){
0177 PSObjectPtr &end=stack_get(v,3);
0178 if(ps_isnumeric(end)){
0179 eidx=tointeger(end);
0180 }
0181 }
0182 else {
0183 eidx = ps_getsize(v,1);
0184 }
0185 return 1;
0186 }
0187
0188 static PSInteger base_print(HPSCRIPTVM v)
0189 {
0190 const PSChar *str;
0191 if(PS_SUCCEEDED(ps_tostring(v,2)))
0192 {
0193 if(PS_SUCCEEDED(ps_getstring(v,-1,&str))) {
0194 if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);
0195 return 0;
0196 }
0197 }
0198 return PS_ERROR;
0199 }
0200
0201 static PSInteger base_error(HPSCRIPTVM v)
0202 {
0203 const PSChar *str;
0204 if(PS_SUCCEEDED(ps_tostring(v,2)))
0205 {
0206 if(PS_SUCCEEDED(ps_getstring(v,-1,&str))) {
0207 if(_ss(v)->_errorfunc) _ss(v)->_errorfunc(v,_SC("%s"),str);
0208 return 0;
0209 }
0210 }
0211 return PS_ERROR;
0212 }
0213
0214 static PSInteger base_compilestring(HPSCRIPTVM v)
0215 {
0216 PSInteger nargs=ps_gettop(v);
0217 const PSChar *src=NULL,*name=_SC("unnamedbuffer");
0218 PSInteger size;
0219 ps_getstring(v,2,&src);
0220 size=ps_getsize(v,2);
0221 if(nargs>2){
0222 ps_getstring(v,3,&name);
0223 }
0224 if(PS_SUCCEEDED(ps_compilebuffer(v,src,size,name,PSFalse)))
0225 return 1;
0226 else
0227 return PS_ERROR;
0228 }
0229
0230 static PSInteger base_newthread(HPSCRIPTVM v)
0231 {
0232 PSObjectPtr &func = stack_get(v,2);
0233 PSInteger stksize = (_closure(func)->_function->_stacksize << 1) +2;
0234 HPSCRIPTVM newv = ps_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
0235 ps_move(newv,v,-2);
0236 return 1;
0237 }
0238
0239 static PSInteger base_suspend(HPSCRIPTVM v)
0240 {
0241 return ps_suspendvm(v);
0242 }
0243
0244 static PSInteger base_array(HPSCRIPTVM v)
0245 {
0246 PSArray *a;
0247 PSObject &size = stack_get(v,2);
0248 if(ps_gettop(v) > 2) {
0249 a = PSArray::Create(_ss(v),0);
0250 a->Resize(tointeger(size),stack_get(v,3));
0251 }
0252 else {
0253 a = PSArray::Create(_ss(v),tointeger(size));
0254 }
0255 v->Push(a);
0256 return 1;
0257 }
0258
0259 static PSInteger base_type(HPSCRIPTVM v)
0260 {
0261 PSObjectPtr &o = stack_get(v,2);
0262 v->Push(PSString::Create(_ss(v),GetTypeName(o),-1));
0263 return 1;
0264 }
0265
0266 static PSInteger base_callee(HPSCRIPTVM v)
0267 {
0268 if(v->_callsstacksize > 1)
0269 {
0270 v->Push(v->_callsstack[v->_callsstacksize - 2]._closure);
0271 return 1;
0272 }
0273 return ps_throwerror(v,_SC("no closure in the calls stack"));
0274 }
0275
0276 static const PSRegFunction base_funcs[]={
0277
0278 {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},
0279 {_SC("setdebughook"),base_setdebughook,2, NULL},
0280 {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},
0281 {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
0282 {_SC("getroottable"),base_getroottable,1, NULL},
0283 {_SC("setroottable"),base_setroottable,2, NULL},
0284 {_SC("getconsttable"),base_getconsttable,1, NULL},
0285 {_SC("setconsttable"),base_setconsttable,2, NULL},
0286 {_SC("assert"),base_assert,2, NULL},
0287 {_SC("print"),base_print,2, NULL},
0288 {_SC("error"),base_error,2, NULL},
0289 {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
0290 {_SC("newthread"),base_newthread,2, _SC(".c")},
0291 {_SC("suspend"),base_suspend,-1, NULL},
0292 {_SC("array"),base_array,-2, _SC(".n")},
0293 {_SC("type"),base_type,2, NULL},
0294 {_SC("callee"),base_callee,0,NULL},
0295 {_SC("dummy"),base_dummy,0,NULL},
0296 #ifndef NO_GARBAGE_COLLECTOR
0297 {_SC("collectgarbage"),base_collectgarbage,0, NULL},
0298 {_SC("resurrectunreachable"),base_resurectureachable,0, NULL},
0299 #endif
0300 {NULL,(PSFUNCTION)0,0,NULL}
0301 };
0302
0303 void ps_base_register(HPSCRIPTVM v)
0304 {
0305 PSInteger i=0;
0306 ps_pushroottable(v);
0307 while(base_funcs[i].name!=0) {
0308 ps_pushstring(v,base_funcs[i].name,-1);
0309 ps_newclosure(v,base_funcs[i].f,0);
0310 ps_setnativeclosurename(v,-1,base_funcs[i].name);
0311 ps_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);
0312 ps_newslot(v,-3, PSFalse);
0313 i++;
0314 }
0315
0316 ps_pushstring(v,_SC("_versionnumber_"),-1);
0317 ps_pushinteger(v,PSCRIPT_VERSION_NUMBER);
0318 ps_newslot(v,-3, PSFalse);
0319 ps_pushstring(v,_SC("_version_"),-1);
0320 ps_pushstring(v,PSCRIPT_VERSION,-1);
0321 ps_newslot(v,-3, PSFalse);
0322 ps_pushstring(v,_SC("_charsize_"),-1);
0323 ps_pushinteger(v,sizeof(PSChar));
0324 ps_newslot(v,-3, PSFalse);
0325 ps_pushstring(v,_SC("_intsize_"),-1);
0326 ps_pushinteger(v,sizeof(PSInteger));
0327 ps_newslot(v,-3, PSFalse);
0328 ps_pushstring(v,_SC("_floatsize_"),-1);
0329 ps_pushinteger(v,sizeof(PSFloat));
0330 ps_newslot(v,-3, PSFalse);
0331 ps_pop(v,1);
0332 }
0333
0334 static PSInteger default_delegate_len(HPSCRIPTVM v)
0335 {
0336 v->Push(PSInteger(ps_getsize(v,1)));
0337 return 1;
0338 }
0339
0340 static PSInteger default_delegate_tofloat(HPSCRIPTVM v)
0341 {
0342 PSObjectPtr &o=stack_get(v,1);
0343 switch(type(o)){
0344 case OT_STRING:{
0345 PSObjectPtr res;
0346 if(str2num(_stringval(o),res,10)){
0347 v->Push(PSObjectPtr(tofloat(res)));
0348 break;
0349 }}
0350 return ps_throwerror(v, _SC("cannot convert the string"));
0351 break;
0352 case OT_INTEGER:case OT_FLOAT:
0353 v->Push(PSObjectPtr(tofloat(o)));
0354 break;
0355 case OT_BOOL:
0356 v->Push(PSObjectPtr((PSFloat)(_integer(o)?1:0)));
0357 break;
0358 default:
0359 v->PushNull();
0360 break;
0361 }
0362 return 1;
0363 }
0364
0365 static PSInteger default_delegate_tointeger(HPSCRIPTVM v)
0366 {
0367 PSObjectPtr &o=stack_get(v,1);
0368 PSInteger base = 10;
0369 if(ps_gettop(v) > 1) {
0370 ps_getinteger(v,2,&base);
0371 }
0372 switch(type(o)){
0373 case OT_STRING:{
0374 PSObjectPtr res;
0375 if(str2num(_stringval(o),res,base)){
0376 v->Push(PSObjectPtr(tointeger(res)));
0377 break;
0378 }}
0379 return ps_throwerror(v, _SC("cannot convert the string"));
0380 break;
0381 case OT_INTEGER:case OT_FLOAT:
0382 v->Push(PSObjectPtr(tointeger(o)));
0383 break;
0384 case OT_BOOL:
0385 v->Push(PSObjectPtr(_integer(o)?(PSInteger)1:(PSInteger)0));
0386 break;
0387 default:
0388 v->PushNull();
0389 break;
0390 }
0391 return 1;
0392 }
0393
0394 static PSInteger default_delegate_tostring(HPSCRIPTVM v)
0395 {
0396 if(PS_FAILED(ps_tostring(v,1)))
0397 return PS_ERROR;
0398 return 1;
0399 }
0400
0401 static PSInteger obj_delegate_weakref(HPSCRIPTVM v)
0402 {
0403 ps_weakref(v,1);
0404 return 1;
0405 }
0406
0407 static PSInteger obj_clear(HPSCRIPTVM v)
0408 {
0409 return ps_clear(v,-1);
0410 }
0411
0412
0413 static PSInteger number_delegate_tochar(HPSCRIPTVM v)
0414 {
0415 PSObject &o=stack_get(v,1);
0416 PSChar c = (PSChar)tointeger(o);
0417 v->Push(PSString::Create(_ss(v),(const PSChar *)&c,1));
0418 return 1;
0419 }
0420
0421
0422
0423
0424
0425
0426 static PSInteger table_rawdelete(HPSCRIPTVM v)
0427 {
0428 if(PS_FAILED(ps_rawdeleteslot(v,1,PSTrue)))
0429 return PS_ERROR;
0430 return 1;
0431 }
0432
0433
0434 static PSInteger container_rawexists(HPSCRIPTVM v)
0435 {
0436 if(PS_SUCCEEDED(ps_rawget(v,-2))) {
0437 ps_pushbool(v,PSTrue);
0438 return 1;
0439 }
0440 ps_pushbool(v,PSFalse);
0441 return 1;
0442 }
0443
0444 static PSInteger container_rawset(HPSCRIPTVM v)
0445 {
0446 return ps_rawset(v,-3);
0447 }
0448
0449
0450 static PSInteger container_rawget(HPSCRIPTVM v)
0451 {
0452 return PS_SUCCEEDED(ps_rawget(v,-2))?1:PS_ERROR;
0453 }
0454
0455 static PSInteger table_setdelegate(HPSCRIPTVM v)
0456 {
0457 if(PS_FAILED(ps_setdelegate(v,-2)))
0458 return PS_ERROR;
0459 ps_push(v,-1);
0460 return 1;
0461 }
0462
0463 static PSInteger table_getdelegate(HPSCRIPTVM v)
0464 {
0465 return PS_SUCCEEDED(ps_getdelegate(v,-1))?1:PS_ERROR;
0466 }
0467
0468 const PSRegFunction PSSharedState::_table_default_delegate_funcz[]={
0469 {_SC("len"),default_delegate_len,1, _SC("t")},
0470 {_SC("rawget"),container_rawget,2, _SC("t")},
0471 {_SC("rawset"),container_rawset,3, _SC("t")},
0472 {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
0473 {_SC("rawin"),container_rawexists,2, _SC("t")},
0474 {_SC("weakref"),obj_delegate_weakref,1, NULL },
0475 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
0476 {_SC("clear"),obj_clear,1, _SC(".")},
0477 {_SC("setdelegate"),table_setdelegate,2, _SC(".t|o")},
0478 {_SC("getdelegate"),table_getdelegate,1, _SC(".")},
0479 {NULL,(PSFUNCTION)0,0,NULL}
0480 };
0481
0482
0483
0484 static PSInteger array_append(HPSCRIPTVM v)
0485 {
0486 return ps_arrayappend(v,-2);
0487 }
0488
0489 static PSInteger array_extend(HPSCRIPTVM v)
0490 {
0491 _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
0492 return 0;
0493 }
0494
0495 static PSInteger array_reverse(HPSCRIPTVM v)
0496 {
0497 return ps_arrayreverse(v,-1);
0498 }
0499
0500 static PSInteger array_pop(HPSCRIPTVM v)
0501 {
0502 return PS_SUCCEEDED(ps_arraypop(v,1,PSTrue))?1:PS_ERROR;
0503 }
0504
0505 static PSInteger array_top(HPSCRIPTVM v)
0506 {
0507 PSObject &o=stack_get(v,1);
0508 if(_array(o)->Size()>0){
0509 v->Push(_array(o)->Top());
0510 return 1;
0511 }
0512 else return ps_throwerror(v,_SC("top() on a empty array"));
0513 }
0514
0515 static PSInteger array_insert(HPSCRIPTVM v)
0516 {
0517 PSObject &o=stack_get(v,1);
0518 PSObject &idx=stack_get(v,2);
0519 PSObject &val=stack_get(v,3);
0520 if(!_array(o)->Insert(tointeger(idx),val))
0521 return ps_throwerror(v,_SC("index out of range"));
0522 return 0;
0523 }
0524
0525 static PSInteger array_remove(HPSCRIPTVM v)
0526 {
0527 PSObject &o = stack_get(v, 1);
0528 PSObject &idx = stack_get(v, 2);
0529 if(!ps_isnumeric(idx)) return ps_throwerror(v, _SC("wrong type"));
0530 PSObjectPtr val;
0531 if(_array(o)->Get(tointeger(idx), val)) {
0532 _array(o)->Remove(tointeger(idx));
0533 v->Push(val);
0534 return 1;
0535 }
0536 return ps_throwerror(v, _SC("idx out of range"));
0537 }
0538
0539 static PSInteger array_resize(HPSCRIPTVM v)
0540 {
0541 PSObject &o = stack_get(v, 1);
0542 PSObject &nsize = stack_get(v, 2);
0543 PSObjectPtr fill;
0544 if(ps_isnumeric(nsize)) {
0545 if(ps_gettop(v) > 2)
0546 fill = stack_get(v, 3);
0547 _array(o)->Resize(tointeger(nsize),fill);
0548 return 0;
0549 }
0550 return ps_throwerror(v, _SC("size must be a number"));
0551 }
0552
0553 static PSInteger __map_array(PSArray *dest,PSArray *src,HPSCRIPTVM v) {
0554 PSObjectPtr temp;
0555 PSInteger size = src->Size();
0556 for(PSInteger n = 0; n < size; n++) {
0557 src->Get(n,temp);
0558 v->Push(src);
0559 v->Push(temp);
0560 if(PS_FAILED(ps_call(v,2,PSTrue,PSFalse))) {
0561 return PS_ERROR;
0562 }
0563 dest->Set(n,v->GetUp(-1));
0564 v->Pop();
0565 }
0566 return 0;
0567 }
0568
0569 static PSInteger array_map(HPSCRIPTVM v)
0570 {
0571 PSObject &o = stack_get(v,1);
0572 PSInteger size = _array(o)->Size();
0573 PSObjectPtr ret = PSArray::Create(_ss(v),size);
0574 if(PS_FAILED(__map_array(_array(ret),_array(o),v)))
0575 return PS_ERROR;
0576 v->Push(ret);
0577 return 1;
0578 }
0579
0580 static PSInteger array_apply(HPSCRIPTVM v)
0581 {
0582 PSObject &o = stack_get(v,1);
0583 if(PS_FAILED(__map_array(_array(o),_array(o),v)))
0584 return PS_ERROR;
0585 return 0;
0586 }
0587
0588 static PSInteger array_reduce(HPSCRIPTVM v)
0589 {
0590 PSObject &o = stack_get(v,1);
0591 PSArray *a = _array(o);
0592 PSInteger size = a->Size();
0593 if(size == 0) {
0594 return 0;
0595 }
0596 PSObjectPtr res;
0597 a->Get(0,res);
0598 if(size > 1) {
0599 PSObjectPtr other;
0600 for(PSInteger n = 1; n < size; n++) {
0601 a->Get(n,other);
0602 v->Push(o);
0603 v->Push(res);
0604 v->Push(other);
0605 if(PS_FAILED(ps_call(v,3,PSTrue,PSFalse))) {
0606 return PS_ERROR;
0607 }
0608 res = v->GetUp(-1);
0609 v->Pop();
0610 }
0611 }
0612 v->Push(res);
0613 return 1;
0614 }
0615
0616 static PSInteger array_filter(HPSCRIPTVM v)
0617 {
0618 PSObject &o = stack_get(v,1);
0619 PSArray *a = _array(o);
0620 PSObjectPtr ret = PSArray::Create(_ss(v),0);
0621 PSInteger size = a->Size();
0622 PSObjectPtr val;
0623 for(PSInteger n = 0; n < size; n++) {
0624 a->Get(n,val);
0625 v->Push(o);
0626 v->Push(n);
0627 v->Push(val);
0628 if(PS_FAILED(ps_call(v,3,PSTrue,PSFalse))) {
0629 return PS_ERROR;
0630 }
0631 if(!PSVM::IsFalse(v->GetUp(-1))) {
0632 _array(ret)->Append(val);
0633 }
0634 v->Pop();
0635 }
0636 v->Push(ret);
0637 return 1;
0638 }
0639
0640 static PSInteger array_find(HPSCRIPTVM v)
0641 {
0642 PSObject &o = stack_get(v,1);
0643 PSObjectPtr &val = stack_get(v,2);
0644 PSArray *a = _array(o);
0645 PSInteger size = a->Size();
0646 PSObjectPtr temp;
0647 for(PSInteger n = 0; n < size; n++) {
0648 bool res = false;
0649 a->Get(n,temp);
0650 if(PSVM::IsEqual(temp,val,res) && res) {
0651 v->Push(n);
0652 return 1;
0653 }
0654 }
0655 return 0;
0656 }
0657
0658
0659 static bool _sort_compare(HPSCRIPTVM v,PSObjectPtr &a,PSObjectPtr &b,PSInteger func,PSInteger &ret)
0660 {
0661 if(func < 0) {
0662 if(!v->ObjCmp(a,b,ret)) return false;
0663 }
0664 else {
0665 PSInteger top = ps_gettop(v);
0666 ps_push(v, func);
0667 ps_pushroottable(v);
0668 v->Push(a);
0669 v->Push(b);
0670 if(PS_FAILED(ps_call(v, 3, PSTrue, PSFalse))) {
0671 if(!ps_isstring( v->_lasterror))
0672 v->Raise_Error(_SC("compare func failed"));
0673 return false;
0674 }
0675 if(PS_FAILED(ps_getinteger(v, -1, &ret))) {
0676 v->Raise_Error(_SC("numeric value expected as return value of the compare function"));
0677 return false;
0678 }
0679 ps_settop(v, top);
0680 return true;
0681 }
0682 return true;
0683 }
0684
0685 static bool _hsort_sift_down(HPSCRIPTVM v,PSArray *arr, PSInteger root, PSInteger bottom, PSInteger func)
0686 {
0687 PSInteger maxChild;
0688 PSInteger done = 0;
0689 PSInteger ret;
0690 PSInteger root2;
0691 while (((root2 = root * 2) <= bottom) && (!done))
0692 {
0693 if (root2 == bottom) {
0694 maxChild = root2;
0695 }
0696 else {
0697 if(!_sort_compare(v,arr->_values[root2],arr->_values[root2 + 1],func,ret))
0698 return false;
0699 if (ret > 0) {
0700 maxChild = root2;
0701 }
0702 else {
0703 maxChild = root2 + 1;
0704 }
0705 }
0706
0707 if(!_sort_compare(v,arr->_values[root],arr->_values[maxChild],func,ret))
0708 return false;
0709 if (ret < 0) {
0710 if (root == maxChild) {
0711 v->Raise_Error(_SC("inconsistent compare function"));
0712 return false;
0713 }
0714
0715 _Swap(arr->_values[root],arr->_values[maxChild]);
0716 root = maxChild;
0717 }
0718 else {
0719 done = 1;
0720 }
0721 }
0722 return true;
0723 }
0724
0725 static bool _hsort(HPSCRIPTVM v,PSObjectPtr &arr, PSInteger PS_UNUSED_ARG(l), PSInteger PS_UNUSED_ARG(r),PSInteger func)
0726 {
0727 PSArray *a = _array(arr);
0728 PSInteger i;
0729 PSInteger array_size = a->Size();
0730 for (i = (array_size / 2); i >= 0; i--) {
0731 if(!_hsort_sift_down(v,a, i, array_size - 1,func)) return false;
0732 }
0733
0734 for (i = array_size-1; i >= 1; i--)
0735 {
0736 _Swap(a->_values[0],a->_values[i]);
0737 if(!_hsort_sift_down(v,a, 0, i-1,func)) return false;
0738 }
0739 return true;
0740 }
0741
0742 static PSInteger array_sort(HPSCRIPTVM v)
0743 {
0744 PSInteger func = -1;
0745 PSObjectPtr &o = stack_get(v,1);
0746 if(_array(o)->Size() > 1) {
0747 if(ps_gettop(v) == 2) func = 2;
0748 if(!_hsort(v, o, 0, _array(o)->Size()-1, func))
0749 return PS_ERROR;
0750
0751 }
0752 return 0;
0753 }
0754
0755 static PSInteger array_slice(HPSCRIPTVM v)
0756 {
0757 PSInteger sidx,eidx;
0758 PSObjectPtr o;
0759 if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
0760 PSInteger alen = _array(o)->Size();
0761 if(sidx < 0)sidx = alen + sidx;
0762 if(eidx < 0)eidx = alen + eidx;
0763 if(eidx < sidx)return ps_throwerror(v,_SC("wrong indexes"));
0764 if(eidx > alen || sidx < 0)return ps_throwerror(v, _SC("slice out of range"));
0765 PSArray *arr=PSArray::Create(_ss(v),eidx-sidx);
0766 PSObjectPtr t;
0767 PSInteger count=0;
0768 for(PSInteger i=sidx;i<eidx;i++){
0769 _array(o)->Get(i,t);
0770 arr->Set(count++,t);
0771 }
0772 v->Push(arr);
0773 return 1;
0774
0775 }
0776
0777 const PSRegFunction PSSharedState::_array_default_delegate_funcz[]={
0778 {_SC("len"),default_delegate_len,1, _SC("a")},
0779 {_SC("append"),array_append,2, _SC("a")},
0780 {_SC("extend"),array_extend,2, _SC("aa")},
0781 {_SC("push"),array_append,2, _SC("a")},
0782 {_SC("pop"),array_pop,1, _SC("a")},
0783 {_SC("top"),array_top,1, _SC("a")},
0784 {_SC("insert"),array_insert,3, _SC("an")},
0785 {_SC("remove"),array_remove,2, _SC("an")},
0786 {_SC("resize"),array_resize,-2, _SC("an")},
0787 {_SC("reverse"),array_reverse,1, _SC("a")},
0788 {_SC("sort"),array_sort,-1, _SC("ac")},
0789 {_SC("slice"),array_slice,-1, _SC("ann")},
0790 {_SC("weakref"),obj_delegate_weakref,1, NULL },
0791 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
0792 {_SC("clear"),obj_clear,1, _SC(".")},
0793 {_SC("map"),array_map,2, _SC("ac")},
0794 {_SC("apply"),array_apply,2, _SC("ac")},
0795 {_SC("reduce"),array_reduce,2, _SC("ac")},
0796 {_SC("filter"),array_filter,2, _SC("ac")},
0797 {_SC("find"),array_find,2, _SC("a.")},
0798 {NULL,(PSFUNCTION)0,0,NULL}
0799 };
0800
0801
0802 static PSInteger string_slice(HPSCRIPTVM v)
0803 {
0804 PSInteger sidx,eidx;
0805 PSObjectPtr o;
0806 if(PS_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
0807 PSInteger slen = _string(o)->_len;
0808 if(sidx < 0)sidx = slen + sidx;
0809 if(eidx < 0)eidx = slen + eidx;
0810 if(eidx < sidx) return ps_throwerror(v,_SC("wrong indexes"));
0811 if(eidx > slen || sidx < 0) return ps_throwerror(v, _SC("slice out of range"));
0812 v->Push(PSString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
0813 return 1;
0814 }
0815
0816 static PSInteger string_find(HPSCRIPTVM v)
0817 {
0818 PSInteger top,start_idx=0;
0819 const PSChar *str,*substr,*ret;
0820 if(((top=ps_gettop(v))>1) && PS_SUCCEEDED(ps_getstring(v,1,&str)) && PS_SUCCEEDED(ps_getstring(v,2,&substr))){
0821 if(top>2)ps_getinteger(v,3,&start_idx);
0822 if((ps_getsize(v,1)>start_idx) && (start_idx>=0)){
0823 ret=scstrstr(&str[start_idx],substr);
0824 if(ret){
0825 ps_pushinteger(v,(PSInteger)(ret-str));
0826 return 1;
0827 }
0828 }
0829 return 0;
0830 }
0831 return ps_throwerror(v,_SC("invalid param"));
0832 }
0833
0834 #define STRING_TOFUNCZ(func) static PSInteger string_##func(HPSCRIPTVM v) \
0835 {\
0836 PSInteger sidx,eidx; \
0837 PSObjectPtr str; \
0838 if(PS_FAILED(get_slice_params(v,sidx,eidx,str)))return -1; \
0839 PSInteger slen = _string(str)->_len; \
0840 if(sidx < 0)sidx = slen + sidx; \
0841 if(eidx < 0)eidx = slen + eidx; \
0842 if(eidx < sidx) return ps_throwerror(v,_SC("wrong indexes")); \
0843 if(eidx > slen || sidx < 0) return ps_throwerror(v,_SC("slice out of range")); \
0844 PSInteger len=_string(str)->_len; \
0845 const PSChar *sthis=_stringval(str); \
0846 PSChar *snew=(_ss(v)->GetScratchPad(ps_rsl(len))); \
0847 memcpy(snew,sthis,ps_rsl(len));\
0848 for(PSInteger i=sidx;i<eidx;i++) snew[i] = func(sthis[i]); \
0849 v->Push(PSString::Create(_ss(v),snew,len)); \
0850 return 1; \
0851 }
0852
0853
0854 STRING_TOFUNCZ(tolower)
0855 STRING_TOFUNCZ(toupper)
0856
0857 const PSRegFunction PSSharedState::_string_default_delegate_funcz[]={
0858 {_SC("len"),default_delegate_len,1, _SC("s")},
0859 {_SC("tointeger"),default_delegate_tointeger,-1, _SC("sn")},
0860 {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
0861 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
0862 {_SC("slice"),string_slice,-1, _SC("s n n")},
0863 {_SC("find"),string_find,-2, _SC("s s n")},
0864 {_SC("tolower"),string_tolower,-1, _SC("s n n")},
0865 {_SC("toupper"),string_toupper,-1, _SC("s n n")},
0866 {_SC("weakref"),obj_delegate_weakref,1, NULL },
0867 {NULL,(PSFUNCTION)0,0,NULL}
0868 };
0869
0870
0871 const PSRegFunction PSSharedState::_number_default_delegate_funcz[]={
0872 {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
0873 {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
0874 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
0875 {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
0876 {_SC("weakref"),obj_delegate_weakref,1, NULL },
0877 {NULL,(PSFUNCTION)0,0,NULL}
0878 };
0879
0880
0881 static PSInteger closure_pcall(HPSCRIPTVM v)
0882 {
0883 return PS_SUCCEEDED(ps_call(v,ps_gettop(v)-1,PSTrue,PSFalse))?1:PS_ERROR;
0884 }
0885
0886 static PSInteger closure_call(HPSCRIPTVM v)
0887 {
0888 return PS_SUCCEEDED(ps_call(v,ps_gettop(v)-1,PSTrue,PSTrue))?1:PS_ERROR;
0889 }
0890
0891 static PSInteger _closure_acall(HPSCRIPTVM v,PSBool raiseerror)
0892 {
0893 PSArray *aparams=_array(stack_get(v,2));
0894 PSInteger nparams=aparams->Size();
0895 v->Push(stack_get(v,1));
0896 for(PSInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);
0897 return PS_SUCCEEDED(ps_call(v,nparams,PSTrue,raiseerror))?1:PS_ERROR;
0898 }
0899
0900 static PSInteger closure_acall(HPSCRIPTVM v)
0901 {
0902 return _closure_acall(v,PSTrue);
0903 }
0904
0905 static PSInteger closure_pacall(HPSCRIPTVM v)
0906 {
0907 return _closure_acall(v,PSFalse);
0908 }
0909
0910 static PSInteger closure_bindenv(HPSCRIPTVM v)
0911 {
0912 if(PS_FAILED(ps_bindenv(v,1)))
0913 return PS_ERROR;
0914 return 1;
0915 }
0916
0917 static PSInteger closure_getroot(HPSCRIPTVM v)
0918 {
0919 if(PS_FAILED(ps_getclosureroot(v,-1)))
0920 return PS_ERROR;
0921 return 1;
0922 }
0923
0924 static PSInteger closure_setroot(HPSCRIPTVM v)
0925 {
0926 if(PS_FAILED(ps_setclosureroot(v,-2)))
0927 return PS_ERROR;
0928 return 1;
0929 }
0930
0931 static PSInteger closure_getinfos(HPSCRIPTVM v) {
0932 PSObject o = stack_get(v,1);
0933 PSTable *res = PSTable::Create(_ss(v),4);
0934 if(type(o) == OT_CLOSURE) {
0935 PSFunctionProto *f = _closure(o)->_function;
0936 PSInteger nparams = f->_nparameters + (f->_varparams?1:0);
0937 PSObjectPtr params = PSArray::Create(_ss(v),nparams);
0938 PSObjectPtr defparams = PSArray::Create(_ss(v),f->_ndefaultparams);
0939 for(PSInteger n = 0; n<f->_nparameters; n++) {
0940 _array(params)->Set((PSInteger)n,f->_parameters[n]);
0941 }
0942 for(PSInteger j = 0; j<f->_ndefaultparams; j++) {
0943 _array(defparams)->Set((PSInteger)j,_closure(o)->_defaultparams[j]);
0944 }
0945 if(f->_varparams) {
0946 _array(params)->Set(nparams-1,PSString::Create(_ss(v),_SC("..."),-1));
0947 }
0948 res->NewSlot(PSString::Create(_ss(v),_SC("native"),-1),false);
0949 res->NewSlot(PSString::Create(_ss(v),_SC("name"),-1),f->_name);
0950 res->NewSlot(PSString::Create(_ss(v),_SC("src"),-1),f->_sourcename);
0951 res->NewSlot(PSString::Create(_ss(v),_SC("parameters"),-1),params);
0952 res->NewSlot(PSString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);
0953 res->NewSlot(PSString::Create(_ss(v),_SC("defparams"),-1),defparams);
0954 }
0955 else {
0956 PSNativeClosure *nc = _nativeclosure(o);
0957 res->NewSlot(PSString::Create(_ss(v),_SC("native"),-1),true);
0958 res->NewSlot(PSString::Create(_ss(v),_SC("name"),-1),nc->_name);
0959 res->NewSlot(PSString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);
0960 PSObjectPtr typecheck;
0961 if(nc->_typecheck.size() > 0) {
0962 typecheck =
0963 PSArray::Create(_ss(v), nc->_typecheck.size());
0964 for(PSUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {
0965 _array(typecheck)->Set((PSInteger)n,nc->_typecheck[n]);
0966 }
0967 }
0968 res->NewSlot(PSString::Create(_ss(v),_SC("typecheck"),-1),typecheck);
0969 }
0970 v->Push(res);
0971 return 1;
0972 }
0973
0974
0975
0976 const PSRegFunction PSSharedState::_closure_default_delegate_funcz[]={
0977 {_SC("call"),closure_call,-1, _SC("c")},
0978 {_SC("pcall"),closure_pcall,-1, _SC("c")},
0979 {_SC("acall"),closure_acall,2, _SC("ca")},
0980 {_SC("pacall"),closure_pacall,2, _SC("ca")},
0981 {_SC("weakref"),obj_delegate_weakref,1, NULL },
0982 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
0983 {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},
0984 {_SC("getinfos"),closure_getinfos,1, _SC("c")},
0985 {_SC("getroot"),closure_getroot,1, _SC("c")},
0986 {_SC("setroot"),closure_setroot,2, _SC("ct")},
0987 {NULL,(PSFUNCTION)0,0,NULL}
0988 };
0989
0990
0991 static PSInteger generator_getstatus(HPSCRIPTVM v)
0992 {
0993 PSObject &o=stack_get(v,1);
0994 switch(_generator(o)->_state){
0995 case PSGenerator::eSuspended:v->Push(PSString::Create(_ss(v),_SC("suspended")));break;
0996 case PSGenerator::eRunning:v->Push(PSString::Create(_ss(v),_SC("running")));break;
0997 case PSGenerator::eDead:v->Push(PSString::Create(_ss(v),_SC("dead")));break;
0998 }
0999 return 1;
1000 }
1001
1002 const PSRegFunction PSSharedState::_generator_default_delegate_funcz[]={
1003 {_SC("getstatus"),generator_getstatus,1, _SC("g")},
1004 {_SC("weakref"),obj_delegate_weakref,1, NULL },
1005 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
1006 {NULL,(PSFUNCTION)0,0,NULL}
1007 };
1008
1009
1010 static PSInteger thread_call(HPSCRIPTVM v)
1011 {
1012 PSObjectPtr o = stack_get(v,1);
1013 if(type(o) == OT_THREAD) {
1014 PSInteger nparams = ps_gettop(v);
1015 _thread(o)->Push(_thread(o)->_roottable);
1016 for(PSInteger i = 2; i<(nparams+1); i++)
1017 ps_move(_thread(o),v,i);
1018 if(PS_SUCCEEDED(ps_call(_thread(o),nparams,PSTrue,PSTrue))) {
1019 ps_move(v,_thread(o),-1);
1020 ps_pop(_thread(o),1);
1021 return 1;
1022 }
1023 v->_lasterror = _thread(o)->_lasterror;
1024 return PS_ERROR;
1025 }
1026 return ps_throwerror(v,_SC("wrong parameter"));
1027 }
1028
1029 static PSInteger thread_wakeup(HPSCRIPTVM v)
1030 {
1031 PSObjectPtr o = stack_get(v,1);
1032 if(type(o) == OT_THREAD) {
1033 PSVM *thread = _thread(o);
1034 PSInteger state = ps_getvmstate(thread);
1035 if(state != PS_VMSTATE_SUSPENDED) {
1036 switch(state) {
1037 case PS_VMSTATE_IDLE:
1038 return ps_throwerror(v,_SC("cannot wakeup a idle thread"));
1039 break;
1040 case PS_VMSTATE_RUNNING:
1041 return ps_throwerror(v,_SC("cannot wakeup a running thread"));
1042 break;
1043 }
1044 }
1045
1046 PSInteger wakeupret = ps_gettop(v)>1?PSTrue:PSFalse;
1047 if(wakeupret) {
1048 ps_move(thread,v,2);
1049 }
1050 if(PS_SUCCEEDED(ps_wakeupvm(thread,wakeupret,PSTrue,PSTrue,PSFalse))) {
1051 ps_move(v,thread,-1);
1052 ps_pop(thread,1);
1053 if(ps_getvmstate(thread) == PS_VMSTATE_IDLE) {
1054 ps_settop(thread,1);
1055 }
1056 return 1;
1057 }
1058 ps_settop(thread,1);
1059 v->_lasterror = thread->_lasterror;
1060 return PS_ERROR;
1061 }
1062 return ps_throwerror(v,_SC("wrong parameter"));
1063 }
1064
1065 static PSInteger thread_wakeupthrow(HPSCRIPTVM v)
1066 {
1067 PSObjectPtr o = stack_get(v,1);
1068 if(type(o) == OT_THREAD) {
1069 PSVM *thread = _thread(o);
1070 PSInteger state = ps_getvmstate(thread);
1071 if(state != PS_VMSTATE_SUSPENDED) {
1072 switch(state) {
1073 case PS_VMSTATE_IDLE:
1074 return ps_throwerror(v,_SC("cannot wakeup a idle thread"));
1075 break;
1076 case PS_VMSTATE_RUNNING:
1077 return ps_throwerror(v,_SC("cannot wakeup a running thread"));
1078 break;
1079 }
1080 }
1081
1082 ps_move(thread,v,2);
1083 ps_throwobject(thread);
1084 PSBool rethrow_error = PSTrue;
1085 if(ps_gettop(v) > 2) {
1086 ps_getbool(v,3,&rethrow_error);
1087 }
1088 if(PS_SUCCEEDED(ps_wakeupvm(thread,PSFalse,PSTrue,PSTrue,PSTrue))) {
1089 ps_move(v,thread,-1);
1090 ps_pop(thread,1);
1091 if(ps_getvmstate(thread) == PS_VMSTATE_IDLE) {
1092 ps_settop(thread,1);
1093 }
1094 return 1;
1095 }
1096 ps_settop(thread,1);
1097 if(rethrow_error) {
1098 v->_lasterror = thread->_lasterror;
1099 return PS_ERROR;
1100 }
1101 return PS_OK;
1102 }
1103 return ps_throwerror(v,_SC("wrong parameter"));
1104 }
1105
1106 static PSInteger thread_getstatus(HPSCRIPTVM v)
1107 {
1108 PSObjectPtr &o = stack_get(v,1);
1109 switch(ps_getvmstate(_thread(o))) {
1110 case PS_VMSTATE_IDLE:
1111 ps_pushstring(v,_SC("idle"),-1);
1112 break;
1113 case PS_VMSTATE_RUNNING:
1114 ps_pushstring(v,_SC("running"),-1);
1115 break;
1116 case PS_VMSTATE_SUSPENDED:
1117 ps_pushstring(v,_SC("suspended"),-1);
1118 break;
1119 default:
1120 return ps_throwerror(v,_SC("internal VM error"));
1121 }
1122 return 1;
1123 }
1124
1125 static PSInteger thread_getstackinfos(HPSCRIPTVM v)
1126 {
1127 PSObjectPtr o = stack_get(v,1);
1128 if(type(o) == OT_THREAD) {
1129 PSVM *thread = _thread(o);
1130 PSInteger threadtop = ps_gettop(thread);
1131 PSInteger level;
1132 ps_getinteger(v,-1,&level);
1133 PSRESULT res = __getcallstackinfos(thread,level);
1134 if(PS_FAILED(res))
1135 {
1136 ps_settop(thread,threadtop);
1137 if(type(thread->_lasterror) == OT_STRING) {
1138 ps_throwerror(v,_stringval(thread->_lasterror));
1139 }
1140 else {
1141 ps_throwerror(v,_SC("unknown error"));
1142 }
1143 }
1144 if(res > 0) {
1145
1146 ps_move(v,thread,-1);
1147 ps_settop(thread,threadtop);
1148 return 1;
1149 }
1150
1151 ps_settop(thread,threadtop);
1152 return 0;
1153
1154 }
1155 return ps_throwerror(v,_SC("wrong parameter"));
1156 }
1157
1158 const PSRegFunction PSSharedState::_thread_default_delegate_funcz[] = {
1159 {_SC("call"), thread_call, -1, _SC("v")},
1160 {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
1161 {_SC("wakeupthrow"), thread_wakeupthrow, -2, _SC("v.b")},
1162 {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
1163 {_SC("weakref"),obj_delegate_weakref,1, NULL },
1164 {_SC("getstackinfos"),thread_getstackinfos,2, _SC("vn")},
1165 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
1166 {NULL,(PSFUNCTION)0,0,NULL}
1167 };
1168
1169 static PSInteger class_getattributes(HPSCRIPTVM v)
1170 {
1171 return PS_SUCCEEDED(ps_getattributes(v,-2))?1:PS_ERROR;
1172 }
1173
1174 static PSInteger class_setattributes(HPSCRIPTVM v)
1175 {
1176 return PS_SUCCEEDED(ps_setattributes(v,-3))?1:PS_ERROR;
1177 }
1178
1179 static PSInteger class_instance(HPSCRIPTVM v)
1180 {
1181 return PS_SUCCEEDED(ps_createinstance(v,-1))?1:PS_ERROR;
1182 }
1183
1184 static PSInteger class_getbase(HPSCRIPTVM v)
1185 {
1186 return PS_SUCCEEDED(ps_getbase(v,-1))?1:PS_ERROR;
1187 }
1188
1189 static PSInteger class_newmember(HPSCRIPTVM v)
1190 {
1191 PSInteger top = ps_gettop(v);
1192 PSBool bstatic = PSFalse;
1193 if(top == 5)
1194 {
1195 ps_tobool(v,-1,&bstatic);
1196 ps_pop(v,1);
1197 }
1198
1199 if(top < 4) {
1200 ps_pushnull(v);
1201 }
1202 return PS_SUCCEEDED(ps_newmember(v,-4,bstatic))?1:PS_ERROR;
1203 }
1204
1205 static PSInteger class_rawnewmember(HPSCRIPTVM v)
1206 {
1207 PSInteger top = ps_gettop(v);
1208 PSBool bstatic = PSFalse;
1209 if(top == 5)
1210 {
1211 ps_tobool(v,-1,&bstatic);
1212 ps_pop(v,1);
1213 }
1214
1215 if(top < 4) {
1216 ps_pushnull(v);
1217 }
1218 return PS_SUCCEEDED(ps_rawnewmember(v,-4,bstatic))?1:PS_ERROR;
1219 }
1220
1221 const PSRegFunction PSSharedState::_class_default_delegate_funcz[] = {
1222 {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
1223 {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
1224 {_SC("rawget"),container_rawget,2, _SC("y")},
1225 {_SC("rawset"),container_rawset,3, _SC("y")},
1226 {_SC("rawin"),container_rawexists,2, _SC("y")},
1227 {_SC("weakref"),obj_delegate_weakref,1, NULL },
1228 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
1229 {_SC("instance"),class_instance,1, _SC("y")},
1230 {_SC("getbase"),class_getbase,1, _SC("y")},
1231 {_SC("newmember"),class_newmember,-3, _SC("y")},
1232 {_SC("rawnewmember"),class_rawnewmember,-3, _SC("y")},
1233 {NULL,(PSFUNCTION)0,0,NULL}
1234 };
1235
1236
1237 static PSInteger instance_getclass(HPSCRIPTVM v)
1238 {
1239 if(PS_SUCCEEDED(ps_getclass(v,1)))
1240 return 1;
1241 return PS_ERROR;
1242 }
1243
1244 const PSRegFunction PSSharedState::_instance_default_delegate_funcz[] = {
1245 {_SC("getclass"), instance_getclass, 1, _SC("x")},
1246 {_SC("rawget"),container_rawget,2, _SC("x")},
1247 {_SC("rawset"),container_rawset,3, _SC("x")},
1248 {_SC("rawin"),container_rawexists,2, _SC("x")},
1249 {_SC("weakref"),obj_delegate_weakref,1, NULL },
1250 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
1251 {NULL,(PSFUNCTION)0,0,NULL}
1252 };
1253
1254 static PSInteger weakref_ref(HPSCRIPTVM v)
1255 {
1256 if(PS_FAILED(ps_getweakrefval(v,1)))
1257 return PS_ERROR;
1258 return 1;
1259 }
1260
1261 const PSRegFunction PSSharedState::_weakref_default_delegate_funcz[] = {
1262 {_SC("ref"),weakref_ref,1, _SC("r")},
1263 {_SC("weakref"),obj_delegate_weakref,1, NULL },
1264 {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
1265 {NULL,(PSFUNCTION)0,0,NULL}
1266 };