tor-browser

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

testFunctionNonSyntactic.cpp (3223B)


      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 *
      4 * Test function with enclosing non-syntactic scope.
      5 */
      6 /* This Source Code Form is subject to the terms of the Mozilla Public
      7 * License, v. 2.0. If a copy of the MPL was not distributed with this
      8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      9 
     10 #include "mozilla/Utf8.h"  // mozilla::Utf8Unit
     11 
     12 #include "js/CallAndConstruct.h"
     13 #include "js/CompilationAndEvaluation.h"  // JS::CompileFunction
     14 #include "js/EnvironmentChain.h"          // JS::EnvironmentChain
     15 #include "js/PropertyAndElement.h"        // JS_DefineProperty
     16 #include "js/SourceText.h"                // JS::Source{Ownership,Text}
     17 #include "jsapi-tests/tests.h"
     18 #include "util/Text.h"
     19 #include "vm/JSFunction.h"  // JSFunction
     20 #include "vm/Scope.h"       // Scope
     21 #include "vm/ScopeKind.h"   // ScopeKind
     22 
     23 using namespace js;
     24 
     25 BEGIN_TEST(testFunctionNonSyntactic) {
     26  JS::EnvironmentChain envChain(cx, JS::SupportUnscopables::No);
     27 
     28  {
     29    JS::RootedObject scopeObj(cx, JS_NewPlainObject(cx));
     30    CHECK(scopeObj);
     31    JS::RootedValue val(cx);
     32    val.setNumber(1);
     33    CHECK(JS_DefineProperty(cx, scopeObj, "foo", val, JSPROP_ENUMERATE));
     34    CHECK(envChain.append(scopeObj));
     35  }
     36 
     37  {
     38    JS::RootedObject scopeObj(cx, JS_NewPlainObject(cx));
     39    CHECK(scopeObj);
     40    JS::RootedValue val(cx);
     41    val.setNumber(20);
     42    CHECK(JS_DefineProperty(cx, scopeObj, "bar", val, JSPROP_ENUMERATE));
     43    CHECK(envChain.append(scopeObj));
     44  }
     45 
     46  {
     47    static const char src[] = "return foo + bar;";
     48 
     49    JS::SourceText<mozilla::Utf8Unit> srcBuf;
     50    CHECK(srcBuf.init(cx, src, js_strlen(src), JS::SourceOwnership::Borrowed));
     51 
     52    JS::CompileOptions options(cx);
     53    options.setFileAndLine(__FILE__, __LINE__);
     54    RootedFunction fun(cx, JS::CompileFunction(cx, envChain, options, "test", 0,
     55                                               nullptr, srcBuf));
     56    CHECK(fun);
     57 
     58    CHECK(fun->enclosingScope()->kind() == ScopeKind::NonSyntactic);
     59 
     60    JS::RootedValue funVal(cx, JS::ObjectValue(*fun));
     61    JS::RootedValue rval(cx);
     62    CHECK(JS::Call(cx, JS::UndefinedHandleValue, funVal,
     63                   JS::HandleValueArray::empty(), &rval));
     64    CHECK(rval.isNumber());
     65    CHECK(rval.toNumber() == 21);
     66  }
     67 
     68  // With extra body bar.
     69  {
     70    const char* args[] = {
     71        "a = 300",
     72    };
     73    static const char src[] = "var x = 4000; return a + x + foo + bar;";
     74 
     75    JS::SourceText<mozilla::Utf8Unit> srcBuf;
     76    CHECK(srcBuf.init(cx, src, js_strlen(src), JS::SourceOwnership::Borrowed));
     77 
     78    JS::CompileOptions options(cx);
     79    options.setFileAndLine(__FILE__, __LINE__);
     80    RootedFunction fun(cx, JS::CompileFunction(cx, envChain, options, "test", 1,
     81                                               args, srcBuf));
     82    CHECK(fun);
     83 
     84    CHECK(fun->enclosingScope()->kind() == ScopeKind::NonSyntactic);
     85 
     86    JS::RootedValue funVal(cx, JS::ObjectValue(*fun));
     87    JS::RootedValue rval(cx);
     88    CHECK(JS::Call(cx, JS::UndefinedHandleValue, funVal,
     89                   JS::HandleValueArray::empty(), &rval));
     90    CHECK(rval.isNumber());
     91    CHECK(rval.toNumber() == 4321);
     92  }
     93 
     94  return true;
     95 }
     96 END_TEST(testFunctionNonSyntactic)