Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/base/nsJSUtils.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
/**
8
 * This is not a generated file. It contains common utility functions
9
 * invoked from the JavaScript code generated from IDL interfaces.
10
 * The goal of the utility functions is to cut down on the size of
11
 * the generated code itself.
12
 */
13
14
#include "nsJSUtils.h"
15
#include "jsapi.h"
16
#include "jsfriendapi.h"
17
#include "js/CompilationAndEvaluation.h"
18
#include "js/OffThreadScriptCompilation.h"
19
#include "js/SourceBufferHolder.h"
20
#include "nsIScriptContext.h"
21
#include "nsIScriptElement.h"
22
#include "nsIScriptGlobalObject.h"
23
#include "nsIXPConnect.h"
24
#include "nsCOMPtr.h"
25
#include "nsIScriptSecurityManager.h"
26
#include "nsPIDOMWindow.h"
27
#include "GeckoProfiler.h"
28
#include "nsJSPrincipals.h"
29
#include "xpcpublic.h"
30
#include "nsContentUtils.h"
31
#include "nsGlobalWindow.h"
32
#include "nsXBLPrototypeBinding.h"
33
#include "mozilla/CycleCollectedJSContext.h"
34
#include "mozilla/dom/BindingUtils.h"
35
#include "mozilla/dom/Date.h"
36
#include "mozilla/dom/Element.h"
37
#include "mozilla/dom/ScriptSettings.h"
38
39
using namespace mozilla;
40
using namespace mozilla::dom;
41
42
bool
43
nsJSUtils::GetCallingLocation(JSContext* aContext, nsACString& aFilename,
44
                              uint32_t* aLineno, uint32_t* aColumn)
45
0
{
46
0
  JS::AutoFilename filename;
47
0
  if (!JS::DescribeScriptedCaller(aContext, &filename, aLineno, aColumn)) {
48
0
    return false;
49
0
  }
50
0
51
0
  aFilename.Assign(filename.get());
52
0
  return true;
53
0
}
54
55
bool
56
nsJSUtils::GetCallingLocation(JSContext* aContext, nsAString& aFilename,
57
                              uint32_t* aLineno, uint32_t* aColumn)
58
0
{
59
0
  JS::AutoFilename filename;
60
0
  if (!JS::DescribeScriptedCaller(aContext, &filename, aLineno, aColumn)) {
61
0
    return false;
62
0
  }
63
0
64
0
  aFilename.Assign(NS_ConvertUTF8toUTF16(filename.get()));
65
0
  return true;
66
0
}
67
68
uint64_t
69
nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(JSContext *aContext)
70
0
{
71
0
  if (!aContext)
72
0
    return 0;
73
0
74
0
  nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(aContext);
75
0
  return win ? win->WindowID() : 0;
76
0
}
77
78
nsresult
79
nsJSUtils::CompileFunction(AutoJSAPI& jsapi,
80
                           JS::AutoObjectVector& aScopeChain,
81
                           JS::CompileOptions& aOptions,
82
                           const nsACString& aName,
83
                           uint32_t aArgCount,
84
                           const char** aArgArray,
85
                           const nsAString& aBody,
86
                           JSObject** aFunctionObject)
87
0
{
88
0
  JSContext* cx = jsapi.cx();
89
0
  MOZ_ASSERT(js::GetContextRealm(cx));
90
0
  MOZ_ASSERT_IF(aScopeChain.length() != 0,
91
0
                js::IsObjectInContextCompartment(aScopeChain[0], cx));
92
0
93
0
  // Do the junk Gecko is supposed to do before calling into JSAPI.
94
0
  for (size_t i = 0; i < aScopeChain.length(); ++i) {
95
0
    JS::ExposeObjectToActiveJS(aScopeChain[i]);
96
0
  }
97
0
98
0
  // Compile.
99
0
  JS::Rooted<JSFunction*> fun(cx);
100
0
  JS::SourceBufferHolder source(PromiseFlatString(aBody).get(), aBody.Length(),
101
0
                                JS::SourceBufferHolder::NoOwnership);
102
0
  if (!JS::CompileFunction(cx, aScopeChain, aOptions,
103
0
                           PromiseFlatCString(aName).get(),
104
0
                           aArgCount, aArgArray,
105
0
                           source, &fun))
106
0
  {
107
0
    return NS_ERROR_FAILURE;
108
0
  }
109
0
110
0
  *aFunctionObject = JS_GetFunctionObject(fun);
111
0
  return NS_OK;
112
0
}
113
114
static nsresult
115
EvaluationExceptionToNSResult(JSContext* aCx)
116
0
{
117
0
  if (JS_IsExceptionPending(aCx)) {
118
0
    return NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW;
119
0
  }
120
0
  return NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE;
121
0
}
122
123
nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
124
                                              JS::Handle<JSObject*> aGlobal)
125
  :
126
#ifdef MOZ_GECKO_PROFILER
127
    mAutoProfilerLabel("nsJSUtils::ExecutionContext", /* dynamicStr */ nullptr,
128
                       __LINE__, js::ProfilingStackFrame::Category::JS),
129
#endif
130
    mCx(aCx)
131
  , mRealm(aCx, aGlobal)
132
  , mRetValue(aCx)
133
  , mScopeChain(aCx)
134
  , mRv(NS_OK)
135
  , mSkip(false)
136
  , mCoerceToString(false)
137
  , mEncodeBytecode(false)
138
#ifdef DEBUG
139
  , mWantsReturnValue(false)
140
  , mExpectScopeChain(false)
141
#endif
142
0
{
143
0
  MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
144
0
  MOZ_ASSERT(NS_IsMainThread());
145
0
  MOZ_ASSERT(CycleCollectedJSContext::Get() &&
146
0
             CycleCollectedJSContext::Get()->MicroTaskLevel());
147
0
  MOZ_ASSERT(mRetValue.isUndefined());
148
0
149
0
  MOZ_ASSERT(JS_IsGlobalObject(aGlobal));
150
0
  if (MOZ_UNLIKELY(!xpc::Scriptability::Get(aGlobal).Allowed())) {
151
0
    mSkip = true;
152
0
    mRv = NS_OK;
153
0
  }
154
0
}
155
156
void
157
nsJSUtils::ExecutionContext::SetScopeChain(
158
  const JS::AutoObjectVector& aScopeChain)
159
0
{
160
0
  if (mSkip) {
161
0
    return;
162
0
  }
163
0
164
#ifdef DEBUG
165
  mExpectScopeChain = true;
166
#endif
167
  // Now make sure to wrap the scope chain into the right compartment.
168
0
  if (!mScopeChain.reserve(aScopeChain.length())) {
169
0
    mSkip = true;
170
0
    mRv = NS_ERROR_OUT_OF_MEMORY;
171
0
    return;
172
0
  }
173
0
174
0
  for (size_t i = 0; i < aScopeChain.length(); ++i) {
175
0
    JS::ExposeObjectToActiveJS(aScopeChain[i]);
176
0
    mScopeChain.infallibleAppend(aScopeChain[i]);
177
0
    if (!JS_WrapObject(mCx, mScopeChain[i])) {
178
0
      mSkip = true;
179
0
      mRv = NS_ERROR_OUT_OF_MEMORY;
180
0
      return;
181
0
    }
182
0
  }
183
0
}
184
185
nsresult
186
nsJSUtils::ExecutionContext::JoinAndExec(JS::OffThreadToken** aOffThreadToken,
187
                                         JS::MutableHandle<JSScript*> aScript)
188
0
{
189
0
  if (mSkip) {
190
0
    return mRv;
191
0
  }
192
0
193
0
  MOZ_ASSERT(!mWantsReturnValue);
194
0
  MOZ_ASSERT(!mExpectScopeChain);
195
0
  aScript.set(JS::FinishOffThreadScript(mCx, *aOffThreadToken));
196
0
  *aOffThreadToken = nullptr; // Mark the token as having been finished.
197
0
  if (!aScript) {
198
0
    mSkip = true;
199
0
    mRv = EvaluationExceptionToNSResult(mCx);
200
0
    return mRv;
201
0
  }
202
0
203
0
  if (mEncodeBytecode && !StartIncrementalEncoding(mCx, aScript)) {
204
0
    mSkip = true;
205
0
    mRv = EvaluationExceptionToNSResult(mCx);
206
0
    return mRv;
207
0
  }
208
0
209
0
  if (!JS_ExecuteScript(mCx, mScopeChain, aScript)) {
210
0
    mSkip = true;
211
0
    mRv = EvaluationExceptionToNSResult(mCx);
212
0
    return mRv;
213
0
  }
214
0
215
0
  return NS_OK;
216
0
}
217
218
nsresult
219
nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
220
                                            JS::SourceBufferHolder& aSrcBuf,
221
                                            JS::MutableHandle<JSScript*> aScript)
222
0
{
223
0
  if (mSkip) {
224
0
    return mRv;
225
0
  }
226
0
227
0
  MOZ_ASSERT(aSrcBuf.get());
228
0
  MOZ_ASSERT(mRetValue.isUndefined());
229
#ifdef DEBUG
230
  mWantsReturnValue = !aCompileOptions.noScriptRval;
231
#endif
232
233
0
  bool compiled = true;
234
0
  if (mScopeChain.length() == 0) {
235
0
    compiled = JS::Compile(mCx, aCompileOptions, aSrcBuf, aScript);
236
0
  } else {
237
0
    compiled = JS::CompileForNonSyntacticScope(mCx, aCompileOptions, aSrcBuf, aScript);
238
0
  }
239
0
240
0
  MOZ_ASSERT_IF(compiled, aScript);
241
0
  if (!compiled) {
242
0
    mSkip = true;
243
0
    mRv = EvaluationExceptionToNSResult(mCx);
244
0
    return mRv;
245
0
  }
246
0
247
0
  if (mEncodeBytecode && !StartIncrementalEncoding(mCx, aScript)) {
248
0
    mSkip = true;
249
0
    mRv = EvaluationExceptionToNSResult(mCx);
250
0
    return mRv;
251
0
  }
252
0
253
0
  MOZ_ASSERT(!mCoerceToString || mWantsReturnValue);
254
0
  if (!JS_ExecuteScript(mCx, mScopeChain, aScript, &mRetValue)) {
255
0
    mSkip = true;
256
0
    mRv = EvaluationExceptionToNSResult(mCx);
257
0
    return mRv;
258
0
  }
259
0
260
0
  return NS_OK;
261
0
}
262
263
nsresult
264
nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
265
                                            const nsAString& aScript)
266
0
{
267
0
  MOZ_ASSERT(!mEncodeBytecode, "A JSScript is needed for calling FinishIncrementalEncoding");
268
0
  if (mSkip) {
269
0
    return mRv;
270
0
  }
271
0
272
0
  const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
273
0
  JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
274
0
                                JS::SourceBufferHolder::NoOwnership);
275
0
  JS::Rooted<JSScript*> script(mCx);
276
0
  return CompileAndExec(aCompileOptions, srcBuf, &script);
277
0
}
278
279
nsresult
280
nsJSUtils::ExecutionContext::DecodeAndExec(JS::CompileOptions& aCompileOptions,
281
                                           mozilla::Vector<uint8_t>& aBytecodeBuf,
282
                                           size_t aBytecodeIndex)
283
0
{
284
0
  MOZ_ASSERT(!mEncodeBytecode, "A JSScript is needed for calling FinishIncrementalEncoding");
285
0
  if (mSkip) {
286
0
    return mRv;
287
0
  }
288
0
289
0
  MOZ_ASSERT(!mWantsReturnValue);
290
0
  JS::Rooted<JSScript*> script(mCx);
291
0
  JS::TranscodeResult tr = JS::DecodeScript(mCx, aBytecodeBuf, &script, aBytecodeIndex);
292
0
  // These errors are external parameters which should be handled before the
293
0
  // decoding phase, and which are the only reasons why you might want to
294
0
  // fallback on decoding failures.
295
0
  MOZ_ASSERT(tr != JS::TranscodeResult_Failure_BadBuildId &&
296
0
             tr != JS::TranscodeResult_Failure_WrongCompileOption);
297
0
  if (tr != JS::TranscodeResult_Ok) {
298
0
    mSkip = true;
299
0
    mRv = NS_ERROR_DOM_JS_DECODING_ERROR;
300
0
    return mRv;
301
0
  }
302
0
303
0
  if (!JS_ExecuteScript(mCx, mScopeChain, script)) {
304
0
    mSkip = true;
305
0
    mRv = EvaluationExceptionToNSResult(mCx);
306
0
    return mRv;
307
0
  }
308
0
309
0
  return mRv;
310
0
}
311
312
nsresult
313
nsJSUtils::ExecutionContext::DecodeJoinAndExec(JS::OffThreadToken** aOffThreadToken)
314
0
{
315
0
  if (mSkip) {
316
0
    return mRv;
317
0
  }
318
0
319
0
  MOZ_ASSERT(!mWantsReturnValue);
320
0
  MOZ_ASSERT(!mExpectScopeChain);
321
0
  JS::Rooted<JSScript*> script(mCx);
322
0
  script.set(JS::FinishOffThreadScriptDecoder(mCx, *aOffThreadToken));
323
0
  *aOffThreadToken = nullptr; // Mark the token as having been finished.
324
0
  if (!script || !JS_ExecuteScript(mCx, mScopeChain, script)) {
325
0
    mSkip = true;
326
0
    mRv = EvaluationExceptionToNSResult(mCx);
327
0
    return mRv;
328
0
  }
329
0
330
0
  return NS_OK;
331
0
}
332
333
nsresult
334
nsJSUtils::ExecutionContext::DecodeBinASTJoinAndExec(JS::OffThreadToken** aOffThreadToken,
335
                                                     JS::MutableHandle<JSScript*> aScript)
336
0
{
337
0
#ifdef JS_BUILD_BINAST
338
0
  if (mSkip) {
339
0
    return mRv;
340
0
  }
341
0
342
0
  MOZ_ASSERT(!mWantsReturnValue);
343
0
  MOZ_ASSERT(!mExpectScopeChain);
344
0
345
0
  aScript.set(JS::FinishOffThreadBinASTDecode(mCx, *aOffThreadToken));
346
0
  *aOffThreadToken = nullptr; // Mark the token as having been finished.
347
0
348
0
  if (!aScript) {
349
0
    mSkip = true;
350
0
    mRv = EvaluationExceptionToNSResult(mCx);
351
0
    return mRv;
352
0
  }
353
0
354
0
  if (mEncodeBytecode && !StartIncrementalEncoding(mCx, aScript)) {
355
0
    mSkip = true;
356
0
    mRv = EvaluationExceptionToNSResult(mCx);
357
0
    return mRv;
358
0
  }
359
0
360
0
  if (!JS_ExecuteScript(mCx, mScopeChain, aScript)) {
361
0
    mSkip = true;
362
0
    mRv = EvaluationExceptionToNSResult(mCx);
363
0
    return mRv;
364
0
  }
365
0
366
0
  return NS_OK;
367
#else
368
  return NS_ERROR_NOT_IMPLEMENTED;
369
#endif
370
}
371
372
nsresult
373
nsJSUtils::ExecutionContext::DecodeBinASTAndExec(JS::CompileOptions& aCompileOptions,
374
                                                 const uint8_t* aBuf, size_t aLength,
375
                                                 JS::MutableHandle<JSScript*> aScript)
376
0
{
377
0
#ifdef JS_BUILD_BINAST
378
0
  MOZ_ASSERT(mScopeChain.length() == 0,
379
0
             "BinAST decoding is not supported in non-syntactic scopes");
380
0
381
0
  if (mSkip) {
382
0
    return mRv;
383
0
  }
384
0
385
0
  MOZ_ASSERT(aBuf);
386
0
  MOZ_ASSERT(mRetValue.isUndefined());
387
#ifdef DEBUG
388
  mWantsReturnValue = !aCompileOptions.noScriptRval;
389
#endif
390
391
0
  aScript.set(JS::DecodeBinAST(mCx, aCompileOptions, aBuf, aLength));
392
0
393
0
  if (!aScript) {
394
0
    mSkip = true;
395
0
    mRv = EvaluationExceptionToNSResult(mCx);
396
0
    return mRv;
397
0
  }
398
0
399
0
  if (mEncodeBytecode && !StartIncrementalEncoding(mCx, aScript)) {
400
0
    mSkip = true;
401
0
    mRv = EvaluationExceptionToNSResult(mCx);
402
0
    return mRv;
403
0
  }
404
0
405
0
  MOZ_ASSERT(!mCoerceToString || mWantsReturnValue);
406
0
  if (!JS_ExecuteScript(mCx, mScopeChain, aScript, &mRetValue)) {
407
0
    mSkip = true;
408
0
    mRv = EvaluationExceptionToNSResult(mCx);
409
0
    return mRv;
410
0
  }
411
0
412
0
  return NS_OK;
413
#else
414
  return NS_ERROR_NOT_IMPLEMENTED;
415
#endif
416
}
417
418
static bool
419
IsPromiseValue(JSContext* aCx, JS::Handle<JS::Value> aValue)
420
0
{
421
0
  if (!aValue.isObject()) {
422
0
    return false;
423
0
  }
424
0
425
0
  JS::Rooted<JSObject*> obj(aCx, js::CheckedUnwrap(&aValue.toObject()));
426
0
  if (!obj) {
427
0
    return false;
428
0
  }
429
0
430
0
  return JS::IsPromiseObject(obj);
431
0
}
432
433
nsresult
434
nsJSUtils::ExecutionContext::ExtractReturnValue(JS::MutableHandle<JS::Value> aRetValue)
435
0
{
436
0
  MOZ_ASSERT(aRetValue.isUndefined());
437
0
  if (mSkip) {
438
0
    // Repeat earlier result, as NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW are not
439
0
    // failures cases.
440
#ifdef DEBUG
441
    mWantsReturnValue = false;
442
#endif
443
    return mRv;
444
0
  }
445
0
446
0
  MOZ_ASSERT(mWantsReturnValue);
447
#ifdef DEBUG
448
  mWantsReturnValue = false;
449
#endif
450
0
  if (mCoerceToString && IsPromiseValue(mCx, mRetValue)) {
451
0
    // We're a javascript: url and we should treat Promise return values as
452
0
    // undefined.
453
0
    //
454
0
    // Once bug 1477821 is fixed this code might be able to go away, or will
455
0
    // become enshrined in the spec, depending.
456
0
    mRetValue.setUndefined();
457
0
  }
458
0
459
0
  if (mCoerceToString && !mRetValue.isUndefined()) {
460
0
    JSString* str = JS::ToString(mCx, mRetValue);
461
0
    if (!str) {
462
0
      // ToString can be a function call, so an exception can be raised while
463
0
      // executing the function.
464
0
      mSkip = true;
465
0
      return EvaluationExceptionToNSResult(mCx);
466
0
    }
467
0
    mRetValue.set(JS::StringValue(str));
468
0
  }
469
0
470
0
  aRetValue.set(mRetValue);
471
0
  return NS_OK;
472
0
}
473
474
nsresult
475
nsJSUtils::CompileModule(JSContext* aCx,
476
                       JS::SourceBufferHolder& aSrcBuf,
477
                       JS::Handle<JSObject*> aEvaluationGlobal,
478
                       JS::CompileOptions &aCompileOptions,
479
                       JS::MutableHandle<JSScript*> aScript)
480
0
{
481
0
  AUTO_PROFILER_LABEL("nsJSUtils::CompileModule", JS);
482
0
483
0
  MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
484
0
  MOZ_ASSERT(aSrcBuf.get());
485
0
  MOZ_ASSERT(JS_IsGlobalObject(aEvaluationGlobal));
486
0
  MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == aEvaluationGlobal);
487
0
  MOZ_ASSERT(NS_IsMainThread());
488
0
  MOZ_ASSERT(CycleCollectedJSContext::Get() &&
489
0
             CycleCollectedJSContext::Get()->MicroTaskLevel());
490
0
491
0
  NS_ENSURE_TRUE(xpc::Scriptability::Get(aEvaluationGlobal).Allowed(), NS_OK);
492
0
493
0
  if (!JS::CompileModule(aCx, aCompileOptions, aSrcBuf, aScript)) {
494
0
    return NS_ERROR_FAILURE;
495
0
  }
496
0
497
0
  return NS_OK;
498
0
}
499
500
nsresult
501
nsJSUtils::InitModuleSourceElement(JSContext* aCx,
502
                                   JS::Handle<JSScript*> aScript,
503
                                   nsIScriptElement* aElement)
504
0
{
505
0
  JS::Rooted<JS::Value> value(aCx);
506
0
  nsresult rv = nsContentUtils::WrapNative(aCx, aElement, &value,
507
0
                                           /* aAllowWrapping = */ true);
508
0
  if (NS_FAILED(rv)) {
509
0
    return rv;
510
0
  }
511
0
512
0
  MOZ_ASSERT(value.isObject());
513
0
  JS::Rooted<JSObject*> object(aCx, &value.toObject());
514
0
515
0
  if (!JS::InitScriptSourceElement(aCx, aScript, object, nullptr)) {
516
0
    return NS_ERROR_FAILURE;
517
0
  }
518
0
519
0
  return NS_OK;
520
0
}
521
522
nsresult
523
nsJSUtils::ModuleInstantiate(JSContext* aCx, JS::Handle<JSScript*> aScript)
524
0
{
525
0
  AUTO_PROFILER_LABEL("nsJSUtils::ModuleInstantiate", JS);
526
0
527
0
  MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
528
0
  MOZ_ASSERT(NS_IsMainThread());
529
0
  MOZ_ASSERT(CycleCollectedJSContext::Get() &&
530
0
             CycleCollectedJSContext::Get()->MicroTaskLevel());
531
0
532
0
  NS_ENSURE_TRUE(xpc::Scriptability::Get(aScript).Allowed(), NS_OK);
533
0
534
0
  if (!JS::ModuleInstantiate(aCx, aScript)) {
535
0
    return NS_ERROR_FAILURE;
536
0
  }
537
0
538
0
  return NS_OK;
539
0
}
540
541
nsresult
542
nsJSUtils::ModuleEvaluate(JSContext* aCx, JS::Handle<JSScript*> aScript)
543
0
{
544
0
  AUTO_PROFILER_LABEL("nsJSUtils::ModuleEvaluate", JS);
545
0
546
0
  MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
547
0
  MOZ_ASSERT(NS_IsMainThread());
548
0
  MOZ_ASSERT(CycleCollectedJSContext::Get() &&
549
0
             CycleCollectedJSContext::Get()->MicroTaskLevel());
550
0
551
0
  NS_ENSURE_TRUE(xpc::Scriptability::Get(aScript).Allowed(), NS_OK);
552
0
553
0
  if (!JS::ModuleEvaluate(aCx, aScript)) {
554
0
    return NS_ERROR_FAILURE;
555
0
  }
556
0
557
0
  return NS_OK;
558
0
}
559
560
static bool
561
AddScopeChainItem(JSContext* aCx,
562
                  nsINode* aNode,
563
                  JS::AutoObjectVector& aScopeChain)
564
0
{
565
0
  JS::RootedValue val(aCx);
566
0
  if (!GetOrCreateDOMReflector(aCx, aNode, &val)) {
567
0
    return false;
568
0
  }
569
0
570
0
  if (!aScopeChain.append(&val.toObject())) {
571
0
    return false;
572
0
  }
573
0
574
0
  return true;
575
0
}
576
577
/* static */
578
bool
579
nsJSUtils::GetScopeChainForElement(JSContext* aCx,
580
                                   Element* aElement,
581
                                   JS::AutoObjectVector& aScopeChain)
582
0
{
583
0
  for (nsINode* cur = aElement; cur; cur = cur->GetScopeChainParent()) {
584
0
    if (!AddScopeChainItem(aCx, cur, aScopeChain)) {
585
0
      return false;
586
0
    }
587
0
  }
588
0
589
0
  return true;
590
0
}
591
592
/* static */
593
bool
594
nsJSUtils::GetScopeChainForXBL(JSContext* aCx,
595
                               Element* aElement,
596
                               const nsXBLPrototypeBinding& aProtoBinding,
597
                               JS::AutoObjectVector& aScopeChain)
598
0
{
599
0
  if (!aElement) {
600
0
    return true;
601
0
  }
602
0
603
0
  if (!aProtoBinding.SimpleScopeChain()) {
604
0
    return GetScopeChainForElement(aCx, aElement, aScopeChain);
605
0
  }
606
0
607
0
  if (!AddScopeChainItem(aCx, aElement, aScopeChain)) {
608
0
    return false;
609
0
  }
610
0
611
0
  if (!AddScopeChainItem(aCx, aElement->OwnerDoc(), aScopeChain)) {
612
0
    return false;
613
0
  }
614
0
  return true;
615
0
}
616
617
/* static */
618
void
619
nsJSUtils::ResetTimeZone()
620
3
{
621
3
  JS::ResetTimeZone();
622
3
}
623
624
//
625
// nsDOMJSUtils.h
626
//
627
628
bool nsAutoJSString::init(const JS::Value &v)
629
0
{
630
0
  // Note: it's okay to use danger::GetJSContext here instead of AutoJSAPI,
631
0
  // because the init() call below is careful not to run script (for instance,
632
0
  // it only calls JS::ToString for non-object values).
633
0
  JSContext* cx = danger::GetJSContext();
634
0
  if (!init(cx, v)) {
635
0
    JS_ClearPendingException(cx);
636
0
    return false;
637
0
  }
638
0
639
0
  return true;
640
0
}
641