/* duk_del_prop_index(), success cases */ static duk_ret_t test_delpropindex_a_safecall(duk_context *ctx, void *udata) { duk_ret_t rc; (void) udata; prep(ctx); rc = duk_del_prop_index(ctx, 0, 31337); printf("delete obj[31337] -> rc=%d\n", (int) rc); rc = duk_del_prop_index(ctx, 0, 123); printf("delete obj[123] -> rc=%d\n", (int) rc); rc = duk_del_prop_index(ctx, 1, 31337); printf("delete arr[31337] -> rc=%d\n", (int) rc); rc = duk_del_prop_index(ctx, 1, 2); printf("delete arr[2] -> rc=%d\n", (int) rc); duk_json_encode(ctx, 0); printf("final object: %s\n", duk_to_string(ctx, 0)); duk_json_encode(ctx, 1); printf("final array: %s\n", duk_to_string(ctx, 1)); printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
/* duk_del_prop_index(), success cases */ int test_3a(duk_context *ctx) { int rc; prep(ctx); rc = duk_del_prop_index(ctx, 0, 31337); printf("delete obj[31337] -> rc=%d\n", rc); rc = duk_del_prop_index(ctx, 0, 123); printf("delete obj[123] -> rc=%d\n", rc); rc = duk_del_prop_index(ctx, 1, 31337); printf("delete arr[31337] -> rc=%d\n", rc); rc = duk_del_prop_index(ctx, 1, 2); printf("delete arr[2] -> rc=%d\n", rc); rc = duk_del_prop_index(ctx, 2, 5); printf("delete 'test_string'[5] -> rc=%d\n", rc); duk_json_encode(ctx, 0); printf("final object: %s\n", duk_to_string(ctx, 0)); duk_json_encode(ctx, 1); printf("final array: %s\n", duk_to_string(ctx, 1)); printf("final top: %d\n", duk_get_top(ctx)); return 0; }
DUK_LOCAL void duk__array_sort_swap(duk_context *ctx, duk_int_t l, duk_int_t r) { duk_bool_t have_l, have_r; duk_idx_t idx_obj = 1; /* fixed offset in valstack */ if (l == r) { return; } /* swap elements; deal with non-existent elements correctly */ have_l = duk_get_prop_index(ctx, idx_obj, (duk_uarridx_t) l); have_r = duk_get_prop_index(ctx, idx_obj, (duk_uarridx_t) r); if (have_r) { /* right exists, [[Put]] regardless whether or not left exists */ duk_put_prop_index(ctx, idx_obj, (duk_uarridx_t) l); } else { duk_del_prop_index(ctx, idx_obj, (duk_uarridx_t) l); duk_pop(ctx); } if (have_l) { duk_put_prop_index(ctx, idx_obj, (duk_uarridx_t) r); } else { duk_del_prop_index(ctx, idx_obj, (duk_uarridx_t) r); duk_pop(ctx); } }
void JSEventDispatcher::EndSendEvent(Context* context, Object* sender, StringHash eventType, VariantMap& eventData) { if (!jsEvents_.Contains(eventType)) return; JSVM* vm = JSVM::GetJSVM(NULL); if (!vm) return; duk_context* ctx = vm->GetJSContext(); duk_push_global_stash(ctx); duk_get_prop_index(ctx, -1, JS_GLOBALSTASH_VARIANTMAP_CACHE); duk_push_pointer(ctx, (void*) &eventData); duk_get_prop(ctx, -2); // If this issue is addressed, revisit this to simply remove // the variantmap object from the cache, if the user explicitly // keeps the event object alive in a local closure, that is allowed // (though, will keep object properties from being GC'd) // https://github.com/svaarala/duktape/issues/229 // Ok, this is unfortunate, in an event callback it is possible // to capture the Proxy object which represents the event VariantMap // in a function() {} closure, which will keep the event data alive // until the function happens to be gc'd (it is a member of the eventhandler) // which will leave things like scenes up if there was a P_SCENE event data // member, etc // So, we need to check if we have an object in the variant map cache // and thense call it's delete property method on the Proxy, which will clear // all the data (the proxy can still be alive as a captured local, though // the members won't be held // This all makes it that much more important that the pointer to eventData // is consistent across entire event, otherwise references may be held // see note above about: https://github.com/svaarala/duktape/issues/229 if (duk_is_object(ctx, -1)) { // deletes all properties, thus freeing references, even if // the variant map object is held onto by script (it will be invalid, post // event send) // see JSAPI.cpp variantmap_property_deleteproperty duk_del_prop_index(ctx, -1, 0); duk_push_pointer(ctx, (void*) &eventData); duk_push_undefined(ctx); // clear the variant map object from the cache duk_put_prop(ctx, -4); } duk_pop_3(ctx); }
DUK_INTERNAL duk_ret_t duk_bi_array_prototype_reverse(duk_context *ctx) { duk_uint32_t len; duk_uint32_t middle; duk_uint32_t lower, upper; duk_bool_t have_lower, have_upper; len = duk__push_this_obj_len_u32(ctx); middle = len / 2; /* If len <= 1, middle will be 0 and for-loop bails out * immediately (0 < 0 -> false). */ for (lower = 0; lower < middle; lower++) { DUK_ASSERT(len >= 2); DUK_ASSERT_TOP(ctx, 2); DUK_ASSERT(len >= lower + 1); upper = len - lower - 1; have_lower = duk_get_prop_index(ctx, -2, (duk_uarridx_t) lower); have_upper = duk_get_prop_index(ctx, -3, (duk_uarridx_t) upper); /* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */ if (have_upper) { duk_put_prop_index(ctx, -4, (duk_uarridx_t) lower); } else { duk_del_prop_index(ctx, -4, (duk_uarridx_t) lower); duk_pop(ctx); } if (have_lower) { duk_put_prop_index(ctx, -3, (duk_uarridx_t) upper); } else { duk_del_prop_index(ctx, -3, (duk_uarridx_t) upper); duk_pop(ctx); } DUK_ASSERT_TOP(ctx, 2); } DUK_ASSERT_TOP(ctx, 2); duk_pop(ctx); /* -> [ ToObject(this) ] */ return 1; }
DUK_INTERNAL duk_ret_t duk_bi_array_prototype_unshift(duk_context *ctx) { duk_idx_t nargs; duk_uint32_t len; duk_uint32_t i; nargs = duk_get_top(ctx); len = duk__push_this_obj_len_u32(ctx); /* stack[0...nargs-1] = unshift args (vararg) * stack[nargs] = ToObject(this) * stack[nargs+1] = ToUint32(length) */ DUK_ASSERT_TOP(ctx, nargs + 2); /* Note: unshift() may operate on indices above unsigned 32-bit range * and the final length may be >= 2**32. However, we restrict the * final result to 32-bit range for practicality. */ if (len + (duk_uint32_t) nargs < len) { DUK_D(DUK_DPRINT("Array.prototype.unshift() would go beyond 32-bit length, throw")); return DUK_RET_RANGE_ERROR; } i = len; while (i > 0) { DUK_ASSERT_TOP(ctx, nargs + 2); i--; /* k+argCount-1; note that may be above 32-bit range */ if (duk_get_prop_index(ctx, -2, (duk_uarridx_t) i)) { /* fromPresent = true */ /* [ ... ToObject(this) ToUint32(length) val ] */ duk_put_prop_index(ctx, -3, (duk_uarridx_t) (i + nargs)); /* -> [ ... ToObject(this) ToUint32(length) ] */ } else { /* fromPresent = false */ /* [ ... ToObject(this) ToUint32(length) val ] */ duk_pop(ctx); duk_del_prop_index(ctx, -2, (duk_uarridx_t) (i + nargs)); /* -> [ ... ToObject(this) ToUint32(length) ] */ } DUK_ASSERT_TOP(ctx, nargs + 2); } for (i = 0; i < (duk_uint32_t) nargs; i++) { DUK_ASSERT_TOP(ctx, nargs + 2); duk_dup(ctx, i); /* -> [ ... ToObject(this) ToUint32(length) arg[i] ] */ duk_put_prop_index(ctx, -3, (duk_uarridx_t) i); DUK_ASSERT_TOP(ctx, nargs + 2); } DUK_ASSERT_TOP(ctx, nargs + 2); duk_push_u32(ctx, len + nargs); duk_dup_top(ctx); /* -> [ ... ToObject(this) ToUint32(length) final_len final_len ] */ duk_put_prop_stridx(ctx, -4, DUK_STRIDX_LENGTH); return 1; }
/* duk_del_prop_index(), DUK_INVALID_INDEX */ static duk_ret_t test_delpropindex_d(duk_context *ctx) { duk_ret_t rc; prep(ctx); rc = duk_del_prop_index(ctx, DUK_INVALID_INDEX, 123); printf("delete obj[123] -> rc=%d\n", (int) rc); printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
/* duk_del_prop_index(), DUK_INVALID_INDEX */ int test_3d(duk_context *ctx) { int rc; prep(ctx); rc = duk_del_prop_index(ctx, DUK_INVALID_INDEX, 123); printf("delete obj[123] -> rc=%d\n", rc); printf("final top: %d\n", duk_get_top(ctx)); return 0; }
/* duk_del_prop_index(), non-configurable virtual property of a plain string, * called from inside a Duktape/C context. */ int test_3b(duk_context *ctx) { int rc; prep(ctx); rc = duk_del_prop_index(ctx, 2, 5); printf("delete 'test_string'[5] -> rc=%d\n", rc); printf("final top: %d\n", duk_get_top(ctx)); return 0; }
/* duk_del_prop_index(), invalid index */ static duk_ret_t test_3c(duk_context *ctx) { duk_ret_t rc; prep(ctx); rc = duk_del_prop_index(ctx, 234, 123); printf("delete obj[123] -> rc=%d\n", (int) rc); printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
/* duk_del_prop_index(), non-configurable virtual property of a plain string. * Same behavior when called inside/outside of a Duktape/C activation. */ static duk_ret_t test_delpropindex_b(duk_context *ctx) { duk_ret_t rc; prep(ctx); rc = duk_del_prop_index(ctx, 2, 5); printf("delete 'test_string'[5] -> rc=%d\n", (int) rc); printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
int duk_bi_array_prototype_reverse(duk_context *ctx) { unsigned int len; unsigned int middle; unsigned int lower, upper; int have_lower, have_upper; len = duk__push_this_obj_len_u32(ctx); middle = len / 2; for (lower = 0; lower < middle; lower++) { DUK_ASSERT_TOP(ctx, 2); upper = len - lower - 1; have_lower = duk_get_prop_index(ctx, -2, lower); have_upper = duk_get_prop_index(ctx, -3, upper); /* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */ if (have_upper) { duk_put_prop_index(ctx, -4, lower); /* FIXME: Throw */ } else { duk_del_prop_index(ctx, -4, lower); duk_pop(ctx); } if (have_lower) { duk_put_prop_index(ctx, -3, upper); } else { duk_del_prop_index(ctx, -3, upper); duk_pop(ctx); } DUK_ASSERT_TOP(ctx, 2); } DUK_ASSERT_TOP(ctx, 2); duk_pop(ctx); /* -> [ ToObject(this) ] */ return 1; }
int duk_bi_array_prototype_shift(duk_context *ctx) { unsigned int len; unsigned int i; len = duk__push_this_obj_len_u32(ctx); if (len == 0) { duk_push_int(ctx, 0); duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH); /* FIXME: Throw */ return 0; } duk_get_prop_index(ctx, 0, 0); /* stack[0] = object (this) * stack[1] = ToUint32(length) * stack[2] = elem at index 0 (retval) */ for (i = 1; i < len; i++) { DUK_ASSERT_TOP(ctx, 3); if (duk_get_prop_index(ctx, 0, i)) { /* fromPresent = true */ duk_put_prop_index(ctx, 0, i - 1); /* FIXME: Throw */ } else { /* fromPresent = false */ duk_del_prop_index(ctx, 0, i - 1); duk_pop(ctx); } } duk_del_prop_index(ctx, 0, len - 1); /* FIXME: Throw */ duk_push_number(ctx, (double) (len - 1)); /* FIXME: push uint */ duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH); DUK_ASSERT_TOP(ctx, 3); return 1; }
DUK_INTERNAL duk_ret_t duk_bi_array_prototype_shift(duk_context *ctx) { duk_uint32_t len; duk_uint32_t i; len = duk__push_this_obj_len_u32(ctx); if (len == 0) { duk_push_int(ctx, 0); duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH); return 0; } duk_get_prop_index(ctx, 0, 0); /* stack[0] = object (this) * stack[1] = ToUint32(length) * stack[2] = elem at index 0 (retval) */ for (i = 1; i < len; i++) { DUK_ASSERT_TOP(ctx, 3); if (duk_get_prop_index(ctx, 0, (duk_uarridx_t) i)) { /* fromPresent = true */ duk_put_prop_index(ctx, 0, (duk_uarridx_t) (i - 1)); } else { /* fromPresent = false */ duk_del_prop_index(ctx, 0, (duk_uarridx_t) (i - 1)); duk_pop(ctx); } } duk_del_prop_index(ctx, 0, (duk_uarridx_t) (len - 1)); duk_push_u32(ctx, (duk_uint32_t) (len - 1)); duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH); DUK_ASSERT_TOP(ctx, 3); return 1; }
static int ClearTriggerCallback(duk_context* ctx, int pinFunc, AJS_IO_PinTriggerCondition condition) { int32_t trigId; AJS_TargetIO_PinDisableTrigger(PinCtxPtr(ctx), pinFunc, condition, &trigId); if (trigId != AJS_IO_PIN_NO_TRIGGER) { duk_get_global_string(ctx, AJS_IOObjectName); duk_get_prop_string(ctx, -1, AJS_HIDDEN_PROP("trigs")); duk_del_prop_index(ctx, -1, trigId); duk_pop_2(ctx); } duk_push_this(ctx); duk_del_prop_string(ctx, -1, "trigger"); /* * Leave pin object on the stack */ return 1; }
int duk_bi_array_prototype_pop(duk_context *ctx) { unsigned int len; unsigned int idx; DUK_ASSERT_TOP(ctx, 0); len = duk__push_this_obj_len_u32(ctx); if (len == 0) { duk_push_int(ctx, 0); duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH); /* FIXME: Throw */ return 0; } idx = len - 1; duk_get_prop_index(ctx, 0, idx); duk_del_prop_index(ctx, 0, idx); /* FIXME: Throw */ duk_push_int(ctx, idx); /* FIXME: unsigned */ duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH); /* FIXME: Throw */ return 1; }
DUK_INTERNAL duk_ret_t duk_bi_array_prototype_pop(duk_context *ctx) { duk_uint32_t len; duk_uint32_t idx; DUK_ASSERT_TOP(ctx, 0); len = duk__push_this_obj_len_u32(ctx); if (len == 0) { duk_push_int(ctx, 0); duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH); return 0; } idx = len - 1; duk_get_prop_index(ctx, 0, (duk_uarridx_t) idx); duk_del_prop_index(ctx, 0, (duk_uarridx_t) idx); duk_push_u32(ctx, idx); duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LENGTH); return 1; }
JavaScriptObject::~JavaScriptObject() { if (!m_instance) { // Instance has already been cleaned up. return; } // The instance still exists - detach from it. duk_push_global_object(m_context); duk_push_heapptr(m_context, m_instance); // Remove this pointer from the JS object's property. if (duk_get_prop_string(m_context, -1, WRAPPER_THIS_PROP_NAME)) { const duk_size_t length = duk_get_length(m_context, -1); for (duk_uarridx_t i = 0; i < length; ++i) { duk_get_prop_index(m_context, -1, i); const void* ptr = duk_get_pointer(m_context, -1); duk_pop(m_context); if (this == ptr) { // Remove this object from the array. duk_del_prop_index(m_context, -1, i); break; } } } // Pop the array (or undefined if there was none). duk_pop(m_context); if (m_nextFinalizer) { // Reset to the object's previous finalizer. duk_push_c_function(m_context, m_nextFinalizer, 1); duk_set_finalizer(m_context, -2); } // Pop the instance & global object. duk_pop_2(m_context); }
/* * Called with "sessions" at the top of the stack. * * Iterate over the accumulated announcents and make callbacks into JavaScript */ static void AnnouncementCallbacks(duk_context* ctx, const char* peer, SessionInfo* sessionInfo) { size_t i; size_t numSvcs; AJ_ASSERT(sessionInfo->sessionId); /* * Get the session object (indexed by the peer string) and from this get the announcements array */ duk_get_prop_string(ctx, -1, peer); duk_get_prop_string(ctx, -1, "anno"); /* * Iterate over the services implemented by this peer */ numSvcs = duk_get_length(ctx, -1); for (i = 0; i < numSvcs; ++i) { size_t j; size_t numIfaces; duk_idx_t svcIdx; duk_get_prop_index(ctx, -1, i); if (duk_is_undefined(ctx, -1)) { /* * Undefined means the iface has been deleted so pop "interfaces" */ duk_pop(ctx); /* * Delete the announcement entry and continue */ duk_del_prop_index(ctx, -1, i); continue; } svcIdx = duk_get_top_index(ctx); /* * Iterate over the interfaces for this service */ duk_get_prop_string(ctx, svcIdx, "interfaces"); numIfaces = duk_get_length(ctx, -1); for (j = 0; j < numIfaces; ++j) { const char* iface; duk_get_prop_index(ctx, -1, j); iface = duk_get_string(ctx, -1); duk_pop(ctx); /* * If there is a callback registered for this interface call it * * TODO - should we really make a callback for each interface or just call the first one * that has an callback referenced. If the same callback function has been registered * for multiple interfaces we definitely don't want to call it multiple times. */ if (PushServiceCallback(ctx, iface)) { /* * Set the session information on the service */ duk_push_int(ctx, sessionInfo->sessionId); duk_put_prop_string(ctx, svcIdx, "session"); duk_push_string(ctx, peer); duk_put_prop_string(ctx, svcIdx, "dest"); /* * Call the callback function */ duk_dup(ctx, svcIdx); if (duk_pcall(ctx, 1) != DUK_EXEC_SUCCESS) { AJS_ConsoleSignalError(ctx); } duk_pop(ctx); } } /* * Pop "interfaces" and the service object */ duk_pop_2(ctx); /* * Delete the announcement entry */ duk_del_prop_index(ctx, -1, i); } /* Pop "anno" and the session object */ duk_pop_2(ctx); }
static duk_ret_t test_func(duk_context *ctx, void *udata) { (void) udata; if (ctx) { printf("dummy - return here\n"); fflush(stdout); return 0; } /* Up-to-date for Duktape 1.3.0, alphabetical order: * $ cd website/api; ls *.yaml */ (void) duk_alloc_raw(ctx, 0); (void) duk_alloc(ctx, 0); (void) duk_base64_decode(ctx, 0); (void) duk_base64_encode(ctx, 0); (void) duk_buffer_to_string(ctx, 0); (void) duk_call_method(ctx, 0); (void) duk_call_prop(ctx, 0, 0); (void) duk_call(ctx, 0); (void) duk_char_code_at(ctx, 0, 0); (void) duk_check_stack_top(ctx, 0); (void) duk_check_stack(ctx, 0); (void) duk_check_type_mask(ctx, 0, 0); (void) duk_check_type(ctx, 0, 0); (void) duk_compact(ctx, 0); (void) duk_compile_lstring_filename(ctx, 0, "dummy", 0); (void) duk_compile_lstring(ctx, 0, "dummy", 0); (void) duk_compile_string_filename(ctx, 0, "dummy"); (void) duk_compile_string(ctx, 0, "dummy"); (void) duk_compile(ctx, 0); (void) duk_concat(ctx, 0); (void) duk_config_buffer(ctx, 0, NULL, 0); (void) duk_copy(ctx, 0, 0); (void) duk_create_heap_default(); (void) duk_create_heap(NULL, NULL, NULL, NULL, NULL); (void) duk_debugger_attach(ctx, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); (void) duk_debugger_cooperate(ctx); (void) duk_debugger_detach(ctx); (void) duk_debugger_notify(ctx, 0); (void) duk_debugger_pause(ctx); (void) duk_decode_string(ctx, 0, NULL, NULL); (void) duk_def_prop(ctx, 0, 0); (void) duk_del_prop_index(ctx, 0, 0); (void) duk_del_prop_string(ctx, 0, "dummy"); (void) duk_del_prop(ctx, 0); (void) duk_destroy_heap(ctx); (void) duk_dump_function(ctx); (void) duk_dup_top(ctx); (void) duk_dup(ctx, 0); (void) duk_enum(ctx, 0, 0); (void) duk_equals(ctx, 0, 0); duk_error_va(ctx, 0, NULL, NULL); duk_error(ctx, 0, "dummy"); /* (void) cast won't work without variadic macros */ (void) duk_eval_lstring_noresult(ctx, "dummy", 0); (void) duk_eval_lstring(ctx, "dummy", 0); (void) duk_eval_noresult(ctx); (void) duk_eval_string_noresult(ctx, "dummy"); (void) duk_eval_string(ctx, "dummy"); (void) duk_eval(ctx); (void) duk_fatal(ctx, "dummy"); (void) duk_free_raw(ctx, NULL); (void) duk_free(ctx, NULL); (void) duk_gc(ctx, 0); (void) duk_get_boolean(ctx, 0); (void) duk_get_buffer_data(ctx, 0, NULL); (void) duk_get_buffer(ctx, 0, NULL); (void) duk_get_c_function(ctx, 0); (void) duk_get_context(ctx, 0); (void) duk_get_current_magic(ctx); (void) duk_get_error_code(ctx, 0); (void) duk_get_finalizer(ctx, 0); (void) duk_get_global_string(ctx, 0); (void) duk_get_heapptr(ctx, 0); (void) duk_get_int(ctx, 0); (void) duk_get_length(ctx, 0); (void) duk_get_lstring(ctx, 0, NULL); (void) duk_get_magic(ctx, 0); (void) duk_get_memory_functions(ctx, NULL); (void) duk_get_number(ctx, 0); (void) duk_get_pointer(ctx, 0); (void) duk_get_prop_index(ctx, 0, 0); (void) duk_get_prop_string(ctx, 0, "dummy"); (void) duk_get_prop(ctx, 0); (void) duk_get_prototype(ctx, 0); (void) duk_get_string(ctx, 0); (void) duk_get_top_index(ctx); (void) duk_get_top(ctx); (void) duk_get_type_mask(ctx, 0); (void) duk_get_type(ctx, 0); (void) duk_get_uint(ctx, 0); (void) duk_has_prop_index(ctx, 0, 0); (void) duk_has_prop_string(ctx, 0, "dummy"); (void) duk_has_prop(ctx, 0); (void) duk_hex_decode(ctx, 0); (void) duk_hex_encode(ctx, 0); (void) duk_insert(ctx, 0); (void) duk_instanceof(ctx, 0, 0); (void) duk_is_array(ctx, 0); (void) duk_is_boolean(ctx, 0); (void) duk_is_bound_function(ctx, 0); (void) duk_is_buffer(ctx, 0); (void) duk_is_callable(ctx, 0); (void) duk_is_c_function(ctx, 0); (void) duk_is_constructor_call(ctx); (void) duk_is_dynamic_buffer(ctx, 0); (void) duk_is_ecmascript_function(ctx, 0); (void) duk_is_error(ctx, 0); (void) duk_is_eval_error(ctx, 0); (void) duk_is_fixed_buffer(ctx, 0); (void) duk_is_function(ctx, 0); (void) duk_is_lightfunc(ctx, 0); (void) duk_is_nan(ctx, 0); (void) duk_is_null_or_undefined(ctx, 0); (void) duk_is_null(ctx, 0); (void) duk_is_number(ctx, 0); (void) duk_is_object_coercible(ctx, 0); (void) duk_is_object(ctx, 0); (void) duk_is_pointer(ctx, 0); (void) duk_is_primitive(ctx, 0); (void) duk_is_range_error(ctx, 0); (void) duk_is_reference_error(ctx, 0); (void) duk_is_strict_call(ctx); (void) duk_is_string(ctx, 0); (void) duk_is_syntax_error(ctx, 0); (void) duk_is_thread(ctx, 0); (void) duk_is_type_error(ctx, 0); (void) duk_is_undefined(ctx, 0); (void) duk_is_uri_error(ctx, 0); (void) duk_is_valid_index(ctx, 0); (void) duk_join(ctx, 0); (void) duk_json_decode(ctx, 0); (void) duk_json_encode(ctx, 0); (void) duk_load_function(ctx); (void) duk_map_string(ctx, 0, NULL, NULL); (void) duk_new(ctx, 0); (void) duk_next(ctx, 0, 0); (void) duk_normalize_index(ctx, 0); (void) duk_pcall_method(ctx, 0); (void) duk_pcall_prop(ctx, 0, 0); (void) duk_pcall(ctx, 0); (void) duk_pcompile_lstring_filename(ctx, 0, "dummy", 0); (void) duk_pcompile_lstring(ctx, 0, "dummy", 0); (void) duk_pcompile_string_filename(ctx, 0, "dummy"); (void) duk_pcompile_string(ctx, 0, "dummy"); (void) duk_pcompile(ctx, 0); (void) duk_peval_lstring_noresult(ctx, "dummy", 0); (void) duk_peval_lstring(ctx, "dummy", 0); (void) duk_peval_noresult(ctx); (void) duk_peval_string_noresult(ctx, "dummy"); (void) duk_peval_string(ctx, "dummy"); (void) duk_peval(ctx); (void) duk_pnew(ctx, 0); (void) duk_pop_2(ctx); (void) duk_pop_3(ctx); (void) duk_pop_n(ctx, 0); (void) duk_pop(ctx); (void) duk_push_array(ctx); (void) duk_push_boolean(ctx, 0); (void) duk_push_buffer_object(ctx, 0, 0, 0, 0); (void) duk_push_buffer(ctx, 0, 0); (void) duk_push_c_function(ctx, NULL, 0); (void) duk_push_c_lightfunc(ctx, NULL, 0, 0, 0); (void) duk_push_context_dump(ctx); (void) duk_push_current_function(ctx); (void) duk_push_current_thread(ctx); (void) duk_push_dynamic_buffer(ctx, 0); (void) duk_push_error_object_va(ctx, 0, NULL, NULL); (void) duk_push_error_object(ctx, 0, "dummy"); (void) duk_push_external_buffer(ctx); (void) duk_push_false(ctx); (void) duk_push_fixed_buffer(ctx, 0); (void) duk_push_global_object(ctx); (void) duk_push_global_stash(ctx); (void) duk_push_heap_stash(ctx); (void) duk_push_heapptr(ctx, NULL); (void) duk_push_int(ctx, 0); (void) duk_push_lstring(ctx, "dummy", 0); (void) duk_push_nan(ctx); (void) duk_push_null(ctx); (void) duk_push_number(ctx, 0.0); (void) duk_push_object(ctx); (void) duk_push_pointer(ctx, NULL); (void) duk_push_sprintf(ctx, "dummy"); (void) duk_push_string(ctx, "dummy"); (void) duk_push_this(ctx); (void) duk_push_thread_new_globalenv(ctx); (void) duk_push_thread_stash(ctx, NULL); (void) duk_push_thread(ctx); (void) duk_push_true(ctx); (void) duk_push_uint(ctx, 0); (void) duk_push_undefined(ctx); (void) duk_push_vsprintf(ctx, "dummy", NULL); (void) duk_put_function_list(ctx, 0, NULL); (void) duk_put_global_string(ctx, NULL); (void) duk_put_number_list(ctx, 0, NULL); (void) duk_put_prop_index(ctx, 0, 0); (void) duk_put_prop_string(ctx, 0, "dummy"); (void) duk_put_prop(ctx, 0); (void) duk_realloc_raw(ctx, NULL, 0); (void) duk_realloc(ctx, NULL, 0); (void) duk_remove(ctx, 0); (void) duk_replace(ctx, 0); (void) duk_require_boolean(ctx, 0); (void) duk_require_buffer_data(ctx, 0, NULL); (void) duk_require_buffer(ctx, 0, NULL); (void) duk_require_c_function(ctx, 0); (void) duk_require_callable(ctx, 0); (void) duk_require_context(ctx, 0); (void) duk_require_function(ctx, 0); (void) duk_require_heapptr(ctx, 0); (void) duk_require_int(ctx, 0); (void) duk_require_lstring(ctx, 0, NULL); (void) duk_require_normalize_index(ctx, 0); (void) duk_require_null(ctx, 0); (void) duk_require_number(ctx, 0); (void) duk_require_object_coercible(ctx, 0); (void) duk_require_pointer(ctx, 0); (void) duk_require_stack_top(ctx, 0); (void) duk_require_stack(ctx, 0); (void) duk_require_string(ctx, 0); (void) duk_require_top_index(ctx); (void) duk_require_type_mask(ctx, 0, 0); (void) duk_require_uint(ctx, 0); (void) duk_require_undefined(ctx, 0); (void) duk_require_valid_index(ctx, 0); (void) duk_resize_buffer(ctx, 0, 0); (void) duk_safe_call(ctx, NULL, NULL, 0, 0); (void) duk_safe_to_lstring(ctx, 0, NULL); (void) duk_safe_to_string(ctx, 0); (void) duk_set_finalizer(ctx, 0); (void) duk_set_global_object(ctx); (void) duk_set_magic(ctx, 0, 0); (void) duk_set_prototype(ctx, 0); (void) duk_set_top(ctx, 0); (void) duk_steal_buffer(ctx, 0, NULL); (void) duk_strict_equals(ctx, 0, 0); (void) duk_substring(ctx, 0, 0, 0); (void) duk_swap_top(ctx, 0); (void) duk_swap(ctx, 0, 0); (void) duk_throw(ctx); (void) duk_to_boolean(ctx, 0); (void) duk_to_buffer(ctx, 0, NULL); (void) duk_to_defaultvalue(ctx, 0, 0); (void) duk_to_dynamic_buffer(ctx, 0, NULL); (void) duk_to_fixed_buffer(ctx, 0, NULL); (void) duk_to_int32(ctx, 0); (void) duk_to_int(ctx, 0); (void) duk_to_lstring(ctx, 0, NULL); (void) duk_to_null(ctx, 0); (void) duk_to_number(ctx, 0); (void) duk_to_object(ctx, 0); (void) duk_to_pointer(ctx, 0); (void) duk_to_primitive(ctx, 0, 0); (void) duk_to_string(ctx, 0); (void) duk_to_uint16(ctx, 0); (void) duk_to_uint32(ctx, 0); (void) duk_to_uint(ctx, 0); (void) duk_to_undefined(ctx, 0); (void) duk_trim(ctx, 0); (void) duk_xcopy_top(ctx, NULL, 0); (void) duk_xmove_top(ctx, NULL, 0); printf("never here\n"); fflush(stdout); return 0; }
//duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index); duk_bool_t aperl_duk_del_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index) { duk_bool_t ret = duk_del_prop_index(ctx, obj_index, arr_index); return ret; }
static AJ_Status HandleMessage(duk_context* ctx, duk_idx_t ajIdx, AJ_Message* msg) { duk_idx_t msgIdx; uint8_t accessor = AJS_NOT_ACCESSOR; const char* func; AJ_Status status; uint8_t ldstate; #if !defined(AJS_CONSOLE_LOCKDOWN) status = AJS_GetLockdownState(&ldstate); if (status == AJ_OK && ldstate == AJS_CONSOLE_UNLOCKED) { status = AJS_ConsoleMsgHandler(ctx, msg); if (status != AJ_ERR_NO_MATCH) { if (status != AJ_OK) { AJ_WarnPrintf(("AJS_ConsoleMsgHandler returned %s\n", AJ_StatusText(status))); } return status; } } #endif /* * JOIN_SESSION replies are handled in the AllJoyn.js layer and don't get passed to JavaScript */ if (msg->msgId == AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION)) { return AJS_HandleJoinSessionReply(ctx, msg); } /* * Nothing more to do if the AllJoyn module was not loaded */ if (ajIdx < 0) { return AJ_OK; } /* * Let the bases services layer take a look at the message */ status = AJS_ServicesMsgHandler(msg); if (status != AJ_ERR_NO_MATCH) { if (status != AJ_OK) { AJ_WarnPrintf(("AJS_ServicesMsgHandler returned %s\n", AJ_StatusText(status))); } return status; } /* * Push the appropriate callback function onto the duktape stack */ if (msg->hdr->msgType == AJ_MSG_SIGNAL) { /* * About announcements and found name signal get special handling */ if (msg->msgId == AJ_SIGNAL_ABOUT_ANNOUNCE) { return AJS_AboutAnnouncement(ctx, msg); } if (msg->msgId == AJ_SIGNAL_FOUND_ADV_NAME) { return AJS_FoundAdvertisedName(ctx, msg); } if ((msg->msgId == AJ_SIGNAL_SESSION_LOST) || (msg->msgId == AJ_SIGNAL_SESSION_LOST_WITH_REASON)) { if (AJS_DebuggerIsAttached()) { msg = AJS_CloneAndCloseMessage(ctx, msg); } return AJS_SessionLost(ctx, msg); } func = "onSignal"; duk_get_prop_string(ctx, ajIdx, func); } else if (msg->hdr->msgType == AJ_MSG_METHOD_CALL) { accessor = IsPropAccessor(msg); switch (accessor) { case AJS_NOT_ACCESSOR: func = "onMethodCall"; break; case AJ_PROP_GET: func = "onPropGet"; break; case AJ_PROP_SET: func = "onPropSet"; break; case AJ_PROP_GET_ALL: func = "onPropGetAll"; break; default: return AJ_ERR_INVALID; } duk_get_prop_string(ctx, ajIdx, func); } else { func = "onReply"; AJS_GetGlobalStashObject(ctx, func); if (duk_is_object(ctx, -1)) { duk_get_prop_index(ctx, -1, msg->replySerial); duk_swap_top(ctx, -2); /* * Clear the onReply entry */ duk_del_prop_index(ctx, -1, msg->replySerial); duk_pop(ctx); } } /* * Skip if there is no function to call. */ if (!duk_is_function(ctx, -1)) { if (msg->hdr->msgType == AJ_MSG_METHOD_CALL) { AJ_Message error; AJ_WarnPrintf(("%s: not registered - rejecting message\n", func)); AJ_MarshalErrorMsg(msg, &error, AJ_ErrRejected); status = AJ_DeliverMsg(&error); } else { AJ_WarnPrintf(("%s: not registered - ignoring message\n", func)); status = AJ_OK; } duk_pop(ctx); return status; } /* * Opens up a stack entry above the function */ duk_dup_top(ctx); msgIdx = AJS_UnmarshalMessage(ctx, msg, accessor); AJ_ASSERT(msgIdx == (ajIdx + 3)); /* * Save the message object on the stack */ duk_copy(ctx, msgIdx, -3); /* * Special case for GET prop so we can get the signature for marshalling the result */ if (accessor == AJS_NOT_ACCESSOR) { status = AJS_UnmarshalMsgArgs(ctx, msg); } else { status = AJS_UnmarshalPropArgs(ctx, msg, accessor, msgIdx); } if (status == AJ_OK) { duk_idx_t numArgs = duk_get_top(ctx) - msgIdx - 1; /* * If attached, the debugger will begin to unmarshal a message when the * method handler is called, therefore it must be cloned-and-closed now. */ if (AJS_DebuggerIsAttached()) { msg = AJS_CloneAndCloseMessage(ctx, msg); } if (duk_pcall_method(ctx, numArgs) != DUK_EXEC_SUCCESS) { const char* err = duk_safe_to_string(ctx, -1); AJ_ErrPrintf(("%s: %s\n", func, err)); /* * Generate an error reply if this was a method call */ if (msg->hdr->msgType == AJ_MSG_METHOD_CALL) { duk_push_c_lightfunc(ctx, AJS_MethodCallError, 1, 0, 0); duk_insert(ctx, -3); (void)duk_pcall_method(ctx, 1); } } } /* * Cleanup stack back to the AJ object */ duk_set_top(ctx, ajIdx + 1); return status; }
DUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) { duk_idx_t nargs; duk_uint32_t len; duk_bool_t have_delcount; duk_int_t item_count; duk_int_t act_start; duk_int_t del_count; duk_int_t i, n; DUK_UNREF(have_delcount); nargs = duk_get_top(ctx); if (nargs < 2) { duk_set_top(ctx, 2); nargs = 2; have_delcount = 0; } else { have_delcount = 1; } /* XXX: len >= 0x80000000 won't work below because we need to be * able to represent -len. */ len = duk__push_this_obj_len_u32_limited(ctx); act_start = duk_to_int_clamped(ctx, 0, -((duk_int_t) len), (duk_int_t) len); if (act_start < 0) { act_start = len + act_start; } DUK_ASSERT(act_start >= 0 && act_start <= (duk_int_t) len); #ifdef DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT if (have_delcount) { #endif del_count = duk_to_int_clamped(ctx, 1, 0, len - act_start); #ifdef DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT } else { /* E5.1 standard behavior when deleteCount is not given would be * to treat it just like if 'undefined' was given, which coerces * ultimately to 0. Real world behavior is to splice to the end * of array, see test-bi-array-proto-splice-no-delcount.js. */ del_count = len - act_start; } #endif DUK_ASSERT(nargs >= 2); item_count = (duk_int_t) (nargs - 2); DUK_ASSERT(del_count >= 0 && del_count <= (duk_int_t) len - act_start); DUK_ASSERT(del_count + act_start <= (duk_int_t) len); /* For now, restrict result array into 32-bit length range. */ if (((duk_double_t) len) - ((duk_double_t) del_count) + ((duk_double_t) item_count) > (duk_double_t) DUK_UINT32_MAX) { DUK_D(DUK_DPRINT("Array.prototype.splice() would go beyond 32-bit length, throw")); return DUK_RET_RANGE_ERROR; } duk_push_array(ctx); /* stack[0] = start * stack[1] = deleteCount * stack[2...nargs-1] = items * stack[nargs] = ToObject(this) -3 * stack[nargs+1] = ToUint32(length) -2 * stack[nargs+2] = result array -1 */ DUK_ASSERT_TOP(ctx, nargs + 3); /* Step 9: copy elements-to-be-deleted into the result array */ for (i = 0; i < del_count; i++) { if (duk_get_prop_index(ctx, -3, (duk_uarridx_t) (act_start + i))) { duk_xdef_prop_index_wec(ctx, -2, i); /* throw flag irrelevant (false in std alg) */ } else { duk_pop(ctx); } } duk_push_u32(ctx, (duk_uint32_t) del_count); duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W); /* Steps 12 and 13: reorganize elements to make room for itemCount elements */ if (item_count < del_count) { /* [ A B C D E F G H ] rel_index = 2, del_count 3, item count 1 * -> [ A B F G H ] (conceptual intermediate step) * -> [ A B . F G H ] (placeholder marked) * [ A B C F G H ] (actual result at this point, C will be replaced) */ DUK_ASSERT_TOP(ctx, nargs + 3); n = len - del_count; for (i = act_start; i < n; i++) { if (duk_get_prop_index(ctx, -3, (duk_uarridx_t) (i + del_count))) { duk_put_prop_index(ctx, -4, (duk_uarridx_t) (i + item_count)); } else { duk_pop(ctx); duk_del_prop_index(ctx, -3, (duk_uarridx_t) (i + item_count)); } } DUK_ASSERT_TOP(ctx, nargs + 3); /* loop iterator init and limit changed from standard algorithm */ n = len - del_count + item_count; for (i = len - 1; i >= n; i--) { duk_del_prop_index(ctx, -3, (duk_uarridx_t) i); } DUK_ASSERT_TOP(ctx, nargs + 3); } else if (item_count > del_count) { /* [ A B C D E F G H ] rel_index = 2, del_count 3, item count 4 * -> [ A B F G H ] (conceptual intermediate step) * -> [ A B . . . . F G H ] (placeholder marked) * [ A B C D E F F G H ] (actual result at this point) */ DUK_ASSERT_TOP(ctx, nargs + 3); /* loop iterator init and limit changed from standard algorithm */ for (i = len - del_count - 1; i >= act_start; i--) { if (duk_get_prop_index(ctx, -3, (duk_uarridx_t) (i + del_count))) { duk_put_prop_index(ctx, -4, (duk_uarridx_t) (i + item_count)); } else { duk_pop(ctx); duk_del_prop_index(ctx, -3, (duk_uarridx_t) (i + item_count)); } } DUK_ASSERT_TOP(ctx, nargs + 3); } else { /* [ A B C D E F G H ] rel_index = 2, del_count 3, item count 3 * -> [ A B F G H ] (conceptual intermediate step) * -> [ A B . . . F G H ] (placeholder marked) * [ A B C D E F G H ] (actual result at this point) */ } DUK_ASSERT_TOP(ctx, nargs + 3); /* Step 15: insert itemCount elements into the hole made above */ for (i = 0; i < item_count; i++) { duk_dup(ctx, i + 2); /* args start at index 2 */ duk_put_prop_index(ctx, -4, (duk_uarridx_t) (act_start + i)); } /* Step 16: update length; note that the final length may be above 32 bit range * (but we checked above that this isn't the case here) */ duk_push_u32(ctx, len - del_count + item_count); duk_put_prop_stridx(ctx, -4, DUK_STRIDX_LENGTH); /* result array is already at the top of stack */ DUK_ASSERT_TOP(ctx, nargs + 3); return 1; }
int duk_bi_array_prototype_splice(duk_context *ctx) { int nargs; int have_delcount; int item_count; int len; int act_start; int del_count; int i; DUK_UNREF(have_delcount); nargs = duk_get_top(ctx); if (nargs < 2) { duk_set_top(ctx, 2); nargs = 2; have_delcount = 0; } else { have_delcount = 1; } len = duk__push_this_obj_len_u32(ctx); act_start = duk_to_int_clamped(ctx, 0, -len, len); if (act_start < 0) { act_start = len + act_start; } DUK_ASSERT(act_start >= 0 && act_start <= len); #ifdef DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT if (have_delcount) { #endif del_count = duk_to_int_clamped(ctx, 1, 0, len - act_start); #ifdef DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT } else { /* E5.1 standard behavior when deleteCount is not given would be * to treat it just like if 'undefined' was given, which coerces * ultimately to 0. Real world behavior is to splice to the end * of array, see test-bi-array-proto-splice-no-delcount.js. */ del_count = len - act_start; } #endif DUK_ASSERT(del_count >= 0 && del_count <= len - act_start); DUK_ASSERT(del_count + act_start <= len); duk_push_array(ctx); /* stack[0] = start * stack[1] = deleteCount * stack[2...nargs-1] = items * stack[nargs] = ToObject(this) -3 * stack[nargs+1] = ToUint32(length) -2 * stack[nargs+2] = result array -1 */ DUK_ASSERT_TOP(ctx, nargs + 3); /* Step 9: copy elements-to-be-deleted into the result array */ for (i = 0; i < del_count; i++) { if (duk_get_prop_index(ctx, -3, act_start + i)) { duk_def_prop_index(ctx, -2, i, DUK_PROPDESC_FLAGS_WEC); /* throw flag irrelevant (false in std alg) */ } else { duk_pop(ctx); } } duk_push_int(ctx, del_count); /* FIXME: typing */ duk_def_prop_stridx(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W); /* Steps 12 and 13: reorganize elements to make room for itemCount elements */ DUK_ASSERT(nargs >= 2); item_count = nargs - 2; if (item_count < del_count) { /* [ A B C D E F G H ] rel_index = 2, del_count 3, item count 1 * -> [ A B F G H ] (conceptual intermediate step) * -> [ A B . F G H ] (placeholder marked) * [ A B C F G H ] (actual result at this point, C will be replaced) */ DUK_ASSERT_TOP(ctx, nargs + 3); for (i = act_start; i < len - del_count; i++) { if (duk_get_prop_index(ctx, -3, i + del_count)) { duk_put_prop_index(ctx, -4, i + item_count); /* FIXME: Throw */ } else { duk_pop(ctx); duk_del_prop_index(ctx, -3, i + item_count); /* FIXME: Throw */ } } DUK_ASSERT_TOP(ctx, nargs + 3); /* loop iterator init and limit changed from standard algorithm */ for (i = len - 1; i >= len - del_count + item_count; i--) { duk_del_prop_index(ctx, -3, i); /* FIXME: Throw */ } DUK_ASSERT_TOP(ctx, nargs + 3); } else if (item_count > del_count) { /* [ A B C D E F G H ] rel_index = 2, del_count 3, item count 4 * -> [ A B F G H ] (conceptual intermediate step) * -> [ A B . . . . F G H ] (placeholder marked) * [ A B C D E F F G H ] (actual result at this point) */ DUK_ASSERT_TOP(ctx, nargs + 3); /* loop iterator init and limit changed from standard algorithm */ for (i = len - del_count - 1; i >= act_start; i--) { if (duk_get_prop_index(ctx, -3, i + del_count)) { duk_put_prop_index(ctx, -4, i + item_count); /* FIXME: Throw */ } else { duk_pop(ctx); duk_del_prop_index(ctx, -3, i + item_count); /* FIXME: Throw */ } } DUK_ASSERT_TOP(ctx, nargs + 3); } else { /* [ A B C D E F G H ] rel_index = 2, del_count 3, item count 3 * -> [ A B F G H ] (conceptual intermediate step) * -> [ A B . . . F G H ] (placeholder marked) * [ A B C D E F G H ] (actual result at this point) */ } DUK_ASSERT_TOP(ctx, nargs + 3); /* Step 15: insert itemCount elements into the hole made above */ for (i = 0; i < item_count; i++) { duk_dup(ctx, i + 2); /* args start at index 2 */ duk_put_prop_index(ctx, -4, act_start + i); /* FIXME: Throw */ } /* Step 16: update length; note that the final length may be above 32 bit range */ duk_push_number(ctx, ((double) len) - ((double) del_count) + ((double) item_count)); duk_put_prop_stridx(ctx, -4, DUK_STRIDX_LENGTH); /* result array is already at the top of stack */ DUK_ASSERT_TOP(ctx, nargs + 3); return 1; }