Example #1
0
Ink_Object *InkNative_Object_New(Ink_InterpreteEngine *engine, Ink_ContextChain *context, Ink_ArgcType argc, Ink_Object **argv, Ink_Object *this_p)
{
	Ink_Object *base = context->searchSlot(engine, "base");
	Ink_Object *new_obj = new Ink_Object(engine);
	Ink_HashTable *prototype_hash = base->getSlotMapping(engine, "prototype");

	if (prototype_hash) {
		new_obj->setSlot("prototype", prototype_hash->getValue());
	}

	if (base->type == INK_FUNCTION) {
		return base->call(engine, context, argc, argv, new_obj);
	}

	return new_obj;
}
Example #2
0
Ink_Object *Ink_CallExpression::eval(Ink_InterpreteEngine *engine, Ink_ContextChain *context_chain, Ink_EvalFlag flags)
{
    const char *file_name_back;
    Ink_LineNoType line_num_back;
    SET_LINE_NUM;

    Ink_ArgumentList::size_type i;
    Ink_Object **argv = NULL, **argv_back = NULL;
    Ink_Object *ret_val, *expandee;
    /* eval callee to get parameter declaration */
    Ink_Object *func = callee->eval(engine, context_chain);
    Ink_FunctionObject *tmp_func = NULL;
    if (INTER_SIGNAL_RECEIVED)
        return engine->getInterruptValue();
    Ink_ParamList param_list = Ink_ParamList();
    Ink_ArgumentList dispose_list, tmp_arg_list, another_tmp_arg_list;

    /* this part was moved from Ink_FunctionObject::call */
    bool is_arg_completed = true,
         if_delete_argv = false;
    Ink_ArgcType tmp_argc, j, argi, argc;
    Ink_Object **tmp_argv;

    if (func->type == INK_FUNCTION) {
        param_list = as<Ink_FunctionObject>(func)->param;
        tmp_func = as<Ink_FunctionObject>(func);
    }
    if (is_new) {
        func = Ink_HashExpression::getSlot(engine, context_chain, func, "new");
    }


    tmp_arg_list = Ink_ArgumentList();
    for (Ink_ArgumentList::iterator arg_list_iter = arg_list.begin();
            arg_list_iter != arg_list.end(); arg_list_iter++) {
        if ((*arg_list_iter)->is_expand) {
            /* if the argument is 'with' argument attachment */

            /* eval expandee */
            expandee = (*arg_list_iter)->expandee->eval(engine, context_chain);
            if (INTER_SIGNAL_RECEIVED) {
                ret_val = engine->getInterruptValue();
                goto DISPOSE_LIST;
            }

            /* expand argument */
            another_tmp_arg_list = expandArgument(engine, expandee);

            /* insert expanded argument to dispose list and temporary argument list */
            dispose_list.insert(dispose_list.end(), another_tmp_arg_list.begin(), another_tmp_arg_list.end());
            tmp_arg_list.insert(tmp_arg_list.end(), another_tmp_arg_list.begin(), another_tmp_arg_list.end());
        } else {
            /* normal argument, directly push to argument list */
            tmp_arg_list.push_back(*arg_list_iter);
        }
    }

    if (tmp_arg_list.size()) {
        /* allocate argument list */
        argv = (Ink_Object **)malloc(tmp_arg_list.size() * sizeof(Ink_Object *));
        argv_back = argv;

        /* set argument list, according to the parameter declaration */
        for (i = 0; i < tmp_arg_list.size(); i++) {
            if (i < param_list.size() && param_list[i].is_ref) {
                /* if the paramete is declared as reference, seal the expression to a anonymous function */
                if (param_list[i].is_variant) {
                    for (; i < tmp_arg_list.size(); i++) {
                        if (tmp_arg_list[i]->arg->is_unknown) {
                            argv[i] = new Ink_Unknown(engine);
                        } else {
                            Ink_ExpressionList exp_list = Ink_ExpressionList();
                            exp_list.push_back(tmp_arg_list[i]->arg);
                            argv[i] = new Ink_FunctionObject(engine, Ink_ParamList(), exp_list,
                                                             context_chain->copyContextChain(),
                                                             true);
                        }
                    }
                } else {
                    if (tmp_arg_list[i]->arg->is_unknown) {
                        argv[i] = new Ink_Unknown(engine);
                    } else {
                        Ink_ExpressionList exp_list = Ink_ExpressionList();
                        exp_list.push_back(tmp_arg_list[i]->arg);
                        argv[i] = new Ink_FunctionObject(engine, Ink_ParamList(), exp_list,
                                                         context_chain->copyContextChain(),
                                                         true);
                    }
                }
            } else {
                /* normal argument */
                argv[i] = tmp_arg_list[i]->arg->eval(engine, context_chain);
                if (INTER_SIGNAL_RECEIVED) {
                    ret_val = engine->getInterruptValue();
                    /* goto dispose and interrupt */
                    goto DISPOSE_ARGV;
                }
            }
        }
    }

    argc = tmp_arg_list.size();
    /* if some arguments have been applied already */
    if (tmp_func && tmp_func->partial_applied_argv) {
        tmp_argc = tmp_func->partial_applied_argc;
        tmp_argv = copyArgv(tmp_func->partial_applied_argc,
                            tmp_func->partial_applied_argv);
        for (j = 0, argi = 0; j < tmp_argc; j++) {
            /* find unknown place to put in arguments */
            if (isUnknown(tmp_argv[j])) {
                if (argi < argc /* not excess */
                        && !isUnknown(argv[argi]) /* not another unknown argument */)
                    tmp_argv[j] = argv[argi];
                else
                    is_arg_completed = false;
                argi++;
            }
        }

        if (!is_arg_completed) {
            /* still missing arguments -- return another PAF */
            if (argi < argc) {
                Ink_ArgcType remainc = argc - argi; /* remaining arguments */
                argc = remainc + tmp_argc;
                /* link the PA arguments and remaining arguments */
                argv = linkArgv(tmp_argc, tmp_argv,
                                remainc, &argv[argi]);

                free(tmp_argv);
                tmp_argc = argc;
                tmp_argv = argv;
            }
            ret_val = tmp_func->cloneWithPA(engine, tmp_argc, tmp_argv, true);
            goto DISPOSE_ARGV;
        }

        Ink_ArgcType remainc = argc - argi; /* remaining arguments */
        argc = remainc + tmp_argc;
        /* link the PA arguments and remaining arguments */
        argv = linkArgv(tmp_argc, tmp_argv,
                        remainc, &argv[argi]);
        free(tmp_argv);
        if_delete_argv = true;
    }

    for (argi = 0; tmp_func && argi < argc; argi++) {
        if (isUnknown(argv[argi])) { /* find unknown argument */
            ret_val = tmp_func->cloneWithPA(engine, argc, copyArgv(argc, argv), true);
            goto DISPOSE_ARGV;
        }
    }

    ret_val = func->call(engine, context_chain, argc, argv);

DISPOSE_ARGV:
    if (if_delete_argv)
        free(argv);
    if (argv_back)
        free(argv_back);

DISPOSE_LIST:
    for (i = 0; i < dispose_list.size(); i++) {
        delete dispose_list[i];
    }

    RESTORE_LINE_NUM;

    return ret_val;
}
Example #3
0
Ink_Object *InkNative_Direct_Each(Ink_InterpreteEngine *engine, Ink_ContextChain *context, Ink_ArgcType argc, Ink_Object **argv, Ink_Object *this_p)
{
	Ink_Object *base = context->searchSlot(engine, "base");
	string *tmp_path;
	Ink_Object **args = NULL;
	Ink_Object *ret_tmp;
	Ink_ArrayValue ret_val;
	Ink_ArrayValue::size_type i;
	Ink_Object *block = NULL;

	ASSUME_BASE_TYPE(engine, DIRECT_TYPE);

	if (!(tmp_path = as<Ink_DirectPointer>(base)->path)) {
		InkWarn_IO_Uninitialized_Direct_Pointer(engine);
		return NULL_OBJ;
	}

	if (argc && argv[0]->type == INK_FUNCTION)
		block = argv[0];

	args = (Ink_Object **)malloc(sizeof(Ink_Object *));

#if defined(INK_PLATFORM_LINUX)
	DIR *dir_handle = opendir(tmp_path->c_str());
	struct dirent *child;

	if (!dir_handle) {
		InkWarn_Direct_Not_Exist(engine, tmp_path->c_str());
		free(args);
		return NULL_OBJ;
	}

	while ((child = readdir(dir_handle)) != NULL) {

	#define CLOSE_HANDLER closedir(dir_handle)
	#define CHILD_NAME (child->d_name)
#elif defined(INK_PLATFORM_WIN32)
	WIN32_FIND_DATA data;
	HANDLE dir_handle = NULL;

	dir_handle = FindFirstFile((string(INK_MODULE_DIR) + "/*").c_str(), &data);

	if (dir_handle == INVALID_HANDLE_VALUE) {
		do {

	#define CLOSE_HANDLER FindClose(dir_handle)
	#define CHILD_NAME (data.cFileName)
#endif

	if (block) {
		args[0] = new Ink_String(engine, string(CHILD_NAME));
		ret_val.push_back(new Ink_HashTable(ret_tmp = block->call(engine, context, 1, args)));
		if (engine->getSignal() != INTER_NONE) {
			switch (engine->getSignal()) {
				case INTER_RETURN:
					free(args);
					cleanArrayHashTable(ret_val);
					CLOSE_HANDLER;
					return engine->getInterruptValue(); // signal penetrated
				case INTER_DROP:
				case INTER_BREAK:
					free(args);
					cleanArrayHashTable(ret_val);
					CLOSE_HANDLER;
					return engine->trapSignal(); // trap the signal
				case INTER_CONTINUE:
					engine->trapSignal(); // trap the signal, but do not return
					continue;
				default:
					free(args);
					cleanArrayHashTable(ret_val);
					CLOSE_HANDLER;
					return NULL_OBJ;
			}
		}
	} else {
		ret_val.push_back(new Ink_HashTable(new Ink_String(engine, string(CHILD_NAME))));
	}


#if defined(INK_PLATFORM_LINUX)
	}

	closedir(dir_handle);
#elif defined(INK_PLATFORM_WIN32)
		} while (FindNextFile(dir_handle, &data));
	} else {