blob: 8614a8a3e495bcb0c41769fed07d478355e04474 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
//
// Created by Darin on 03/08/2018.
//
#include "android/jsengine/object/weex_console_object.h"
#include "android/jsengine/weex_jsc_utils.h"
#include "base/utils/log_utils.h"
//#include "inspector/ScriptCallStackFactory.h"
//#include "inspector/ScriptArguments.h"
//#include "ConsoleClient.h"
//#include "JSObject.h"
STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(WeexConsoleObject);
const ClassInfo WeexConsoleObject::s_info = {"Console", &Base::s_info, 0, CREATE_METHOD_TABLE(WeexConsoleObject)};
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDebug(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncError(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncLog(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncInfo(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncWarn(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncClear(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDir(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDirXML(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTable(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTrace(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncAssert(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncCount(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfile(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfileEnd(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTakeHeapSnapshot(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTime(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeEnd(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeStamp(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroup(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupCollapsed(ExecState *);
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupEnd(ExecState *);
void addFunction(VM &vm, JSGlobalObject *object, const char *name, NativeFunction function, unsigned arguments) {
Identifier identifier = Identifier::fromString(&vm, name);
object->putDirect(vm, identifier, JSFunction::create(vm, object, arguments, identifier.string(), function));
}
WeexConsoleObject::WeexConsoleObject(VM &vm, Structure *structure) : JSNonFinalObject(vm, structure) {
}
void WeexConsoleObject::finishCreation(VM &vm, JSGlobalObject *globalObject) {
Base::finishCreation(vm);
ASSERT(inherits(vm, info()));
// For legacy reasons, console properties are enumerable, writable, deleteable,
// and all have a length of 0. This may change if Console is standardized.
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("debug", consoleProtoFuncDebug, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("error", consoleProtoFuncError, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("log", consoleProtoFuncLog, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("info", consoleProtoFuncInfo, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("warn", consoleProtoFuncWarn, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->clear, consoleProtoFuncClear, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("dir", consoleProtoFuncDir, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("dirxml", consoleProtoFuncDirXML, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("table", consoleProtoFuncTable, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("trace", consoleProtoFuncTrace, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("assert", consoleProtoFuncAssert, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->count, consoleProtoFuncCount, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("profile", consoleProtoFuncProfile, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("profileEnd", consoleProtoFuncProfileEnd, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("time", consoleProtoFuncTime, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("timeEnd", consoleProtoFuncTimeEnd, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("timeStamp", consoleProtoFuncTimeStamp, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("takeHeapSnapshot", consoleProtoFuncTakeHeapSnapshot, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("group", consoleProtoFuncGroup, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("groupCollapsed", consoleProtoFuncGroupCollapsed, None, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("groupEnd", consoleProtoFuncGroupEnd, None, 0);
}
static String valueToStringWithUndefinedOrNullCheck(ExecState *exec, JSValue value) {
if (value.isUndefinedOrNull())
return String();
return value.toWTFString(exec);
}
static void printConsoleLog(ExecState *exec, MessageLevel level) {
JSValue val = exec->argument(0);
if (val.isString()) {
String s = val.toWTFString(exec);
Weex::LogUtil::ConsoleLogPrint((int) level, "jsLog timeline", s.utf8().data());
return;
} else if (val.isObject()) {
VM &vm_catch = exec->vm();
auto scope = DECLARE_CATCH_SCOPE(vm_catch);
String str = JSONStringify(exec, val, 0);
JSC::VM &vm = exec->vm();
if (UNLIKELY(scope.exception())) {
scope.clearException();
return;
}
Weex::LogUtil::ConsoleLogPrint((int)level, "jsLog", str.utf8().data());
}
Weex::LogUtil::ConsoleLogPrint((int) level, "jsLog", "[object]");
}
static EncodedJSValue consoleLogWithLevel(ExecState *exec, MessageLevel level) {
printConsoleLog(exec, level);
// ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
// if (!client)
// return JSValue::encode(jsUndefined());
//
// client->logWithLevel(exec, Inspector::createScriptArguments(exec, 0), level);
JSValue::equalSlowCaseInline(exec,JSC::jsUndefined(),JSC::jsUndefined());
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDebug(ExecState *exec) {
return consoleLogWithLevel(exec, MessageLevel::Debug);
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncError(ExecState *exec) {
return consoleLogWithLevel(exec, MessageLevel::Error);
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncLog(ExecState *exec) {
return consoleLogWithLevel(exec, MessageLevel::Log);
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncInfo(ExecState *exec) {
return consoleLogWithLevel(exec, MessageLevel::Info);
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncWarn(ExecState *exec) {
return consoleLogWithLevel(exec, MessageLevel::Warning);
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncClear(ExecState *exec) {
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
client->clear(exec);
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDir(ExecState *exec) {
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
client->dir(exec, Inspector::createScriptArguments(exec, 0));
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncDirXML(ExecState *exec) {
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
client->dirXML(exec, Inspector::createScriptArguments(exec, 0));
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTable(ExecState *exec) {
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
client->table(exec, Inspector::createScriptArguments(exec, 0));
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTrace(ExecState *exec) {
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
client->trace(exec, Inspector::createScriptArguments(exec, 0));
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncAssert(ExecState *exec) {
VM &vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
bool condition = exec->argument(0).toBoolean(exec);
RETURN_IF_EXCEPTION(scope, encodedJSValue());
if (condition)
return JSValue::encode(jsUndefined());
client->assertion(exec, Inspector::createScriptArguments(exec, 1));
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncCount(ExecState *exec) {
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
client->count(exec, Inspector::createScriptArguments(exec, 0));
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfile(ExecState *exec) {
VM &vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
size_t argsCount = exec->argumentCount();
if (!argsCount) {
client->profile(exec, String());
return JSValue::encode(jsUndefined());
}
const String &title(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)));
RETURN_IF_EXCEPTION(scope, encodedJSValue());
client->profile(exec, title);
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncProfileEnd(ExecState *exec) {
VM &vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
size_t argsCount = exec->argumentCount();
if (!argsCount) {
client->profileEnd(exec, String());
return JSValue::encode(jsUndefined());
}
const String &title(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)));
RETURN_IF_EXCEPTION(scope, encodedJSValue());
client->profileEnd(exec, title);
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTakeHeapSnapshot(ExecState *exec) {
VM &vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
size_t argsCount = exec->argumentCount();
if (!argsCount) {
client->takeHeapSnapshot(exec, String());
return JSValue::encode(jsUndefined());
}
const String &title(valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)));
RETURN_IF_EXCEPTION(scope, encodedJSValue());
client->takeHeapSnapshot(exec, title);
return JSValue::encode(jsUndefined());
}
static String valueOrDefaultLabelString(ExecState *exec, JSValue value) {
if (value.isUndefined())
return ASCIILiteral("default");
return value.toWTFString(exec);
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTime(ExecState *exec) {
VM &vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
String title;
if (exec->argumentCount() < 1)
title = ASCIILiteral("default");
else {
title = valueOrDefaultLabelString(exec, exec->argument(0));
RETURN_IF_EXCEPTION(scope, encodedJSValue());
}
client->time(exec, title);
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeEnd(ExecState *exec) {
VM &vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
String title;
if (exec->argumentCount() < 1)
title = ASCIILiteral("default");
else {
title = valueOrDefaultLabelString(exec, exec->argument(0));
RETURN_IF_EXCEPTION(scope, encodedJSValue());
}
client->timeEnd(exec, title);
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncTimeStamp(ExecState *exec) {
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
client->timeStamp(exec, Inspector::createScriptArguments(exec, 0));
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroup(ExecState *exec) {
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
client->group(exec, Inspector::createScriptArguments(exec, 0));
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupCollapsed(ExecState *exec) {
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
client->groupCollapsed(exec, Inspector::createScriptArguments(exec, 0));
return JSValue::encode(jsUndefined());
}
static EncodedJSValue JSC_HOST_CALL consoleProtoFuncGroupEnd(ExecState *exec) {
ConsoleClient *client = exec->lexicalGlobalObject()->consoleClient();
if (!client)
return JSValue::encode(jsUndefined());
client->groupEnd(exec, Inspector::createScriptArguments(exec, 0));
return JSValue::encode(jsUndefined());
}