Как я могу определить, какой движок JavaScript (v8 или JSC) используется во время выполнения в Android? - PullRequest
12 голосов
/ 21 июля 2011

Более новые версии Android (> 2.2) включают движок JavaScript v8, в то время как в более старых версиях был только JSC.Однако, согласно http://blogs.nitobi.com/joe/2011/01/14/android-your-js-engine-is-not-always-v8/,, какой движок JavaScript используется во время выполнения, похоже, зависит от переменной среды, присутствующей во время сборки (JS_ENGINE), а также от аппаратных характеристик устройства:

# The default / alternative engine depends on the device class.
# On devices with a lot of memory (e.g. Passion/Sholes), the
# default is V8. On everything else, the only choice is JSC.

У меня такой вопрос: могу ли я определить, какой движок javascript используется на веб-странице, во встроенном WebView или в приложении?

Если ответ отрицательный, кто-нибудьзнаете, какой движок JS используется эмулятором Android?


Причина, по которой я спрашиваю об этом, заключается в следующем: http://code.google.com/p/android/issues/detail?id=12987

По сути, это может быть то, что JavaScriptМост-to-java в JSC сломан на Android 2.3.X, и это влияет на приложение, которое я пытаюсь написать.Я вижу segfault где-то глубоко в JNI на моем эмуляторе, но не на нескольких физических устройствах, которые я тестировал.Я пытаюсь определить, является ли это вещью только для эмулятора, только для АО или чем-то другим.

Ответы [ 3 ]

19 голосов
/ 21 июля 2011

Я думаю, что лучший вопрос: почему тебя это волнует?Вы попадаете в ловушку «обнаружения браузеров», в которую многие попали в конце 90-х - начале 00-х годов.Однако с тех пор мы узнали, что обнаружение функций - это более полезный подход, не в последнюю очередь потому, что функции, поддерживаемые в данном браузере, были (в основном) движущейся целью.Теперь есть код, работающий на IE9 с его значительно улучшенной поддержкой DOM и JavaScript, который не использует эти функции, потому что он выполняет обнаружение браузера и использует методы IE6.

Так что вместо того, чтобы беспокоиться о V8 против JSC,просто беспокойтесь о функциях, которые вы хотите.Я ничего не знаю о JSC, но, например, давайте предположим, что у него нет метода forEach для массивов, который есть у V8 (часть стандарта ECMAScript 5-е издание).Вместо того, чтобы бросать большой рычаг «V8 vs. JSC», вы должны сделать:

if (typeof Array.prototype.forEach === "function") {
    // Code that expects `forEach`
}
else {
    // Code that falls back
}

(Ваш «код, который отступает» может добавить forEach к прототипу,или, может быть, этот тест находится в вашей собственной функции итератора, и вы хотите знать, следует ли отложить его до собственной реализации или предоставить свою собственную.)

И аналогично для других функций, которые вы хотите использовать, которые могут присутствовать или не присутствовать.


Но если вам действительно нужно обнаружить V8 против JSC (и из вашего комментария кажется, что вы можете), эта страница , кажется, демонстрирует способ сделать это, хотяэто кажется ужасно хрупким.Вот моя слегка отредактированная версия (не в последнюю очередь заменить window.devicePixelRatio тестом на WebkitAppearance - первый дает ложные срабатывания по крайней мере в некоторых других браузерах [например, Firefox, который использует Gecko, а не WebKit]):

var v8string = 'function%20javaEnabled%28%29%20%7B%20%5Bnative%20code%5D%20%7D';

if ('WebkitAppearance' in document.documentElement.style) { //If (probably) WebKit browser
    if (escape(navigator.javaEnabled.toString()) === v8string) {
        console.log('V8 detected');
    } else {
        console.log('JSC detected');
    }
} else {
    console.log("Not a WebKit browser");
}

Работает для меня, обнаруживая разницу между Chrome (который также использует V8) и Safari (который также использует JSC).

6 голосов
/ 06 августа 2012

Хотя ответ выше указывает на лучшие методы, я подумал, что укажу другой способ сделать это из нативной библиотеки.

void *dlWebCoreHandle = dlopen("libwebcore.so", RTLD_NOW);
void *v8GetVersion = dlsym(dlWebCoreHandle, "_ZN2v82V810GetVersionEv");
if (v8GetVersion == NULL) {
    /* does not appear to be V8 */
} ... etc.

К сожалению, экспортированные символы искажены, поэтому нет 100% гарантии, что компилятор, используемый вашим производителем прошивки, искажал символы таким же образом (используйте nm --defined-only libwebcore.so -g в библиотеке с символами). Можно было бы выставить эту функцию через JNI и проверить изнутри код Java.

В библиотеке libwebcore.so также указан V8_Fatal в качестве одного из символов, который не подвержен искажениям.

JSC будет иметь некоторые другие экспортируемые символы, которые вы можете проверить из внутренней библиотеки. Если оба не существуют, вы можете использовать другие методы.

1 голос
/ 07 декабря 2012

var s = '';
for (x in {
    3: 3,
    1: 1
  }) {
  s += x
}
if (s === '31') {
  alert('JSC');
} else {
  alert('V8');
}

Кстати, это будет относить Firefox к категории «JSC», и более новые версии IE будут выглядеть как V8.

В моем блоге есть больше трюков с V8: http://erikcorry.blogspot.dk/2012/12/which-version-of-v8-do-i-have.html

...