static void ExecDefault(const char *param) { char *temp = strmalloc(param); char *s = skip_ident(temp); int save = *s; int isClass; *s = 0; if (!*temp) { free(temp); temp = strmalloc(NAME_KEYWORD); isClass = (is_class(temp) != 0); } else { isClass = (is_class(temp) != 0); *s = (char) save; } if (isClass) { flt_init_attr(temp); VERBOSE(1, ("set default_attr '%s' %p", default_attr, default_attr)); } else { VERBOSE(1, ("not a class:%s", temp)); } free(temp); }
static void mref_set_optype(operand *op) { int b = op->basereg; int i = op->indexreg; int s = op->scale; /* It is memory, but it can match any r/m operand */ op->type |= MEMORY_ANY; if (b == -1 && (i == -1 || s == 0)) { int is_rel = globalbits == 64 && !(op->eaflags & EAF_ABS) && ((globalrel && !(op->eaflags & EAF_FSGS)) || (op->eaflags & EAF_REL)); op->type |= is_rel ? IP_REL : MEM_OFFS; } if (i != -1) { opflags_t iclass = nasm_reg_flags[i]; if (is_class(XMMREG,iclass)) op->type |= XMEM; else if (is_class(YMMREG,iclass)) op->type |= YMEM; else if (is_class(ZMMREG,iclass)) op->type |= ZMEM; } }
static HRESULT maybe_to_primitive(script_ctx_t *ctx, jsval_t val, jsval_t *r) { jsdisp_t *obj; HRESULT hres; if(!is_object_instance(val) || !get_object(val) || !(obj = iface_to_jsdisp((IUnknown*)get_object(val)))) return jsval_copy(val, r); if(is_class(obj, JSCLASS_NUMBER)) { double n; hres = to_number(ctx, val, &n); jsdisp_release(obj); if(SUCCEEDED(hres)) *r = jsval_number(n); return hres; } if(is_class(obj, JSCLASS_STRING)) { jsstr_t *str; hres = to_string(ctx, val, &str); jsdisp_release(obj); if(SUCCEEDED(hres)) *r = jsval_string(str); return hres; } if(is_class(obj, JSCLASS_BOOLEAN)) { *r = jsval_bool(bool_obj_value(obj)); jsdisp_release(obj); return S_OK; } *r = jsval_obj(obj); return S_OK; }
static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) { FunctionInstance *function; DISPPARAMS args = {NULL,NULL,0,0}; DWORD argc, i; IDispatch *this_obj = NULL; HRESULT hres = S_OK; TRACE("\n"); if(!(function = function_this(jsthis))) return throw_type_error(ctx, ei, JS_E_FUNCTION_EXPECTED, NULL); argc = arg_cnt(dp); if(argc) { VARIANT *v = get_arg(dp,0); if(V_VT(v) != VT_EMPTY && V_VT(v) != VT_NULL) { hres = to_object(ctx, v, &this_obj); if(FAILED(hres)) return hres; } } if(argc >= 2) { jsdisp_t *arg_array = NULL; if(V_VT(get_arg(dp,1)) == VT_DISPATCH) { arg_array = iface_to_jsdisp((IUnknown*)V_DISPATCH(get_arg(dp,1))); if(arg_array && (!is_class(arg_array, JSCLASS_ARRAY) && !is_class(arg_array, JSCLASS_ARGUMENTS) )) { jsdisp_release(arg_array); arg_array = NULL; } } if(arg_array) { hres = array_to_args(ctx, arg_array, ei, caller, &args); jsdisp_release(arg_array); }else { FIXME("throw TypeError\n"); hres = E_FAIL; } } if(SUCCEEDED(hres)) hres = call_function(ctx, function, this_obj, &args, retv, ei, caller); if(this_obj) IDispatch_Release(this_obj); for(i=0; i<args.cArgs; i++) VariantClear(args.rgvarg+i); heap_free(args.rgvarg); return hres; }
static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { FunctionInstance *function; jsval_t *args = NULL; unsigned i, cnt = 0; IDispatch *this_obj = NULL; HRESULT hres = S_OK; TRACE("\n"); if(!(function = function_this(jsthis))) return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL); if(argc) { if(!is_undefined(argv[0]) && !is_null(argv[0])) { hres = to_object(ctx, argv[0], &this_obj); if(FAILED(hres)) return hres; } } if(argc >= 2) { jsdisp_t *arg_array = NULL; if(is_object_instance(argv[1])) { arg_array = iface_to_jsdisp((IUnknown*)get_object(argv[1])); if(arg_array && (!is_class(arg_array, JSCLASS_ARRAY) && !is_class(arg_array, JSCLASS_ARGUMENTS) )) { jsdisp_release(arg_array); arg_array = NULL; } } if(arg_array) { hres = array_to_args(ctx, arg_array, &cnt, &args); jsdisp_release(arg_array); }else { FIXME("throw TypeError\n"); hres = E_FAIL; } } if(SUCCEEDED(hres)) hres = call_function(ctx, function, this_obj, cnt, args, r); if(this_obj) IDispatch_Release(this_obj); for(i=0; i < cnt; i++) jsval_release(args[i]); heap_free(args); return hres; }
static HRESULT Function_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { FunctionInstance *function; BSTR str; HRESULT hres; TRACE("\n"); if(!is_class(dispex, JSCLASS_FUNCTION)) { FIXME("throw TypeError\n"); return E_FAIL; } function = (FunctionInstance*)dispex; hres = function_to_string(function, &str); if(FAILED(hres)) return hres; if(retv) { V_VT(retv) = VT_BSTR; V_BSTR(retv) = str; }else { SysFreeString(str); } return S_OK; }
HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { const BOOL caller_execs_source = (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0; FunctionInstance *function; TRACE("func %p this %p\n", func_this, jsthis); assert(is_class(func_this, JSCLASS_FUNCTION)); function = (FunctionInstance*)func_this; flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; if(function->value_proc) return invoke_value_proc(function->dispex.ctx, function, jsthis, flags, argc, argv, r); if(flags == DISPATCH_CONSTRUCT) { jsdisp_t *this_obj; HRESULT hres; hres = create_object(function->dispex.ctx, &function->dispex, &this_obj); if(FAILED(hres)) return hres; hres = invoke_source(function->dispex.ctx, function, to_disp(this_obj), argc, argv, TRUE, caller_execs_source, r); jsdisp_release(this_obj); return hres; } assert(flags == DISPATCH_METHOD); return invoke_source(function->dispex.ctx, function, jsthis, argc, argv, FALSE, caller_execs_source, r); }
ObjectPtr<Class> create_meta_class(ClassPtr super) { ASSERT(is_class(super)); Value args[] = { super }; ObjectPtr<Class> cls = create_object(get_class_class(), countof(args), args); ObjectPtr<Class> sup = super; cls->name = sup->name; cls->is_meta = true; return cls; }
static HRESULT set_length(jsdisp_t *obj, DWORD length) { if(is_class(obj, JSCLASS_ARRAY)) { ((ArrayInstance*)obj)->length = length; return S_OK; } return jsdisp_propput_name(obj, lengthW, jsval_number(length)); }
static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { TRACE("\n"); switch(flags) { case DISPATCH_METHOD: if(argc) { if(is_object_instance(argv[0])) { jsdisp_t *jsdisp = iface_to_jsdisp((IUnknown*)get_object(argv[0])); if(jsdisp) { if(is_class(jsdisp, JSCLASS_REGEXP)) { if(argc > 1 && !is_undefined(argv[1])) { jsdisp_release(jsdisp); return throw_regexp_error(ctx, JS_E_REGEXP_SYNTAX, NULL); } if(r) *r = jsval_obj(jsdisp); else jsdisp_release(jsdisp); return S_OK; } jsdisp_release(jsdisp); } } } /* fall through */ case DISPATCH_CONSTRUCT: { jsdisp_t *ret; HRESULT hres; if(!argc) { FIXME("no args\n"); return E_NOTIMPL; } hres = create_regexp_var(ctx, argv[0], argc > 1 ? argv+1 : NULL, &ret); if(FAILED(hres)) return hres; if(r) *r = jsval_obj(ret); else jsdisp_release(ret); return S_OK; } default: FIXME("unimplemented flags: %x\n", flags); return E_NOTIMPL; } return S_OK; }
HRESULT create_regexp_var(script_ctx_t *ctx, jsval_t src_arg, jsval_t *flags_arg, jsdisp_t **ret) { unsigned flags, opt_len = 0; const WCHAR *opt = NULL; jsstr_t *src; HRESULT hres; if(is_object_instance(src_arg)) { jsdisp_t *obj; obj = iface_to_jsdisp((IUnknown*)get_object(src_arg)); if(obj) { if(is_class(obj, JSCLASS_REGEXP)) { RegExpInstance *regexp = (RegExpInstance*)obj; hres = create_regexp(ctx, regexp->str, regexp->jsregexp->flags, ret); jsdisp_release(obj); return hres; } jsdisp_release(obj); } } if(!is_string(src_arg)) { FIXME("src_arg = %s\n", debugstr_jsval(src_arg)); return E_NOTIMPL; } src = get_string(src_arg); if(flags_arg) { jsstr_t *opt_str; if(!is_string(*flags_arg)) { FIXME("unimplemented for %s\n", debugstr_jsval(*flags_arg)); return E_NOTIMPL; } opt_str = get_string(*flags_arg); opt = jsstr_flatten(opt_str); if(!opt) return E_OUTOFMEMORY; opt_len = jsstr_length(opt_str); } hres = parse_regexp_flags(opt, opt_len, &flags); if(FAILED(hres)) return hres; return create_regexp(ctx, src, flags, ret); }
static HRESULT set_length(jsdisp_t *obj, jsexcept_t *ei, DWORD length) { VARIANT var; if(is_class(obj, JSCLASS_ARRAY)) { ((ArrayInstance*)obj)->length = length; return S_OK; } V_VT(&var) = VT_I4; V_I4(&var) = length; return jsdisp_propput_name(obj, lengthW, &var, ei); }
char * class_attr(const char *name) { KEYWORD *data; char *result = 0; while ((data = is_class(name)) != 0) { VERBOSE(data->kw_used, ("class_attr(%s) = %s", name, AttrsOnce(data))); name = result = data->kw_attr; VERBOSE(1, ("-> %p", result)); } return result; }
Class *read_class_from_file_name(char *file_name) { FILE *file = fopen(file_name, "r"); if (!file) { fprintf(stderr, "Could not open '%s': %s\n", file_name, strerror(errno)); return NULL; } // Check the file header for .class nature if (!is_class(file)) { fprintf(stderr, "Skipping '%s': not a valid class file\n", file_name); return NULL; } const ClassFile cf = {file_name, file}; return read_class(cf); }
static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *regexp = NULL; const WCHAR *str; jsstr_t *jsstr; match_state_t match, *match_ptr = &match; HRESULT hres; TRACE("\n"); hres = get_string_flat_val(ctx, jsthis, &jsstr, &str); if(FAILED(hres)) return hres; if(!argc) { if(r) *r = jsval_null(); jsstr_release(jsstr); return S_OK; } if(is_object_instance(argv[0])) { regexp = iface_to_jsdisp(get_object(argv[0])); if(regexp && !is_class(regexp, JSCLASS_REGEXP)) { jsdisp_release(regexp); regexp = NULL; } } if(!regexp) { hres = create_regexp_var(ctx, argv[0], NULL, ®exp); if(FAILED(hres)) { jsstr_release(jsstr); return hres; } } match.cp = str; hres = regexp_match_next(ctx, regexp, REM_RESET_INDEX|REM_NO_PARENS, jsstr, &match_ptr); jsstr_release(jsstr); jsdisp_release(regexp); if(FAILED(hres)) return hres; if(r) *r = jsval_number(hres == S_OK ? match.cp-match.match_len-str : -1); return S_OK; }
/* ECMA-262 5.1 Edition 15.4.3.2 */ static HRESULT ArrayConstr_isArray(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *obj; TRACE("\n"); if(!argc || !is_object_instance(argv[0])) { if(r) *r = jsval_bool(FALSE); return S_OK; } obj = iface_to_jsdisp(get_object(argv[0])); if(r) *r = jsval_bool(obj && is_class(obj, JSCLASS_ARRAY)); if(obj) jsdisp_release(obj); return S_OK; }
static HRESULT concat_obj(jsdisp_t *array, IDispatch *obj, DWORD *len) { jsdisp_t *jsobj; HRESULT hres; jsobj = iface_to_jsdisp((IUnknown*)obj); if(jsobj) { if(is_class(jsobj, JSCLASS_ARRAY)) { hres = concat_array(array, (ArrayInstance*)jsobj, len); jsdisp_release(jsobj); return hres; } jsdisp_release(jsobj); } return jsdisp_propput_idx(array, (*len)++, jsval_disp(obj)); }
static const char * color_of(char *s, int arg) { const char *result = ""; char *t; int quoted = 0; int save; s = skip_blanks(s); t = skip_ident(s); if ((save = *t) != 0) *t = 0; if (is_class(s)) { if (FltOptions('c')) { result = keyword_attr(s); if (result == 0) result = class_attr(s); if (result == 0) result = Ident2_attr; } else { result = Ident2_attr; } } else if (arg && (*s != 0)) { char *base = s; if (!FltOptions('c')) result = Action_attr; while (*s != 0) { if (quoted) { if (*s == QUOTE) quoted = 0; } else if (*s == QUOTE) { quoted = 1; result = Literal_attr; } else if ((s == base) && color_code(s, &result)) { break; } s++; } } if (save) *t = (char) save; return result; }
HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { FunctionInstance *function; TRACE("func %p this %p\n", func_this, jsthis); assert(is_class(func_this, JSCLASS_FUNCTION)); function = (FunctionInstance*)func_this; if(function->value_proc) return invoke_value_proc(function->dispex.ctx, function, jsthis, flags, argc, argv, r); if(flags == DISPATCH_CONSTRUCT) return invoke_constructor(function->dispex.ctx, function, argc, argv, r); assert(flags == DISPATCH_METHOD); return invoke_source(function->dispex.ctx, function, jsthis, argc, argv, r); }
/* ECMA-262 3rd Edition 15.5.4.10 */ static HRESULT String_match(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *regexp = NULL; jsstr_t *str; HRESULT hres; TRACE("\n"); if(!argc) { if(r) *r = jsval_null(); return S_OK; } if(is_object_instance(argv[0])) { regexp = iface_to_jsdisp(get_object(argv[0])); if(regexp && !is_class(regexp, JSCLASS_REGEXP)) { jsdisp_release(regexp); regexp = NULL; } } if(!regexp) { jsstr_t *match_str; hres = to_string(ctx, argv[0], &match_str); if(FAILED(hres)) return hres; hres = create_regexp(ctx, match_str, 0, ®exp); jsstr_release(match_str); if(FAILED(hres)) return hres; } hres = get_string_val(ctx, jsthis, &str); if(SUCCEEDED(hres)) hres = regexp_string_match(ctx, regexp, str, r); jsdisp_release(regexp); jsstr_release(str); return hres; }
static HRESULT concat_obj(jsdisp_t *array, IDispatch *obj, DWORD *len, jsexcept_t *ei) { jsdisp_t *jsobj; VARIANT var; HRESULT hres; jsobj = iface_to_jsdisp((IUnknown*)obj); if(jsobj) { if(is_class(jsobj, JSCLASS_ARRAY)) { hres = concat_array(array, (ArrayInstance*)jsobj, len, ei); jsdisp_release(jsobj); return hres; } jsdisp_release(jsobj); } V_VT(&var) = VT_DISPATCH; V_DISPATCH(&var) = obj; return jsdisp_propput_idx(array, (*len)++, &var, ei); }
void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) const { if (script_instance && p_reversed) { p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); script_instance->get_property_list(p_list); } _get_property_listv(p_list, p_reversed); if (!is_class("Script")) // can still be set, but this is for userfriendlyness p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NONZERO)); #ifdef TOOLS_ENABLED if (editor_section_folding.size()) { p_list->push_back(PropertyInfo(Variant::ARRAY, CoreStringNames::get_singleton()->_sections_unfolded, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } #endif if (!metadata.empty()) p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_STORE_IF_NONZERO)); if (script_instance && !p_reversed) { p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); script_instance->get_property_list(p_list); } }
static void ExecDefault(char *param) { char *s = skip_ident(param); const char *t = param; const char *attr = Literal_attr; int save = *s; VERBOSE(1, ("ExecDefault(%s)\n", param)); *s = 0; if (!*t) t = NAME_KEYWORD; if (is_class(t)) { free(default_attr); default_attr = strmalloc(t); } if (FltOptions('c')) { attr = actual_color(t, -1, 1); VERBOSE(2, ("actual_color(%s) = %s\n", t, attr)); } *s = (char) save; flt_puts(param, (int) strlen(param), attr); }
void create(const char* class_path ) { value cls = value_by_path(get_vm(), class_path); assert( is_class(vm,cls) ); val = ni()->create_object(get_vm(), cls); }
/* ECMA-262 5.1 Edition 15.12.3 (abstract operation Str) */ static HRESULT stringify(stringify_ctx_t *ctx, jsval_t val) { jsval_t value; HRESULT hres; if(is_object_instance(val) && get_object(val)) { jsdisp_t *obj; DISPID id; obj = iface_to_jsdisp((IUnknown*)get_object(val)); if(!obj) return S_FALSE; hres = jsdisp_get_id(obj, toJSONW, 0, &id); jsdisp_release(obj); if(hres == S_OK) FIXME("Use toJSON.\n"); } /* FIXME: Support replacer replacer. */ hres = maybe_to_primitive(ctx->ctx, val, &value); if(FAILED(hres)) return hres; switch(jsval_type(value)) { case JSV_NULL: if(!append_string(ctx, nullW)) hres = E_OUTOFMEMORY; break; case JSV_BOOL: if(!append_string(ctx, get_bool(value) ? trueW : falseW)) hres = E_OUTOFMEMORY; break; case JSV_STRING: { jsstr_t *str = get_string(value); const WCHAR *ptr = jsstr_flatten(str); if(ptr) hres = json_quote(ctx, ptr, jsstr_length(str)); else hres = E_OUTOFMEMORY; break; } case JSV_NUMBER: { double n = get_number(value); if(is_finite(n)) { const WCHAR *ptr; jsstr_t *str; /* FIXME: Optimize. There is no need for jsstr_t here. */ hres = double_to_string(n, &str); if(FAILED(hres)) break; ptr = jsstr_flatten(str); assert(ptr != NULL); hres = ptr && !append_string_len(ctx, ptr, jsstr_length(str)) ? E_OUTOFMEMORY : S_OK; jsstr_release(str); }else { if(!append_string(ctx, nullW)) hres = E_OUTOFMEMORY; } break; } case JSV_OBJECT: { jsdisp_t *obj; obj = iface_to_jsdisp((IUnknown*)get_object(value)); if(!obj) { hres = S_FALSE; break; } if(!is_callable(obj)) hres = is_class(obj, JSCLASS_ARRAY) ? stringify_array(ctx, obj) : stringify_object(ctx, obj); else hres = S_FALSE; jsdisp_release(obj); break; } case JSV_UNDEFINED: hres = S_FALSE; break; case JSV_VARIANT: FIXME("VARIANT\n"); hres = E_NOTIMPL; break; } jsval_release(value); return hres; }
static inline BOOL is_callable(jsdisp_t *obj) { return is_class(obj, JSCLASS_FUNCTION); }
/* ECMA-262 3rd Edition 15.4.4.11 */ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei) { jsdisp_t *jsthis, *cmp_func = NULL; VARIANT *vtab, **sorttab = NULL; DWORD length; DWORD i; HRESULT hres = S_OK; TRACE("\n"); hres = get_length(ctx, vthis, ei, &jsthis, &length); if(FAILED(hres)) return hres; if(arg_cnt(dp) > 1) { WARN("invalid arg_cnt %d\n", arg_cnt(dp)); return E_FAIL; } if(arg_cnt(dp) == 1) { VARIANT *arg = get_arg(dp, 0); if(V_VT(arg) != VT_DISPATCH) { WARN("arg is not dispatch\n"); return E_FAIL; } cmp_func = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg)); if(!cmp_func || !is_class(cmp_func, JSCLASS_FUNCTION)) { WARN("cmp_func is not a function\n"); if(cmp_func) jsdisp_release(cmp_func); return E_FAIL; } } if(!length) { if(cmp_func) jsdisp_release(cmp_func); if(retv) { jsdisp_addref(jsthis); var_set_jsdisp(retv, jsthis); } return S_OK; } vtab = heap_alloc_zero(length * sizeof(VARIANT)); if(vtab) { for(i=0; i<length; i++) { hres = jsdisp_get_idx(jsthis, i, vtab+i, ei); if(hres == DISP_E_UNKNOWNNAME) { V_VT(vtab+i) = VT_EMPTY; hres = S_OK; } else if(FAILED(hres)) { WARN("Could not get elem %d: %08x\n", i, hres); break; } } }else { hres = E_OUTOFMEMORY; } if(SUCCEEDED(hres)) { sorttab = heap_alloc(length*2*sizeof(VARIANT*)); if(!sorttab) hres = E_OUTOFMEMORY; } /* merge-sort */ if(SUCCEEDED(hres)) { VARIANT *tmpv, **tmpbuf; INT cmp; tmpbuf = sorttab + length; for(i=0; i < length; i++) sorttab[i] = vtab+i; for(i=0; i < length/2; i++) { hres = sort_cmp(ctx, cmp_func, sorttab[2*i+1], sorttab[2*i], ei, &cmp); if(FAILED(hres)) break; if(cmp < 0) { tmpv = sorttab[2*i]; sorttab[2*i] = sorttab[2*i+1]; sorttab[2*i+1] = tmpv; } } if(SUCCEEDED(hres)) { DWORD k, a, b, bend; for(k=2; k < length; k *= 2) { for(i=0; i+k < length; i += 2*k) { a = b = 0; if(i+2*k <= length) bend = k; else bend = length - (i+k); memcpy(tmpbuf, sorttab+i, k*sizeof(VARIANT*)); while(a < k && b < bend) { hres = sort_cmp(ctx, cmp_func, tmpbuf[a], sorttab[i+k+b], ei, &cmp); if(FAILED(hres)) break; if(cmp < 0) { sorttab[i+a+b] = tmpbuf[a]; a++; }else { sorttab[i+a+b] = sorttab[i+k+b]; b++; } } if(FAILED(hres)) break; if(a < k) memcpy(sorttab+i+a+b, tmpbuf+a, (k-a)*sizeof(VARIANT*)); } if(FAILED(hres)) break; } } for(i=0; SUCCEEDED(hres) && i < length; i++) hres = jsdisp_propput_idx(jsthis, i, sorttab[i], ei); } if(vtab) { for(i=0; i < length; i++) VariantClear(vtab+i); heap_free(vtab); } heap_free(sorttab); if(cmp_func) jsdisp_release(cmp_func); if(FAILED(hres)) return hres; if(retv) { jsdisp_addref(jsthis); var_set_jsdisp(retv, jsthis); } return S_OK; }
/* ECMA-262 3rd Edition 15.4.4.11 */ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *jsthis, *cmp_func = NULL; jsval_t *vtab, **sorttab = NULL; DWORD length; DWORD i; HRESULT hres = S_OK; TRACE("\n"); hres = get_length(ctx, vthis, &jsthis, &length); if(FAILED(hres)) return hres; if(argc > 1) { WARN("invalid arg_cnt %d\n", argc); return E_FAIL; } if(argc == 1) { if(!is_object_instance(argv[0])) { WARN("arg is not dispatch\n"); return E_FAIL; } cmp_func = iface_to_jsdisp((IUnknown*)get_object(argv[0])); if(!cmp_func || !is_class(cmp_func, JSCLASS_FUNCTION)) { WARN("cmp_func is not a function\n"); if(cmp_func) jsdisp_release(cmp_func); return E_FAIL; } } if(!length) { if(cmp_func) jsdisp_release(cmp_func); if(r) *r = jsval_obj(jsdisp_addref(jsthis)); return S_OK; } vtab = heap_alloc_zero(length * sizeof(*vtab)); if(vtab) { for(i=0; i<length; i++) { hres = jsdisp_get_idx(jsthis, i, vtab+i); if(hres == DISP_E_UNKNOWNNAME) { vtab[i] = jsval_undefined(); hres = S_OK; } else if(FAILED(hres)) { WARN("Could not get elem %d: %08x\n", i, hres); break; } } }else { hres = E_OUTOFMEMORY; } if(SUCCEEDED(hres)) { sorttab = heap_alloc(length*2*sizeof(*sorttab)); if(!sorttab) hres = E_OUTOFMEMORY; } /* merge-sort */ if(SUCCEEDED(hres)) { jsval_t *tmpv, **tmpbuf; INT cmp; tmpbuf = sorttab + length; for(i=0; i < length; i++) sorttab[i] = vtab+i; for(i=0; i < length/2; i++) { hres = sort_cmp(ctx, cmp_func, *sorttab[2*i+1], *sorttab[2*i], &cmp); if(FAILED(hres)) break; if(cmp < 0) { tmpv = sorttab[2*i]; sorttab[2*i] = sorttab[2*i+1]; sorttab[2*i+1] = tmpv; } } if(SUCCEEDED(hres)) { DWORD k, a, b, bend; for(k=2; k < length; k *= 2) { for(i=0; i+k < length; i += 2*k) { a = b = 0; if(i+2*k <= length) bend = k; else bend = length - (i+k); memcpy(tmpbuf, sorttab+i, k*sizeof(jsval_t*)); while(a < k && b < bend) { hres = sort_cmp(ctx, cmp_func, *tmpbuf[a], *sorttab[i+k+b], &cmp); if(FAILED(hres)) break; if(cmp < 0) { sorttab[i+a+b] = tmpbuf[a]; a++; }else { sorttab[i+a+b] = sorttab[i+k+b]; b++; } } if(FAILED(hres)) break; if(a < k) memcpy(sorttab+i+a+b, tmpbuf+a, (k-a)*sizeof(jsval_t*)); } if(FAILED(hres)) break; } } for(i=0; SUCCEEDED(hres) && i < length; i++) hres = jsdisp_propput_idx(jsthis, i, *sorttab[i]); } if(vtab) { for(i=0; i < length; i++) jsval_release(vtab[i]); heap_free(vtab); } heap_free(sorttab); if(cmp_func) jsdisp_release(cmp_func); if(FAILED(hres)) return hres; if(r) *r = jsval_obj(jsdisp_addref(jsthis)); return S_OK; }
void loop() { int type = 0; recordedTime = millis(); unsigned long timestamp = (recordedTime-startingTime); //Serial.println( timestamp ); chip.getMotion6( &(a_xyz[0]), &(a_xyz[1]), &(a_xyz[2]), &(g_xyz[0]), &(g_xyz[1]), &(g_xyz[2]) ); data[ head ] = data[ head ] + a_xyz[0] / 16384; data[ head + 1 ] = data[ head + 1 ] + a_xyz[1] / 16384; data[ head + 2 ] = data[ head + 2 ] + a_xyz[2] / 16384; data[ head + 3 ] = data[ head + 3 ] + g_xyz[0] * 250 / 32768; data[ head + 4 ] = data[ head + 4 ] + g_xyz[1] * 250 / 32768; data[ head + 5 ] = data[ head + 5 ] + g_xyz[2] * 250 / 32768; n++; // Move onto next 5th time segment (1 time segment = 3 seconds) if ( timestamp > 600 ) { float data_in_order[ 30 ]; // Update startingTime as soon as possible startingTime = millis(); Serial.print("---"); data[ head ] = data[ head ] / n; data[ head + 1 ] = data[ head + 1 ] / n; data[ head + 2 ] = data[ head + 2 ] / n; data[ head + 3 ] = data[ head + 3 ] / n; data[ head + 4 ] = data[ head + 4 ] / n; data[ head + 5 ] = data[ head + 5 ] / n; // Update n, head n = 0; if (head == 24) head = 0; else head = head + 6; // Shuffle circular buffer into the correct order // Unfortunately, for loops are slow so.... data_in_order[0] = data[ head ]; data_in_order[1] = data[ (head + 1) % 30 ]; data_in_order[2] = data[ (head + 2) % 30 ]; data_in_order[3] = data[ (head + 3) % 30 ]; data_in_order[4] = data[ (head + 4) % 30 ]; data_in_order[5] = data[ (head + 5) % 30 ]; data_in_order[6] = data[ (head + 6) % 30 ]; data_in_order[7] = data[ (head + 7) % 30 ]; data_in_order[8] = data[ (head + 8) % 30 ]; data_in_order[9] = data[ (head + 9) % 30 ]; data_in_order[10] = data[ (head + 10) % 30 ]; data_in_order[11] = data[ (head + 11) % 30 ]; data_in_order[12] = data[ (head + 12) % 30 ]; data_in_order[13] = data[ (head + 13) % 30 ]; data_in_order[14] = data[ (head + 14) % 30 ]; data_in_order[15] = data[ (head + 15) % 30 ]; data_in_order[16] = data[ (head + 16) % 30 ]; data_in_order[17] = data[ (head + 17) % 30 ]; data_in_order[18] = data[ (head + 18) % 30 ]; data_in_order[19] = data[ (head + 19) % 30 ]; data_in_order[20] = data[ (head + 20) % 30 ]; data_in_order[21] = data[ (head + 21) % 30 ]; data_in_order[22] = data[ (head + 22) % 30 ]; data_in_order[23] = data[ (head + 23) % 30 ]; data_in_order[24] = data[ (head + 24) % 30 ]; data_in_order[25] = data[ (head + 25) % 30 ]; data_in_order[26] = data[ (head + 26) % 30 ]; data_in_order[27] = data[ (head + 27) % 30 ]; data_in_order[28] = data[ (head + 28) % 30 ]; data_in_order[29] = data[ (head + 29) % 30 ]; // Classification if (is_class( data_in_order, forehand )) // type = type + 2; Serial.print( "Forehand " ); else Serial.print( "Backhand " ); if (is_class( data_in_order, drive )) // type = type + 1; Serial.println( "drive" ); else Serial.println( "chop" ); // Serial.println(type); data[ head ] = 0; data[ head + 1 ] = 0; data[ head + 2 ] = 0; data[ head + 3 ] = 0; data[ head + 4 ] = 0; data[ head + 5 ] = 0; } }
inline value create_object(HVM vm, const char* class_path ) { value cls = value_by_path(vm, class_path); assert( is_class(vm,cls) ); return ni()->create_object(vm, cls); }