Annotation of sbbs/src/sbbs3/js_internal.c, revision 1.1.1.2

1.1       root        1: /* js_internal.c */
                      2: 
                      3: /* Synchronet "js" object, for internal JavaScript branch and GC control */
                      4: 
1.1.1.2 ! root        5: /* $Id: js_internal.c,v 1.55 2011/08/31 22:01:27 rswindell Exp $ */
1.1       root        6: 
                      7: /****************************************************************************
                      8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                     10:  *                                                                                                                                                     *
1.1.1.2 ! root       11:  * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html         *
1.1       root       12:  *                                                                                                                                                     *
                     13:  * This program is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU General Public License                         *
                     15:  * as published by the Free Software Foundation; either version 2                      *
                     16:  * of the License, or (at your option) any later version.                                      *
                     17:  * See the GNU General Public License for more details: gpl.txt or                     *
                     18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
                     19:  *                                                                                                                                                     *
                     20:  * Anonymous FTP access to the most recent released source is available at     *
                     21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     22:  *                                                                                                                                                     *
                     23:  * Anonymous CVS access to the development source and modification history     *
                     24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     26:  *     (just hit return, no password is necessary)                                                     *
                     27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     28:  *                                                                                                                                                     *
                     29:  * For Synchronet coding style and modification guidelines, see                                *
                     30:  * http://www.synchro.net/source.html                                                                          *
                     31:  *                                                                                                                                                     *
                     32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     33:  * format) via e-mail to [email protected]                                                                      *
                     34:  *                                                                                                                                                     *
                     35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     36:  ****************************************************************************/
                     37: 
                     38: #include "sbbs.h"
1.1.1.2 ! root       39: #include "js_request.h"
1.1       root       40: 
1.1.1.2 ! root       41: #ifdef _DEBUG
        !            42:        #include <jscntxt.h>    /* Needed for Context-private data structure */
        !            43: #endif
1.1       root       44: 
                     45: enum {
                     46:         PROP_VERSION
                     47:        ,PROP_TERMINATED
                     48:        ,PROP_AUTO_TERMINATE
                     49:        ,PROP_BRANCH_COUNTER
                     50:        ,PROP_BRANCH_LIMIT
                     51:        ,PROP_YIELD_INTERVAL
                     52:        ,PROP_GC_INTERVAL
                     53:        ,PROP_GC_ATTEMPTS
                     54: #ifdef jscntxt_h___
                     55:        ,PROP_GC_COUNTER
                     56:        ,PROP_GC_LASTBYTES
                     57:        ,PROP_BYTES
                     58:        ,PROP_MAXBYTES
                     59: #endif
                     60:        ,PROP_GLOBAL
                     61: };
                     62: 
                     63: static JSBool js_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                     64: {
                     65:     jsint                      tiny;
                     66:        js_branch_t*    branch;
                     67: 
                     68:        if((branch=(js_branch_t*)JS_GetPrivate(cx,obj))==NULL)
                     69:                return(JS_FALSE);
                     70: 
                     71:     tiny = JSVAL_TO_INT(id);
                     72: 
                     73:        switch(tiny) {
                     74:                case PROP_VERSION:
                     75:                        *vp=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,(char *)JS_GetImplementationVersion()));
                     76:                        break;
                     77:                case PROP_TERMINATED:
                     78:                        if(branch->terminated==NULL)
                     79:                                *vp=JSVAL_FALSE;
                     80:                        else
                     81:                                *vp=BOOLEAN_TO_JSVAL(*branch->terminated);
                     82:                        break;
                     83:                case PROP_AUTO_TERMINATE:
                     84:                        *vp=BOOLEAN_TO_JSVAL(branch->auto_terminate);
                     85:                        break;
                     86:                case PROP_BRANCH_COUNTER:
                     87:                        JS_NewNumberValue(cx,branch->counter,vp);
                     88:                        break;
                     89:                case PROP_BRANCH_LIMIT:
                     90:                        JS_NewNumberValue(cx,branch->limit,vp);
                     91:                        break;
                     92:                case PROP_YIELD_INTERVAL:
                     93:                        JS_NewNumberValue(cx,branch->yield_interval,vp);
                     94:                        break;
                     95:                case PROP_GC_INTERVAL:
                     96:                        JS_NewNumberValue(cx,branch->gc_interval,vp);
                     97:                        break;
                     98:                case PROP_GC_ATTEMPTS:
                     99:                        JS_NewNumberValue(cx,branch->gc_attempts,vp);
                    100:                        break;
                    101: #ifdef jscntxt_h___
                    102:                case PROP_GC_COUNTER:
                    103:                        JS_NewNumberValue(cx,cx->runtime->gcNumber,vp);
                    104:                        break;
                    105:                case PROP_GC_LASTBYTES:
                    106:                        JS_NewNumberValue(cx,cx->runtime->gcLastBytes,vp);
                    107:                        break;
                    108:                case PROP_BYTES:
                    109:                        JS_NewNumberValue(cx,cx->runtime->gcBytes,vp);
                    110:                        break;
                    111:                case PROP_MAXBYTES:
                    112:                        JS_NewNumberValue(cx,cx->runtime->gcMaxBytes,vp);
                    113:                        break;
1.1.1.2 ! root      114: #endif
1.1       root      115:                case PROP_GLOBAL:
1.1.1.2 ! root      116:                        *vp = OBJECT_TO_JSVAL(JS_GetGlobalObject(cx));  
1.1       root      117:                        break;
                    118:        }
                    119: 
                    120:        return(JS_TRUE);
                    121: }
                    122: 
                    123: static JSBool js_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                    124: {
                    125:     jsint                      tiny;
                    126:        js_branch_t*    branch;
                    127: 
                    128:        if((branch=(js_branch_t*)JS_GetPrivate(cx,obj))==NULL)
                    129:                return(JS_FALSE);
                    130: 
                    131:     tiny = JSVAL_TO_INT(id);
                    132: 
                    133:        switch(tiny) {
                    134:                case PROP_TERMINATED:
                    135:                        if(branch->terminated!=NULL)
1.1.1.2 ! root      136:                                JS_ValueToBoolean(cx, *vp, (int *)branch->terminated);
1.1       root      137:                        break;
                    138:                case PROP_AUTO_TERMINATE:
                    139:                        JS_ValueToBoolean(cx,*vp,&branch->auto_terminate);
                    140:                        break;
                    141:                case PROP_BRANCH_COUNTER:
                    142:                        JS_ValueToInt32(cx, *vp, (int32*)&branch->counter);
                    143:                        break;
                    144:                case PROP_BRANCH_LIMIT:
                    145:                        JS_ValueToInt32(cx, *vp, (int32*)&branch->limit);
                    146:                        break;
                    147:                case PROP_GC_INTERVAL:
                    148:                        JS_ValueToInt32(cx, *vp, (int32*)&branch->gc_interval);
                    149:                        break;
                    150:                case PROP_YIELD_INTERVAL:
                    151:                        JS_ValueToInt32(cx, *vp, (int32*)&branch->yield_interval);
                    152:                        break;
                    153: #ifdef jscntxt_h___
                    154:                case PROP_MAXBYTES:
                    155:                        JS_ValueToInt32(cx, *vp, (int32*)&cx->runtime->gcMaxBytes);
                    156:                        break;
                    157: #endif
                    158:        }
                    159: 
                    160:        return(JS_TRUE);
                    161: }
                    162: 
                    163: #define PROP_FLAGS     JSPROP_ENUMERATE|JSPROP_READONLY
                    164: 
                    165: static jsSyncPropertySpec js_properties[] = {
                    166: /*              name,                          tinyid,                                         flags,          ver     */
                    167: 
                    168:        {       "version",                      PROP_VERSION,           PROP_FLAGS,                     311 },
                    169:        {       "auto_terminate",       PROP_AUTO_TERMINATE,JSPROP_ENUMERATE,   311 },
                    170:        {       "terminated",           PROP_TERMINATED,        JSPROP_ENUMERATE,       311 },
                    171:        {       "branch_counter",       PROP_BRANCH_COUNTER,JSPROP_ENUMERATE,   311 },
                    172:        {       "branch_limit",         PROP_BRANCH_LIMIT,      JSPROP_ENUMERATE,       311 },
                    173:        {       "yield_interval",       PROP_YIELD_INTERVAL,JSPROP_ENUMERATE,   311 },
                    174:        {       "gc_interval",          PROP_GC_INTERVAL,       JSPROP_ENUMERATE,       311 },
                    175:        {       "gc_attempts",          PROP_GC_ATTEMPTS,       PROP_FLAGS,                     311 },
                    176: #ifdef jscntxt_h___
                    177:        {       "gc_counter",           PROP_GC_COUNTER,        PROP_FLAGS,                     311 },
                    178:        {       "gc_last_bytes",        PROP_GC_LASTBYTES,      PROP_FLAGS,                     311 },
                    179:        {       "bytes",                        PROP_BYTES,                     PROP_FLAGS,                     311 },
                    180:        {       "max_bytes",            PROP_MAXBYTES,          JSPROP_ENUMERATE,       311 },
                    181: #endif
                    182:        {       "global",                       PROP_GLOBAL,            PROP_FLAGS,                     314 },
                    183:        {0}
                    184: };
                    185: 
                    186: #ifdef BUILD_JSDOCS
                    187: static char* prop_desc[] = {
                    188:         "JavaScript engine version information (AKA system.js_version)"
                    189:        ,"set to <i>false</i> to disable the automatic termination of the script upon external request"
                    190:        ,"termination has been requested (stop execution as soon as possible)"
                    191:        ,"number of branch operations performed in this runtime"
                    192:        ,"maximum number of branches, used for infinite-loop detection (0=disabled)"
                    193:        ,"interval of periodic time-slice yields (lower number=higher frequency, 0=disabled)"
                    194:        ,"interval of periodic garbage collection attempts (lower number=higher frequency, 0=disabled)"
                    195:        ,"number of garbage collections attempted in this runtime - <small>READ ONLY</small>"
                    196: #ifdef jscntxt_h___
                    197:        ,"number of garbage collections performed in this runtime - <small>READ ONLY</small>"
                    198:        ,"number of heap bytes in use after last garbage collection - <small>READ ONLY</small>"
                    199:        ,"number of heap bytes currently in use - <small>READ ONLY</small>"
                    200:        ,"maximum number of bytes available for heap"
                    201: #endif
                    202:        ,"global (top level) object - <small>READ ONLY</small>"
                    203:        ,NULL
                    204: };
                    205: #endif
                    206: 
                    207: JSBool DLLCALL
                    208: js_CommonBranchCallback(JSContext *cx, js_branch_t* branch)
                    209: {
                    210:        branch->counter++;
                    211: 
                    212:        /* Terminated? */
                    213:        if(branch->auto_terminate &&
                    214:                (branch->terminated!=NULL && *branch->terminated)) {
1.1.1.2 ! root      215:                JS_ReportWarning(cx,"Terminated");
1.1       root      216:                branch->counter=0;
                    217:                return(JS_FALSE);
                    218:        }
                    219: 
                    220:        /* Infinite loop? */
                    221:        if(branch->limit && branch->counter > branch->limit) {
                    222:                JS_ReportError(cx,"Infinite loop (%lu branches) detected",branch->counter);
                    223:                branch->counter=0;
                    224:                return(JS_FALSE);
                    225:        }
                    226: 
1.1.1.2 ! root      227: #ifndef USE_JS_OPERATION_CALLBACK
1.1       root      228:        /* Give up timeslices every once in a while */
1.1.1.2 ! root      229:        if(branch->yield_interval && (branch->counter%branch->yield_interval)==0) {
        !           230:                jsrefcount      rc;
        !           231: 
        !           232:                rc=JS_SUSPENDREQUEST(cx);
1.1       root      233:                YIELD();
1.1.1.2 ! root      234:                JS_RESUMEREQUEST(cx, rc);
        !           235:        }
1.1       root      236: 
                    237:        /* Periodic Garbage Collection */
                    238:        if(branch->gc_interval && (branch->counter%branch->gc_interval)==0)
                    239:                JS_MaybeGC(cx), branch->gc_attempts++;
1.1.1.2 ! root      240: #endif
1.1       root      241: 
                    242:     return(JS_TRUE);
                    243: }
                    244: 
                    245: /* Execute a string in its own context (away from Synchronet objects) */
                    246: static JSBool
                    247: js_eval(JSContext *parent_cx, JSObject *parent_obj, uintN argc, jsval *argv, jsval *rval)
                    248: {
                    249:        char*                   buf;
                    250:        size_t                  buflen;
                    251:        JSString*               str;
                    252:     JSScript*          script;
                    253:        JSContext*              cx;
                    254:        JSObject*               obj;
                    255:        JSErrorReporter reporter;
                    256: #ifndef EVAL_BRANCH_CALLBACK
1.1.1.2 ! root      257: #ifndef USE_JS_OPERATION_CALLBACK
1.1       root      258:        JSBranchCallback callback;
                    259: #endif
1.1.1.2 ! root      260: #endif
1.1       root      261: 
                    262:        if(argc<1)
                    263:                return(JS_TRUE);
                    264: 
                    265:        if((str=JS_ValueToString(parent_cx, argv[0]))==NULL)
                    266:                return(JS_FALSE);
                    267:        if((buf=JS_GetStringBytes(str))==NULL)
                    268:                return(JS_FALSE);
                    269:        buflen=JS_GetStringLength(str);
                    270: 
                    271:        if((cx=JS_NewContext(JS_GetRuntime(parent_cx),JAVASCRIPT_CONTEXT_STACK))==NULL)
                    272:                return(JS_FALSE);
                    273: 
                    274:        /* Use the error reporter from the parent context */
                    275:        reporter=JS_SetErrorReporter(parent_cx,NULL);
                    276:        JS_SetErrorReporter(parent_cx,reporter);
                    277:        JS_SetErrorReporter(cx,reporter);
                    278: 
                    279: #ifdef EVAL_BRANCH_CALLBACK
                    280:        JS_SetContextPrivate(cx, JS_GetPrivate(parent_cx, parent_obj));
1.1.1.2 ! root      281: #ifdef USE_JS_OPERATION_CALLBACK
        !           282:        JS_SetOperationCallback(cx, js_OperationCallback);
        !           283: #else
1.1       root      284:        JS_SetBranchCallback(cx, js_BranchCallback);
1.1.1.2 ! root      285: #endif
1.1       root      286: #else  /* Use the branch callback from the parent context */
                    287:        JS_SetContextPrivate(cx, JS_GetContextPrivate(parent_cx));
1.1.1.2 ! root      288: #ifdef USE_JS_OPERATION_CALLBACK
        !           289:        JS_SetOperationCallback(cx, JS_GetOperationCallback(parent_cx));
        !           290: #else
1.1       root      291:        callback=JS_SetBranchCallback(parent_cx,NULL);
                    292:        JS_SetBranchCallback(parent_cx, callback);
                    293:        JS_SetBranchCallback(cx, callback);
                    294: #endif
1.1.1.2 ! root      295: #endif
1.1       root      296: 
                    297:        if((obj=JS_NewObject(cx, NULL, NULL, NULL))==NULL
                    298:                || !JS_InitStandardClasses(cx,obj)) {
                    299:                JS_DestroyContext(cx);
                    300:                return(JS_FALSE);
                    301:        }
                    302: 
                    303:        if((script=JS_CompileScript(cx, obj, buf, buflen, NULL, 0))!=NULL) {
                    304:                JS_ExecuteScript(cx, obj, script, rval);
                    305:                JS_DestroyScript(cx, script);
                    306:        }
                    307: 
                    308:        JS_DestroyContext(cx);
                    309: 
                    310:     return(JS_TRUE);
                    311: }
                    312: 
                    313: static JSBool
                    314: js_gc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    315: {
                    316:        JSBool                  forced=JS_TRUE;
                    317:        js_branch_t*    branch;
                    318: 
                    319:        if((branch=(js_branch_t*)JS_GetPrivate(cx,obj))==NULL)
                    320:                return(JS_FALSE);
                    321: 
                    322:        if(argc)
                    323:                JS_ValueToBoolean(cx,argv[0],&forced);
                    324: 
                    325:        if(forced)
                    326:                JS_GC(cx);
                    327:        else
                    328:                JS_MaybeGC(cx);
                    329: 
                    330:        branch->gc_attempts++;
                    331: 
                    332:        return(JS_TRUE);
                    333: }
                    334: 
                    335: static JSBool
                    336: js_report_error(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    337: {
                    338:        JS_ReportError(cx,"%s",JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
                    339: 
                    340:        if(argc>1 && argv[1]==JSVAL_TRUE)
                    341:                return(JS_FALSE);       /* fatal */
                    342: 
                    343:        return(JS_TRUE);
                    344: }
                    345: 
                    346: static JSBool
                    347: js_on_exit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    348: {
                    349:        js_branch_t*    branch;
                    350: 
                    351:        if((branch=(js_branch_t*)JS_GetPrivate(cx,obj))==NULL)
                    352:                return(JS_FALSE);
                    353: 
                    354:        if(branch->exit_func==NULL)
                    355:                branch->exit_func=strListInit();
                    356: 
                    357:        strListPush(&branch->exit_func,JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
                    358: 
                    359:        return(JS_TRUE);
                    360: }
                    361: 
                    362: static JSBool
                    363: js_get_parent(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    364: {
                    365:        JSObject* child=NULL;
                    366:        JSObject* parent;
                    367: 
                    368:        if(JS_ValueToObject(cx, argv[0], &child)
                    369:                && child!=NULL
                    370:                && (parent=JS_GetParent(cx,child))!=NULL)
                    371:                *rval = OBJECT_TO_JSVAL(parent);
                    372: 
                    373:        return(JS_TRUE);
                    374: }
                    375: 
                    376: static jsSyncMethodSpec js_functions[] = {
                    377:        {"eval",            js_eval,            0,      JSTYPE_UNDEF,   JSDOCSTR("script")
                    378:        ,JSDOCSTR("evaluate a JavaScript string in its own (secure) context, returning the result")
                    379:        ,311
                    380:        },              
                    381:        {"gc",                          js_gc,                          0,      JSTYPE_VOID,    JSDOCSTR("forced=<tt>true</tt>")
                    382:        ,JSDOCSTR("perform a garbage collection operation (freeing memory for unused allocated objects), "
                    383:                "if <i>forced</i> is <i>true</i> (the default) a garbage collection is always performed, "
                    384:                "otherwise it is only performed if deemed appropriate by the JavaScript engine")
                    385:        ,311
                    386:        },
                    387:        {"on_exit",                     js_on_exit,                     1,      JSTYPE_VOID,    JSDOCSTR("to_eval")
                    388:        ,JSDOCSTR("add a string to evaluate/execute (LIFO stack) upon script's termination")
                    389:        ,313
                    390:        },
                    391:        {"report_error",        js_report_error,        1,      JSTYPE_VOID,    JSDOCSTR("error [,fatal=<tt>false</tt>]")
                    392:        ,JSDOCSTR("report an error using the standard JavaScript error reporting mechanism "
                    393:        "(including script filename and line number), "
                    394:        "if <i>fatal</i> is <i>true</i>, immediately terminates script")
                    395:        ,313
                    396:        },
                    397:        {"get_parent",          js_get_parent,          1,      JSTYPE_OBJECT,  JSDOCSTR("object")
                    398:        ,JSDOCSTR("return the parent of the specified object")
                    399:        ,314
                    400:        },
                    401:        {0}
                    402: };
                    403: 
1.1.1.2 ! root      404: static JSBool js_internal_resolve(JSContext *cx, JSObject *obj, jsval id)
        !           405: {
        !           406:        char*                   name=NULL;
        !           407: 
        !           408:        if(id != JSVAL_NULL)
        !           409:                name=JS_GetStringBytes(JSVAL_TO_STRING(id));
        !           410: 
        !           411:        return(js_SyncResolve(cx, obj, name, js_properties, js_functions, NULL, 0));
        !           412: }
        !           413: 
        !           414: static JSBool js_internal_enumerate(JSContext *cx, JSObject *obj)
        !           415: {
        !           416:        return(js_internal_resolve(cx, obj, JSVAL_NULL));
        !           417: }
        !           418: 
        !           419: static JSClass js_internal_class = {
        !           420:      "JsInternal"                              /* name                 */
        !           421:     ,JSCLASS_HAS_PRIVATE       /* flags                */
        !           422:        ,JS_PropertyStub                /* addProperty  */
        !           423:        ,JS_PropertyStub                /* delProperty  */
        !           424:        ,js_get                                 /* getProperty  */
        !           425:        ,js_set                                 /* setProperty  */
        !           426:        ,js_internal_enumerate  /* enumerate    */
        !           427:        ,js_internal_resolve    /* resolve              */
        !           428:        ,JS_ConvertStub                 /* convert              */
        !           429:        ,JS_FinalizeStub                /* finalize             */
        !           430: };
        !           431: 
1.1       root      432: void DLLCALL js_EvalOnExit(JSContext *cx, JSObject *obj, js_branch_t* branch)
                    433: {
                    434:        char*   p;
                    435:        jsval   rval;
                    436:        JSScript* script;
1.1.1.2 ! root      437:        BOOL    auto_terminate=branch->auto_terminate;
        !           438: 
        !           439:        branch->auto_terminate=FALSE;
1.1       root      440: 
                    441:        while((p=strListPop(&branch->exit_func))!=NULL) {
                    442:                if((script=JS_CompileScript(cx, obj, p, strlen(p), NULL, 0))!=NULL) {
                    443:                        JS_ExecuteScript(cx, obj, script, &rval);
                    444:                        JS_DestroyScript(cx, script);
                    445:                }
1.1.1.2 ! root      446:                free(p);
1.1       root      447:        }
                    448: 
                    449:        strListFree(&branch->exit_func);
1.1.1.2 ! root      450: 
        !           451:        if(auto_terminate)
        !           452:                branch->auto_terminate = TRUE;
1.1       root      453: }
                    454: 
1.1.1.2 ! root      455: JSObject* DLLCALL js_CreateInternalJsObject(JSContext* cx, JSObject* parent, js_branch_t* branch, js_startup_t* startup)
1.1       root      456: {
                    457:        JSObject*       obj;
                    458: 
                    459:        if((obj = JS_DefineObject(cx, parent, "js", &js_internal_class, NULL
                    460:                ,JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
                    461:                return(NULL);
                    462: 
                    463:        if(!JS_SetPrivate(cx, obj, branch))     /* Store a pointer to js_branch_t */
                    464:                return(NULL);
                    465: 
1.1.1.2 ! root      466:        if(startup!=NULL) {
        !           467:                JSObject*       load_path_list;
        !           468:                jsval           val;
        !           469:                str_list_t      load_path;
        !           470: 
        !           471:                if((load_path_list=JS_NewArrayObject(cx, 0, NULL))==NULL) 
        !           472:                        return(NULL);
        !           473:                val=OBJECT_TO_JSVAL(load_path_list);
        !           474:                if(!JS_SetProperty(cx, obj, JAVASCRIPT_LOAD_PATH_LIST, &val)) 
        !           475:                        return(NULL);
        !           476: 
        !           477:                if((load_path=strListSplitCopy(NULL, startup->load_path, ",")) != NULL) {
        !           478:                        JSString*       js_str;
        !           479:                        unsigned        i;
        !           480: 
        !           481:                        for(i=0; load_path[i]!=NULL; i++) {
        !           482:                                if((js_str=JS_NewStringCopyZ(cx, load_path[i]))==NULL)
        !           483:                                        break;
        !           484:                                val=STRING_TO_JSVAL(js_str);
        !           485:                                if(!JS_SetElement(cx, load_path_list, i, &val))
        !           486:                                        break;
        !           487:                        }
        !           488:                        strListFree(&load_path);
        !           489:                }
        !           490:        }
1.1       root      491: 
                    492: #ifdef BUILD_JSDOCS
                    493:        js_DescribeSyncObject(cx,obj,"JavaScript execution and garbage collection control object",311);
                    494:        js_CreateArrayOfStrings(cx, obj, "_property_desc_list", prop_desc, JSPROP_READONLY);
                    495: #endif
                    496: 
                    497:        return(obj);
                    498: }
1.1.1.2 ! root      499: 
        !           500: void DLLCALL js_PrepareToExecute(JSContext *cx, JSObject *obj, const char *filename, const char* startup_dir)
        !           501: {
        !           502:        JSString*       str;
        !           503:        jsval           val;
        !           504: 
        !           505:        if(JS_GetProperty(cx, obj, "js", &val) && JSVAL_IS_OBJECT(val)) {
        !           506:                JSObject* js = JSVAL_TO_OBJECT(val);
        !           507:                char    dir[MAX_PATH+1];
        !           508: 
        !           509:                if(filename!=NULL) {
        !           510:                        char* p;
        !           511: 
        !           512:                        if((str=JS_NewStringCopyZ(cx, filename)) != NULL)
        !           513:                                JS_DefineProperty(cx, js, "exec_path", STRING_TO_JSVAL(str)
        !           514:                                        ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
        !           515:                        if((str=JS_NewStringCopyZ(cx, getfname(filename))) != NULL)
        !           516:                                JS_DefineProperty(cx, js, "exec_file", STRING_TO_JSVAL(str)
        !           517:                                        ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
        !           518:                        SAFECOPY(dir,filename);
        !           519:                        p=getfname(dir);
        !           520:                        *p=0;
        !           521:                        if((str=JS_NewStringCopyZ(cx, dir)) != NULL)
        !           522:                                JS_DefineProperty(cx, js, "exec_dir", STRING_TO_JSVAL(str)
        !           523:                                        ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
        !           524:                }
        !           525:                if(startup_dir==NULL)
        !           526:                        startup_dir="";
        !           527:                if((str=JS_NewStringCopyZ(cx, startup_dir)) != NULL)
        !           528:                        JS_DefineProperty(cx, js, "startup_dir", STRING_TO_JSVAL(str)
        !           529:                                ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
        !           530:        }
        !           531: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.