Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | First example of a non-trivial event-driven Tcl program interacting with JS. Features after, [bgerror] and a primitive [domset]. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | ferrieux-nacl |
Files: | files | file ages | folders |
SHA1: |
21b74633e5401b388308e948136da8bc |
User & Date: | ferrieux 2011-04-08 22:47:23 |
Context
2011-04-10
| ||
11:25 | Cleanup of init, wrappers now compiled in. Coro-based [source $url]. Detailed description in README. check-in: 4d49dfa58c user: ferrieux tags: ferrieux-nacl | |
2011-04-08
| ||
22:47 | First example of a non-trivial event-driven Tcl program interacting with JS. Features after, [bger... check-in: 21b74633e5 user: ferrieux tags: ferrieux-nacl | |
2011-04-06
| ||
21:44 | Let nacl/tclUnixPort.h be a generated file rather than a source. check-in: bf7fead8fd user: ferrieux tags: ferrieux-nacl | |
Changes
Added nacl/balls.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | <!DOCTYPE html> <html> <!-- Copyright (c) 2010 The Native Client Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> <head> <title>Tcl in Nacl</title> <script type="text/javascript"> tclModule = null; // Global application object. xhr = null; tclReportError = ""; statusText = 'NO-STATUS'; function tclDo(s) { console.log("do:"+s); try { t = tclModule.eval("naclwrap {"+s+"}"); console.log("ret:"+t); eval(t); } catch(err) { console.log("err:"+err); tclReportError="bgerror {"+err+" -- while doing: "+t+"}"; setTimeout('tclDo(tclReportError)',0); } } function moduleDidLoad() { tclModule = document.getElementById('tcl'); tclModule.eval('proc bgerror s {printf "### BGERROR: $s";regsub -all {[\'\'\\\\]} $s {\\\\&} s;regsub -all \\n $s \t s;return "alert(\'### BGERROR: $s\');";}'); tclModule.eval('proc naclwrap s {set ::JS "";if {[catch {uplevel 1 $s} err]} {set ::JS [bgerror $err]};return $::JS} '); updateStatus('NaTcl Loaded ; fetching script...'); xhr = new XMLHttpRequest(); xhr.open("GET","balls.natcl",true); xhr.send(null); xhr.onreadystatechange = function() { if (xhr.readyState==4) { if (xhr.status==200) { updateStatus("Running"); tclDo(xhr.responseText); } else { updateStatus("Cannot load script: "+xhr.status+" "+xhr.statusText); } } }; } var statusField = null; // If the page loads before the Native Client module loads, then set the // status message indicating that the module is still loading. Otherwise, // do not change the status message. function pageDidLoad() { statusField = document.getElementById('status'); if (tclModule == null) { updateStatus('Loading Nacl...'); } else { // It's possible that the Native Client module onload event fired // before the page's onload event. In this case, the status message // will reflect 'SUCCESS', but won't be displayed. This call will // display the current message. updateStatus(); } } function doeval() { try { alert(tclModule.eval(this.the_form.input_id.value)); } catch(e) { alert(e.message); } } // Set the global status message. If the element with id 'status' // exists, then set its HTML to the status message as well. // opt_message The message test. If this is null or undefined, then // attempt to set the element with id 'status' to the value of // |statusText|. function updateStatus(opt_message) { if (opt_message) statusText = opt_message; if (statusField) { statusField.innerHTML = statusText; } } </script> </head> <body onload="pageDidLoad()"> <h1>Native Client Tcl Module</h1> <p> <form name="the_form" action="" method="get"> <input type="text" id="input_id" name="inputbox" value="list a b c"><p> <input type="button" value="Call eval()" onclick="doeval()"> </form> <!-- Load the published .nexe. This includes the 'nacl' attribute which shows how to load multi-architecture modules. Each entry in the "nexes" object in the .nmf manifest file is a key-value pair: the key is the runtime ('x86-32', 'x86-64', etc.); the value is a URL for the desired NaCl module. To load the debug versions of your .nexes, set the 'nacl' attribute to the _dbg.nmf version of the manifest file. --> <embed name="nacl_module" id="tcl" width=0 height=0 nacl="tcl.nmf" type="application/x-nacl" onload="moduleDidLoad();" /> </p> <p>If the module is working correctly, a click on the "Call eval()" button should open a popup dialog containing the Tcl result as its value.</p> <h2>Status</h2> <div id="status">NO-STATUS</div> <hr> </body> </html> |
Added nacl/balls.natcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #------ Std preamble proc after {ms script} { regsub -all {[""''\\]} $script {\\&} script append ::JS "setTimeout(\"tclDo('$script')\",$ms);\n" } proc domset {element inner} { regsub -all {[''\\]} $inner {\\&} inner regsub -all \n $inner \t inner append ::JS "$element.innerHTML='$inner';\n" } #------ App callbacks set cnt 0 proc daemon {} { after 1000 daemon printf DAEMON:$::cnt domset statusField "<h1 align='center'>DAEMON:$::cnt</h1>" incr ::cnt if {$::cnt>10} { error "Oh, I barfed !" } } #------ Runtime printf Salut!!! daemon |
Changes to nacl/index.html.
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 | // If the page loads before the Native Client module loads, then set the // status message indicating that the module is still loading. Otherwise, // do not change the status message. function pageDidLoad() { if (tclModule == null) { updateStatus('LOADING...'); } else { // It's possible that the Native Client module onload event fired // before the page's onload event. In this case, the status message // will reflect 'SUCCESS', but won't be displayed. This call will // display the current message. updateStatus(); } | > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // If the page loads before the Native Client module loads, then set the // status message indicating that the module is still loading. Otherwise, // do not change the status message. function pageDidLoad() { if (tclModule == null) { updateStatus('LOADING...'); alert(' FOO \' BAR \\ BAZ'); } else { // It's possible that the Native Client module onload event fired // before the page's onload event. In this case, the status message // will reflect 'SUCCESS', but won't be displayed. This call will // display the current message. updateStatus(); } |
︙ | ︙ |
Changes to nacl/naclMain.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <errno.h> #include "tcl.h" #include "tclInt.h" static Tcl_Interp *interp = NULL; const char *init_tcl_contents = "set ::tcl_library {/}\n" # include "init.tcl.c" ; static Tcl_Interp *NewTcl(void) { Tcl_Interp *ii; | > > > > > > > > > > > > > > > > | | < | < | | | | > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | #include <errno.h> #include "tcl.h" #include "tclInt.h" static Tcl_Interp *interp = NULL; static int pid = 0; const char *init_tcl_contents = "set ::tcl_library {/}\n" # include "init.tcl.c" ; static int PrintfObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "string"); return TCL_ERROR; } printf("NaTcl(%d): %s\n", pid, Tcl_GetString(objv[1])); return TCL_OK; } static Tcl_Interp *NewTcl(void) { Tcl_Interp *ii; //printf("DBUG:TclInitSubsystems\n"); TclInitSubsystems(); //printf("DBUG:TclpSetInitialEncodings\n"); TclpSetInitialEncodings(); { volatile int x; x=0; if (x) printf("NaTcl(%d): BUSYLOOP : break out by resetting the var (set $eax=0)\n",pid); while(x) {} } // printf("DBUG:CreateInterp\n"); ii=Tcl_CreateInterp(); if (!ii) { printf("NaTcl(%d): Tcl CreateInterp Failed !!!\n",pid); return NULL; } //printf("DBUG:Tcl_Init2\n"); if (Tcl_Eval(ii,init_tcl_contents)!=TCL_OK) { printf("NaTcl(%d): Tcl Init Failed: %s !!!\n",pid,Tcl_GetStringResult(ii)); return NULL; } Tcl_CreateObjCommand(ii,"printf",PrintfObjCmd,NULL,NULL); return ii; } static const char *EvalTcl(char *s) { if (!interp) return "No Tcl Interp!!!"; Tcl_Eval(interp,s); return Tcl_GetStringResult(interp); |
︙ | ︙ | |||
228 229 230 231 232 233 234 | /** * Create scriptable object for the given instance. * @param[in] instance The instance ID. * @return A scriptable object. */ static struct PP_Var Instance_GetInstanceObject(PP_Instance instance) { | | > | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | /** * Create scriptable object for the given instance. * @param[in] instance The instance ID. * @return A scriptable object. */ static struct PP_Var Instance_GetInstanceObject(PP_Instance instance) { if (var_interface) { return var_interface->CreateObject(instance, &ppp_class, NULL); } return PP_MakeUndefined(); } /** * Check existence of the function associated with @a name. * @param[in] object unused * @param[in] name method name |
︙ | ︙ | |||
298 299 300 301 302 303 304 305 306 307 308 | * Initialize instance interface and scriptable object class. * @param[in] a_module_id module ID * @param[in] get_browser pointer to PPB_GetInterface * @return PP_OK on success, any other value on failure. */ PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface get_browser) { module_id = a_module_id; var_interface = (struct PPB_Var_Deprecated*)(get_browser(PPB_VAR_DEPRECATED_INTERFACE)); | > | | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | * Initialize instance interface and scriptable object class. * @param[in] a_module_id module ID * @param[in] get_browser pointer to PPB_GetInterface * @return PP_OK on success, any other value on failure. */ PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface get_browser) { pid = getpid(); module_id = a_module_id; var_interface = (struct PPB_Var_Deprecated*)(get_browser(PPB_VAR_DEPRECATED_INTERFACE)); printf("NaTcl(%d): DBUG: NaTcl starting\n",pid); interp = NewTcl(); if (!interp) return PP_ERROR_FAILED; memset(&ppp_class, 0, sizeof(ppp_class)); ppp_class.Call = Tcl_Call; ppp_class.HasMethod = Tcl_HasMethod; return PP_OK; |
︙ | ︙ |
Changes to nacl/tools/chrd.
1 | #! /bin/sh -x | | > | 1 2 3 4 | #! /bin/sh -x ./chromedebug http://localhost:5103/tcl/${1:-balls.html} |
Changes to nacl/tools/chromedebug.
1 2 | #! /bin/sh -x | > > | | 1 2 3 4 5 6 | #! /bin/sh -x google-chrome --no-sandbox "$@" #NACLVERBOSITY=2 google-chrome --no-sandbox "$@" #PPAPI_BROWSER_DEBUG=1 NACL_PLUGIN_DEBUG=1 NACL_PPAPI_PROXY_DEBUG=1 NACLVERBOSITY=15 google-chrome --no-sandbox "$@" |