Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update to new (incompatible, stabilized) ABI. Now requires Chrome 15 or above. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | ferrieux-nacl |
Files: | files | file ages | folders |
SHA1: |
d6b778727b6a5879d15fb2bbc0a583b1 |
User & Date: | ferrieux 2011-10-18 06:33:49 |
Context
2011-10-18
| ||
22:03 | Streamline demo setup; update README to reflect API changes. check-in: 91aea72dbd user: ferrieux tags: ferrieux-nacl | |
06:33 | Update to new (incompatible, stabilized) ABI. Now requires Chrome 15 or above. check-in: d6b778727b user: ferrieux tags: ferrieux-nacl | |
2011-10-07
| ||
12:16 | Merge updates from trunk check-in: 59daece720 user: ferrieux tags: ferrieux-nacl | |
Changes
Changes to nacl/Makefile.patch.
1 2 | --- Makefile 2011-04-10 13:21:12.773175132 +0200 +++ tweaked.Makefile 2011-04-10 12:34:27.256426620 +0200 | | | < | < | < | 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 | --- Makefile 2011-04-10 13:21:12.773175132 +0200 +++ tweaked.Makefile 2011-04-10 12:34:27.256426620 +0200 @@ -102,12 +102,17 @@ #CFLAGS = $(CFLAGS_DEBUG) #CFLAGS = $(CFLAGS_OPTIMIZE) #CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE) -CFLAGS = $(CFLAGS_OPTIMIZE) -Wno-long-long -pthread -DNACL -pipe +CFLAGS = $(CFLAGS_OPTIMIZE) -pipe -fvisibility=hidden + + +CFLAGS += -Wno-long-long -pthread -DNACL # Flags to pass to the linker LDFLAGS_DEBUG = LDFLAGS_OPTIMIZE = -LDFLAGS = $(LDFLAGS_OPTIMIZE) -Wl,--export-dynamic +LDFLAGS = $(LDFLAGS_OPTIMIZE) -Wl,--export-dynamic -lm \ + -lppapi \ + -lpthread # To disable ANSI-C procedure prototypes reverse the comment characters on the # following lines: @@ -176,7 +184,7 @@ STLIB_LD = ${AR} cr SHLIB_LD = ${CC} -shared ${CFLAGS} ${LDFLAGS} |
︙ | ︙ |
Changes to nacl/configure.
︙ | ︙ | |||
28 29 30 31 32 33 34 | CC="nacl-gcc -m$arch" CPP="nacl-cpp -m$arch" CFLAGS="-Wno-long-long -pthread -DNACL" ../unix/configure --host nacl --disable-threads --disable-shared rm -f a.out core.* || true cat Makefile > $tmp.mk sed -e '/^CC[ ]*=/ a\ CCPLUS = nacl-g++ -m'$arch'\ arch='$arch' ' < $tmp.mk > Makefile | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | CC="nacl-gcc -m$arch" CPP="nacl-cpp -m$arch" CFLAGS="-Wno-long-long -pthread -DNACL" ../unix/configure --host nacl --disable-threads --disable-shared rm -f a.out core.* || true cat Makefile > $tmp.mk sed -e '/^CC[ ]*=/ a\ CCPLUS = nacl-g++ -m'$arch'\ arch='$arch' ' < $tmp.mk > Makefile patch -l -p0 < Makefile.patch set +x echo " Makefile generated and patched for NaCl. Ready for 'make' :) ">&2 exit 0 |
Changes to nacl/demo/balls.html.
1 2 3 4 5 6 7 | <!DOCTYPE html> <html> <head> <script type="text/javascript" src="loader.js"></script> </head> <body> | > > > > > | | < > > | < | 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 | <!DOCTYPE html> <html> <head> <script type="text/javascript" src="loader.js"></script> </head> <body> <div id="listener"> <script type="text/javascript"> document.getElementById('listener') .addEventListener('load', moduleDidLoad, true); </script> <embed name='nacl_module' id='tcl' width=0 height=0 src='tcl.nmf' type='application/x-nacl' verbose=0 source='balls.natcl'> <canvas id="canvas" width="578" height="200"></canvas> <h2>Status</h2> <div id="modstatus">NO-STATUS</div> </embed> </div> <p style="font-size : smaller;"> To run this demo, you need <ul style="font-size : smaller;"> <li> An x86-family processor</li> <li> Chrome 15 or higher</li> <li> Enabled "Native Client" item in about:flags</li> <li> if everything else fails, try the Nacl demos at <a href="http://code.google.com/chrome/nativeclient/docs/examples.html">http://code.google.com/chrome/nativeclient/docs/examples.html</a></li> </ul> </p> <script type="text/javascript"> var statusField = document.getElementById('modstatus'); var canvas = document.getElementById('canvas'); |
︙ | ︙ |
Changes to nacl/demo/balls.natcl.
1 2 3 4 5 6 7 8 9 10 | source canv.natcl #set ::canv_verbose 1 domset statusField "Running..." # will be retrieved by [domget] set width 578 set height 200 # animation globals set t 0 | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | source canv.natcl #set ::canv_verbose 1 domset statusField "Running..." # will be retrieved by [domget] set width 578 set height 200 # animation globals set t 0 set frameInterval 33 # ball globals set ballRadius 10 # physics global set collisionDamper 0.3 set floorFriction [expr {0.0005*$frameInterval}] |
︙ | ︙ |
Changes to nacl/demo/index.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 | <!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. statusText = 'NO-STATUS'; function moduleDidLoad() { tclModule = document.getElementById('tcl'); updateStatus('SUCCESS'); } // 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(); } } function doeval() { try { | > > > > > > > > > > > > | | 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 | <!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. statusText = 'NO-STATUS'; function nil() {}; // Handle a message coming from the NaCl module. function handleMessage(message_event) { alert("Result: "+message_event.data); } function moduleDidLoad() { tclModule = document.getElementById('tcl'); tclModule.addEventListener('message', handleMessage, false); updateStatus('SUCCESS'); } // 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(); } } function doeval() { try { tclModule.postMessage("eval:"+this.the_form.input_id.value); } catch(e) { alert(e.message); } } // Set the global status message. If the element with id 'statusField' // exists, then set its HTML to the status message as well. |
︙ | ︙ | |||
55 56 57 58 59 60 61 | } </script> </head> <body onload="pageDidLoad()"> <h1>Native Client Tcl Module</h1> <p> | | > | | > > > > > > > > > > > | | | | | > | | 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 | } </script> </head> <body onload="pageDidLoad()"> <h1>Native Client Tcl Module</h1> <p> <form name="the_form" action="javascript:doeval()"> <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 'src' 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 'src' attribute to the _dbg.nmf version of the manifest file. Note that the <EMBED> element is wrapped inside a <DIV>, which has a 'load' event listener attached. This method is used instead of attaching the 'load' event listener directly to the <EMBED> element to ensure that the listener is active before the NaCl module 'load' event fires. --> <div id="listener"> <script type="text/javascript"> document.getElementById('listener') .addEventListener('load', moduleDidLoad, true); </script> <embed name="nacl_module" id="tcl" width=0 height=0 src="tcl.nmf" type="application/x-nacl"/> </div> </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_field">NO-STATUS</div> </body> </html> |
Changes to nacl/demo/loader.js.
1 2 3 4 5 6 7 8 | // NaTcl -- JS glue var tclModule = null; // our singleton Tcl interp function printf() { // I like debugging to stderr instead of console.log, // because when things go wrong, the JS console is not // alays reachable. | < < < < < < < < | < < | < < < < < | > > > > | < < < < < < | | < | | | < > | 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 | // NaTcl -- JS glue var tclModule = null; // our singleton Tcl interp function printf() { // I like debugging to stderr instead of console.log, // because when things go wrong, the JS console is not // alays reachable. tclModule.postMessage('eval:printf '+Array.prototype.slice.call(arguments).join(' ')); } // --- tclDo is the main JS-Tcl trampoline. // // Its job is to pass a Tcl string to [eval] (through naclwrap, see // init.nacl), and then take back the result as JS and eval() it. // It also detects errors in the latter eval() and pipes them back // to [bgerror]. function tclEsc(text) { return text.replace(/[][\\$""]/g,'\\$0'); } function tclDo(s) { tclModule.postMessage("eval:::nacl::wrap {" + s + "}"); } function tcl() { tclDo(Array.prototype.slice.call(arguments).join(" ")); } // Handle a message coming from the NaCl module. function handleMessage(message_event) { try { t = message_event.data; //printf("ret:"+t); eval(t); } catch(err) { //printf("JS-err:"+err); alert("ERROR:"+err); } } function serialT (thing) { alert("serialT " + thing.type + " " + thing.toString()); var result = '{'; switch (thing.type) { |
︙ | ︙ | |||
104 105 106 107 108 109 110 | } } // --- tclsource starts an XHR, and calls the given 'tcb' (Tcl // --- Callback) on completion. A catchable Tcl-level error is raised // --- in case of not-200. Used by [source]. function tclsource(url,tcb) { | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | } } // --- tclsource starts an XHR, and calls the given 'tcb' (Tcl // --- Callback) on completion. A catchable Tcl-level error is raised // --- in case of not-200. Used by [source]. function tclsource(url,tcb) { //printf('tclsource:'+url); xs = new XMLHttpRequest(); xs.open("GET",url,true); xs.send(null); xs.onreadystatechange = function() { //printf("XHR-source:"+xs.readyState); if (xs.readyState==4) { |
︙ | ︙ | |||
149 150 151 152 153 154 155 156 157 158 159 160 161 162 | return result; } // ---------- GUI and standard NaCl-loading machinery -------- function moduleDidLoad() { tclModule = document.getElementById('tcl'); // tcl('lappend', '::JS', "alert('ARGV:[join $::argv]')"); tcl('eval', 'coroutine', '::main_coro', 'source', '[dict get $::argv source]'); } // runTclScripts - collect all <script> elements with type text/tcl // Pass them to the Tcl header given in 'where' (or uplevel) function runTclScripts(where) { | > | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | return result; } // ---------- GUI and standard NaCl-loading machinery -------- function moduleDidLoad() { tclModule = document.getElementById('tcl'); tclModule.addEventListener('message', handleMessage, false); // tcl('lappend', '::JS', "alert('ARGV:[join $::argv]')"); tcl('eval', 'coroutine', '::main_coro', 'source', '[dict get $::argv source]'); } // runTclScripts - collect all <script> elements with type text/tcl // Pass them to the Tcl header given in 'where' (or uplevel) function runTclScripts(where) { |
︙ | ︙ |
Changes to nacl/demo/tcl.nmf.
1 | { | | | | | 1 2 3 4 5 6 | { "program": { "x86-32": {"url":"../tcl32.nexe"}, "x86-64": {"url":"../tcl64.nexe"} } } |
Changes to nacl/naclMain.c.
1 2 | #include <stdlib.h> #include <string.h> | | | > | | > > > > > > > > > > > > > | 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 | #include <stdlib.h> #include <string.h> //#include <ppapi/c/dev/ppb_var_deprecated.h> //#include <ppapi/c/dev/ppp_class_deprecated.h> #include <ppapi/c/pp_errors.h> #include <ppapi/c/pp_module.h> #include <ppapi/c/pp_var.h> #include <ppapi/c/ppb.h> #include <ppapi/c/ppb_instance.h> #include <ppapi/c/ppb_messaging.h> #include <ppapi/c/ppb_var.h> #include <ppapi/c/ppp.h> #include <ppapi/c/ppp_instance.h> #include <ppapi/c/ppp_messaging.h> struct MessageInfo { PP_Instance instance; struct PP_Var message; }; static struct PPB_Messaging* messaging_interface = NULL; static struct PPB_Var* var_interface = NULL; static PP_Module module_id = 0; #include <errno.h> #include "tcl.h" #include "tclInt.h" static Tcl_Interp *interp = NULL; static int pid = 0; |
︙ | ︙ | |||
39 40 41 42 43 44 45 | } static Tcl_Interp *NewTcl(void) { Tcl_Interp *ii; | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > > > > | | | | > > > > > > > | 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 122 123 124 | } 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); Tcl_LinkVar(ii, "::nacl::verbose", (char *)&verbose, TCL_LINK_INT); TclSetPreInitScript("proc ::tclInit {} {}"); return ii; } static const char *EvalTcl(const char *s) { if (!interp) return "No Tcl Interp!!!"; Tcl_Eval(interp,s); return Tcl_GetStringResult(interp); } /** * Returns a mutable C string contained in the @a var or NULL if @a var is not * string. This makes a copy of the string in the @ var and adds a NULL * terminator. Note that VarToUtf8() does not guarantee the NULL terminator on * the returned string. See the comments for VatToUtf8() in ppapi/c/ppb_var.h * for more info. The caller is responsible for freeing the returned memory. * @param[in] var PP_Var containing string. * @return a C string representation of @a var. * @note The caller is responsible for freeing the returned string. */ static char* VarToCStr(struct PP_Var var) { uint32_t len = 0; if (var_interface != NULL) { const char* var_c_str = var_interface->VarToUtf8(var, &len); if (len > 0) { char* c_str = (char*)malloc(len + 1); memcpy(c_str, var_c_str, len); c_str[len] = 0; return c_str; } } return NULL; } /** * Creates new string PP_Var from C string. The resulting object will be a * refcounted string object. It will be AddRef()ed for the caller. When the * caller is done with it, it should be Release()d. |
︙ | ︙ | |||
239 240 241 242 243 244 245 | * event focus. */ static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus) { } /** | | < < < < | < < < < < < < > | | | | | | > > | < > > | < < < | < < < < < < < < < < < < | < | < < < < < | > | > > | > > > > | < < < < < < < < < < < < < < < < < | < < < < | | | | | | | | | | < | | > | < < < | | < < | < | | < < < < | < < < < < < < < < < < < < < < < < < < < < > > | < < < | | > > > > > > > | > > > > > > | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | * event focus. */ static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus) { } /** * Handler that gets called after a full-frame module is instantiated based on * registered MIME types. This function is not called on NaCl modules. This * function is essentially a place-holder for the required function pointer in * the PPP_Instance structure. * @param[in] instance The identifier of the instance representing this NaCl * module. * @param[in] url_loader A PP_Resource an open PPB_URLLoader instance. * @return PP_FALSE. */ static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader) { /* NaCl modules do not need to handle the document load function. */ return PP_FALSE; } /** * Handler for messages coming in from the browser via postMessage. Extracts * the method call from @a message, parses it for method name and value, then * calls the appropriate function. * @param[in] instance The instance ID. * @param[in] message The contents, copied by value, of the message sent from * browser via postMessage. */ void Messaging_HandleMessage(PP_Instance instance, struct PP_Var var_message) { struct PP_Var v = PP_MakeUndefined(); const char *message = NULL; if (var_message.type != PP_VARTYPE_STRING) { /* Only handle string messages */ v = StrToVar("ERROR:Method+Arg from Javascript is not a string!"); goto post; } message = VarToCStr(var_message); if (message == NULL) { v = StrToVar("ERROR:Method+Arg from Javascript is empty!"); goto post; } if (strncmp(message, "eval:", 5) == 0) { const char* str = message+5; if (verbose) { printf("NaTcl(%d): EVAL of: %s\n",pid, str); } const char* res = EvalTcl(str); if (verbose) { printf("NaTcl(%d): EVAL result: %s\n",pid, res); } v = StrToVar(res); goto post; } else { v = StrToVar("Unknown method"); goto post; } post: if (message) free((void *)message); messaging_interface->PostMessage(instance, v); if (v.type == PP_VARTYPE_STRING) { var_interface->Release(v); } } /** * Entrypoints for the module. * 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; messaging_interface = (struct PPB_Messaging*)(get_browser(PPB_MESSAGING_INTERFACE)); var_interface = (struct PPB_Var*)(get_browser(PPB_VAR_INTERFACE)); printf("NaTcl(%d): DBUG: PPP_InitializeModule\n",pid); interp = NewTcl(); if (!interp) return PP_ERROR_FAILED; return PP_OK; } /** * Returns an interface pointer for the interface of the given name, or NULL * if the interface is not supported. * @param[in] interface_name name of the interface * @return pointer to the interface */ PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { printf("NaTcl(%d): DBUG: PPP_GetInterface '%s'\n", getpid(), (char *)interface_name); if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) { static struct PPP_Instance itf = { &Instance_DidCreate, &Instance_DidDestroy, &Instance_DidChangeView, &Instance_DidChangeFocus, &Instance_HandleDocumentLoad, }; return &itf; } else if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) { static struct PPP_Messaging itf = { &Messaging_HandleMessage }; return &itf; } return NULL; } /** * Called before the plugin module is unloaded. */ PP_EXPORT void PPP_ShutdownModule() { // if (interp) EndTcl(interp); } |
Changes to nacl/tcl.nmf.
1 | { | | | | | 1 2 3 4 5 6 | { "program": { "x86-32": {"url":"tcl32.nexe"}, "x86-64": {"url":"tcl64.nexe"} } } |