tor-browser

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

jsshell.cpp (3509B)


      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 // jsshell.cpp - Utilities for the JS shell
      8 
      9 #include "shell/jsshell.h"
     10 
     11 #include "mozilla/Sprintf.h"
     12 
     13 #include "jsfriendapi.h"
     14 
     15 #include "js/GlobalObject.h"
     16 #include "js/PropertyAndElement.h"  // JS_DefineProperty, JS_GetProperty, JS_GetPropertyById
     17 #include "util/StringBuilder.h"
     18 
     19 using namespace JS;
     20 
     21 namespace js {
     22 namespace shell {
     23 
     24 // Generate 'usage' and 'help' properties for the given object.
     25 // JS_DefineFunctionsWithHelp will define individual function objects with both
     26 // of those properties (eg getpid.usage = "getpid()" and getpid.help = "return
     27 // the process id"). This function will generate strings for an "interface
     28 // object", eg os.file, which contains some number of functions.
     29 //
     30 // .usage will be set to "<name> - interface object".
     31 //
     32 // .help will be set to a newline-separated list of functions that have either
     33 // 'help' or 'usage' properties. Functions are described with their usage
     34 // strings, if they have them, else with just their names.
     35 //
     36 bool GenerateInterfaceHelp(JSContext* cx, HandleObject obj, const char* name) {
     37  RootedIdVector idv(cx);
     38  if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY | JSITER_HIDDEN, &idv)) {
     39    return false;
     40  }
     41 
     42  JSStringBuilder buf(cx);
     43  int numEntries = 0;
     44  for (size_t i = 0; i < idv.length(); i++) {
     45    RootedId id(cx, idv[i]);
     46    RootedValue v(cx);
     47    if (!JS_GetPropertyById(cx, obj, id, &v)) {
     48      return false;
     49    }
     50    if (!v.isObject()) {
     51      continue;
     52    }
     53    RootedObject prop(cx, &v.toObject());
     54 
     55    RootedValue usage(cx);
     56    RootedValue help(cx);
     57    if (!JS_GetProperty(cx, prop, "usage", &usage)) {
     58      return false;
     59    }
     60    if (!JS_GetProperty(cx, prop, "help", &help)) {
     61      return false;
     62    }
     63    if (!usage.isString() && !help.isString()) {
     64      continue;
     65    }
     66 
     67    if (numEntries && !buf.append("\n")) {
     68      return false;
     69    }
     70    numEntries++;
     71 
     72    if (!buf.append("  ")) {
     73      return false;
     74    }
     75 
     76    if (!buf.append(usage.isString() ? usage.toString() : id.toString())) {
     77      return false;
     78    }
     79  }
     80 
     81  RootedString s(cx, buf.finishString());
     82  if (!s || !JS_DefineProperty(cx, obj, "help", s, 0)) {
     83    return false;
     84  }
     85 
     86  buf.clear();
     87  if (!buf.append(name, strlen(name)) ||
     88      !buf.append(" - interface object with ")) {
     89    return false;
     90  }
     91  char cbuf[100];
     92  SprintfLiteral(cbuf, "%d %s", numEntries,
     93                 numEntries == 1 ? "entry" : "entries");
     94  if (!buf.append(cbuf, strlen(cbuf))) {
     95    return false;
     96  }
     97  s = buf.finishString();
     98  if (!s || !JS_DefineProperty(cx, obj, "usage", s, 0)) {
     99    return false;
    100  }
    101 
    102  return true;
    103 }
    104 
    105 bool CreateAlias(JSContext* cx, const char* dstName,
    106                 JS::HandleObject namespaceObj, const char* srcName) {
    107  RootedObject global(cx, JS::GetNonCCWObjectGlobal(namespaceObj));
    108 
    109  RootedValue val(cx);
    110  if (!JS_GetProperty(cx, namespaceObj, srcName, &val)) {
    111    return false;
    112  }
    113 
    114  if (!val.isObject()) {
    115    JS_ReportErrorASCII(cx, "attempted to alias nonexistent function");
    116    return false;
    117  }
    118 
    119  RootedObject function(cx, &val.toObject());
    120  if (!JS_DefineProperty(cx, global, dstName, function, 0)) {
    121    return false;
    122  }
    123 
    124  return true;
    125 }
    126 
    127 }  // namespace shell
    128 }  // namespace js