inline result_t _jsonEncode(v8::Local<v8::Value> data, std::string &retVal) { Isolate* isolate = Isolate::current(); v8::Local<v8::Object> _json; if (isolate->m_json.IsEmpty()) { v8::Local<v8::Object> glob = v8::Local<v8::Object>::New(isolate->m_isolate, isolate->m_global); _json = glob->Get(isolate->NewFromUtf8("JSON"))->ToObject(); isolate->m_json.Reset(isolate->m_isolate, _json); isolate->m_stringify.Reset(isolate->m_isolate, v8::Local<v8::Function>::Cast(_json->Get(isolate->NewFromUtf8("stringify")))); } else _json = v8::Local<v8::Object>::New(isolate->m_isolate, isolate->m_json); TryCatch try_catch; v8::Local<v8::Value> str = v8::Local<v8::Function>::New(isolate->m_isolate, isolate->m_stringify)->Call(_json, 1, &data); if (try_catch.HasCaught()) return CHECK_ERROR(Runtime::setError(*v8::String::Utf8Value(try_catch.Exception()))); v8::String::Utf8Value v(str); retVal.assign(*v, v.length()); return 0; }
result_t HttpsServer::create(v8::Local<v8::Array> certs, const char *addr, int32_t port, v8::Local<v8::Value> hdlr) { result_t hr; obj_ptr<SslServer_base> _server; obj_ptr<HttpHandler_base> _handler; hr = HttpHandler_base::_new(hdlr, _handler); if (hr < 0) return hr; hr = SslServer_base::_new(certs, addr, port, _handler->wrap(), _server); if (hr < 0) return hr; v8::Local<v8::Object> o = wrap(); Isolate* isolate = holder(); m_handler = _handler; o->SetHiddenValue(isolate->NewFromUtf8("handler"), _handler->wrap()); m_server = _server; o->SetHiddenValue(isolate->NewFromUtf8("server"), _server->wrap()); return 0; }
result_t process_base::get_env(v8::Local<v8::Object>& retVal) { Isolate* isolate = Isolate::current(); v8::Local<v8::Object> glob = v8::Local<v8::Object>::New(isolate->m_isolate, isolate->m_global); v8::Local<v8::Value> ev = isolate->GetPrivate(glob, "_env"); if (ev->IsUndefined()) { v8::Local<v8::Object> o = v8::Object::New(isolate->m_isolate); char** env = environ; const char *p, *p1; while ((p = *env++) != NULL) { p1 = qstrchr(p, '='); if (p1) o->Set(isolate->NewFromUtf8(p, (int32_t)(p1 - p)), isolate->NewFromUtf8(p1 + 1)); } isolate->SetPrivate(glob, "_env", o); retVal = o; } else retVal = v8::Local<v8::Object>::Cast(ev); return 0; }
v8::Local<v8::Value> ThrowResult(result_t hr) { Isolate* isolate = Isolate::current(); v8::Local<v8::Value> e = v8::Exception::Error( isolate->NewFromUtf8(getResultMessage(hr))); e->ToObject()->Set(isolate->NewFromUtf8("number"), v8::Int32::New(isolate->m_isolate, -hr)); return isolate->m_isolate->ThrowException(e); }
result_t BufferedStream::readLines(int32_t maxlines, v8::Local<v8::Array> &retVal) { result_t hr = 0; std::string str; int32_t n = 0; Isolate* isolate = holder(); retVal = v8::Array::New(isolate->m_isolate); if (maxlines == 0) return 0; while (true) { hr = ac_readLine(-1, str); if (hr < 0) return hr; if (hr > 0) return 0; retVal->Set(n ++, isolate->NewFromUtf8(str)); if (maxlines > 0) { maxlines --; if (maxlines == 0) break; } } return 0; }
result_t util_base::map(v8::Local<v8::Value> list, v8::Local<v8::Function> iterator, v8::Local<v8::Value> context, v8::Local<v8::Array> &retVal) { Isolate* isolate = Isolate::current(); v8::Local<v8::Array> arr = v8::Array::New(isolate->m_isolate); if (!list->IsObject()) { retVal = arr; return 0; } v8::Local<v8::Value> args[3]; args[2] = list; v8::Local<v8::Object> o = v8::Local<v8::Object>::Cast(list); v8::Local<v8::Value> v = o->Get(isolate->NewFromUtf8("length")); int32_t cnt = 0; if (IsEmpty(v)) { v8::Local<v8::Array> keys = o->GetPropertyNames(); int32_t len = keys->Length(); int32_t i; for (i = 0; i < len; i ++) { args[1] = keys->Get(i); args[0] = o->Get(args[1]); v = iterator->Call(context, 3, args); if (v.IsEmpty()) return CALL_E_JAVASCRIPT; arr->Set(cnt ++, v); } } else { int32_t len = v->Int32Value(); int32_t i; for (i = 0; i < len; i ++) { args[1] = v8::Int32::New(isolate->m_isolate, i); args[0] = o->Get(args[1]); v = iterator->Call(context, 3, args); if (v.IsEmpty()) return CALL_E_JAVASCRIPT; arr->Set(cnt ++, v); } } retVal = arr; return 0; }
result_t X509Crl::dump(v8::Local<v8::Array> &retVal) { Isolate* isolate = holder(); retVal = v8::Array::New(isolate->m_isolate); const mbedtls_x509_crl *pCrl = &m_crl; int32_t ret, n = 0; exlib::string buf; size_t olen; while (pCrl) { if (pCrl->raw.len > 0) { buf.resize(pCrl->raw.len * 2 + 64); ret = mbedtls_pem_write_buffer(PEM_BEGIN_CRL, PEM_END_CRL, pCrl->raw.p, pCrl->raw.len, (unsigned char *)&buf[0], buf.length(), &olen); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); retVal->Set(n ++, isolate->NewFromUtf8(buf.c_str(), (int32_t) olen - 1)); } pCrl = pCrl->next; } return 0; }
result_t Buffer::toJSON(const char *key, v8::Local<v8::Value> &retVal) { Isolate* isolate = holder(); v8::Local<v8::Object> o = v8::Object::New(isolate->m_isolate); v8::Local<v8::Array> a = v8::Array::New(isolate->m_isolate, (int32_t) m_data.length()); int32_t i; for (i = 0; i < (int32_t) m_data.length(); i++) a->Set(i, v8::Number::New(isolate->m_isolate, (unsigned char) m_data[i])); o->Set(isolate->NewFromUtf8("type"), isolate->NewFromUtf8("Buffer")); o->Set(isolate->NewFromUtf8("data"), a); retVal = o; return 0; }
result_t DBResult::toJSON(exlib::string key, v8::Local<v8::Value> &retVal) { if (m_size) return m_array->toJSON(key, retVal); Isolate* isolate = holder(); v8::Local<v8::Object> o = v8::Object::New(isolate->m_isolate); o->Set(isolate->NewFromUtf8("affected", 8), v8::Number::New(isolate->m_isolate, (double) m_affected)); o->Set(isolate->NewFromUtf8("insertId", 8), v8::Number::New(isolate->m_isolate, (double) m_insertId)); retVal = o; return 0; }
result_t util_base::flatten(v8::Local<v8::Value> list, bool shallow, v8::Local<v8::Array> &retVal) { if (!list->IsObject()) return CHECK_ERROR(CALL_E_TYPEMISMATCH); bool bNext = true; Isolate* isolate = Isolate::current(); if (retVal.IsEmpty()) retVal = v8::Array::New(isolate->m_isolate); else if (shallow) bNext = false; v8::Local<v8::Object> o = v8::Local<v8::Object>::Cast(list); v8::Local<v8::Value> v = o->Get(isolate->NewFromUtf8("length")); if (IsEmpty(v)) return CHECK_ERROR(CALL_E_TYPEMISMATCH); int32_t len = v->Int32Value(); int32_t cnt = retVal->Length(); int32_t i; for (i = 0; i < len; i ++) { v = o->Get(i); if (bNext && v->IsObject()) { v8::Local<v8::Object> o1 = v8::Local<v8::Object>::Cast(v); v = o->Get(isolate->NewFromUtf8("length")); if (IsEmpty(v)) retVal->Set(cnt ++, o->Get(i)); else { flatten(o1, shallow, retVal); cnt = retVal->Length(); } } else retVal->Set(cnt ++, o->Get(i)); } return 0; }
result_t LruCache::get(exlib::string name, v8::Local<v8::Function> updater, v8::Local<v8::Value> &retVal) { static _linkedNode newNode; v8::Handle<v8::Object> o = wrap(); Isolate* isolate = holder(); exlib::string sname(name); v8::Handle<v8::Value> a = isolate->NewFromUtf8(name); std::map<exlib::string, _linkedNode>::iterator find; cleanup(); while (true) { obj_ptr<Event_base> e; find = m_datas.find(sname); if (find != m_datas.end()) break; if (updater.IsEmpty()) return 0; std::map<exlib::string, obj_ptr<Event_base> >::iterator padding; padding = m_paddings.find(sname); if (padding == m_paddings.end()) { e = new Event(); padding = m_paddings.insert(std::pair<exlib::string, obj_ptr<Event_base> >(sname, e)).first; v8::Local<v8::Value> v = updater->Call(o, 1, &a); m_paddings.erase(padding); e->set(); if (v.IsEmpty()) return CALL_E_JAVASCRIPT; find = m_datas.insert(std::pair<exlib::string, _linkedNode>(sname, newNode)).first; insert(find); if (m_timeout > 0) find->second.insert.now(); SetPrivate(name, v); retVal = v; return 0; } e = padding->second; e->wait(); } update(find); retVal = GetPrivate(name); return 0; }
result_t HttpUploadCollection::_named_enumerator(v8::Local<v8::Array> &retVal) { int32_t i; Isolate* isolate = holder(); retVal = v8::Array::New(isolate->m_isolate); for (i = 0; i < m_count; i++) retVal->Set(i, isolate->NewFromUtf8(m_names[i])); return 0; }
result_t process_base::get_argv(v8::Local<v8::Array> &retVal) { Isolate* isolate = Isolate::current(); v8::Local<v8::Array> args = v8::Array::New(isolate->m_isolate, (int32_t)s_argv.size()); for (int32_t i = 0; i < (int32_t)s_argv.size(); i ++) args->Set(i, isolate->NewFromUtf8(s_argv[i])); retVal = args; return 0; }
result_t Map::_named_enumerator(v8::Local<v8::Array> &retVal) { int32_t i = 0; Isolate* isolate = holder(); retVal = v8::Array::New(isolate->m_isolate, (int32_t)m_datas.size()); std::map<exlib::string, VariantEx>::iterator iter; for (iter = m_datas.begin(); iter != m_datas.end(); iter++) retVal->Set(i++, isolate->NewFromUtf8(iter->first)); return 0; }
result_t HttpCollection::_named_enumerator(v8::Local<v8::Array> &retVal) { int32_t i, n; std::set<exlib::string> name_set; Isolate* isolate = holder(); retVal = v8::Array::New(isolate->m_isolate); for (i = 0, n = 0; i < m_count; i++) { exlib::string& name = m_names[i]; if (name_set.insert(name).second) retVal->Set(n ++, isolate->NewFromUtf8(name)); } return 0; }
result_t LruCache::toJSON(exlib::string key, v8::Local<v8::Value> &retVal) { cleanup(); Isolate* isolate = holder(); std::map<exlib::string, _linkedNode>::iterator it = m_begin_lru; v8::Local<v8::Object> obj = v8::Object::New(isolate->m_isolate); while (it != m_datas.end()) { v8::Local<v8::String> name = isolate->NewFromUtf8(it->first); obj->Set(name, GetPrivate(it->first)); it = _instantiate(it->second.m_next); } retVal = obj; return 0; }
result_t Regex::exec(const char *str, v8::Local<v8::Array> &retVal) { int32_t rc = 0; int32_t ovector[RE_SIZE]; int32_t len = (int32_t) qstrlen(str); const char *end = str + len; int32_t i; if (m_bGlobal) { int32_t n = m_nlastIndex; while (n > 0 && utf8_getchar(str, end)) n--; } if (*str) { len = (int32_t) qstrlen(str); rc = pcre_exec(m_re, NULL, str, len, 0, 0, ovector, RE_SIZE); if (rc < 0) { rc = 0; m_nlastIndex = 0; } } if (rc) { Isolate* isolate = holder(); retVal = v8::Array::New(isolate->m_isolate, rc); for (i = 0; i < rc; i++) retVal->Set(i, isolate->NewFromUtf8(str + ovector[2 * i], ovector[2 * i + 1] - ovector[2 * i])); if (m_bGlobal) m_nlastIndex += utf8_strlen(str, ovector[2 * rc - 1]); } return rc ? 0 : CALL_RETURN_NULL; }
result_t WebSocketHandler::onerror(v8::Local<v8::Object> hdlrs) { Isolate* isolate = holder(); v8::Local<v8::String> key = isolate->NewFromUtf8("500"); v8::Local<v8::Value> hdlr = hdlrs->Get(key); if (!IsEmpty(hdlr)) { obj_ptr<Handler_base> hdlr1; result_t hr = JSHandler::New(hdlr, hdlr1); if (hr < 0) return hr; SetPrivate("500", hdlr1->wrap()); m_err_hdlr = hdlr1; } return 0; }
result_t util_base::without(v8::Local<v8::Value> arr, const v8::FunctionCallbackInfo<v8::Value> &args, v8::Local<v8::Array> &retVal) { if (!arr->IsObject()) return CHECK_ERROR(CALL_E_TYPEMISMATCH); Isolate* isolate = Isolate::current(); v8::Local<v8::Object> o = v8::Local<v8::Object>::Cast(arr); v8::Local<v8::Value> v = o->Get(isolate->NewFromUtf8("length")); if (IsEmpty(v)) return CHECK_ERROR(CALL_E_TYPEMISMATCH); int32_t len = v->Int32Value(); v8::Local<v8::Array> arr1 = v8::Array::New(isolate->m_isolate); int32_t argc = args.Length(); int32_t i, j, n = 0; for (i = 0; i < len; i ++) { v8::Local<v8::Value> v = o->Get(i); for (j = 1; j < argc; j ++) if (v->StrictEquals(args[j])) break; if (j == argc) arr1->Set(n ++, v); } retVal = arr1; return 0; }
result_t JsonRpcHandler::invoke(object_base *v, obj_ptr<Handler_base> &retVal, AsyncEvent *ac) { if (ac) return CHECK_ERROR(CALL_E_NOASYNC); obj_ptr<Message_base> msg = Message_base::getInstance(v); if (msg == NULL) return CHECK_ERROR(CALL_E_BADVARTYPE); Isolate* isolate = holder(); obj_ptr<HttpRequest_base> htreq = HttpRequest_base::getInstance(v); obj_ptr<SeekableStream_base> body; obj_ptr<Buffer_base> buf; v8::Local<v8::Value> jsval; v8::Local<v8::Object> o; Variant result; exlib::string str; int64_t len; int32_t sz, i; result_t hr; obj_ptr<List_base> params; if (htreq != NULL) { if (htreq->firstHeader("Content-Type", result) == CALL_RETURN_NULL) return CHECK_ERROR(Runtime::setError("jsonrpc: Content-Type is missing.")); str = result.string(); if (qstricmp(str.c_str(), "application/json", 16)) return CHECK_ERROR(Runtime::setError("jsonrpc: Invalid Content-Type.")); } msg->get_body(body); body->size(len); sz = (int32_t) len; body->rewind(); hr = body->ac_read(sz, buf); if (hr < 0) return hr; if (hr == CALL_RETURN_NULL) return CHECK_ERROR(Runtime::setError("jsonrpc: request body is empty.")); body.Release(); buf->toString(str); buf.Release(); hr = json_base::decode(str, jsval); if (hr < 0) return hr; if (!jsval->IsObject()) return CHECK_ERROR(Runtime::setError("jsonrpc: Invalid rpc request.")); o = v8::Local<v8::Object>::Cast(jsval); jsval = o->Get(isolate->NewFromUtf8("method", 6)); if (IsEmpty(jsval)) return CHECK_ERROR(Runtime::setError("jsonrpc: method is missing.")); msg->get_value(str); str += '/'; str.append(*v8::String::Utf8Value(jsval)); msg->set_value(str); jsval = o->Get(isolate->NewFromUtf8("params", 6)); if (!jsval.IsEmpty() && jsval->IsArray()) { v8::Local<v8::Array> jsparams = v8::Local<v8::Array>::Cast(jsval); sz = jsparams->Length(); msg->get_params(params); params->resize(sz); for (i = 0; i < sz; i++) params->_indexed_setter(i, jsparams->Get(i)); } obj_ptr<Handler_base> hdlr1; hr = JSHandler::js_invoke(m_handler, v, hdlr1, NULL); if (hr >= 0 && hr != CALL_RETURN_NULL) hr = mq_base::ac_invoke(hdlr1, v); v8::Local<v8::String> strId = isolate->NewFromUtf8("id", 2); jsval = o->Get(strId); o = v8::Object::New(isolate->m_isolate); o->Set(strId, jsval); if (hr < 0) { errorLog("JsonRpcHandler: " + getResultMessage(hr)); result_t hr1 = json_base::encode(o, str); if (hr1 < 0) return hr1; if (str.length() <= 2) str.assign("{", 1); else { str.resize(str.length() - 1); str += ','; } if (hr == CALL_E_INVALID_CALL) str.append( "\"error\": {\"code\": -32601, \"message\": \"Method not found.\"}}"); else str.append( "\"error\": {\"code\": -32603, \"message\": \"Internal error.\"}}"); } else { msg->get_result(result); o->Set(isolate->NewFromUtf8("result", 6), result); hr = json_base::encode(o, str); if (hr < 0) return hr; } body = new MemoryStream(); buf = new Buffer(str); hr = body->ac_write(buf); if (hr < 0) return hr; obj_ptr<Message_base> rep; hr = msg->get_response(rep); if (hr < 0) return hr; rep->set_body(body); if (htreq) ((HttpMessage_base *)(Message_base *)rep)->setHeader( "Content-Type", "application/json"); return CALL_RETURN_NULL; }
result_t os_base::CPUInfo(v8::Local<v8::Array> &retVal) { Isolate* isolate = Isolate::current(); retVal = v8::Array::New(isolate->m_isolate); v8::Local<v8::Object> cpuinfo; v8::Local<v8::Object> cputimes; uint32_t ticks = (uint32_t) sysconf(_SC_CLK_TCK), multiplier = ((uint64_t) 1000L / ticks), cpuspeed; int32_t numcpus = 0, i = 0; unsigned long long ticks_user, ticks_sys, ticks_idle, ticks_nice, ticks_intr; char line[512], speedPath[256], model[512] = ""; FILE *fpStat = fopen("/proc/stat", "r"); FILE *fpModel = fopen("/proc/cpuinfo", "r"); FILE *fpSpeed; if (fpModel) { while (fgets(line, 511, fpModel) != NULL) { if (strncmp(line, "processor", 9) == 0) numcpus++; else if (strncmp(line, "model name", 10) == 0) { if (numcpus == 1) { char *p = strchr(line, ':') + 2; strcpy(model, p); model[strlen(model) - 1] = 0; } } else if (strncmp(line, "cpu MHz", 7) == 0) { if (numcpus == 1) sscanf(line, "%*s %*s : %u", &cpuspeed); } } fclose(fpModel); } if (fpStat) { while (fgets(line, 511, fpStat) != NULL) { if (strncmp(line, "cpu ", 4) == 0) continue; else if (strncmp(line, "cpu", 3) != 0) break; sscanf(line, "%*s %llu %llu %llu %llu %*llu %llu", &ticks_user, &ticks_nice, &ticks_sys, &ticks_idle, &ticks_intr); snprintf(speedPath, sizeof(speedPath), "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_max_freq", i); fpSpeed = fopen(speedPath, "r"); if (fpSpeed) { if (fgets(line, 511, fpSpeed) != NULL) { sscanf(line, "%u", &cpuspeed); cpuspeed /= 1000; } fclose(fpSpeed); } cpuinfo = v8::Object::New(isolate->m_isolate); cputimes = v8::Object::New(isolate->m_isolate); cputimes->Set(isolate->NewFromUtf8("user"), v8::Number::New(isolate->m_isolate, ticks_user * multiplier)); cputimes->Set(isolate->NewFromUtf8("nice"), v8::Number::New(isolate->m_isolate, ticks_nice * multiplier)); cputimes->Set(isolate->NewFromUtf8("sys"), v8::Number::New(isolate->m_isolate, ticks_sys * multiplier)); cputimes->Set(isolate->NewFromUtf8("idle"), v8::Number::New(isolate->m_isolate, ticks_idle * multiplier)); cputimes->Set(isolate->NewFromUtf8("irq"), v8::Number::New(isolate->m_isolate, ticks_intr * multiplier)); if (model[0]) cpuinfo->Set(isolate->NewFromUtf8("model"), isolate->NewFromUtf8(model)); cpuinfo->Set(isolate->NewFromUtf8("speed"), v8::Number::New(isolate->m_isolate, cpuspeed)); cpuinfo->Set(isolate->NewFromUtf8("times"), cputimes); retVal->Set(i++, cpuinfo); } fclose(fpStat); } return 0; }
result_t os_base::memoryUsage(v8::Local<v8::Object> &retVal) { size_t rss = 0; FILE *f; int32_t itmp; char ctmp; uint32_t utmp; size_t page_size = getpagesize(); char *cbuf; int32_t foundExeEnd; static char buf[MAXPATHLEN + 1]; f = fopen("/proc/self/stat", "r"); if (!f) return CHECK_ERROR(LastError()); /* PID */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* Exec file */ cbuf = buf; foundExeEnd = 0; if (fscanf(f, "%c", cbuf++) == 0) goto error; while (1) { if (fscanf(f, "%c", cbuf) == 0) goto error; if (*cbuf == ')') { foundExeEnd = 1; } else if (foundExeEnd && *cbuf == ' ') { *cbuf = 0; break; } cbuf++; } /* State */ if (fscanf(f, "%c ", &ctmp) == 0) goto error; /* coverity[secure_coding] */ /* Parent process */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* Process group */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* Session id */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* TTY */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* TTY owner process group */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* Flags */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ /* Minor faults (no memory page) */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ /* Minor faults, children */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ /* Major faults (memory page faults) */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ /* Major faults, children */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ /* utime */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* stime */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* utime, children */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* stime, children */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* jiffies remaining in current time slice */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* 'nice' value */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* jiffies until next timeout */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ /* jiffies until next SIGALRM */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ /* start time (jiffies since system boot) */ if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ /* Virtual memory size */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ /* Resident set size */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ rss = (size_t) utmp * page_size; /* rlim */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ /* Start of text */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ /* End of text */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ /* Start of stack */ if (fscanf(f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */ error: fclose(f); Isolate* isolate = Isolate::current(); v8::Local<v8::Object> info = v8::Object::New(isolate->m_isolate); v8::HeapStatistics v8_heap_stats; isolate->m_isolate->GetHeapStatistics(&v8_heap_stats); info->Set(isolate->NewFromUtf8("rss"), v8::Number::New(isolate->m_isolate, (double)rss)); info->Set(isolate->NewFromUtf8("heapTotal"), v8::Number::New(isolate->m_isolate, (double)v8_heap_stats.total_heap_size())); info->Set(isolate->NewFromUtf8("heapUsed"), v8::Number::New(isolate->m_isolate, (double)v8_heap_stats.used_heap_size())); v8::Local<v8::Object> objs; object_base::class_info().dump(objs); info->Set(isolate->NewFromUtf8("nativeObjects"), objs); retVal = info; return 0; }
result_t util_base::compile(exlib::string srcname, exlib::string script, int32_t mode, obj_ptr<Buffer_base>& retVal) { Isolate* isolate = Isolate::current(); exlib::string oname = srcname; v8::Local<v8::String> soname = isolate->NewFromUtf8(oname); v8::Local<v8::Script> code; { TryCatch try_catch; { v8::ScriptCompiler::Source script_source( isolate->NewFromUtf8(script)); if (v8::ScriptCompiler::CompileUnbound( isolate->m_isolate, &script_source) .IsEmpty()) return throwSyntaxError(try_catch); } const char* args; switch (mode) { case 1: args = main_args; break; case 2: args = script_args; break; case 3: args = worker_args; break; default: args = module_args; break; } script = args + script + "\n});"; v8::ScriptCompiler::Source script_source( isolate->NewFromUtf8(script), v8::ScriptOrigin(soname)); if (v8::ScriptCompiler::CompileUnbound( isolate->m_isolate, &script_source, v8::ScriptCompiler::kProduceCodeCache) .IsEmpty()) return throwSyntaxError(try_catch); const v8::ScriptCompiler::CachedData* cache = script_source.GetCachedData(); exlib::string buf((const char*)cache->data, cache->length); int32_t len = (int32_t)script.length(); buf.append((const char*)&len, sizeof(len)); obj_ptr<Buffer_base> unz = new Buffer(buf); return zlib_base::cc_gzip(unz, retVal); } return 0; }
result_t SandBox::Context::repl(v8::Local<v8::Array> cmds, Stream_base* out) { result_t hr = 0; std::string buf; v8::Local<v8::Value> v, v1; Isolate* isolate = Isolate::current(); v8::Local<v8::String> strFname = isolate->NewFromUtf8("repl", 4); obj_ptr<BufferedStream_base> bs; stream_logger* logger = NULL; if (out) { if ((logger = s_stream) != NULL) { s_stream = NULL; logger->close(); } s_stream = logger = new stream_logger(out); bs = new BufferedStream(out); } output(console_base::_INFO, "Type \".help\" for more information."); while (true) { if (!v.IsEmpty() && !v->IsUndefined()) console_base::dir(v); v = v1; std::string line; if (out) { output(console_base::_PRINT, buf.empty() ? "> " : " ... "); hr = bs->ac_readLine(-1, line); if (hr >= 0) s_std->log(console_base::_INFO, line); } else hr = console_base::ac_readLine(buf.empty() ? "> " : " ... ", line); if (hr < 0) break; if (line.empty()) continue; if (line[0] == '.') { if (!repl_command(line, cmds)) break; continue; } buf += line; buf.append("\n", 1); { v8::Local<v8::Script> script; TryCatch try_catch; script = v8::Script::Compile(isolate->NewFromUtf8(buf), strFname); if (script.IsEmpty()) { v8::String::Utf8Value exception(try_catch.Exception()); if (*exception && qstrcmp(*exception, "SyntaxError: Unexpected end of input")) { buf.clear(); ReportException(try_catch, 0); } continue; } buf.clear(); v = script->Run(); if (v.IsEmpty()) ReportException(try_catch, 0); } } if (out) { if (logger == s_stream) s_stream = NULL; delete logger; } return hr; }
result_t HeapSnapshot::load(const char* fname) { Isolate* isolate = holder(); result_t hr; v8::Local<v8::Value> v; v8::Local<v8::Object> o; QuickArray<int32_t> nodes; QuickArray<int32_t> edges; QuickArray<qstring> names; QuickArray<qstring> node_fields; QuickArray<qstring> node_types; QuickArray<qstring> edge_fields; QuickArray<qstring> edge_types; int32_t node_count, edge_count; static const char* node_fields_chk[] = {"type", "name", "id", "self_size", "edge_count"}; static const char* node_types_chk[] = {"hidden", "array", "string", "object", "code", "closure", "regexp", "number", "native", "synthetic", "concatenated string", "sliced string" }; static const char* edge_fields_chk[] = {"type", "name_or_index", "to_node"}; static const char* edge_types_chk[] = {"context", "element", "property", "internal", "hidden", "shortcut", "weak" }; qstring data; hr = fs_base::ac_readFile(fname, data); if (hr < 0) return hr; hr = json_base::decode(data.c_str(), v); if (hr < 0) return hr; data.resize(0); if (!v->IsObject()) return CHECK_ERROR(CALL_E_INVALID_DATA); o = v8::Local<v8::Object>::Cast(v); hr = GetArray(o->Get(isolate->NewFromUtf8("nodes")), nodes); if (hr < 0) return CHECK_ERROR(CALL_E_INVALID_DATA); hr = GetArray(o->Get(isolate->NewFromUtf8("edges")), edges); if (hr < 0) return CHECK_ERROR(CALL_E_INVALID_DATA); hr = GetArray(o->Get(isolate->NewFromUtf8("strings")), names); if (hr < 0) return CHECK_ERROR(CALL_E_INVALID_DATA); v = o->Get(isolate->NewFromUtf8("snapshot")); if (v.IsEmpty() || !v->IsObject()) return CHECK_ERROR(CALL_E_INVALID_DATA); o = v8::Local<v8::Object>::Cast(v); hr = GetConfigValue(isolate->m_isolate, o, "node_count", node_count); if (hr < 0) return CHECK_ERROR(CALL_E_INVALID_DATA); hr = GetConfigValue(isolate->m_isolate, o, "edge_count", edge_count); if (hr < 0) return CHECK_ERROR(CALL_E_INVALID_DATA); v = o->Get(isolate->NewFromUtf8("meta")); if (v.IsEmpty() || !v->IsObject()) return CHECK_ERROR(CALL_E_INVALID_DATA); o = v8::Local<v8::Object>::Cast(v); hr = GetArray(o->Get(isolate->NewFromUtf8("node_fields")), node_fields); if (hr < 0 || checkArray(node_fields, node_fields_chk, ARRAYSIZE(node_fields_chk))) return CHECK_ERROR(CALL_E_INVALID_DATA); hr = GetArray(o->Get(isolate->NewFromUtf8("edge_fields")), edge_fields); if (hr < 0 || checkArray(edge_fields, edge_fields_chk, ARRAYSIZE(edge_fields_chk))) return CHECK_ERROR(CALL_E_INVALID_DATA); if (node_fields.size() * node_count != nodes.size()) return CHECK_ERROR(CALL_E_INVALID_DATA); if (edge_fields.size() * edge_count != edges.size()) return CHECK_ERROR(CALL_E_INVALID_DATA); v = o->Get(isolate->NewFromUtf8("node_types")); if (v.IsEmpty() || !v->IsArray()) return CHECK_ERROR(CALL_E_INVALID_DATA); hr = GetArray(v8::Local<v8::Array>::Cast(v)->Get(0), node_types); if (hr < 0 || checkArray(node_types, node_types_chk, ARRAYSIZE(node_types_chk))) return CHECK_ERROR(CALL_E_INVALID_DATA); v = o->Get(isolate->NewFromUtf8("edge_types")); if (v.IsEmpty() || !v->IsArray()) return CHECK_ERROR(CALL_E_INVALID_DATA); hr = GetArray(v8::Local<v8::Array>::Cast(v)->Get(0), edge_types); if (hr < 0 || checkArray(edge_types, edge_types_chk, ARRAYSIZE(edge_types_chk))) return CHECK_ERROR(CALL_E_INVALID_DATA); int32_t node_pos = 0, edge_pos = 0; m_nodes = new List(); while (node_pos < node_count) { int32_t _base = node_pos * (int32_t)node_fields.size(); int32_t _node_type = nodes[_base]; int32_t _node_name_id = nodes[_base + 1]; if (_node_name_id < 0 || _node_name_id >= (int32_t)names.size()) return CHECK_ERROR(CALL_E_INVALID_DATA); qstring _node_name = names[_node_name_id]; int32_t _node_id = nodes[_base + 2]; int32_t _node_size = nodes[_base + 3]; int32_t _node_edge = nodes[_base + 4]; obj_ptr<List> _edges = new List(); if (edge_pos + _node_edge > edge_count) return CHECK_ERROR(CALL_E_INVALID_DATA); while (_node_edge --) { int32_t _base = edge_pos * (int32_t)edge_fields.size(); int32_t _edge_type = edges[_base]; int32_t _edge_name_id = edges[_base + 1]; int32_t _edge_toid = edges[_base + 2]; qstring _edge_name; if (is_num_type(_edge_type)) { char buf[64]; sprintf(buf, "%d", _edge_name_id); _edge_name = buf; } else _edge_name = names[_edge_name_id]; if (_edge_toid % node_fields.size() != 0 || _edge_toid >= (int32_t)edges.size()) return CHECK_ERROR(CALL_E_INVALID_DATA); _edge_toid = nodes[_edge_toid + 2]; obj_ptr<HeapGraphEdge> _edge = new HeapGraphEdge(this, _edge_type, _edge_name, _node_id, _edge_toid); _edges->append(_edge); edge_pos ++; } _edges->freeze(); obj_ptr<HeapGraphNode> _node = new HeapGraphNode(_node_type, _node_name, _node_id, _node_size, _edges); _nodes.insert(std::pair<int32_t, int32_t>(_node_id, node_pos)); m_nodes->append(_node); node_pos ++; } m_nodes->freeze(); return 0; }
result_t os_base::CPUInfo(v8::Local<v8::Array> &retVal) { Isolate* isolate = Isolate::current(); retVal = v8::Array::New(isolate->m_isolate); v8::Local<v8::Object> cpuinfo; v8::Local<v8::Object> cputimes; uint32_t ticks = (uint32_t) sysconf(_SC_CLK_TCK), multiplier = ((uint64_t) 1000L / ticks), cpuspeed, maxcpus, cur = 0; char model[512]; long *cp_times; int32_t numcpus; size_t size; int32_t i; size = sizeof(model); if (sysctlbyname("hw.model", &model, &size, NULL, 0) < 0) return CHECK_ERROR(LastError()); size = sizeof(numcpus); if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0) < 0) return CHECK_ERROR(LastError()); size = sizeof(cpuspeed); if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0) < 0) return CHECK_ERROR(LastError()); size = sizeof(maxcpus); #ifdef __DragonFly__ if (sysctlbyname("hw.ncpu", &maxcpus, &size, NULL, 0) < 0) return CHECK_ERROR(LastError()); #else if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) return CHECK_ERROR(LastError()); #endif size = maxcpus * CPUSTATES * sizeof(long); cp_times = (long int *) malloc(size); if (cp_times == NULL) return CHECK_ERROR(LastError()); if (sysctlbyname("kern.cp_times", cp_times, &size, NULL, 0) < 0) { free(cp_times); return CHECK_ERROR(LastError()); } for (i = 0; i < numcpus; i++) { cpuinfo = v8::Object::New(isolate->m_isolate); cputimes = v8::Object::New(isolate->m_isolate); cputimes->Set( isolate->NewFromUtf8("user"), v8::Number::New(isolate->m_isolate, (uint64_t)(cp_times[CP_USER + cur]) * multiplier)); cputimes->Set( isolate->NewFromUtf8("nice"), v8::Number::New(isolate->m_isolate, (uint64_t)(cp_times[CP_NICE + cur]) * multiplier)); cputimes->Set( isolate->NewFromUtf8("sys"), v8::Number::New(isolate->m_isolate, (uint64_t)(cp_times[CP_SYS + cur]) * multiplier)); cputimes->Set( isolate->NewFromUtf8("idle"), v8::Number::New(isolate->m_isolate, (uint64_t)(cp_times[CP_IDLE + cur]) * multiplier)); cputimes->Set( isolate->NewFromUtf8("irq"), v8::Number::New(isolate->m_isolate, (uint64_t)(cp_times[CP_INTR + cur]) * multiplier)); cpuinfo->Set(isolate->NewFromUtf8("model"), isolate->NewFromUtf8(model)); cpuinfo->Set(isolate->NewFromUtf8("speed"), v8::Number::New(isolate->m_isolate, cpuspeed)); cpuinfo->Set(isolate->NewFromUtf8("times"), cputimes); retVal->Set(i, cpuinfo); cur += CPUSTATES; } free(cp_times); return 0; }
std::string json_format(v8::Local<v8::Value> obj) { StringBuffer strBuffer; Isolate* isolate = Isolate::current(); QuickArray<_item> stk; QuickArray<v8::Local<v8::Object>> vals; v8::Local<v8::Value> v = obj; v8::Local<v8::String> mark_name = isolate->NewFromUtf8("_util_format_mark"); int32_t padding = 0; const int32_t tab_size = 2; _item *it = NULL; while (true) { if (v.IsEmpty()) strBuffer.append("undefined"); else if (v->IsUndefined() || v->IsNull() || v->IsDate() || v->IsBoolean() || v->IsBooleanObject()) strBuffer.append(*v8::String::Utf8Value(v)); else if (v->IsNumber() || v->IsNumberObject()) strBuffer.append(*v8::String::Utf8Value(v->ToNumber())); else if (v->IsString() || v->IsStringObject()) string_format(strBuffer, v); else if (v->IsRegExp()) { v8::Local<v8::RegExp> re = v8::Local<v8::RegExp>::Cast(v); v8::Local<v8::String> src = re->GetSource(); v8::RegExp::Flags flgs = re->GetFlags(); strBuffer.append('/'); strBuffer.append(*v8::String::Utf8Value(src)); strBuffer.append('/'); if (flgs & v8::RegExp::kIgnoreCase) strBuffer.append('i'); if (flgs & v8::RegExp::kGlobal) strBuffer.append('g'); if (flgs & v8::RegExp::kMultiline) strBuffer.append('m'); } else if (v->IsObject()) { do { v8::Local<v8::Object> obj = v->ToObject(); v8::Local<v8::Array> keys = obj->GetPropertyNames(); if (v->IsFunction() && keys->Length() == 0) { strBuffer.append("[Function]"); break; } obj_ptr<Buffer_base> buf = Buffer_base::getInstance(v); if (buf) { static char hexs[] = "0123456789abcdef"; std::string data; std::string s; int32_t len, i; buf->toString(data); len = (int32_t)data.length(); s.resize(len * 3 + 8); memcpy(&s[0], "<Buffer", 7); for (i = 0; i < len; i ++) { int32_t ch = (unsigned char)data[i]; s[i * 3 + 7] = ' '; s[i * 3 + 8] = hexs[ch >> 4]; s[i * 3 + 9] = hexs[ch & 0xf]; } s[i * 3 + 7] = '>'; strBuffer.append(s); break; } obj_ptr<Int64_base> int64Val = Int64_base::getInstance(v); if (int64Val) { std::string s; int64Val->toString(10, s); strBuffer.append(s); break; } v8::Local<v8::Value> mk = obj->GetHiddenValue(mark_name); if (!mk.IsEmpty()) { strBuffer.append("[Circular]"); break; } vals.append(obj); obj->SetHiddenValue(mark_name, obj); v8::Local<v8::Value> toArray = obj->Get(isolate->NewFromUtf8("toArray")); if (!IsEmpty(toArray) && toArray->IsFunction()) { v = v8::Local<v8::Function>::Cast(toArray)->Call(obj, 0, NULL); obj = v->ToObject(); } int32_t sz = (int32_t)stk.size(); if (v->IsArray()) { v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(v); int32_t len = array->Length(); if (len == 0) strBuffer.append("[]"); else { if (len == 1 && v->StrictEquals(array->Get(0))) strBuffer.append("[Circular]"); else { stk.resize(sz + 1); it = &stk[sz]; it->val = v; it->keys = array; it->len = len; strBuffer.append('['); padding += tab_size; } } break; } int32_t len = keys->Length(); if (len == 0) strBuffer.append("{}"); else { if (len == 1 && v->StrictEquals(obj->Get(keys->Get(0)))) strBuffer.append("[Circular]"); else { stk.resize(sz + 1); it = &stk[sz]; it->val = v; it->obj = obj; it->keys = keys; it->len = len; strBuffer.append('{'); padding += tab_size; } } } while (false); } if (it) { while (it && it->pos == it->len) { padding -= tab_size; newline(strBuffer, padding); strBuffer.append(it->obj.IsEmpty() ? ']' : '}'); int32_t sz = (int32_t)stk.size(); stk.resize(sz - 1); if (sz > 1) it = &stk[sz - 2]; else it = NULL; } if (!it) break; if (it->pos) strBuffer.append(','); newline(strBuffer, padding); v = it->keys->Get(it->pos ++); if (!it->obj.IsEmpty()) { TryCatch try_catch; string_format(strBuffer, v); strBuffer.append(": "); v = it->obj->Get(v); } } else break; } int32_t sz1 = (int32_t)vals.size(); int32_t i; for (i = 0; i < sz1; i ++) vals[i]->DeleteHiddenValue(mark_name); return strBuffer.str(); }
result_t util_base::buildInfo(v8::Local<v8::Object> &retVal) { Isolate* isolate = Isolate::current(); retVal = v8::Object::New(isolate->m_isolate); retVal->Set(isolate->NewFromUtf8("fibjs"), isolate->NewFromUtf8(s_version)); #ifdef GIT_INFO retVal->Set(isolate->NewFromUtf8("git"), isolate->NewFromUtf8(GIT_INFO)); #endif #if defined(__clang__) retVal->Set(isolate->NewFromUtf8("clang"), isolate->NewFromUtf8( STR(__clang_major__) "." STR(__clang_minor__))); #elif defined(__GNUC__) retVal->Set(isolate->NewFromUtf8("gcc"), isolate->NewFromUtf8( STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__))); #elif defined(_MSC_VER) retVal->Set(isolate->NewFromUtf8("msvc"), isolate->NewFromUtf8( STR(_MSC_VER))); #endif retVal->Set(isolate->NewFromUtf8("date"), isolate->NewFromUtf8(__DATE__ " " __TIME__)); #ifndef NDEBUG retVal->Set(isolate->NewFromUtf8("debug"), v8::True(isolate->m_isolate)); #endif { v8::Local<v8::Object> vender = v8::Object::New(isolate->m_isolate); char str[64]; retVal->Set(isolate->NewFromUtf8("vender"), vender); vender->Set(isolate->NewFromUtf8("ev"), isolate->NewFromUtf8( STR(EV_VERSION_MAJOR) "." STR(EV_VERSION_MINOR))); vender->Set(isolate->NewFromUtf8("expat"), isolate->NewFromUtf8( STR(XML_MAJOR_VERSION) "." STR(XML_MINOR_VERSION) "." STR(XML_MICRO_VERSION))); vender->Set(isolate->NewFromUtf8("gd"), isolate->NewFromUtf8(GD_VERSION_STRING)); vender->Set(isolate->NewFromUtf8("jpeg"), isolate->NewFromUtf8( STR(JPEG_LIB_VERSION_MAJOR) "." STR(JPEG_LIB_VERSION_MINOR))); sprintf(str, "%d.%d", leveldb::kMajorVersion, leveldb::kMinorVersion); vender->Set(isolate->NewFromUtf8("leveldb"), isolate->NewFromUtf8( str)); vender->Set(isolate->NewFromUtf8("mongo"), isolate->NewFromUtf8( STR(MONGO_MAJOR) "." STR(MONGO_MINOR))); vender->Set(isolate->NewFromUtf8("pcre"), isolate->NewFromUtf8( STR(PCRE_MAJOR) "." STR(PCRE_MINOR))); vender->Set(isolate->NewFromUtf8("png"), isolate->NewFromUtf8(PNG_LIBPNG_VER_STRING)); vender->Set(isolate->NewFromUtf8("mbedtls"), isolate->NewFromUtf8(MBEDTLS_VERSION_STRING)); vender->Set(isolate->NewFromUtf8("snappy"), isolate->NewFromUtf8( STR(SNAPPY_MAJOR) "." STR(SNAPPY_MINOR) "." STR(SNAPPY_PATCHLEVEL))); vender->Set(isolate->NewFromUtf8("sqlite"), isolate->NewFromUtf8(SQLITE_VERSION)); vender->Set(isolate->NewFromUtf8("tiff"), isolate->NewFromUtf8(TIFFLIB_VERSION_STR)); vender->Set(isolate->NewFromUtf8("uuid"), isolate->NewFromUtf8("1.6.2")); vender->Set(isolate->NewFromUtf8("v8"), isolate->NewFromUtf8(v8::V8::GetVersion())); vender->Set(isolate->NewFromUtf8("zlib"), isolate->NewFromUtf8(ZLIB_VERSION)); } return 0; }
result_t os_base::memoryUsage(v8::Local<v8::Object> &retVal) { size_t rss; kvm_t *kd = NULL; struct kinfo_proc *kinfo = NULL; pid_t pid; int32_t nprocs; size_t page_size = getpagesize(); static bool _init = false; static kvm_t *(*_kvm_open)(char *, const char *, char *, int32_t, const char *); static void (*_kvm_close)(kvm_t *); static struct kinfo_proc* (*_kvm_getprocs)(kvm_t *, int32_t, int32_t, int32_t *); if (!_init) { void *handle = dlopen("libkvm.so", RTLD_LAZY); if (handle) { _kvm_open = (kvm_t * (*)(char *, const char *, char *, int32_t, const char *))dlsym(handle, "kvm_open"); _kvm_getprocs = (struct kinfo_proc * (*)(kvm_t *, int32_t, int32_t, int32_t *))dlsym(handle, "kvm_getprocs"); _kvm_close = (void (*)(kvm_t *))dlsym(handle, "kvm_close"); } } if (!_kvm_open || !_kvm_getprocs || !_kvm_close) return CHECK_ERROR(CALL_E_INVALID_CALL); pid = getpid(); kd = _kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); if (kd == NULL) return CHECK_ERROR(LastError()); kinfo = _kvm_getprocs(kd, KERN_PROC_PID, pid, &nprocs); if (kinfo == NULL) { _kvm_close(kd); return CHECK_ERROR(LastError()); } #ifdef __DragonFly__ rss = kinfo->kp_vm_rssize * page_size; #else rss = kinfo->ki_rssize * page_size; #endif _kvm_close(kd); Isolate* isolate = Isolate::current(); v8::Local<v8::Object> info = v8::Object::New(isolate->m_isolate); v8::HeapStatistics v8_heap_stats; isolate->m_isolate->GetHeapStatistics(&v8_heap_stats); info->Set(isolate->NewFromUtf8("rss"), v8::Number::New(isolate->m_isolate, (double)rss)); info->Set(isolate->NewFromUtf8("heapTotal"), v8::Number::New(isolate->m_isolate, (double)v8_heap_stats.total_heap_size())); info->Set(isolate->NewFromUtf8("heapUsed"), v8::Number::New(isolate->m_isolate, (double)v8_heap_stats.used_heap_size())); v8::Local<v8::Object> objs; object_base::class_info().dump(objs); info->Set(isolate->NewFromUtf8("nativeObjects"), objs); retVal = info; return 0; }