/* ECMA-262 5.1 Edition 15.12.3 (abstract operation JA) */ static HRESULT stringify_array(stringify_ctx_t *ctx, jsdisp_t *obj) { unsigned length, i, j; jsval_t val; HRESULT hres; if(is_on_stack(ctx, obj)) { FIXME("Found a cycle\n"); return E_FAIL; } if(!stringify_push_obj(ctx, obj)) return E_OUTOFMEMORY; if(!append_char(ctx, '[')) return E_OUTOFMEMORY; length = array_get_length(obj); for(i=0; i < length; i++) { if(i && !append_char(ctx, ',')) return E_OUTOFMEMORY; if(*ctx->gap) { if(!append_char(ctx, '\n')) return E_OUTOFMEMORY; for(j=0; j < ctx->stack_top; j++) { if(!append_string(ctx, ctx->gap)) return E_OUTOFMEMORY; } } hres = jsdisp_get_idx(obj, i, &val); if(FAILED(hres)) return hres; hres = stringify(ctx, val); if(FAILED(hres)) return hres; if(hres == S_FALSE && !append_string(ctx, nullW)) return E_OUTOFMEMORY; } if((length && *ctx->gap && !append_char(ctx, '\n')) || !append_char(ctx, ']')) return E_OUTOFMEMORY; stringify_pop_obj(ctx); return S_OK; }
int release_slot(memblock_t *mb, void **slot) { assert(NULL != mb); assert(is_valid_memblock(mb)); // make sure the given pointer is an actual slot const size_t offset = *slot - mb->ptr; assert(offset > 0); // make sure the offset is a multiple of the unit size assert(offset % mb->unit_size == 0); const size_t index = offset / mb->unit_size; // make sure the index does not cross the array boundary assert(index < mb->n_units); // make sure it's been acquired beforehand // there's know efficient way without introducing another data structure // FIXME releasing a slot twice will f**k up the entire thing assert(!is_on_stack(mb, *slot)); // // put it on the stack // // make sure that there's still space on the stack assert(mb->stack_top < mb->stack_end); assert(is_valid_memblock(mb)); // advance the stack "pointer" to the next free position mb->stack_top++; *mb->stack_top = *slot; // invalidate the given pointer to render the slot unreachable *slot = NULL; // now that we've just put an item on the stack, it's certainly // not empty mb->stack_empty = 0; return 1; }
/* ECMA-262 5.1 Edition 15.12.3 (abstract operation JO) */ static HRESULT stringify_object(stringify_ctx_t *ctx, jsdisp_t *obj) { DISPID dispid = DISPID_STARTENUM; jsval_t val = jsval_undefined(); unsigned prop_cnt = 0, i; size_t stepback; BSTR prop_name; HRESULT hres; if(is_on_stack(ctx, obj)) { FIXME("Found a cycle\n"); return E_FAIL; } if(!stringify_push_obj(ctx, obj)) return E_OUTOFMEMORY; if(!append_char(ctx, '{')) return E_OUTOFMEMORY; while((hres = IDispatchEx_GetNextDispID(&obj->IDispatchEx_iface, fdexEnumDefault, dispid, &dispid)) == S_OK) { jsval_release(val); hres = jsdisp_propget(obj, dispid, &val); if(FAILED(hres)) return hres; if(is_undefined(val)) continue; stepback = ctx->buf_len; if(prop_cnt && !append_char(ctx, ',')) { hres = E_OUTOFMEMORY; break; } if(*ctx->gap) { if(!append_char(ctx, '\n')) { hres = E_OUTOFMEMORY; break; } for(i=0; i < ctx->stack_top; i++) { if(!append_string(ctx, ctx->gap)) { hres = E_OUTOFMEMORY; break; } } } hres = IDispatchEx_GetMemberName(&obj->IDispatchEx_iface, dispid, &prop_name); if(FAILED(hres)) break; hres = json_quote(ctx, prop_name, SysStringLen(prop_name)); SysFreeString(prop_name); if(FAILED(hres)) break; if(!append_char(ctx, ':') || (*ctx->gap && !append_char(ctx, ' '))) { hres = E_OUTOFMEMORY; break; } hres = stringify(ctx, val); if(FAILED(hres)) break; if(hres == S_FALSE) { ctx->buf_len = stepback; continue; } prop_cnt++; } jsval_release(val); if(FAILED(hres)) return hres; if(prop_cnt && *ctx->gap) { if(!append_char(ctx, '\n')) return E_OUTOFMEMORY; for(i=1; i < ctx->stack_top; i++) { if(!append_string(ctx, ctx->gap)) { hres = E_OUTOFMEMORY; break; } } } if(!append_char(ctx, '}')) return E_OUTOFMEMORY; stringify_pop_obj(ctx); return S_OK; }
bool is_unused(Assembler::Register reg) { return !is_on_stack(reg); }