예제 #1
0
파일: define.cpp 프로젝트: cwyiu/fibjs
result_t doDefine(v8::Local<v8::Object> &mod)
{
    v8::Local<v8::Array> defs;
    {
        v8::Local<v8::Value> v;
        v8::Local<v8::String> strDefs = v8::String::NewFromUtf8(isolate, "defs");

        // get define array from default module
        v = mod->GetHiddenValue(strDefs);
        mod->DeleteHiddenValue(strDefs);

        if (!v.IsEmpty() && v->IsArray())
            defs = v8::Local<v8::Array>::Cast(v);
        else
            return 0;
    }

    int an = defs->Length(), i, j;
    std::vector<v8::Local<v8::Object> > mods;
    std::vector<std::string> modIds;
    std::set<std::string> depns;

    // cache string
    v8::Local<v8::String> strRequire = v8::String::NewFromUtf8(isolate, "require");
    v8::Local<v8::String> strExports = v8::String::NewFromUtf8(isolate, "exports");
    v8::Local<v8::String> strDeps = v8::String::NewFromUtf8(isolate, "deps");
    v8::Local<v8::String> strFactory = v8::String::NewFromUtf8(isolate, "factory");
    v8::Local<v8::String> strId = v8::String::NewFromUtf8(isolate, "id");

    // copy data to local
    mods.resize(an);
    modIds.resize(an);
    for (i = 0; i < an; i++)
    {
        mods[i] = defs->Get(i)->ToObject();
        modIds[i] = *v8::String::Utf8Value(mods[i]->Get(strId));
        depns.insert(modIds[i]);
    }

    // two step
    int doStep = 2;
    bool bNext = false;

    while (doStep)
    {
        bNext = true;

        for (i = 0; i < an; i++)
        {
            if (!modIds[i].empty())
            {
                // get deps array
                v8::Local<v8::Value> a1 = mods[i]->GetHiddenValue(strDeps);

                if (a1.IsEmpty() || !a1->IsArray())
                {
                    // not found deps array
                    depns.erase(modIds[i]);
                    modIds[i].clear();
                    bNext = false;

                    continue;
                }

                v8::Local<v8::Array> a = v8::Local<v8::Array>::Cast(a1);

                int n = a->Length();

                // check if the module depend a module defined in same script
                for (j = 0; j < n; j++)
                    if (doStep == 2
                            && depns.find(*v8::String::Utf8Value(a->Get(j)))
                            != depns.end())
                        break;

                if (j == n)
                {
                    std::vector<v8::Local<v8::Value> > deps;
                    deps.resize(n);

                    for (j = 0; j < n; j++)
                    {
                        v8::String::Utf8Value id(a->Get(j));

                        if (!qstrcmp(*id, "require"))
                            deps[j] = mods[i]->Get(strRequire);
                        else if (!qstrcmp(*id, "exports"))
                            deps[j] = mods[i]->Get(strExports);
                        else if (!qstrcmp(*id, "module"))
                            deps[j] = mods[i];
                        else
                        {
                            // load module use require
                            result_t hr = global_base::require(*id, deps[j]);
                            if (hr < 0)
                                return hr;
                        }
                    }

                    v8::Local<v8::Value> v;

                    // get factory and remove hidden value.
                    v = mods[i]->GetHiddenValue(strFactory);
                    mods[i]->DeleteHiddenValue(strFactory);
                    mods[i]->DeleteHiddenValue(strDeps);

                    if (v->IsFunction())
                    {
                        v8::Local<v8::Function> func =
                            v8::Local<v8::Function>::Cast(v);

                        v = func->Call(func, n, deps.data());
                        if (v.IsEmpty())
                            return CALL_E_JAVASCRIPT;
                    }

                    // use the result as exports if the factory return something
                    if (!IsEmpty(v))
                        mods[i]->Set(strExports, v);
                    else
                        v = mods[i]->Get(strExports);

                    InstallModule(modIds[i], v);

                    // remove id name, we don't like to call it again
                    depns.erase(modIds[i]);
                    modIds[i].clear();
                    bNext = false;
                }
            }
        }

        if (bNext)
            doStep--;
    }

    return 0;
}
예제 #2
0
파일: util.cpp 프로젝트: jim4node/fibjs
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();
}
예제 #3
0
v8::Local<v8::Value> V8HiddenValue::getHiddenValue(v8::Isolate* isolate, v8::Local<v8::Object> object, v8::Local<v8::String> key)
{
    return object->GetHiddenValue(key);
}