Skip to content

Commit

Permalink
Merge branch 'fix-bytecode-load-fastint'
Browse files Browse the repository at this point in the history
Fix bytecode dump/load to preserve fastint status of number constants.
  • Loading branch information
svaarala committed Aug 27, 2015
2 parents 1677e3b + ae8247b commit d3abfae
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/duk_api_bytecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,15 @@ static duk_uint8_t *duk__load_func(duk_context *ctx, duk_uint8_t *p, duk_uint8_t
break;
}
case DUK__SER_NUMBER: {
/* Important to do a fastint check so that constants are
* properly read back as fastints.
*/
duk_tval tv_tmp;
duk_double_t val;
DUK__ASSERT_LEFT(8);
val = DUK_RAW_READ_DOUBLE_BE(p);
duk_push_number(ctx, val);
DUK_TVAL_SET_NUMBER_CHKFAST(&tv_tmp, val);
duk_push_tval(ctx, &tv_tmp);
break;
}
default: {
Expand Down
66 changes: 66 additions & 0 deletions tests/api/test-dump-load-fastint.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Fastint compatible integer constants should read back as fastints.
*/

/*---
{
"specialoptions": "requires DUK_OPT_FASTINT"
}
---*/

/*===
*** test_1 (duk_safe_call)
4886718345
true
4886718345
true
final top: 0
==> rc=0, result='undefined'
===*/

static duk_ret_t test_1(duk_context *ctx) {
/* copied from polyfills/duktape-isfastint.js */
duk_eval_string_noresult(ctx,
"Object.defineProperty(Duktape, 'fastintTag', {\n"
" /* Tag number depends on duk_tval packing. */\n"
" value: (Duktape.info(true)[1] === 0xfff4) ?\n"
" 0xfff1 /* tag for packed duk_tval */ :\n"
" 1 /* tag for unpacked duk_tval */,\n"
" writable: false,\n"
" enumerable: false,\n"
" configurable: true\n"
"});\n"
"Object.defineProperty(Duktape, 'isFastint', {\n"
" value: function (v) {\n"
" return Duktape.info(v)[0] === 4 && /* public type is DUK_TYPE_NUMBER */\n"
" Duktape.info(v)[1] === Duktape.fastintTag; /* internal tag is fastint */\n"
" },\n"
" writable: false, enumerable: false, configurable: true\n"
"});\n");

/* Constant must be large enough to avoid a LDINT instead of
* LDCONST.
*/
duk_eval_string(ctx,
"(function () {\n"
" var v1 = 0x123456789;\n"
" print(v1);\n"
" print(Duktape.isFastint(v1));\n"
"})");

duk_dup_top(ctx);
duk_call(ctx, 0);
duk_pop(ctx);

duk_dump_function(ctx);
duk_load_function(ctx);
duk_call(ctx, 0);
duk_pop(ctx);

printf("final top: %ld\n", (long) duk_get_top(ctx));
return 0;
}

void test(duk_context *ctx) {
TEST_SAFE_CALL(test_1);
}

0 comments on commit d3abfae

Please sign in to comment.