tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Iterator.cpp (3396B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
      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 #include "js/Iterator.h"
      8 
      9 #include "js/Conversions.h"
     10 #include "vm/Interpreter.h"
     11 #include "vm/JSAtomState.h"
     12 #include "vm/JSContext.h"
     13 #include "vm/ObjectOperations.h"
     14 #include "vm/SelfHosting.h"
     15 #include "vm/StringType.h"
     16 #include "vm/JSContext-inl.h"  // JSContext::check
     17 #include "vm/JSObject-inl.h"
     18 
     19 using namespace js;
     20 
     21 namespace JS {
     22 
     23 // https://tc39.es/ecma262/#sec-getiterator
     24 // GetIterator(obj [, hint [, method]])
     25 JSObject* GetIteratorObject(JSContext* cx, HandleValue obj, bool isAsync) {
     26  cx->check(obj);
     27 
     28  FixedInvokeArgs<3> args(cx);
     29  args[0].set(obj);
     30  args[1].setBoolean(isAsync);
     31  args[2].setUndefined();  // method
     32 
     33  RootedValue rval(cx);
     34  if (!CallSelfHostedFunction(cx, cx->names().GetIterator, UndefinedHandleValue,
     35                              args, &rval)) {
     36    return nullptr;
     37  }
     38 
     39  MOZ_ASSERT(rval.isObject());
     40  return &rval.toObject();
     41 }
     42 
     43 // https://tc39.es/ecma262/#sec-iteratornext
     44 bool IteratorNext(JSContext* cx, HandleObject iteratorRecord,
     45                  MutableHandleValue result) {
     46  cx->check(iteratorRecord);
     47 
     48  FixedInvokeArgs<1> args(cx);
     49  args[0].setObject(*iteratorRecord);
     50  return CallSelfHostedFunction(cx, cx->names().IteratorNext,
     51                                UndefinedHandleValue, args, result);
     52 }
     53 
     54 // https://tc39.es/ecma262/#sec-iteratorcomplete
     55 bool IteratorComplete(JSContext* cx, HandleObject iterResult, bool* done) {
     56  cx->check(iterResult);
     57 
     58  RootedValue doneV(cx);
     59  if (!GetProperty(cx, iterResult, iterResult, cx->names().done, &doneV)) {
     60    return false;
     61  }
     62 
     63  *done = ToBoolean(doneV);
     64  return true;
     65 }
     66 
     67 // https://tc39.es/ecma262/#sec-iteratorvalue
     68 bool IteratorValue(JSContext* cx, HandleObject iterResult,
     69                   MutableHandleValue value) {
     70  cx->check(iterResult);
     71  return GetProperty(cx, iterResult, iterResult, cx->names().value, value);
     72 }
     73 
     74 bool GetIteratorRecordIterator(JSContext* cx, HandleObject iteratorRecord,
     75                               MutableHandleValue iterator) {
     76  cx->check(iteratorRecord);
     77  return GetProperty(cx, iteratorRecord, iteratorRecord, cx->names().iterator,
     78                     iterator);
     79 }
     80 
     81 // https://tc39.es/ecma262/#sec-getmethod
     82 static bool GetMethod(JSContext* cx, HandleValue v, Handle<PropertyName*> name,
     83                      MutableHandleValue result) {
     84  // Step 1. Let func be ? GetV(V, P).
     85  RootedValue func(cx);
     86  if (!GetProperty(cx, v, name, &func)) {
     87    return false;
     88  }
     89 
     90  // Step 2. If func is either undefined or null, return undefined.
     91  if (func.isNullOrUndefined()) {
     92    result.setUndefined();
     93    return true;
     94  }
     95 
     96  // Step 3. If IsCallable(func) is false, throw a TypeError exception.
     97  if (!IsCallable(func)) {
     98    return ReportIsNotFunction(cx, func, -1);
     99  }
    100 
    101  // Step 4. Return func.
    102  result.set(func);
    103  return true;
    104 }
    105 
    106 bool GetReturnMethod(JSContext* cx, HandleValue iterator,
    107                     MutableHandleValue result) {
    108  cx->check(iterator);
    109  // Step 2. Let returnMethod be GetMethod(iterator, "return").
    110  return GetMethod(cx, iterator, cx->names().return_, result);
    111 }
    112 
    113 }  // namespace JS