Пример #1
0
static void
CreateGlobalAndRunTest(JSRuntime* rt, JSContext* cx)
{
  static const JSClass GlobalClass = {
    "global", JSCLASS_GLOBAL_FLAGS,
    JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
    nullptr, nullptr, nullptr, nullptr,
    JS_GlobalObjectTraceHook
  };

  JS::CompartmentOptions options;
  options.setVersion(JSVERSION_LATEST);
  JS::RootedObject global(cx);
  global = JS_NewGlobalObject(cx, &GlobalClass, nullptr, JS::FireOnNewGlobalHook, options);
  ASSERT_TRUE(global != nullptr);

  JS_AddNamedObjectRoot(cx, global.address(), "test-global");
  JSCompartment *oldCompartment = JS_EnterCompartment(cx, global);

  RunTest(rt, cx);

  JS_LeaveCompartment(cx, oldCompartment);
  JS_RemoveObjectRoot(cx, global.address());
}
Пример #2
0
ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptRuntime>& runtime) :
	m_runtime(runtime), m_glob(runtime->m_rt), m_nativeScope(runtime->m_rt)
{
	bool ok;

	m_cx = JS_NewContext(m_runtime->m_rt, STACK_CHUNK_SIZE);
	ENSURE(m_cx);

	JS_SetParallelIonCompilationEnabled(m_runtime->m_rt, true);

	// For GC debugging:
	// JS_SetGCZeal(m_cx, 2);

	JS_SetContextPrivate(m_cx, NULL);

	JS_SetErrorReporter(m_cx, ErrorReporter);

	JS_SetGlobalJitCompilerOption(m_runtime->m_rt, JSJITCOMPILER_ION_ENABLE, 1);
	JS_SetGlobalJitCompilerOption(m_runtime->m_rt, JSJITCOMPILER_BASELINE_ENABLE, 1);

	JS::ContextOptionsRef(m_cx).setExtraWarnings(1)
		.setWerror(0)
		.setVarObjFix(1)
		.setStrictMode(1);

	JS::CompartmentOptions opt;
	opt.setVersion(JSVERSION_LATEST);

	JSAutoRequest rq(m_cx);
	JS::RootedObject globalRootedVal(m_cx, JS_NewGlobalObject(m_cx, &global_class, NULL, JS::OnNewGlobalHookOption::FireOnNewGlobalHook, opt));
	m_comp = JS_EnterCompartment(m_cx, globalRootedVal);
	ok = JS_InitStandardClasses(m_cx, globalRootedVal);
	ENSURE(ok);
	m_glob = globalRootedVal.get();

	// Use the testing functions to globally enable gcPreserveCode. This brings quite a 
	// big performance improvement. In future SpiderMonkey versions, we should probably 
	// use the functions implemented here: https://bugzilla.mozilla.org/show_bug.cgi?id=1068697
	JS::RootedObject testingFunctionsObj(m_cx, js::GetTestingFunctions(m_cx));
	ENSURE(testingFunctionsObj);
	JS::RootedValue ret(m_cx);
	JS_CallFunctionName(m_cx, testingFunctionsObj, "gcPreserveCode", JS::HandleValueArray::empty(), &ret);

	JS_DefineProperty(m_cx, m_glob, "global", globalRootedVal, JSPROP_ENUMERATE | JSPROP_READONLY
			| JSPROP_PERMANENT);

	m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY
			| JSPROP_PERMANENT);

	JS_DefineFunction(m_cx, globalRootedVal, "print", ::print,        0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "log",   ::logmsg,       1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "warn",  ::warn,         1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "error", ::error,        1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "deepcopy", ::deepcopy,  1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);

	Register("ProfileStart", ::ProfileStart, 1);
	Register("ProfileStop", ::ProfileStop, 0);

	runtime->RegisterContext(m_cx);
}
Пример #3
0
JSObject *newDelegate()
{
    static const JSClass delegateClass = {
        "delegate",
        JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_RESERVED_SLOTS(1),
        JS_PropertyStub,
        JS_DeletePropertyStub,
        JS_PropertyStub,
        JS_StrictPropertyStub,
        JS_EnumerateStub,
        JS_ResolveStub,
        JS_ConvertStub,
        nullptr,
        nullptr,
        nullptr,
        nullptr,
        JS_GlobalObjectTraceHook
    };

    /* Create the global object. */
    JS::CompartmentOptions options;
    options.setVersion(JSVERSION_LATEST);
    JS::RootedObject global(cx);
    global = JS_NewGlobalObject(cx, &delegateClass, nullptr, JS::FireOnNewGlobalHook, options);
    JS_SetReservedSlot(global, 0, JS::Int32Value(42));

    /*
     * Ensure the delegate is not in the nursery because for the purpose of this
     * test we're going to put it in a private slot where it won't get updated.
     */
    JS_GC(rt);

    return global;
}
Пример #4
0
JSObject*
createTestGlobal(bool preserveJitCode)
{
    JS::CompartmentOptions options;
    options.setVersion(JSVERSION_LATEST);
    options.setPreserveJitCode(preserveJitCode);
    return JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, options);
}
Пример #5
0
void JavaScriptInterpreter::ReadEvalPrintLoop()
{
	JSAutoRequest ar(cx);
	JS::CompartmentOptions compartmentOptions;
	compartmentOptions.setVersion(JSVERSION_DEFAULT);
	JS::RootedObject global(cx, JS_NewGlobalObject(cx, &global_class, nullptr, JS::FireOnNewGlobalHook, compartmentOptions));
	if (!global)
		return;

	JS::RootedValue rval(cx);

	JSAutoCompartment ac(cx, global);

	if (!JS_InitStandardClasses(cx, global))
		return;

	v = JS_GetVersion(cx);
	actionJSVersion->setDisabled(false);

	/////////////////////////////////////////////////////////////

	int lineno = 1;
	int startline = lineno;
	errno = 1;

	u16string source = TextEdit_input->toPlainText().toStdU16String();
	
	if (source.empty()) {
		if (errno) {
			char buffer[80];
			strerror_s(buffer, 80, errno);
			JS_ReportError(cx, buffer);
			return;
		}
		return;
	}
	
	lineno++;

	QString output = EvalAndPrint(source.c_str(), source.length(), startline);
	if (output.isEmpty())
	{
		JS_ReportPendingException(cx);
	}
	
	if (checkBox->isChecked()) {
		TextEdit_output->setPlainText(output);
	}
	else {
		TextEdit_output->insertPlainText(output + "\n");
	}
	
}
Пример #6
0
ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptRuntime>& runtime) :
	m_runtime(runtime), m_glob(runtime->m_rt), m_nativeScope(runtime->m_rt)
{
	bool ok;

	m_cx = JS_NewContext(m_runtime->m_rt, STACK_CHUNK_SIZE);
	ENSURE(m_cx);

	JS_SetOffthreadIonCompilationEnabled(m_runtime->m_rt, true);

	// For GC debugging:
	// JS_SetGCZeal(m_cx, 2, JS_DEFAULT_ZEAL_FREQ);

	JS_SetContextPrivate(m_cx, NULL);

	JS_SetErrorReporter(m_runtime->m_rt, ErrorReporter);

	JS_SetGlobalJitCompilerOption(m_runtime->m_rt, JSJITCOMPILER_ION_ENABLE, 1);
	JS_SetGlobalJitCompilerOption(m_runtime->m_rt, JSJITCOMPILER_BASELINE_ENABLE, 1);

	JS::RuntimeOptionsRef(m_cx).setExtraWarnings(1)
		.setWerror(0)
		.setVarObjFix(1)
		.setStrictMode(1);

	JS::CompartmentOptions opt;
	opt.setVersion(JSVERSION_LATEST);
	// Keep JIT code during non-shrinking GCs. This brings a quite big performance improvement.
	opt.setPreserveJitCode(true);

	JSAutoRequest rq(m_cx);
	JS::RootedObject globalRootedVal(m_cx, JS_NewGlobalObject(m_cx, &global_class, NULL, JS::OnNewGlobalHookOption::FireOnNewGlobalHook, opt));
	m_comp = JS_EnterCompartment(m_cx, globalRootedVal);
	ok = JS_InitStandardClasses(m_cx, globalRootedVal);
	ENSURE(ok);
	m_glob = globalRootedVal.get();

	JS_DefineProperty(m_cx, m_glob, "global", globalRootedVal, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);

	m_nativeScope = JS_DefineObject(m_cx, m_glob, nativeScopeName, nullptr, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);

	JS_DefineFunction(m_cx, globalRootedVal, "print", ::print,        0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "log",   ::logmsg,       1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "warn",  ::warn,         1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "error", ::error,        1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
	JS_DefineFunction(m_cx, globalRootedVal, "deepcopy", ::deepcopy,  1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);

	Register("ProfileStart", ::ProfileStart, 1);
	Register("ProfileStop", ::ProfileStop, 0);
	Register("ProfileAttribute", ::ProfileAttribute, 1);

	runtime->RegisterContext(m_cx);
}
Пример #7
0
bool JSAudioContext::createContext()
{
    if (m_JsRt != NULL) return false;

    if ((m_JsRt = JS_NewRuntime(JS::DefaultHeapMaxBytes, JS::DefaultNurseryBytes))
        == NULL) {
        fprintf(stderr, "Failed to init JS runtime");
        return false;
    }

    NidiumJS::SetJSRuntimeOptions(m_JsRt);

    JS_SetGCParameter(m_JsRt, JSGC_MAX_BYTES, 0xffffffff);
    JS_SetGCParameter(m_JsRt, JSGC_SLICE_TIME_BUDGET, 15);

    if ((m_JsTcx = JS_NewContext(m_JsRt, 8192)) == NULL) {
        fprintf(stderr, "Failed to init JS context");
        return false;
    }

    NidiumLocalContext::InitJSThread(m_JsRt, m_JsTcx);

    JSAutoRequest ar(m_JsTcx);

    // JS_SetGCParameterForThread(this->tcx, JSGC_MAX_CODE_CACHE_BYTES, 16 *
    // 1024 * 1024);
    JS::CompartmentOptions options;
    options.setVersion(JSVERSION_LATEST);

    JS::RootedObject global(
        m_JsTcx, JS_NewGlobalObject(m_JsTcx, &Global_AudioThread_class, nullptr,
                                    JS::DontFireOnNewGlobalHook, options));

    JSAutoCompartment ac(m_JsTcx, global);

    m_JsGlobalObj = global;

    // We don't actually needs to root a global object, but we
    // need to store a reference to the global object in a
    // JS::Heap and this reference needs to be traced.
    NidiumLocalContext::RootObjectUntilShutdown(m_JsGlobalObj);

    if (!JS_InitStandardClasses(m_JsTcx, global)) {
        fprintf(stderr, "Failed to init std class");
        return false;
    }
    JS_SetErrorReporter(m_JsRt, reportError);
    JS_FireOnNewGlobalObject(m_JsTcx, global);
    JSConsole::RegisterObject(m_JsTcx);
    JSAudioNodeThreaded::RegisterObject(m_JsTcx);

    return true;
}
Пример #8
0
static void
CreateGlobalAndRunTest(JSRuntime* rt, JSContext* cx)
{
  static const JSClass GlobalClass = {
    "global", JSCLASS_GLOBAL_FLAGS,
    nullptr, nullptr, nullptr, nullptr,
    nullptr, nullptr, nullptr, nullptr,
    nullptr, nullptr, nullptr,
    JS_GlobalObjectTraceHook
  };

  JS::CompartmentOptions options;
  options.setVersion(JSVERSION_LATEST);
  JS::PersistentRootedObject global(cx);
  global = JS_NewGlobalObject(cx, &GlobalClass, nullptr, JS::FireOnNewGlobalHook, options);
  ASSERT_TRUE(global != nullptr);

  JSCompartment *oldCompartment = JS_EnterCompartment(cx, global);

  typedef Heap<JSObject*> ElementT;

  {
    nsTArray<ElementT>* array = new nsTArray<ElementT>(InitialElements);
    RunTest(rt, cx, array);
    delete array;
  }

  {
    FallibleTArray<ElementT>* array = new FallibleTArray<ElementT>(InitialElements);
    RunTest(rt, cx, array);
    delete array;
  }

  {
    nsAutoTArray<ElementT, InitialElements> array;
    RunTest(rt, cx, &array);
  }

  {
    AutoFallibleTArray<ElementT, InitialElements> array;
    RunTest(rt, cx, &array);
  }

  JS_LeaveCompartment(cx, oldCompartment);
}
Пример #9
0
int
main (int argc, const char **argv)
{
    JSRuntime *runtime = checkPtr(JS_NewRuntime(1024 * 1024, JS_USE_HELPER_THREADS));
    JS_SetGCParameter(runtime, JSGC_MAX_BYTES, 0xffffffff);
    JS_SetNativeStackQuota(runtime, 5000000);

    JSContext *cx = checkPtr(JS_NewContext(runtime, 8192));
    JS_SetErrorReporter(cx, reportError);

    JSAutoRequest ar(cx);

    /* Create the global object. */
    JS::CompartmentOptions options;
    options.setVersion(JSVERSION_LATEST);
    RootedObject global(cx, checkPtr(JS_NewGlobalObject(cx, &global_class, NULL,
                        JS::FireOnNewGlobalHook, options)));
    js::SetDefaultObjectForContext(cx, global);

    JSAutoCompartment ac(cx, global);

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

    argv++;
    while (*argv) {
        const char *name = *argv++;
        GDBFragment *fragment;
        for (fragment = GDBFragment::allFragments; fragment; fragment = fragment->next) {
            if (strcmp(fragment->name(), name) == 0) {
                fragment->run(cx, argv);
                break;
            }
        }
        if (!fragment) {
            fprintf(stderr, "Unrecognized fragment name: %s\n", name);
            exit(1);
        }
    }

    return 0;
}
Пример #10
0
JSObject * JSAPITest::createGlobal(JSPrincipals *principals)
{
    /* Create the global object. */
    JS::CompartmentOptions options;
    options.setVersion(JSVERSION_LATEST);
    global = JS_NewGlobalObject(cx, getGlobalClass(), principals, options);
    if (!global)
        return NULL;
    JS_AddNamedObjectRoot(cx, &global, "test-global");
    JS::HandleObject globalHandle = JS::HandleObject::fromMarkedLocation(&global);

    JSAutoCompartment ac(cx, globalHandle);

    /* Populate the global object with the standard globals, like Object and
       Array. */
    if (!JS_InitStandardClasses(cx, globalHandle))
        return NULL;
    return global;
}
Пример #11
0
JSObject* newDelegate()
{
    static const js::Class delegateClass = {
        "delegate",
        JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_RESERVED_SLOTS(1),
        nullptr, /* addProperty */
        nullptr, /* delProperty */
        nullptr, /* getProperty */
        nullptr, /* setProperty */
        nullptr, /* enumerate */
        nullptr, /* resolve */
        nullptr, /* mayResolve */
        nullptr, /* convert */
        nullptr, /* finalize */
        nullptr, /* call */
        nullptr, /* hasInstance */
        nullptr, /* construct */
        JS_GlobalObjectTraceHook,
        JS_NULL_CLASS_SPEC,
        {
            nullptr,
            nullptr,
            false,
            nullptr,
            DelegateObjectMoved
        },
        JS_NULL_OBJECT_OPS
    };

    /* Create the global object. */
    JS::CompartmentOptions options;
    options.setVersion(JSVERSION_LATEST);
    JS::RootedObject global(cx);
    global = JS_NewGlobalObject(cx, Jsvalify(&delegateClass), nullptr, JS::FireOnNewGlobalHook,
                                options);
    JS_SetReservedSlot(global, 0, JS::Int32Value(42));

    return global;
}
Пример #12
0
bool CompileFile(const std::string &inputFilePath, const std::string &outputFilePath) {
    bool result = false;
    std::string ofp;
    if (!outputFilePath.empty()) {
        ofp = outputFilePath;
    }
    else {
        ofp = RemoveFileExt(inputFilePath) + BYTE_CODE_FILE_EXT;
    }
    
    if (!JS_Init())
        return false;
    
    std::cout << "Input file: " << inputFilePath << std::endl;
    JSRuntime * runtime = JS_NewRuntime(10 * 1024 * 1024, JS_NO_HELPER_THREADS);

    JSContext *cx = JS_NewContext(runtime, 10240);
    JS_SetOptions(cx, JSOPTION_TYPE_INFERENCE);
    
    JS::CompartmentOptions options;
    options.setVersion(JSVERSION_LATEST);
    
    JS::RootedObject global(cx, JS_NewGlobalObject(cx, &GlobalClass, NULL, JS::DontFireOnNewGlobalHook, options));
    
    JS_SetErrorReporter(cx, &ReportError);
    
    {
        JSAutoCompartment ac(cx, global);
    
        if (JS_InitStandardClasses(cx, global)) {
            
            JS_InitReflect(cx, global);
            
            JS_FireOnNewGlobalObject(cx, global);
            
            JS::CompileOptions options(cx);
            options.setUTF8(true);
            options.setSourcePolicy(JS::CompileOptions::NO_SOURCE);
            std::cout << "Compiling ..." << std::endl;
            
            JS::RootedScript script(cx, JS::Compile(cx, global, options, inputFilePath.c_str()));
            
            if (script) {
                void *data = NULL;
                uint32_t length = 0;
                std::cout << "Encoding ..." << std::endl;
                data = JS_EncodeScript(cx, script, &length);
                
                if (data) {
                    if (WriteFile(ofp, data, length)) {
                        std::cout << "Done! " << "Output file: " << ofp << std::endl;
                        result = true;
                    }
                }
            }
            else
            {
                std::cout << "Compiled " << inputFilePath << " fails!" << std::endl;
            }
        }
        else
        {
            std::cout << "JS_InitStandardClasses failed! " << std::endl;
        }
    }
    if (cx) {
        JS_DestroyContext(cx);
        cx = NULL;
    }
    if (runtime) {
        JS_DestroyRuntime(runtime);
        runtime = NULL;
    }
    
    JS_ShutDown();
    
    return result;
}