aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/spidermonkey/jsapi_user_guide/index.html
blob: 724dfae781ed13633af89185e5ea189e1d1dcc62 (plain)
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
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
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
---
title: JSAPI User Guide
slug: SpiderMonkey/JSAPI_User_Guide
translation_of: Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide
---
<p>{{SpiderMonkeySidebar("General")}}</p>

<p><span id="result_box" lang="pt"><span class="hps">Este documento explica</span> <span class="hps">como incorporar</span> <span class="hps">SpiderMonkey</span><span>, o motor</span> <span class="hps">JavaScript</span> <span class="hps">do Mozilla</span><span>,</span> <span class="hps">em</span> <span class="hps">seu</span> <span class="hps">programa na linguagem C ++</span><span>.</span><br>
 <br>
 <span class="hps">JavaScript</span> <span class="hps">é amplamente utilizado para</span> <span class="hps">se executar scripts</span> <span class="hps">do lado do cliente</span> <span class="hps">que rodam</span> <span class="hps">no navegador.</span> <span class="hps">Mas</span> <span class="hps">motor de</span> <span class="hps">JavaScript</span> <span class="hps">da Mozilla</span> <span class="hps">é uma biblioteca</span> <span class="hps">que pode ser lincada</span> <span class="hps">a qualquer programa</span> <span class="hps">C</span> <span class="hps">+</span><span class="hps">+</span><span>, e não apenas</span> em <span class="hps">um navegador.</span> <span class="hps">Muitas aplicações</span> <span class="hps">podem se beneficiar disto</span><span>.</span> <span class="hps">Estes programas podem</span> <span class="hps">executar código</span> <span class="hps">JavaScript</span> <span class="hps">através da linguagem</span> <span class="hps">C</span> <span class="hps">+</span><span class="hps">+</span> <span class="hps">usando a API do</span> <span class="hps">SpiderMonkey</span><span>.</span></span></p>

<div class="note"><strong>Nota:</strong> <span id="result_box" lang="pt"><span class="hps">A página</span> <span class="hps">wiki</span></span> <a class="internal" href="/En/SpiderMonkey/FOSS" title="En/SpiderMonkey/FOSS">FOSS</a> <span id="result_box" lang="pt"> <span class="hps">contém</span> <span class="hps">alguns links para</span> <span class="hps">outras bibliotecas</span> <span class="hps">e programas que</span> <span class="hps">podem tornar a vida</span> <span class="hps">mais fácil</span> <span class="hps">quando se utiliza</span> Spidermonkey <span class="hps">e</span> <span class="hps">JSAPI</span><span>.</span></span></div>

<h2 id="What_SpiderMonkey_does" name="What_SpiderMonkey_does">Oque o SpiderMonkey faz</h2>

<p><span id="result_box" lang="pt"><span class="hps">O motor de</span> <span class="hps">JavaScript</span> <span class="hps">compila e</span> <span class="hps">executa scripts</span> <span class="hps">que contêm</span> <span class="hps">instruções e funções</span> <span class="hps">de JavaScript.</span> <span class="hps">O motor</span> <span class="hps">lida com</span> <span class="hps">a alocação de memória</span> <span class="hps">para os objetos</span> <span class="hps">necessários para executar</span> <span class="hps">scripts,</span> <span class="hps">e</span> <span class="hps">ele tabém limpa</span> <span class="hps">o lixo e</span> <span class="hps">recolhe</span> <span class="hps">os objetos</span> <span class="hps">que já não</span> <span class="hps">necessita.</span><br>
 <br>
 <span class="hps">A palavra</span> <span class="hps">JavaScript</span> <span class="hps">pode trazer na</span> <span class="hps">mente <span id="result_box" lang="pt"> <span class="hps">características</span></span></span> <span class="hps">como manipuladores de eventos</span> <span class="hps">(como</span> <a href="https://developer.mozilla.org/en/DOM/element.onclick"><span class="hps">onclick</span><span>)</span></a><span>,</span> <span class="hps">objetos <a href="https://developer.mozilla.org/en/DOM">DOM</a></span><span>,</span> <a href="https://developer.mozilla.org/en/DOM/window.open"><span class="hps">window.open</span></a> <span class="hps">e</span> <span class="hps"><a href="https://developer.mozilla.org/en/DOM/XMLHttpRequest">XMLHttpRequest</a>.</span> <span class="hps">Mas no</span> <span class="hps">Mozilla,</span> <span class="hps">todos esses recursos</span> <span class="hps">são efetivamente prestados</span> <span class="hps">por outros componentes</span><span>, e não pelo</span> <span class="hps">SpiderMonkey</span> <span class="hps">em si</span><span>.</span> <span class="hps">SpiderMonkey</span> <span class="hps">fornece</span> <span class="hps">alguns</span> <span class="hps">tipos dados</span> <span class="hps">do núcleo do</span> <span class="hps">JavaScript</span> <span class="hps">como </span><span>números, strings,</span> <span class="hps">arrays</span><span>, objetos,</span> <span class="hps">e</span> <span class="hps">assim por diante,</span> <span class="hps">e alguns</span> <span class="hps">métodos, como</span> <span class="hps">Array.push</span><span>.</span> <span class="hps">Também torna mais</span> <span class="hps">fácil</span> <span class="hps">para cada</span> <span class="hps">aplicativo  expor</span> <span class="hps">alguns de seus</span> <span class="hps">próprios objetos</span> <span class="hps">e funções</span> <span class="hps">no código</span> <span class="hps">JavaScript.</span> <span class="hps">Browsers</span> <span class="hps">expoem objetos</span> <span class="hps">DOM.</span> <span class="hps">O aplicativo</span> <span class="hps">irá expor</span> <span class="hps">objetos</span> <span class="hps">que são relevantes</span> <span class="hps">para o tipo de</span> <span class="hps">script que você</span> <span class="hps">desejar escrever.</span> <span class="hps">É até</span> <span class="hps">o desenvolvedor do aplicativo</span> <span class="hps">para decidir</span> <span class="hps">quais objetos</span> <span class="hps">e</span> <span class="hps">métodos</span> <span class="hps">serão expostos nos</span> <span class="hps">scripts.</span></span></p>

<h2 id="Hello_world">Hello world</h2>

<h3 id="Using_the_SpiderMonkey_library" name="Using_the_SpiderMonkey_library">Usando a biblioteca SpiderMonkey</h3>

<p><span id="result_box" lang="pt"><span class="hps">Para construir</span> <span class="hps">SpiderMonkey</span> <span class="hps">a partir do código fonte</span><span>, consulte</span></span> <a href="/En/SpiderMonkey/Build_Documentation" title="en/SpiderMonkey_Build_Documentation">SpiderMonkey Build Documentation</a>.</p>

<p><span id="result_box" lang="pt"><span class="hps">Alguns sistemas</span> <span class="hps">(como o</span> <span class="hps">Debian</span><span>) fornecem</span> <span class="hps">SpiderMonkey</span> <span class="hps">como um</span> <span class="hps">pacote pré-construído</span><span>,</span> <span class="hps">porém construí-lo</span> <span class="hps">a partir do fonte</span> tornará<span class="hps"> o seu</span> <span class="hps">programa</span> <span class="hps">mais fácil de depurar</span><span>.</span><br>
 <br>
 <span class="hps">Os código em linguagem</span> <span class="hps">C</span><span class="hps">+</span>+ <span class="hps">acessam o</span> <span class="hps">SpiderMonkey</span> <span class="hps">via</span> <span class="hps">JSAPI</span><span>, ao incluir</span> <span class="hps">o cabeçalho</span> <span class="atn hps">"</span><span>jsapi.h</span><span>"</span><span>.</span> <span class="hps">Uma visão geral da</span> <span class="hps">funcionalidade</span> da <span class="hps">JSAPI</span> virá a seguir<span class="hps">.</span> <span class="hps">Para mais detalhes</span><span>, consulte a</span></span> <a href="/en/SpiderMonkey/JSAPI_Reference" title="en/JSAPI_Reference">Referencia JSAPI </a>.</p>

<h3 id="O_Universo_SpiderMonkey">O Universo SpiderMonkey</h3>

<p><span id="result_box" lang="pt"><span title="In order to run any JavaScript code in SpiderMonkey, an application must have three key elements: a JSRuntime, a JSContext, and a global object.">A fim de executar qualquer código JavaScript em SpiderMonkey , um aplicativo deve ter três elementos-chave : a JSRuntime , um JSContext e um objeto global. </span><span title="This section describes what these things are.">Esta seção descreve o que são essas coisas. </span><span title="The next section explains how to set them up, using JSAPI functions.">A próxima seção explica como configurá-los , usando as funções JSAPI .</span><br>
 <br>
 <strong><span title="Runtimes.">Runtimes . </span></strong><span title="A JSRuntime, or runtime, is the space in which the JavaScript variables, objects, scripts, and contexts used by your application are allocated.">A JSRuntime , ou execução, é o espaço no qual as variáveis ​​de JavaScript , objetos , scripts e contextos usados ​​pelo seu aplicativo são alocados . </span><span title="Every JSContext and every object in an application lives within a JSRuntime.">Cada JSContext e cada objeto em um aplicativo vive dentro de uma JSRuntime . </span><span title="They cannot travel to other runtimes or be shared across runtimes.">Eles não podem viajar para outros tempos de execução ou ser compartilhado entre os tempos de execução . </span><span title="Most applications only need one runtime.">A maioria dos aplicativos só precisa de um tempo de execução.</span><br>
 <br>
 <strong><span title="Contexts.">Contextos. </span></strong><span title="A JSContext, or context, is like a little machine that can do many things involving JavaScript code and objects.">A JSContext , ou contexto, é como uma pequena máquina que pode fazer muitas coisas que envolvem código JavaScript e objetos. </span><span title="It can compile and execute scripts, get and set object properties, call JavaScript functions, convert JavaScript data from one type to another, create objects, and so on.">Ele pode compilar e executar scripts, obter e definir propriedades do objeto, chamar funções JavaScript , converter os dados em JavaScript a partir de um tipo para outro , criar objetos , e assim por diante . </span><span title="Almost all JSAPI functions require a JSContext * as the first argument, just like most &lt;stdio.h> functions require a FILE *.">Quase todas as funções JSAPI exigem um JSContext * como o primeiro argumento , assim como a maioria das funções &lt;stdio.h&gt; requerem um arquivo * .</span><br>
 <br>
 <span title="There is a close association between contexts and threads.">Existe uma estreita associação entre contextos e threads. </span><span title="Simple, single-threaded applications can use a single context for everything.">Simples, aplicações single-threaded pode usar um único contexto para tudo. </span><span title="But each context can only do one thing at a time, so in a multithreaded application, only one thread at a time should use any given context.">Mas cada contexto só pode fazer uma coisa de cada vez , de modo que em um aplicativo multithread , apenas um thread por vez deve usar um determinado contexto. </span><span title="Such an application typically has one context per thread.">Esse pedido normalmente tem um contexto por segmento. </span><span title="JavaScript objects, on the other hand, are not permanently associated with the script, thread, or context that created them.">JavaScript objetos , por outro lado , não são permanentemente associado com o script , linha, ou o contexto que os criou. </span><span title="They can be shared among many scripts or even many threads, as shown in the figure below.">Eles podem ser compartilhados entre muitos scripts ou até mesmo muitos segmentos , como mostrado na figura abaixo .</span><br>
 <br>
 <span title="Figure 1.1 illustrates the relationship of scripts to the runtime, contexts, and objects.">A Figura 1.1 ilustra a relação de scripts para o tempo de execução , os contextos e objetos.</span></span></p>

<div style="margin-left: 3em;">
<p><strong><small>Figure 1.1</small></strong></p>

<p><img alt="Image:Over3.gif" class="internal" src="/@api/deki/files/291/=Over3.gif"></p>
</div>

<p><strong>Objetos Globais .</strong> <span id="result_box" lang="pt"><span class="hps">Por fim,</span> <span class="hps">o objeto global</span> <span class="hps">contém todas as classes</span><span>, funções e</span> <span class="hps">variáveis</span> <span class="hps">​​que estão disponíveis</span> <span class="hps">para o código</span> <span class="hps">JavaScript</span> <span class="hps">para uso.</span> <span class="hps">Sempre que</span> <span class="hps">o código JavaScript</span> <span class="hps">faz algo como</span> <span class="hps">window.open</span> <span class="atn hps">(</span><span class="atn hps">"</span><span>http://www.mozilla.org/</span><span>")</span><span>,</span> <span class="hps">ele está acessando</span> <span class="hps">uma propriedade</span> <span class="hps">global,</span> <span class="hps">nesta janela</span> <span class="hps">caso.</span> <span class="hps">Aplicações</span> <span class="hps">JSAPI</span> <span class="hps">tem total controle sobre</span> <span class="hps">o que</span> <span class="hps">os scripts</span> <span class="hps">propriedades</span> <span class="hps">globais</span> <span class="hps">podem ver.</span> <span class="hps">A aplicação</span> <span class="hps">começa</span> <span class="hps">com a criação de</span> <span class="hps">um objeto e</span> <span class="hps">preenchê-lo</span> <span class="hps">com as</span> <span class="hps">classes padrão</span> <span class="hps">do JavaScript</span><span>, como</span> <span class="hps">matriz</span> <span class="hps">e objeto.</span> <span class="hps">Em seguida</span><span>, adiciona os</span> <span class="hps">classes personalizadas</span><span>, funções e</span> <span class="atn hps">variáveis ​​(</span><span>como a</span> <span class="hps">janela</span><span>)</span> <span class="hps">a aplicação</span> <span class="hps">quer oferecer</span><span>, ver</span> <span class="hps">objetos personalizados</span> <span class="hps">abaixo.</span> <span class="hps">Cada vez que o</span> <span class="hps">aplicativo é executado</span> <span class="hps">um script</span> <span class="hps">JS</span> <span class="hps">(usando</span><span>, por exemplo,</span> <span class="hps">JS_EvaluateScript</span><span>)</span><span>, ele fornece</span> <span class="hps">o objeto global</span> <span class="hps">para esse script</span> <span class="hps">de usar.</span> <span class="hps">Como</span> <span class="hps">o script é executado</span><span>, ele pode criar</span> <span class="hps">funções globais</span> <span class="hps">e variáveis</span> <span class="hps">​​próprias.</span> <span class="hps">Todas essas funções</span><span>, classes e</span> <span class="hps">variáveis</span> <span class="hps">​​são armazenados como</span> <span class="hps">propriedades do objeto</span> <span class="hps">global.</span></span></p>

<h3 id="Um_pequeno_exemplo">Um pequeno exemplo</h3>

<p><span id="result_box" lang="pt"><span class="hps">Cada um dos três</span> <span class="hps">elementos-chave</span> <span class="hps">descritos na seção</span> <span class="hps">anterior requer</span> <span class="hps">algumas chamadas</span> <span class="hps">JSAPI</span></span>:</p>

<ul>
 <li>
  <p>O runtime: Usa <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewRuntime" title="en/JS_NewRuntime">JS_NewRuntime</a></code> para cria-lo and <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DestroyRuntime" title="en/JS_DestroyRuntime">JS_DestroyRuntime</a></code> para limpa-lo quando finalizado. <span id="result_box" lang="pt"><span class="hps">Quando seu aplicativo</span> <span class="hps">é feito com</span> <span class="hps">SpiderMonkey</span> <span class="hps">completamente</span><span>, use</span> <code><a href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_ShutDown" title="en/JS_ShutDown">JS_ShutDown</a></code> <span class="hps">para</span> <span class="hps">liberar quaisquer</span> <span class="hps">recursos restantes</span> <span class="hps">em cache.</span> <span class="hps">(Isto é uma</span> <span class="hps">mera</span> <span class="hps">minúcia</span> <span class="hps">se o processo</span> <span class="hps">está prestes a</span> <span class="hps">sair</span> <span class="hps">de qualquer maneira.</span> <span class="hps">Mas, como</span> <span class="hps">este nem sempre</span> <span class="hps">é o caso</span><span>, chamando</span> <span class="hps">JS_Shutdown</span> <span class="hps">é um bom</span> <span class="hps">hábito se entrar</span><span>.</span><span>)</span></span></p>
 </li>
 <li>
  <p>O contexto: Usa <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewContext" title="en/JS_NewContext">JS_NewContext</a></code> e <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DestroyContext" title="en/JS_DestroyContext">JS_DestroyContext</a></code>. <span id="result_box" lang="pt"><span class="hps">Para O</span> <span class="hps">Máximo</span> <span class="hps">conformidade com o padrão</span> <span class="hps">ECMAScript</span><span>,</span> <span class="hps">aplicativos também</span> <span class="hps">devem usar</span> <code><a href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_SetOptions" title="en/JS_SetOptions">JS_SetOptions</a></code> <span class="hps">para permitir</span> <code><a href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_SetOptions" title="en/JS_SetOptions">JSOPTION_VAROBJFIX</a></code><span>.</span> <span class="hps">Para</span> <span class="hps">obter os mais recentes</span> <span class="hps">recursos da linguagem</span> <span class="hps">JavaScript</span><span>,</span> <span class="hps">aplicativos podem</span> <span class="hps">usar</span> <span class="hps"><code><a href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_SetVersion" title="en/JS_SetVersion">JS_SetVersion</a></code></span> <span class="hps">O relatório de erros</span> <span class="hps">também</span> <span class="hps">é</span> <span class="atn hps">"per-</span><span>context" e</span> <span class="hps">está habilitado</span> <span class="hps">usando</span> <span class="hps">J<code><a href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_SetErrorReporter" title="en/JS_SetErrorReporter">JS_SetErrorReporter</a></code>.</span><span>.</span></span></p>
 </li>
 <li>
  <p><span id="result_box" lang="pt"><span class="hps">O</span> <span class="hps">objeto global</span><span>:</span> <span class="hps">Para criar este</span> <span class="hps">objeto, você</span> <span class="hps">primeiro</span> <span class="hps">precisa de uma</span> <code><a href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JSClass" title="en/JSClass">JSClass</a></code> <span class="hps">com a opção</span> <code><a href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JSClass.flags" title="en/JSClass.flags">JSCLASS_GLOBAL_FLAGS</a></code><span>.</span> <span class="hps">O exemplo abaixo</span> <span class="hps">define um</span> <span class="hps"><code>JSClass</code></span> <span class="hps">muito básico</span> <span class="hps">(nomeado</span> <span class="hps">global_class</span><span>) sem</span> <span class="hps">métodos ou propriedades</span> <span class="hps">próprias.</span> <span class="hps">Use</span> <code><a href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_NewGlobalObject" title="en/SpiderMonkey/JSAPI_Reference/JS_NewGlobalObject">JS_NewGlobalObject</a> </code><span class="hps">para criar um objeto</span> <span class="hps">global.</span> <span class="hps">Use</span> <code><a href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_InitStandardClasses" title="en/JS_InitStandardClasses">JS_InitStandardClasses</a></code> <span class="hps">para preenchê-lo</span> <span class="hps">com</span> <span class="hps">os</span> <span class="hps">os objetos globals</span> <span class="hps">JavaScript</span> <span class="hps">padrão.</span></span></p>
 </li>
</ul>

<p><span id="result_box" lang="pt"><span class="hps">Isto pode parecer</span> <span class="hps">um monte de blocos</span> <span class="hps">para uma aplicação</span> <span class="hps">simples.</span> <span class="hps">Isso equivale a</span> <span class="hps">cerca de 50</span> <span class="hps">linhas de código,</span> <span class="hps">como mostrado abaixo.</span> <span class="hps">Mas o</span> <span class="hps">JSAPI</span> <span class="hps">é projetado</span> <span class="hps">para escalar</span>  <span class="hps">aplicações que necessitam de</span> <span class="hps">muitos fios</span><span>,</span> <span class="hps">muitos contextos</span><span>, e muitos</span> <span class="hps">objetos globais</span><span>.</span> <span class="hps">É uma</span> <span class="hps">API</span> <span class="hps">refinada</span><span>, apoiando</span> <span class="hps">muitas combinações diferentes de</span> <span class="hps">peças</span><span>,</span> <span class="hps">e dando</span> <span class="hps">às aplicações um</span> <span class="hps">controle preciso sobre</span> <span class="hps">como</span> <span class="hps">SpiderMonkey</span> <span class="hps">se comporta.</span><br>
 <br>
 <span class="hps">Aqui está o código</span> <span class="hps"><span id="result_box" lang="pt"><span class="hps">clichê </span></span>necessário</span>  <span class="hps">para uma aplicação</span> <span class="hps">JSAPI</span> <span class="hps">mínima.</span> <span class="hps">Ele contém tudo o</span> <span class="hps">descrito acima.</span></span></p>

<pre class="brush: cpp">#include "jsapi.h"

/* The class of the global object. */
static JSClass global_class = { "global",
                                JSCLASS_NEW_RESOLVE | JSCLASS_GLOBAL_FLAGS,
                                JS_PropertyStub,
                                JS_DeletePropertyStub,
                                JS_PropertyStub,
                                JS_StrictPropertyStub,
                                JS_EnumerateStub,
                                JS_ResolveStub,
                                JS_ConvertStub,
                                NULL,
                                JSCLASS_NO_OPTIONAL_MEMBERS
};

/* The error reporter callback. */
void reportError(JSContext *cx, const char *message, JSErrorReport *report) {
     fprintf(stderr, "%s:%u:%s\n",
             report-&gt;filename ? report-&gt;filename : "[no filename]",
             (unsigned int) report-&gt;lineno,
             message);
}

int run(JSContext *cx) {
    /* Enter a request before running anything in the context */
    JSAutoRequest ar(cx);

    /* Create the global object in a new compartment. */
    JSObject *global = JS_NewGlobalObject(cx, &amp;global_class, NULL);
    if (global == NULL)
        return 1;

    /* Set the context's global */
    JSAutoCompartment ac(cx, global);
    JS_SetGlobalObject(cx, global);

    /* Populate the global object with the standard globals, like Object and Array. */
    if (!JS_InitStandardClasses(cx, global))
        return 1;

    /* Your application code here. This may include JSAPI calls to create your own custom JS objects and run scripts. */

    return 0;
}

int main(int argc, const char *argv[]) {
    /* Initialize the JS engine -- new/required as of SpiderMonkey 31. */
    if (!JS_Init())
       return 1;

    /* Create a JS runtime. */
    JSRuntime *rt = JS_NewRuntime(8L * 1024L * 1024L, JS_NO_HELPER_THREADS);
    if (rt == NULL)
       return 1;

    /* Create a context. */
    JSContext *cx = JS_NewContext(rt, 8192);
    if (cx == NULL)
       return 1;
    JS_SetOptions(cx, JSOPTION_VAROBJFIX);
    JS_SetErrorReporter(cx, reportError);

    int status = run(cx);

    JS_DestroyContext(cx);
    JS_DestroyRuntime(rt);

    /* Shut down the JS engine. */
    JS_ShutDown();

    return status;
}
</pre>

<p><span id="result_box" lang="pt"><span title="Each JSNative has the same signature, regardless of what arguments it expects to receive from JavaScript.">Cada JSNative tem a mesma assinatura , independentemente de que argumentos ele espera receber a partir do JavaScript.</span><br>
 <br>
 <span title="The JavaScript arguments to the function are given in argc and vp.">Os argumentos de JavaScript para a função que são dadas em argc e vp.</span><span title="argc tells how many actual arguments the caller passed, and JS_ARGV(cx, vp) returns an array of those arguments.">argc dizem quantos argumentos reais o chamador passou, e JS_ARGV ( cx, vp ) retorna um array desses argumentos . </span><span title="The arguments do not have native C++ types like int and float; rather, they are jsvals, JavaScript values.">Os argumentos não têm  tipos nativos C ++ como int e float , mas sim, eles são jsvals , valores de JavaScript. </span><span title="The native function uses JS_ConvertArguments to convert the arguments to C++ types and store them in local variables.">A função nativa usa JS_ConvertArguments para converter os argumentos para tipos C++ e armazená-los em variáveis ​​locais. </span><span title="The native function uses JS_SET_RVAL(cx, vp, val) to store its JavaScript return value.">A função nativa usa JS_SET_RVAL ( cx, vp , val ) para armazenar o valor de retorno JavaScript.</span><br>
 <br>
 <span title="On success, a JSNative must call JS_SET_RVAL and return JS_TRUE.">Em caso de sucesso , um JSNative deve chamar JS_SET_RVAL e retornar JS_TRUE . </span><span title="The value passed to JS_SET_RVAL is returned to the JavaScript caller.">O valor transmitido JS_SET_RVAL é devolvido ao chamador JavaScript .</span><br>
 <br>
 <span title="On failure, a JSNative calls an error-reporting function, in this case JS_ReportError, and returns JS_FALSE.">Em caso de falha , um JSNative chama uma função de erro de comunicação , neste caso JS_ReportError e retorna JS_FALSE . </span><span title="This causes a JavaScript exception to be thrown.">Isso faz com que uma exceção JavaScript seja acionada. </span><span title="The caller can catch the exception using a JavaScript try/catch statement.">O chamador pode capturar a exceção usando uma instrução try / catch em JavaScript.</span><br>
 <br>
 <span title="To make native functions callable from JavaScript, declare a table of JSFunctionSpecs describing the functions.">Para chamar funções nativas do <span id="result_box" lang="pt"><span title="To make native functions callable from JavaScript, declare a table of JSFunctionSpecs describing the functions.">de JavaScript</span></span>  pode-se declarar uma tabela <code style="font-size: 14px;"><a class="internal" href="https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Reference/JSFunctionSpec" title="en/JSFunctionSpec">JSFunctionSpec</a>s</code> descrevendo as funções . </span><span title="Then call JS_DefineFunctions.">Em seguida, chamar <a class="internal" href="https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_DefineFunctions" title="en/JS_DefineFunctions"><code style="font-size: 14px;">JS_DefineFunctions</code></a> .</span></span></p>

<pre>static JSFunctionSpec myjs_global_functions[] = {
    <a class="internal" href="../JS_FS">JS_FS</a>("rand",   myjs_rand,   0, 0),
    JS_FS("srand",  myjs_srand,  0, 0),
    JS_FS("system", myjs_system, 1, 0),
    <a class="internal" href="../JS_FS_END">JS_FS_END</a>
};

    ...
    if (!<a class="internal" href="JSAPI_Reference/JS_DefineFunctions">JS_DefineFunctions</a>(cx, global, myjs_global_functions))
        return JS_FALSE;
    ...
</pre>

<p><span id="result_box" lang="pt"><span class="hps">Uma vez que as</span> <span class="hps">funções são definidas como</span> <span class="hps"><span style="color: #4d4e53; font-family: courier new,andale mono,monospace; line-height: normal;">global</span>,</span> <span class="hps">qualquer</span> <span class="hps">script que usa</span> <span class="hps"><span style="color: #4d4e53; font-family: courier new,andale mono,monospace; line-height: normal;">global</span> como</span> <span class="hps">o objeto global</span> <span class="hps">pode chamá-las</span><span>, assim como qualquer</span> <span class="hps">página da web</span> <span class="hps">pode chamar</span> uma caixa <span class="hps">de alerta.</span> <span class="hps">No ambiente</span> <span class="hps">que criamos</span><span>, o script</span> <span class="atn hps">"</span><span>Olá mundo</span><span>"</span> <span class="hps">ficaria assim</span><span>:</span></span></p>

<pre>system("echo hello world");
</pre>

<h2 id="JSAPI_-_Conceitos">JSAPI - Conceitos</h2>

<p>Esta seção tem como objetivo preencher as principais lacunas no quadro do JSAPI apresentado até agora. Para fazer qualquer coisa útil com SpiderMonkey, você deve ler todas as três seções.</p>

<h3 id="Working_with_JS_Values" name="Working_with_JS_Values">JavaScript Valores</h3>

<p>Artigo Principal : <code><a href="/En/SpiderMonkey/JSAPI_Reference/Jsval" title="en/jsval">JS::Value</a></code></p>

<p>JavaScript é uma linguagem de tipagem dinâmica: as variáveis ​​e propriedades não tem um tipo que é fixado em tempo de compilação. Como é possível que uma linguagem de tipagem estática, como C ou C + +, em que todas as variáveis ​​têm tipos, interagir com JavaScript?O JSAPI fornece um tipo de dados, <a href="/En/SpiderMonkey/JSAPI_Reference/Jsval" style="font-family: 'Courier New', 'Andale Mono', monospace; line-height: normal;" title="en/jsval">JS::Value</a> (também com um typedef jsval obsoleto), que pode conter valores de JavaScript de qualquer tipo. Um  <span style="font-family: courier new,andale mono,monospace; line-height: normal;">JS::Value</span> pode ser um número, uma string, um valor booleano, uma referência a um objeto (como um <code style="font-size: 14px;">Object</code><code style="font-size: 14px;">Array</code><code style="font-size: 14px;">Date</code>, ou <code style="font-size: 14px;">Function</code>), ou um dos valores especiais <code style="font-size: 14px;">null</code> ou <code style="font-size: 14px;">undefined</code>..</p>

<p>Para inteiros e valores booleanos, um <span style="font-family: courier new,andale mono,monospace; line-height: normal;">jsval</span> contém o próprio valor. Em outros casos, o jsval é um ponteiro para um objeto, string ou número.</p>

<div class="warning">
<div><span style="color: #ffffff;"><strong>Atenção:</strong> Como ponteiros em C ++,  ao contrário das variaveis JavaScript (JavaScript vars), um </span><span style="color: #ffffff; font-family: courier new,andale mono,monospace; line-height: normal;">JS::Value</span><span style="color: #ffffff;"> <strong>não</strong> é automaticamente inicializado para um valor seguro, e pode se tornar um "</span><span style="color: #ffffff;">dangling pointer" </span><span style="color: #ffffff;">!</span></div>

<div> </div>

<div><span style="color: #ffffff;">Um ponteiro dangling é um ponteiro que é utilizado para apontar para um objeto válido, mas não o faz  porque o objeto não existe mais. Usando um ponteiro dangling um programa em C++ </span><span style="color: #ffffff; line-height: 1.5;">pode falhar </span><span style="color: #ffffff; line-height: 1.5;"> (ou pior). No caso de um </span><span style="color: #ffffff; font-family: courier new,andale mono,monospace; line-height: normal;">JS::Value</span><span style="color: #ffffff; line-height: 1.5;">, o coletor de lixo JavaScript recicla objetos, strings e números que não parecem estar em uso, e um </span><span style="color: #ffffff; font-family: courier new,andale mono,monospace; line-height: normal;">JS::Value</span><span style="color: #ffffff; line-height: 1.5;"> por si só não protege seu referente deste coletor de lixo. Veja a  "garbage collenction" abaixo para obter informações cruciais sobre a forma de usar </span><span style="color: #ffffff; font-family: courier new,andale mono,monospace; line-height: normal;">JS::Value</span><span style="color: #ffffff; line-height: 1.5;"> com segurança.</span></div>
</div>

<p><span style="font-family: courier new,andale mono,monospace; line-height: normal;">JS::Value</span><span style="line-height: 1.5;"> inclue membros de funções  para testar  tipos de dados JavaScript. Estes são </span><code style="font-size: 14px; color: rgb(77, 78, 83);">isObject()</code><span style="color: #4d4e53;">,</span><code style="font-size: 14px; color: rgb(77, 78, 83);">isNumber()</code><span style="color: #4d4e53;"></span><code style="font-size: 14px; color: rgb(77, 78, 83);">isInt32()</code><span style="color: #4d4e53;"></span><code style="font-size: 14px; color: rgb(77, 78, 83);">isDouble()</code><span style="color: #4d4e53;"></span><code style="font-size: 14px; color: rgb(77, 78, 83);">isString()</code><span style="color: #4d4e53;"></span><code style="font-size: 14px; color: rgb(77, 78, 83);">isBoolean()</code><span style="color: #4d4e53;"></span><code style="font-size: 14px; color: rgb(77, 78, 83);">isNull()</code><span style="color: #4d4e53;">, e </span><code style="font-size: 14px; color: rgb(77, 78, 83);">isUndefined()</code><span style="line-height: 1.5;">.</span></p>

<div> </div>

<div>Se um <span style="font-family: courier new,andale mono,monospace; line-height: normal;">JS::Value</span> contém um <code style="font-size: 14px;"><a href="/en/SpiderMonkey/JSAPI_Reference/JSObject" title="en/JSObject">JSObject</a></code><code style="font-size: 14px;">double</code>, ou <code style="font-size: 14px;"><a href="/en/SpiderMonkey/JSAPI_Reference/JSString" title="en/JSString">JSString</a></code>, você pode lançá-lo para o seu tipo de dados subjacente usando os mesmobros de função <code style="font-size: 14px;">toObject()</code><code style="font-size: 14px;">toDouble()</code>, and <code style="font-size: 14px;">toString()</code>, respectivamente. Isso é útil em alguns casos onde o aplicativo ou uma função JSAPI requer uma variável ou argumento de um tipo de dados específico, em vez de um <span style="font-family: courier new,andale mono,monospace; line-height: normal;">JS::Value</span>. Da mesma forma, você pode criar um <span style="font-family: courier new,andale mono,monospace; line-height: normal;">JS::Value</span> envolvendo um ponteiro  <code style="font-size: 14px;">JSObject</code><code style="font-size: 14px;">double</code>, ou <code style="font-size: 14px;">JSString</code>  usando <code style="font-size: 14px;">JS::ObjectValue(JSObject&amp;)</code><span style="line-height: 1.5;"></span><code style="font-size: 14px;">JS::DoubleValue(double)</code><span style="line-height: 1.5;">, ou </span><code style="font-size: 14px;">JS::StringValue(JSString*)</code><span style="line-height: 1.5;">.</span></div>

<div> </div>

<div> </div>

<h3 id="Garbage_collection">Garbage collection</h3>

<p>As it runs, JavaScript code implicitly allocates memory for objects, strings, variables, and so on.  Garbage collection is the process by which the JavaScript engine detects when those pieces of memory are no longer reachable—that is, they could not possibly ever be used again—and reclaims the memory.</p>

<p>Garbage collection has two important consequences for JSAPI applications. First, the application must be very careful to ensure that any values it needs are GC-reachable. The garbage collector is rather eager about its job. Any object you leave lying around will be destroyed if you don't tell the JSAPI you're still using it. Second, the application should take steps to reduce the performance impact of garbage collection.</p>

<h4 id="Keeping_objects_alive">Keeping objects alive</h4>

<p>If your JSAPI application crashes, it is likely due to a GC-related error. The application must ensure that the garbage collector can reach all the objects, numbers, and strings that are still being used. Otherwise, the GC will free the memory occupied by those values, leading to a probable crash the next time your program tries to use them.</p>

<p>There are many ways to ensure that a value is GC-reachable.</p>

<ul>
 <li>If you just need the value to remain reachable for the duration of a <code><a href="/en/SpiderMonkey/JSAPI_Reference/JSNative" title="en/JSNative">JSNative</a></code> call, store it in <code>*rval</code> or an element of the <code>argv</code> array. The values stored in those locations are always reachable. To get extra <code>argv</code> slots, use <code><a href="/En/SpiderMonkey/JSAPI_Reference/JSFunctionSpec" title="en/JSFunctionSpec">JSFunctionSpec</a>.extra</code>.</li>
</ul>

<ul>
 <li>If a custom object needs certain values to remain in memory, just store the values in <a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetProperty" title="en/JS_SetProperty">properties</a> of the object. As long as the object is reachable, its properties will remain reachable. If these values must not be accessible from JavaScript, use <a href="/en/SpiderMonkey/JSAPI_Reference/JS_GetReservedSlot" title="en/JS_GetReservedSlot">reserved slots</a> instead. Or store the values in <a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetPrivate" title="en/JS_SetPrivate">private data</a> and implement <code><a href="/en/SpiderMonkey/JSAPI_Reference/JSClass.mark" title="en/JSClass.mark">JSClass.mark</a></code>.</li>
</ul>

<ul>
 <li>If a function creates new objects, strings, or numbers, it can use <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_EnterLocalRootScope" title="en/JS_EnterLocalRootScope">JS_EnterLocalRootScope</a></code> and <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_LeaveLocalRootScope" title="en/JS_LeaveLocalRootScope">JS_LeaveLocalRootScope</a></code> to keep those values alive for the duration of the function.</li>
</ul>

<ul>
 <li>To keep a value alive permanently, store it in a <a href="/en/SpiderMonkey/JSAPI_Reference/JS_AddRoot" title="JS_AddRoot">GC root</a>.</li>
</ul>

<p>Still, GC bugs do occur. These two functions, both available only in <code>DEBUG</code> builds, are especially useful for debugging GC-related crashes:</p>

<ul>
 <li>Use <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetGCZeal" title="en/JS_SetGCZeal">JS_SetGCZeal</a></code> to enable extra garbage collection. GC zeal usually causes a GC-related crash to occur much sooner (closer to its cause) and more reliably. It's for development and debugging only, because the extra garbage collection makes JS very slow.</li>
</ul>

<ul>
 <li>Use <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DumpHeap" title="en/JS_DumpHeap">JS_DumpHeap</a></code> to dump the SpiderMonkey heap or specific interesting parts of it.</li>
</ul>

<p>See <a href="/en/SpiderMonkey_Garbage_Collection_Tips" title="en/SpiderMonkey_Garbage_Collection_Tips">SpiderMonkey Garbage Collection Tips</a> for more details.</p>

<h4 id="GC_performance">GC performance</h4>

<p>Overly frequent garbage collection can be a performance issue. Some applications can reduce the frequency of garbage collection simply by increasing the initial size of the <code>JSRuntime</code>.</p>

<p>Perhaps the best technique is to perform garbage collection during idle time, when it is least likely to have any impact on the user. By default, the JavaScript engine performs garbage collection when it has no other choice except to grow the process. This means that garbage collection typically happens when memory-intensive code is running, perhaps the worst possible time. An application can trigger garbage collection at a more convenient time by calling <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GC" title="en/JS_GC">JS_GC</a></code> or <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_MaybeGC" title="en/JS_MaybeGC">JS_MaybeGC</a></code>. <code>JS_GC</code> forces garbage collection. <code>JS_MaybeGC</code> performs garbage collection only if it is likely to reclaim a worthwhile amount of memory.</p>

<h3 id="Errors_and_exceptions">Errors and exceptions</h3>

<p>The importance of checking the return value of JSAPI functions, of course, goes without saying. Almost every JSAPI function that takes a <code><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JSRuntime" title="en/SpiderMonkey/JSAPI Reference/JSRuntime">JSContext</a> *</code> argument can fail. The system might run out of memory. There might be a syntax error in a script. Or a script might explicitly <code>throw</code> an exception.</p>

<p>The JavaScript language has exceptions, and C++ has exceptions, but they are not the same thing. SpiderMonkey does not use C++ exceptions for anything. JSAPI functions never throw C++ exceptions, and when SpiderMonkey calls an application callback, the callback must not throw a C++ exception.</p>

<h4 id="Throwing_and_catching_exceptions">Throwing and catching exceptions</h4>

<p>We have already seen one example of how to throw an exception from a <code>JSNative</code> function. Simply call <a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_ReportError" title="en/SpiderMonkey/JSAPI Reference/JS ReportError"><code>JS_ReportError</code></a>, with <code>printf</code>-style arguments, and return <code>JS_FALSE</code>.</p>

<pre>    rc = system(cmd);
    if (rc != 0) {
        /* Throw a JavaScript exception. */
        <a class="internal" title="en/SpiderMonkey/JSAPI Reference/JS ReportError">JS_ReportError</a>(cx, "Command failed with exit code %d", rc);
        return JS_FALSE;
    }
</pre>

<p>This is very much like the JavaScript statement <code>throw new Error("Command failed with exit code " + rc);</code>. Again, note that calling <code>JS_ReportError</code> does not cause a C++ exception to be thrown. It only creates a new JavaScript Error object and stores it in the context as the current <dfn>pending exception</dfn>. The application must also return JS_FALSE.</p>

<p>Once the C++ function returns JS_FALSE, the JavaScript engine starts unwinding the JavaScript stack, looking for a <code>catch</code> or <code>finally</code> block to execute. But SpiderMonkey's stack unwinding never removes application's C++ functions from the stack. Instead, SpiderMonkey simply returns <code>JS_FALSE</code> or <code>NULL</code> to the application, which can then handle the error as it chooses—or just return <code>JS_FALSE</code> to let it propagate further up the stack.</p>

<p>Several more examples of throwing and catching exceptions can be found in the <a class="internal" href="/En/SpiderMonkey/JSAPI_Cookbook" title="En/SpiderMonkey/JSAPI Phrasebook">JSAPI Phrasebook</a>.</p>

<h4 id="Error_reports">Error reports</h4>

<p>TODO your custom errorreporter</p>

<p>TODO when errors are reported</p>

<h4 id="Automatic_handling_of_uncaught_exceptions">Automatic handling of uncaught exceptions</h4>

<p>The <code>JS_Compile</code>*, <code>JS_Call</code>*, <code>JS_Execute</code>*, and <code>JS_Evaluate</code>* functions automatically pass exceptions to the error reporter in certain cases. Each of these functions checks, just before it returns, to see if an exception is pending in the current <code>JSContext</code>. If so, it then checks to see if there is any other JavaScript script or function on the stack in that <code>JSContext</code>. If so, then the exception might yet be caught, so SpiderMonkey does nothing and returns JS_FALSE, allowing the exception to propagate. But if nothing is on the JavaScript stack, then the uncaught exception is passed to the error reporter and the pending exception is cleared.</p>

<p>The basic consequence is that top-level application code can just set an error reporter and start calling JSAPI functions. It never has to explicitly handle uncaught exceptions; the error reporter is automatically called. An application can disable automatic uncaught-exception handling using the <a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_SetOptions" title="en/SpiderMonkey/JSAPI Reference/JS
SetOptions"><code>JSOPTION_DONT_REPORT_UNCAUGHT</code></a> option, but it must then deal with uncaught exceptions explicitly by calling <a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_IsExceptionPending" title="en/SpiderMonkey/JSAPI Reference/JS IsExceptionPending"><code>JS_IsExceptionPending</code></a>, <a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_GetPendingException" title="en/SpiderMonkey/JSAPI Reference/JS GetPendingException"><code>JS_GetPendingException</code></a>, <a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_ReportPendingException" title="en/SpiderMonkey/JSAPI Reference/JS_ReportPendingException"><code>JS_ReportPendingException</code></a>, and/or <a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_ClearPendingException" title="en/SpiderMonkey/JSAPI Reference/JS ClearPendingException"><code>JS_ClearPendingException</code></a> whenever a JSAPI function returns <code>JS_FALSE</code> or <code>NULL</code>.</p>

<h4 id="Uncatchable_errors">Uncatchable errors</h4>

<p>Another way for a <code>JSNative</code> callback to report an error is like this:</p>

<pre>    if (p == NULL) {
        <a class="internal" title="en/SpiderMonkey/JSAPI Reference/JS ReportOutOfMemory">JS_ReportOutOfMemory</a>(cx);
        return JS_FALSE;
    }
</pre>

<p>This does something subtly different from what <code>JS_ReportError</code> does.</p>

<p>Most errors, including those raised by <code>JS_ReportError</code>, are represented as JavaScript exceptions and thus interact with the JavaScript exception-handling language features, <code>try</code>, <code>catch</code>, and <code>finally</code>. However, in some cases we do not want scripts to be able to <code>catch</code> an error; we want script execution to terminate right away. If the system runs out of memory in the middle of a script, we do not want <code>finally</code> blocks to execute, because almost anything a script does requires at least a little memory, and we have none. If a script has been running too long and we want to kill it, it's no good to throw an exception—the script could just <code>catch</code> it and keep going.</p>

<p>Therefore <code><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_ReportOutOfMemory" title="en/SpiderMonkey/JSAPI Reference/JS ReportOutOfMemory">JS_ReportOutOfMemory</a>(cx)</code> does <em>not</em> set the pending exception. It is an uncatchable error.</p>

<p>If SpiderMonkey runs out of memory, or a JSAPI callback returns <code>JS_FALSE</code> without an exception pending, this is treated as an uncatchable error. The JavaScript stack is unwound in the normal way except that <code>catch</code> and <code>finally</code> blocks are ignored. The most recent JSAPI call returns <code>JS_FALSE</code> or <code>NULL</code> to the application.</p>

<p>An uncatchable error leaves the <code>JSContext</code> in a good state. It can be used again right away. The application does not have to do anything to “recover” from the error, as far as the JSAPI is concerned. (Of course, if the error is that the system is out of memory, that problem remains to be dealt with.)</p>

<p>Here is some example code that throws an uncatchable error.</p>

<pre>    /* Call the error reporter, if any. This part is optional. */
    <a class="internal" title="en/SpiderMonkey/JSAPI Reference/JS ReportError">JS_ReportError</a>(cx, "The server room is on fire!");
    JS_ReportPendingException(cx);

    /* Make sure the error is uncatchable. */
    <a class="internal" title="en/SpiderMonkey/JSAPI Reference/JS ClearPendingException">JS_ClearPendingException</a>(cx);
    return JS_FALSE;
</pre>

<p> </p>

<p> </p>

<h2 id="More sample code" name="More sample code">More sample code</h2>

<p>The following examples illustrate how to achieve a few different effects using the JSAPI.</p>

<p>Note that the most important example is in the "A minimal example" section above. More JSAPI code samples appear in the <a href="/En/SpiderMonkey/JSAPI_Cookbook" title="en/JSAPI_Phrasebook">JSAPI Phrasebook</a>.</p>

<h3 id="Defining_objects_and_properties">Defining objects and properties</h3>

<pre>/* Statically initialize a class to make "one-off" objects. */
<a href="JSAPI_Reference/JSClass">JSClass</a> my_class = {
    "MyClass",

    /* All of these can be replaced with the corresponding JS_*Stub
       function pointers. */
    my_addProperty, my_delProperty, my_getProperty, my_setProperty,
    my_enumerate,   my_resolve,     my_convert,     my_finalize
};

<a href="JSAPI_Reference/JSObject">JSObject</a> *obj;

/*
 * Define an object named in the global scope that can be enumerated by
 * for/in loops.  The parent object is passed as the second argument, as
 * with all other API calls that take an object/name pair.  The prototype
 * passed in is null, so the default object prototype will be used.
 */
obj = <a href="JSAPI_Reference/JS_DefineObject">JS_DefineObject</a>(cx, globalObj, "myObject", &amp;my_class, NULL,
                      <a href="JSAPI_Reference/JS_GetPropertyAttributes">JSPROP_ENUMERATE</a>);

/*
 * Define a bunch of properties with a JSPropertySpec array statically
 * initialized and terminated with a null-name entry.  Besides its name,
 * each property has a "tiny" identifier (MY_COLOR, e.g.) that can be used
 * in switch statements (in a common my_getProperty function, for example).
 */
enum my_tinyid {
    MY_COLOR, MY_HEIGHT, MY_WIDTH, MY_FUNNY, MY_ARRAY, MY_RDONLY
};

static <a href="JSAPI_Reference/JSPropertySpec">JSPropertySpec</a> my_props[] = {
    {"color",       MY_COLOR,       JSPROP_ENUMERATE},
    {"height",      MY_HEIGHT,      JSPROP_ENUMERATE},
    {"width",       MY_WIDTH,       JSPROP_ENUMERATE},
    {"funny",       MY_FUNNY,       JSPROP_ENUMERATE},
    {"array",       MY_ARRAY,       JSPROP_ENUMERATE},
    {"rdonly",      MY_RDONLY,      JSPROP_READONLY},
    {0}
};

<a href="JSAPI_Reference/JS_DefineProperties">JS_DefineProperties</a>(cx, obj, my_props);

/*
 * Given the above definitions and call to JS_DefineProperties, obj will
 * need this sort of "getter" method in its class (my_class, above).  See
 * the example for the "It" class in js.c.
 */
static JSBool
my_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
    if (<a href="JSAPI_Reference/JSVAL_IS_INT">JSVAL_IS_INT</a>(id)) {
        switch (<a href="JSAPI_Reference/JSVAL_TO_INT">JSVAL_TO_INT</a>(id)) {
          case MY_COLOR:  *vp = . . .; break;
          case MY_HEIGHT: *vp = . . .; break;
          case MY_WIDTH:  *vp = . . .; break;
          case MY_FUNNY:  *vp = . . .; break;
          case MY_ARRAY:  *vp = . . .; break;
          case MY_RDONLY: *vp = . . .; break;
        }
    }
    return JS_TRUE;
}
</pre>

<h3 id="Defining_classes" name="Defining_classes">Defining classes</h3>

<p>This pulls together the above API elements by defining a constructor function, a prototype object, and properties of the prototype and of the constructor, all with one API call.</p>

<p>Initialize a class by defining its constructor function, prototype, and per-instance and per-class properties. The latter are called "static" below by analogy to Java. They are defined in the constructor object's scope, so that <code>MyClass.myStaticProp</code> works along with <code>new MyClass()</code>.</p>

<p><code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_InitClass" title="en/JS_InitClass">JS_InitClass</a></code> takes a lot of arguments, but you can pass <code>NULL</code> for any of the last four if there are no such properties or methods.</p>

<p>Note that you do not need to call <code>JS_InitClass</code> to make a new instance of that class—otherwise there would be a chicken-and-egg problem making the global object—but you should call <code>JS_InitClass</code> if you require a constructor function for script authors to call via <code>new</code>, and/or a class prototype object (<code>MyClass.prototype</code>) for authors to extend with new properties at run time. In general, if you want to support multiple instances that share behavior, use <code>JS_InitClass</code>.</p>

<pre>protoObj = <a href="JSAPI_Reference/JS_InitClass">JS_InitClass</a>(cx, globalObj, NULL, &amp;my_class,

                        /* native constructor function and min arg count */
                        MyClass, 0,

                        /* prototype object properties and methods -- these
                           will be "inherited" by all instances through
                           delegation up the instance's prototype link. */
                        my_props, my_methods,

                        /* class constructor properties and methods */
                        my_static_props, my_static_methods);
</pre>

<h3 id="Running_scripts" name="Running_scripts">Running scripts</h3>

<pre>/* These should indicate source location for diagnostics. */
char *filename;
uintN lineno;

/*
 * The return value comes back here -- if it could be a GC thing, you must
 * add it to the GC's "root set" with <a href="JSAPI_Reference/JS_AddRoot">JS_AddRoot</a>(cx, &amp;thing) where thing
 * is a JSString *, JSObject *, or jsdouble *, and remove the root before
 * rval goes out of scope, or when rval is no longer needed.
 */
jsval rval;
JSBool ok;

/*
 * Some example source in a C string.  Larger, non-null-terminated buffers
 * can be used, if you pass the buffer length to JS_EvaluateScript.
 */
char *source = "x * f(y)";

ok = <a href="JSAPI_Reference/JS_EvaluateScript">JS_EvaluateScript</a>(cx, globalObj, source, strlen(source),
                       filename, lineno, &amp;rval);

if (ok) {
    /* Should get a number back from the example source. */
    jsdouble d;

    ok = <a href="JSAPI_Reference/JS_ValueToNumber">JS_ValueToNumber</a>(cx, rval, &amp;d);
    . . .
}
</pre>

<h4 id="Calling_functions" name="Calling_functions">Calling functions</h4>

<pre>/* Call a global function named "foo" that takes no arguments. */
ok = <a href="JSAPI_Reference/JS_CallFunctionName">JS_CallFunctionName</a>(cx, globalObj, "foo", 0, 0, &amp;rval);

jsval argv[2];

/* Call a function in obj's scope named "method", passing two arguments. */
argv[0] = . . .;
argv[1] = . . .;
ok = <a href="JSAPI_Reference/JS_CallFunctionName">JS_CallFunctionName</a>(cx, obj, "method", 2, argv, &amp;rval);
</pre>

<h3 id="JSContext" name="JSContext">JSContext</h3>

<p>Because there is a certain amount of overhead associated with allocating and maintaining contexts, a JSAPI application should:</p>

<ol>
 <li>Create only as many contexts as it needs at one time.</li>
 <li>Keep contexts for as long as they may be needed, rather than destroying and recreating them as needed.</li>
</ol>

<p>If your application creates multiple runtimes, the application may need to know which runtime a context is associated with. In this case, use <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GetRuntime" title="en/JS_GetRuntime">JS_GetRuntime</a></code>.</p>

<p>Use <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GetContextPrivate" title="en/JS_GetContextPrivate">JS_SetContextPrivate</a></code> and <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GetContextPrivate" title="en/JS_GetContextPrivate">JS_GetContextPrivate</a></code> to associate application-specific data with a context.</p>

<h3 id="Initializing_built-in_and_global_JS_objects" name="Initializing_built-in_and_global_JS_objects">Initializing built-in and global JS objects</h3>

<p>For a complete list of built-in objects provided by SpiderMonkey, see <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_InitStandardClasses" title="en/JS_InitStandardClasses">JS_InitStandardClasses</a></code>.</p>

<p>The global object that an application provides to scripts largely determines what those scripts can do. For example, the Firefox browser uses its own global object, <code>window</code>. To change the global object for your application, call <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetGlobalObject" title="en/JS_SetGlobalObject">JS_SetGlobalObject</a></code>.</p>

<h3 id="Creating_and_initializing_custom_objects" name="Creating_and_initializing_custom_objects">Creating and initializing custom objects</h3>

<p>In addition to using the engine's built-in objects, you will create, initialize, and use your own JS objects. This is especially true if you are using the JS engine with scripts to automate your application. Custom JS objects can provide direct program services, or they can serve as interfaces to your program's services. For example, a custom JS object that provides direct service might be one that handles all of an application's network access, or might serve as an intermediary broker of database services. Or a JS object that mirrors data and functions that already exist in the application may provide an object-oriented interface to C code that is not otherwise, strictly-speaking, object-oriented itself. Such a custom object acts as an interface to the application itself, passing values from the application to the user, and receiving and processing user input before returning it to the application. Such an object might also be used to provide access control to the underlying functions of the application.</p>

<p>There are two ways to create custom objects that the JS engine can use:</p>

<ul>
 <li>Write a JS script that creates an object, its properties, methods, and constructor, and then pass the script to the JS engine at run time.</li>
 <li>Embed code in your application that defines the object's properties and methods, call the engine to initialize a new object, and then set the object's properties through additional engine calls. An advantage of this method is that your application can contain native methods that directly manipulate the object embedding.</li>
</ul>

<p>In either case, if you create an object and then want it to persist in the run time where it can be used by other scripts, you must root the object by calling <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_AddRoot" title="en/JS_AddRoot">JS_AddRoot</a></code> or <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_AddRoot" title="en/JS_AddRoot">JS_AddNamedRoot</a></code>. Using these functions ensures that the JS engine will keep track of the objects and clean them up during garbage collection, if appropriate.</p>

<h3 id="Creating_an_object_from_a_script" name="Creating_an_object_from_a_script">Creating an object from a script</h3>

<p>One reason to create a custom JS object from a script is when you only need an object to exist as long as the script that uses it is executing. To create objects that persist across script calls, you can embed the object code in your application instead of using a script.</p>

<p><strong>Note</strong>: You can also use scripts to create persistent objects, too.</p>

<p>To create a custom object using a script:</p>

<ol>
 <li>Define and spec the object. What is it intended to do? What are its data members (properties)? What are its methods (functions)? Does it require a run time constructor function?</li>
 <li>Code the JS script that defines and creates the object. For example: function myfun(){ var x = newObject(); . . . } <strong>NOTE</strong>: Object scripting using JavaScript occurs outside the context of embedding the JS engine in your applications. For more information about object scripting, see the <em>Client-Side JavaScript Guide</em> and the <em>Server-Side JavaScript Guide</em>. Embed the appropriate JS engine call(s) in your application to compile and execute the script. You have two choices: 1.) compile and execute a script with a single call to <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_EvaluateScript" title="en/JS_EvaluateScript">JS_EvaluateScript</a></code>, <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_EvaluateScript" title="en/JS_EvaluateScript">JS_EvaluateUCScript</a></code> or 2.) compile the script once with a call to <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileScript" title="en/JS_CompileScript">JS_CompileScript</a></code> or <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileScript" title="en/JS_CompileScript">JS_CompileUCScript</a></code>, and then execute it repeatedly with individual calls to <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_ExecuteScript" title="en/JS_ExecuteScript">JS_ExecuteScript</a></code>. The "UC" versions of these calls provide support for Unicode-encoded scripts.</li>
</ol>

<p>An object you create using a script only can be made available only during the lifetime of the script, or can be created to persist after the script completes execution. Ordinarily, once script execution is complete, its objects are destroyed. In many cases, this behavior is just what your application needs. In other cases, however, you will want object persistence across scripts, or for the lifetime of your application. In these cases you need to embed object creation code directly in your application, or you need to tie the object directly to the global object so that it persists as long as the global object itself persists.</p>

<h3 id="Custom_objects" name="Custom_objects">Custom objects</h3>

<p>An application can create a custom object without bothering with a <code>JSClass</code>:</p>

<ol>
 <li>Implement the getters, setters, and methods for your custom object in C or C++.  Write a <a class="internal" href="/En/SpiderMonkey/JSAPI_Reference/JSPropertyOp" title="en/JSPropertyOp"><code>JSPropertyOp</code></a> for each getter or setter.  Write a <a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JSNative" title="En/JSNative"><code>JSNative</code></a> or <code>JSFastNative</code> for each method.</li>
 <li>Declare a <code><a href="/en/SpiderMonkey/JSAPI_Reference/JSPropertySpec" title="en/JSPropertySpec">JSPropertySpec</a></code> array containing information about your custom object's properties, including getters and setters.</li>
 <li>Declare a <code><a href="/En/SpiderMonkey/JSAPI_Reference/JSFunctionSpec" title="en/JSFunctionSpec">JSFunctionSpec</a></code> array containing information about your custom object's methods.</li>
 <li>Call <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewObject" title="en/JS_NewObject">JS_NewObject</a></code>, <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_ConstructObject" title="en/JS_ConstructObject">JS_ConstructObject</a></code>, or <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DefineObject" title="en/JS_DefineObject">JS_DefineObject</a></code> to create the object.</li>
 <li>Call <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DefineProperties" title="en/JS_DefineProperties">JS_DefineProperties</a></code> to define the object's properties.</li>
 <li>Call <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DefineFunctions" title="en/JS_DefineFunctions">JS_DefineFunctions</a></code> to define the object's methods.</li>
</ol>

<p><code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetProperty" title="en/JS_SetProperty">JS_SetProperty</a></code> can also be used to create properties on an object. The properties it creates do not have getters or setters; they are ordinary JavaScript properties.</p>

<h3 id="Providing_private_data_for_objects" name="Providing_private_data_for_objects">Providing private data for objects</h3>

<p>Like contexts, you can associate large quantities of data with an object without having to store the data in the object itself. Call <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetPrivate" title="en/JS_SetPrivate">JS_SetPrivate</a></code> to establish a pointer to private data for the object, and call <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GetPrivate" title="en/JS_GetPrivate">JS_GetPrivate</a></code> to retrieve the pointer so that you can access the data. Your application is responsible for creating and managing this optional private data.</p>

<p>To create private data and associate it with an object:</p>

<ol>
 <li>Establish the private data as you would a normal C void pointer variable.</li>
 <li>Call <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetPrivate" title="en/JS_SetPrivate">JS_SetPrivate</a></code>, specify the object for which to establish private data, and specify the pointer to the data.</li>
</ol>

<p>For example:</p>

<pre> JS_SetPrivate(cx, obj, pdata);
</pre>

<p>To retrieve the data at a later time, call <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GetPrivate" title="en/JS_GetPrivate">JS_GetPrivate</a></code>, and pass the object as an argument. This function returns the pointer to an object's private data:</p>

<pre> pdata = JS_GetPrivate(cx, obj);
</pre>

<h2 id="Special_topics">Special topics</h2>

<h3 id="Handling_Unicode" name="Handling_Unicode">Unicode</h3>

<p>To pass Unicode data between JavaScript and native code, represent the data in UTF-16 in memory. JavaScript strings, property names, and programs are all made up of <code>jschar</code>s, which are 16-bit unsigned integers.</p>

<p>Many JSAPI functions operate on null-terminated, 8-bit <code>char</code> strings. These functions convert their <code>char *</code> arguments to 16-bit strings by zero-extending each 8-bit <code>char</code> to 16 bits—unless <a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_C_STRINGS_ARE_UTF8" title="en/SpiderMonkey/JSAPI Reference/JS C STRINGS ARE UTF8"><code>JS_C_STRINGS_ARE_UTF8</code></a> is defined or <a class="internal" href="/En/SpiderMonkey/JSAPI_Reference/JS_CStringsAreUTF8" title="en/SpiderMonkey/JSAPI Reference/JS SetCStringsAreUTF8"><code>JS_SetCStringsAreUTF8</code></a> has been called, in which case each <code>char *</code> string is interpreted as UTF-8 Unicode text.</p>

<p>The JSAPI provides <code>jschar</code>-based versions of many API functions that operate on strings, object properties, and JavaScript code.</p>

<table class="fullwidth-table">
 <thead>
  <tr>
   <th><code>char</code>-based function</th>
   <th><code>jschar</code>-based function</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td colspan="2"><em>Unicode data</em></td>
  </tr>
  <tr>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_GetStringBytes" title="En/SpiderMonkey/JSAPI Reference/JS GetStringBytes">JS_GetStringBytes</a><span class="internal"> {{obsolete_inline}}</span></td>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_GetStringChars" title="en/SpiderMonkey/JSAPI Reference/JS GetStringChars">JS_GetStringChars</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewString" title="en/JS_NewString">JS_NewString</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewString" title="en/JS_NewString">JS_NewUCString</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewStringCopyN" title="en/JS_NewStringCopyN">JS_NewStringCopyN</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewStringCopyN" title="en/JS_NewStringCopyN">JS_NewUCStringCopyN</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewStringCopyZ" title="en/JS_NewStringCopyZ">JS_NewStringCopyZ</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewStringCopyZ" title="en/JS_NewStringCopyZ">JS_NewUCStringCopyZ</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_InternString" title="en/JS_InternString">JS_InternString</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_InternString" title="en/JS_InternString">JS_InternUCString</a>, <a href="/en/SpiderMonkey/JSAPI_Reference/JS_InternString" title="en/JS_InternString">JS_InternUCStringN</a></td>
  </tr>
  <tr>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_ReportErrorNumber" title="En/SpiderMonkey/JSAPI Reference/JS ReportErrorNumber">JS_ReportErrorNumber</a></td>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_ReportErrorNumber" title="en/SpiderMonkey/JSAPI Reference/JS ReportErrorNumberUC">JS_ReportErrorNumberUC</a></td>
  </tr>
  <tr>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_ReportErrorNumber" title="En/SpiderMonkey/JSAPI Reference/JS ReportErrorNumber">JS_ReportErrorFlagsAndNumber</a></td>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_ReportErrorNumber" title="En/SpiderMonkey/JSAPI Reference/JS ReportErrorNumber">JS_ReportErrorFlagsAndNumberUC</a></td>
  </tr>
 </tbody>
 <tbody>
  <tr>
   <td colspan="2"><em>Unicode property names</em></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DefineProperty" title="en/JS_DefineProperty">JS_DefineProperty</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DefineProperty" title="en/JS_DefineProperty">JS_DefineUCProperty</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DefinePropertyWithTinyId" title="en/JS_DefinePropertyWithTinyId">JS_DefinePropertyWithTinyId</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DefinePropertyWithTinyId" title="en/JS_DefinePropertyWithTinyId">JS_DefineUCPropertyWithTinyId</a></td>
  </tr>
  <tr>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_DefineFunction" title="En/SpiderMonkey/JSAPI Reference/JS DefineFunction">JS_DefineFunction</a></td>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_DefineFunction" title="En/SpiderMonkey/JSAPI Reference/JS DefineFunction">JS_DefineUCFunction</a></td>
  </tr>
  <tr>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_HasProperty" title="En/SpiderMonkey/JSAPI Reference/JS HasProperty">JS_HasProperty</a></td>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_HasProperty" title="En/SpiderMonkey/JSAPI Reference/JS HasProperty">JS_HasUCProperty</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_LookupProperty" title="en/JS_LookupProperty">JS_LookupProperty</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_LookupProperty" title="en/JS_LookupProperty">JS_LookupUCProperty</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GetProperty" title="en/JS_GetProperty">JS_GetProperty</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GetProperty" title="en/JS_GetProperty">JS_GetUCProperty</a></td>
  </tr>
  <tr>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_GetPropertyAttributes" title="En/SpiderMonkey/JSAPI Reference/JS GetPropertyAttributes">JS_GetPropertyAttributes</a></td>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_GetPropertyAttributes" title="en/SpiderMonkey/JSAPI Reference/JS GetUCPropertyAttributes">JS_GetUCPropertyAttributes</a></td>
  </tr>
  <tr>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_GetPropertyAttrsGetterAndSetter" title="En/SpiderMonkey/JSAPI Reference/JS GetPropertyAttrsGetterAndSetter">JS_GetPropertyAttrsGetterAndSetter</a></td>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_GetPropertyAttrsGetterAndSetter" title="en/SpiderMonkey/JSAPI Reference/JS GetUCPropertyAttrsGetterAndSetter">JS_GetUCPropertyAttrsGetterAndSetter</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetProperty" title="en/JS_SetProperty">JS_SetProperty</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetProperty" title="en/JS_SetProperty">JS_SetUCProperty</a></td>
  </tr>
  <tr>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_SetPropertyAttributes" title="En/SpiderMonkey/JSAPI Reference/JS SetPropertyAttributes">JS_SetPropertyAttributes</a></td>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_SetPropertyAttributes" title="En/SpiderMonkey/JSAPI Reference/JS SetPropertyAttributes">JS_SetUCPropertyAttributes</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DeleteProperty2" title="en/JS_DeleteProperty2">JS_DeleteProperty2</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_DeleteProperty2" title="en/JS_DeleteProperty2">JS_DeleteUCProperty2</a></td>
  </tr>
  <tr>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_AlreadyHasOwnProperty" title="En/SpiderMonkey/JSAPI Reference/JS AlreadyHasOwnProperty">JS_AlreadyHasOwnProperty</a></td>
   <td><a class="internal" href="/en/SpiderMonkey/JSAPI_Reference/JS_AlreadyHasOwnProperty" title="En/SpiderMonkey/JSAPI Reference/JS AlreadyHasOwnProperty">JS_AlreadyHasOwnUCProperty</a></td>
  </tr>
 </tbody>
 <tbody>
  <tr>
   <td colspan="2"><em>Unicode JavaScript source</em></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileScript" title="en/JS_CompileScript">JS_CompileScript</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileScript" title="en/JS_CompileScript">JS_CompileUCScript</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileScriptForPrincipals" title="en/JS_CompileScriptForPrincipals">JS_CompileScriptForPrincipals</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileScriptForPrincipals" title="en/JS_CompileScriptForPrincipals">JS_CompileUCScriptForPrincipals</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileFunction" title="en/JS_CompileFunction">JS_CompileFunction</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileFunction" title="en/JS_CompileFunction">JS_CompileUCFunction</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileFunctionForPrincipals" title="en/JS_CompileFunctionForPrincipals">JS_CompileFunctionForPrincipals</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileFunctionForPrincipals" title="en/JS_CompileFunctionForPrincipals">JS_CompileUCFunctionForPrincipals</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_EvaluateScript" title="en/JS_EvaluateScript">JS_EvaluateScript</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_EvaluateScript" title="en/JS_EvaluateScript">JS_EvaluateUCScript</a></td>
  </tr>
  <tr>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_EvaluateScriptForPrincipals" title="en/JS_EvaluateScriptForPrincipals">JS_EvaluateScriptForPrincipals</a></td>
   <td><a href="/en/SpiderMonkey/JSAPI_Reference/JS_EvaluateScriptForPrincipals" title="en/JS_EvaluateScriptForPrincipals">JS_EvaluateUCScriptForPrincipals</a></td>
  </tr>
 </tbody>
</table>

<p><code>jschar</code>-based functions work exactly like their <code>char</code>-based namesakes, except that where traditional functions take a <code>char *</code> argument, the Unicode versions take a <code>jschar *</code> argument, usually with a separate argument specifying the length of the string in <code>jschar</code>s.</p>

<h3 id="Compiled_scripts" name="Compiled_scripts">Compiled scripts</h3>

<p>The easiest way to run a script is to use <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_EvaluateScript" title="en/JS_EvaluateScript">JS_EvaluateScript</a></code>, which compiles and executes the script in one go.</p>

<p>But sometimes an application needs to run a script many times. In this case, it may be faster to compile the script once and execute it multiple times.</p>

<p>The JSAPI provides a type, <code><a href="/en/JSScript" title="en/JSScript">JSScript</a></code>, that represents a compiled script. The life cycle of a <code>JSScript</code> looks like this:</p>

<ul>
 <li>The application compiles some JavaScript code using <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileScript" title="en/JS_CompileScript">JS_CompileScript</a></code>, <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileFile" title="en/JS_CompileFile">JS_CompileUTF8File</a></code>, or <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileFileHandle" title="en/JS_CompileFileHandle">JS_CompileFileHandle</a></code>. These functions return a pointer to a new <code>JSScript</code>.</li>
</ul>

<ul>
 <li>The application calls <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_ExecuteScript" title="en/JS_ExecuteScript">JS_ExecuteScript</a></code> (or <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_ExecuteScriptPart" title="en/JS_ExecuteScriptPart">JS_ExecuteScriptPart</a></code>) any number of times. It is safe to use a <code>JSScript</code> in multiple different contexts, but only within the <code>JSRuntime</code> and thread in which it was created.</li>
</ul>

<p>Here is some example code using a compiled script:</p>

<pre>/*
 * Compile a script and execute it repeatedly until an
 * error occurs.  (If this ever returns, it returns false.
 * If there's no error it just keeps going.)
 */
<a href="../SpiderMonkey/JSAPI_Reference/JSBool">JSBool</a> compileAndRepeat(<a href="JSAPI_Reference/JSRuntime">JSContext</a> *cx, const char *filename)
{
    <a href="../JSScript">JSScript</a> *script;

    script = <a href="JSAPI_Reference/JS_CompileFile">JS_CompileUTF8File</a>(cx, <a href="JSAPI_Reference/JS_GetGlobalObject">JS_GetGlobalObject</a>(cx), filename);
    if (script == NULL)
        return JS_FALSE;   /* compilation error */

    for (;;) {
        jsval result;

        if (!<a href="JSAPI_Reference/JS_ExecuteScript">JS_ExecuteScript</a>(cx, <a href="JSAPI_Reference/JS_GetGlobalObject">JS_GetGlobalObject</a>(cx), script, &amp;result))
            break;
        <a href="JSAPI_Reference/JS_MaybeGC">JS_MaybeGC</a>(cx);
    }

    return JS_FALSE;
}
</pre>

<p>The lifetime of the compiled script is tied to the lifetime of a JavaScript object, the garbage collector destroys the script when it is no longer reachable. The JSAPI provides this feature via the <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewScriptObject" title="en/JS_NewScriptObject">JS_NewScriptObject</a></code> function. The life cycle of a script using this feature is like this:</p>

<ul>
 <li>The application compiles some JavaScript code.</li>
</ul>

<ul>
 <li>To protect the compiled script from garbage collection, the application creates a <em>compiled script object</em> by calling <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewScriptObject" title="en/JS_NewScriptObject">JS_NewScriptObject</a></code> and makes that object GC-reachable using <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetProperty" title="en/JS_SetProperty">JS_SetProperty</a></code>, <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_GetReservedSlot" title="en/JS_GetReservedSlot">JS_SetReservedSlot</a></code>, <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_AddRoot" title="en/JS_AddRoot">JS_AddRoot</a></code>, or some other function.</li>
</ul>

<ul>
 <li>The application executes the compiled script any number of times.</li>
</ul>

<ul>
 <li>As the application progresses, eventually it doesn't need the compiled script anymore, and the compiled script object becomes unreachable.</li>
</ul>

<ul>
 <li>The garbage collector then eventually collects the unreachable script and its components.</li>
</ul>

<p>Here is example code demonstrating the technique—but note that this case is not really complex enough to warrant the use of <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_NewScriptObject" title="en/JS_NewScriptObject">JS_NewScriptObject</a></code>. The above example does the same thing more directly.</p>

<pre>/*
 * Compile a script and execute it repeatedly until an
 * error occurs.  (If this ever returns, it returns false.
 * If there's no error it just keeps going.)
 */
<a href="../SpiderMonkey/JSAPI_Reference/JSBool">JSBool</a> compileAndRepeat(<a href="JSAPI_Reference/JSRuntime">JSContext</a> *cx, const char *filename)
{
    <a href="../JSScript">JSScript</a> *script;
    <a href="JSAPI_Reference/JSObject">JSObject</a> *scriptObj;

    script = <a href="JSAPI_Reference/JS_CompileFile">JS_CompileUTF8File</a>(cx, <a href="JSAPI_Reference/JS_GetGlobalObject">JS_GetGlobalObject</a>(cx), filename);
    if (script == NULL)
        return JS_FALSE;   /* compilation error */

    scriptObj = <a href="JSAPI_Reference/JS_NewScriptObject">JS_NewScriptObject</a>(cx, script);
    if (scriptObj == NULL) {
        <a href="JSAPI_Reference/JS_DestroyScript">JS_DestroyScript</a>(cx, script);
        return JS_FALSE;
    }

    if (!<a href="JSAPI_Reference/JS_AddRoot">JS_AddNamedObjectRoot</a>(cx, &amp;scriptObj, "compileAndRepeat script object"))
        return JS_FALSE;

    for (;;) {
        jsval result;

        if (!<a href="JSAPI_Reference/JS_ExecuteScript">JS_ExecuteScript</a>(cx, <a href="JSAPI_Reference/JS_GetGlobalObject">JS_GetGlobalObject</a>(cx), script, &amp;result))
            break;
        <a href="JSAPI_Reference/JS_MaybeGC">JS_MaybeGC</a>(cx);
    }

    <a href="JSAPI_Reference/JS_RemoveRoot">JS_RemoveObjectRoot</a>(cx, &amp;scriptObj);  /* scriptObj becomes unreachable
                                             and will eventually be collected. */
    return JS_FALSE;
}
</pre>

<h3 id="Security" name="Security">Security</h3>

<p>Many applications use SpiderMonkey to run untrusted code. In designing this kind of application, it's important to think through the security concerns ahead of time. Your application will need to do several things.</p>

<ul>
 <li><strong>Deploy security updates</strong> - Firefox automatically installs updates, so security fixes are deployed as soon as they are available. Unless you also regularly deploy SpiderMonkey security updates, a determined hacker could use publicly known bugs in the engine to attack your application. Note that the kind of attack we're talking about here is where a hacker uses JavaScript to attack the C++ code of the engine itself (or your embedding). The rest of the items in this list talk about security issues that arise within JavaScript itself, even if the engine is working properly.</li>
 <li><strong>Block simple denial-of-service attacks</strong> - A program like <code>while(true){}</code> should not hang your application. To stop execution of scripts that run too long, use <a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetOperationCallback" title="en/SpiderMonkey/JSAPI Reference/JS SetOperationCallback"><code>JS_SetOperationCallback</code></a>. Likewise, a function like <code>function f(){f();}</code> should not crash your application with a stack overflow. To block that, use <a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetNativeStackQuota" title="en/SpiderMonkey/JSAPI Reference/JS SetNativeStackQuota"><code>JS_SetNativeStackQuota</code></a>.</li>
 <li><strong>Control access to sensitive data</strong> - Your application might expose data to some scripts that other scripts should not be able to see. For example, you might let your customers write scripts that operate on their own data, but not other customers' data. These access rules must be enforced somehow.</li>
 <li><strong>Control access to dangerous functionality</strong> - Suppose your application has a method deleteUserAccount() which is meant to be used by administrators only. Obviously if untrusted code can use that method, you have a security problem.</li>
</ul>

<p>The first two problems are important but fairly straightforward and will not be discussed further here. The rest of this section tells how you can control scripts' access to data and functionality.</p>

<h4 id="The_best_security_is_no_security_(really)">The best security is no security (really)</h4>

<p>Do you ever worry about your snake eating your mouse? No? If you don't have both a snake and a mouse, you don't have this problem.</p>

<p>Likewise, if your application doesn't have both untrusted users (snakes) and sensitive data or dangerous functionality that's exposed to JavaScript (mice), then you don't need to read any further. The functions and objects created by <a href="/en/SpiderMonkey/JSAPI_Reference/JS_InitStandardClasses" title="en/SpiderMonkey/JSAPI Reference/JS InitStandardClasses"><code>JS_InitStandardClasses</code></a> are safe. They do not provide access to files, the network, or anything browser-related. The most sensitive information they expose to scripts is the current date and time.</p>

<h4 id="Object-capabilities-based_security">Object-capabilities-based security</h4>

<p>One way to keep a snake from eating a mouse is to keep the mouse and the snake in separate cages.</p>

<p>One way to keep user A from accessing user B's sensitive data or dangerous functions is to keep each user's code in a separate sandbox. That is, create a separate JSContext and global object for each user, and always run each script in the appropriate context. When setting up a new global object, simply don't define any functions the user shouldn't have access to. This approach is called object-capabilities security. To learn more about it, <a class="external" href="http://www.youtube.com/watch?v=EGX2I31OhBE" title="http://www.youtube.com/watch?v=EGX2I31OhBE">watch the movie</a> or <a class="external" href="http://www.erights.org/talks/thesis/">read the book</a>.</p>

<p>The metaphor is misleading in one regard: the snake can't reach the mouse because there's a physical barrier in the way. With SpiderMonkey the situation is more subtle. There's no barrier; there's just no way to get there from here. How can a malicious script get a reference to an object from another sandbox? It might as well be in a parallel universe. Even global variables are per-sandbox. There is no <code>getObjectFromOtherSandbox()</code> function. Your application just needs to take care not to expose any such function to scripts.</p>

<p>In short, never pass one user's data and objects to another user's code, and you'll have no access control issues. SpiderMonkey won't do it if you don't.</p>

<p><strong>Trade-offs.</strong> Object-capabilities security is security without run-time security checks. It is easy to implement, easy to reason about, and fast. But in fairness there are some drawbacks. First, the failure mode is pretty severe. If you do accidentally leak an object from one sandbox into another, the genie is out of the bottle. Once a malicious script gets a reference to a single object in a sandbox, it can use that object to get a reference to the sandbox's global object, and from there, almost any other object or function in that sandbox. There is no way to fix it except to destroy both sandboxes and start over. A second drawback is that the system doesn't automatically respond to <em>changes</em> in user privileges. Suppose user A is not an administrator, so you set up sandbox A with no administrator functionality. If you promote user A to be an admin, SpiderMonkey won't magically update sandbox A to have the administrator classes and functions you didn't define before. Your application will have to do that explicitly. Conversely, if you want to <em>strip</em> user A's administrator privileges, but you have already given administrator functions to user A's scripts, that's even worse. You have no choice but to destroy user A's sandbox and start over.</p>

<h4 id="Fine-grained_security">Fine-grained security</h4>

<p>Another way to keep a snake from eating a mouse is to watch the snake constantly, and if it tries to eat the mouse, intervene.</p>

<p>SpiderMonkey is designed to support custom, application-defined security models. For example, the Firefox browser has a complex and powerful security model. Some JavaScript code ("chrome") has full access to the system. Scripts from web pages ("content") have very limited access. The <a class="external" href="http://www.mozilla.org/projects/security/components/same-origin.html">same origin policy</a> governs a script's access to data and functions from other web pages.</p>

<p>The SpiderMonkey security model is based on the Java principals security model. This model provides a common security interface, but the actual security implementation is up to you.</p>

<p>To use SpiderMonkey's fine-grained security features:</p>

<ul>
 <li>
  <p>Decide what security policy you want to enforce.</p>
 </li>
 <li>
  <p>Insert a call to <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CheckAccess" title="en/JS_CheckAccess">JS_CheckAccess</a></code> at each point in your application where a security check is necessary. (Some security checks are also built into the JavaScript engine; you must decide what security policy to enforce for each of these checks.)</p>
 </li>
 <li>
  <p>Implement one or more <code><a href="/en/SpiderMonkey/JSAPI_Reference/JSPrincipals" title="en/JSPrincipals">JSPrincipals</a></code> objects in your application. You need one <code>JSPrincipals</code> object for each different set of privileges that a script might have.</p>
 </li>
 <li>
  <p>When compiling or executing code, use the JSAPI functions that attach principals to the compiled code. These functions have <code>ForPrincipals</code> in the name. They are listed below. The purpose of using these functions is to ensure that your access check callbacks have accurate information about <em>who</em> is trying to access an object.</p>

  <table class="fullwidth-table" style="height: 166px; width: 839px;">
   <tbody>
    <tr>
     <th>Function</th>
     <th>Purpose</th>
    </tr>
    <tr>
     <td><code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileScriptForPrincipals" title="en/JS_CompileScriptForPrincipals">JS_CompileScriptForPrincipals</a></code>,<br>
      <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileScriptForPrincipals" title="en/JS_CompileScriptForPrincipals">JS_CompileUCScriptForPrincipals</a></code>,<br>
      <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileFileHandle" title="en/JS_CompileFileHandle">JS_CompileFileHandleForPrincipals</a></code></td>
     <td>Compile a script with security information. (To execute a compiled script, use <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_ExecuteScript" title="en/JS_ExecuteScript">JS_ExecuteScript</a></code>.)</td>
    </tr>
    <tr>
     <td><code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileFunctionForPrincipals" title="en/JS_CompileFunctionForPrincipals">JS_CompileFunctionForPrincipals</a></code>,<br>
      <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_CompileFunctionForPrincipals" title="en/JS_CompileFunctionForPrincipals">JS_CompileUCFunctionForPrincipals</a></code></td>
     <td>Create a JavaScript function with security information.</td>
    </tr>
    <tr>
     <td><code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_EvaluateScriptForPrincipals" title="en/JS_EvaluateScriptForPrincipals">JS_EvaluateScriptForPrincipals</a></code>,<br>
      <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_EvaluateScriptForPrincipals" title="en/JS_EvaluateScriptForPrincipals">JS_EvaluateUCScriptForPrincipals</a></code></td>
     <td>Compile and execute a script with security information.</td>
    </tr>
   </tbody>
  </table>
 </li>
 <li>
  <p>Implement access check callback functions (see <code><a href="/en/SpiderMonkey/JSAPI_Reference/JSClass.checkAccess" title="en/JSClass.checkAccess">JSClass.checkAccess</a></code> and <code><a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetCheckObjectAccessCallback" title="en/JS_SetCheckObjectAccessCallback">JS_SetCheckObjectAccessCallback</a></code>). These will be called from <code>JS_CheckAccess</code> and sometimes from within the JavaScript engine. An access check callback function can use jsdbgapi.h functions such as <code><a href="/en/JS_FrameIterator" title="en/JS_FrameIterator">JS_FrameIterator</a></code> and <code><a href="/en/JS_StackFramePrincipals" title="en/JS_StackFramePrincipals">JS_StackFramePrincipals</a></code> to obtain the principals of the code that is trying to perform the checked operation. Then it determines whether to allow the operation to proceed.</p>
 </li>
</ul>

<h3 id="Tracing_and_Profiling">Tracing and Profiling</h3>

<p>There are features provided by the JSAPI that make it easier to implement JavaScript tracers and profilers.</p>

<h4 id="Function_tracing">Function tracing</h4>

<p>If you configure with --enable-trace-jscalls, you can use <a href="/en/SpiderMonkey/JSAPI_Reference/JS_SetFunctionCallback" title="en/SpiderMonkey/JSAPI Reference/JS SetFunctionCallback"><code>JS_SetFunctionCallback()</code></a> to set up a C function to be called whenever a JavaScript function is about to be called, or has finished executing:</p>

<pre class="brush: cpp">void funcTransition(const JSFunction *func,
                    const JSScript *scr,
                    const JSContext *const_cx,
                    JSBool entering)
{
  JSContext *cx = const_cast&lt;JSContext*&gt;(const_cx);
  JSString *name = JS_GetFunctionId((JSFunction*)func);
  const char *entExit;
  const char *nameStr;

  /* build a C string for the function's name */

  if (!name) {
    nameStr = "Unnamed function";
  } else {
    nameStr = JS_EncodeString(cx, name);
  }

  /* build a string for whether we're entering or exiting */

  if (entering) {
    entExit = "Entering";
  } else {
    entExit = "Exiting";
  }

  /* output information about the trace */

  printf("%s JavaScript function: %s at time: %ld", entExit, nameStr, clock());
}

void enableTracing(JSContext *cx) {
  JS_SetFunctionCallback(cx, funcTransition);
}

void disableTracing(JSContext *cx) {
  JS_SetFunctionCallback(cx, NULL);
}<span style="font-size: 14px; line-height: 18px; white-space: normal;">
</span></pre>