mirror of
https://github.com/google/pebble.git
synced 2025-05-19 01:44:53 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
720
applib-targets/emscripten/emscripten_jerry_api.c
Normal file
720
applib-targets/emscripten/emscripten_jerry_api.c
Normal file
|
@ -0,0 +1,720 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerry-api.h"
|
||||
#include <emscripten/emscripten.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define TYPE_ERROR \
|
||||
jerry_create_error(JERRY_ERROR_TYPE, NULL);
|
||||
|
||||
#define TYPE_ERROR_ARG \
|
||||
jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *)"wrong type of argument");
|
||||
|
||||
#define TYPE_ERROR_FLAG \
|
||||
jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *)"argument cannot have an error flag");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Parser and Executor Function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Note that `is_strict` is currently unsupported by emscripten
|
||||
jerry_value_t jerry_eval(const jerry_char_t *source_p, size_t source_size, bool is_strict) {
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
// jerry_eval() uses an indirect eval() call,
|
||||
// so the global execution context is used.
|
||||
// Also see ECMA 5.1 -- 10.4.2 Entering Eval Code.
|
||||
var indirectEval = eval;
|
||||
try {
|
||||
return __jerryRefs.ref(indirectEval(Module.Pointer_stringify($0, $1)));
|
||||
} catch (e) {
|
||||
var error_ref = __jerryRefs.ref(e);
|
||||
__jerryRefs.setError(error_ref, true);
|
||||
return error_ref;
|
||||
}
|
||||
}, source_p, source_size);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_acquire_value(jerry_value_t value) {
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
return __jerryRefs.acquire($0);
|
||||
}, value);
|
||||
}
|
||||
|
||||
void jerry_release_value(jerry_value_t value) {
|
||||
EM_ASM_INT({
|
||||
__jerryRefs.release($0);
|
||||
}, value);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Get the global context
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
jerry_value_t jerry_get_global_object(void) {
|
||||
return ((jerry_value_t)EM_ASM_INT_V({ \
|
||||
return __jerryRefs.ref(Function('return this;')()); \
|
||||
}));
|
||||
}
|
||||
|
||||
jerry_value_t jerry_get_global_builtin(const jerry_char_t *builtin_name) {
|
||||
return ((jerry_value_t)EM_ASM_INT({ \
|
||||
return __jerryRefs.ref(Function('return this;')()[Module.Pointer_stringify($0)]); \
|
||||
}, builtin_name));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Jerry Value Type Checking
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define JERRY_VALUE_HAS_TYPE(ref, typename) \
|
||||
((bool)EM_ASM_INT({ \
|
||||
return typeof __jerryRefs.get($0) === (typename); \
|
||||
}, (ref)))
|
||||
|
||||
#define JERRY_VALUE_IS_INSTANCE(ref, type) \
|
||||
((bool)EM_ASM_INT({ \
|
||||
return __jerryRefs.get($0) instanceof (type); \
|
||||
}, (ref)))
|
||||
|
||||
bool jerry_value_is_array(const jerry_value_t value) {
|
||||
return JERRY_VALUE_IS_INSTANCE(value, Array);
|
||||
}
|
||||
|
||||
bool jerry_value_is_boolean(const jerry_value_t value) {
|
||||
return JERRY_VALUE_HAS_TYPE(value, 'boolean');
|
||||
}
|
||||
|
||||
bool jerry_value_is_constructor(const jerry_value_t value) {
|
||||
return jerry_value_is_function(value);
|
||||
}
|
||||
|
||||
bool jerry_value_is_function(const jerry_value_t value) {
|
||||
return JERRY_VALUE_HAS_TYPE(value, 'function');
|
||||
}
|
||||
|
||||
bool jerry_value_is_number(const jerry_value_t value) {
|
||||
return JERRY_VALUE_HAS_TYPE(value, 'number');
|
||||
}
|
||||
|
||||
bool jerry_value_is_null(const jerry_value_t value) {
|
||||
return ((bool)EM_ASM_INT({
|
||||
return __jerryRefs.get($0) === null;
|
||||
}, value));
|
||||
}
|
||||
|
||||
bool jerry_value_is_object(const jerry_value_t value) {
|
||||
return !jerry_value_is_null(value) &&
|
||||
(JERRY_VALUE_HAS_TYPE(value, 'object') || jerry_value_is_function(value));
|
||||
}
|
||||
|
||||
bool jerry_value_is_string(const jerry_value_t value) {
|
||||
return JERRY_VALUE_HAS_TYPE(value, 'string');
|
||||
}
|
||||
|
||||
bool jerry_value_is_undefined(const jerry_value_t value) {
|
||||
return JERRY_VALUE_HAS_TYPE(value, 'undefined');
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Jerry Value Getter Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool jerry_get_boolean_value(const jerry_value_t value) {
|
||||
if (!jerry_value_is_boolean(value)) {
|
||||
return false;
|
||||
}
|
||||
return (bool)EM_ASM_INT({
|
||||
return (__jerryRefs.get($0) === true);
|
||||
}, value);
|
||||
}
|
||||
|
||||
double jerry_get_number_value(const jerry_value_t value) {
|
||||
if (!jerry_value_is_number(value)) {
|
||||
return 0.0;
|
||||
}
|
||||
return EM_ASM_DOUBLE({
|
||||
return __jerryRefs.get($0);
|
||||
}, value);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for UTF-8 encoded string values
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
jerry_size_t jerry_get_utf8_string_size(const jerry_value_t value) {
|
||||
if (!jerry_value_is_string(value)) {
|
||||
return 0;
|
||||
}
|
||||
return (jerry_size_t)EM_ASM_INT({
|
||||
return Module.lengthBytesUTF8(__jerryRefs.get($0));
|
||||
}, value);
|
||||
}
|
||||
|
||||
jerry_size_t jerry_string_to_utf8_char_buffer(const jerry_value_t value,
|
||||
jerry_char_t *buffer_p,
|
||||
jerry_size_t buffer_size) {
|
||||
const jerry_size_t str_size = jerry_get_utf8_string_size(value);
|
||||
if (str_size == 0 || buffer_size < str_size || buffer_p == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
EM_ASM_INT({
|
||||
var str = __jerryRefs.get($0);
|
||||
// Add one onto the buffer size, since Module.stringToUTF8 adds a null
|
||||
// character at the end. This will lead to truncation if we just use
|
||||
// buffer_size. Since the actual jerry-api does not do this, we are
|
||||
// always careful to allocate space for a null character at the end.
|
||||
// Allow stringToUTF8 to write that extra null beyond the passed in
|
||||
// buffer_length.
|
||||
Module.stringToUTF8(str, $1, $2 + 1);
|
||||
}, value, buffer_p, buffer_size);
|
||||
return strlen((const char *)buffer_p);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions for array object values
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint32_t jerry_get_array_length(const jerry_value_t value) {
|
||||
if (!jerry_value_is_array(value)) {
|
||||
return 0;
|
||||
}
|
||||
return (uint32_t)EM_ASM_INT({
|
||||
return __jerryRefs.get($0).length;
|
||||
}, value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Jerry Value Creation API
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define JERRY_CREATE_VALUE(value) \
|
||||
((jerry_value_t)EM_ASM_INT_V({ \
|
||||
return __jerryRefs.ref((value)); \
|
||||
}))
|
||||
|
||||
jerry_value_t jerry_create_array(uint32_t size) {
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
return __jerryRefs.ref(new Array($0));
|
||||
}, size);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_boolean(bool value) {
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
return __jerryRefs.ref(Boolean($0));
|
||||
}, value);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_error(jerry_error_t error_type, const jerry_char_t *message_p) {
|
||||
return jerry_create_error_sz(error_type, message_p, strlen((const char *)message_p));
|
||||
}
|
||||
|
||||
#define JERRY_ERROR(type, msg, sz) (jerry_value_t)(EM_ASM_INT({ \
|
||||
return __jerryRefs.ref(new (type)(Module.Pointer_stringify($0, $1))) \
|
||||
}, (msg), (sz)))
|
||||
|
||||
jerry_value_t jerry_create_error_sz(jerry_error_t error_type,
|
||||
const jerry_char_t *message_p,
|
||||
jerry_size_t message_size) {
|
||||
jerry_value_t error_ref = 0;
|
||||
switch (error_type) {
|
||||
case JERRY_ERROR_COMMON:
|
||||
error_ref = JERRY_ERROR(Error, message_p, message_size);
|
||||
break;
|
||||
case JERRY_ERROR_EVAL:
|
||||
error_ref = JERRY_ERROR(EvalError, message_p, message_size);
|
||||
break;
|
||||
case JERRY_ERROR_RANGE:
|
||||
error_ref = JERRY_ERROR(RangeError, message_p, message_size);
|
||||
break;
|
||||
case JERRY_ERROR_REFERENCE:
|
||||
error_ref = JERRY_ERROR(ReferenceError, message_p, message_size);
|
||||
break;
|
||||
case JERRY_ERROR_SYNTAX:
|
||||
error_ref = JERRY_ERROR(SyntaxError, message_p, message_size);
|
||||
break;
|
||||
case JERRY_ERROR_TYPE:
|
||||
error_ref = JERRY_ERROR(TypeError, message_p, message_size);
|
||||
break;
|
||||
case JERRY_ERROR_URI:
|
||||
error_ref = JERRY_ERROR(URIError, message_p, message_size);
|
||||
break;
|
||||
default:
|
||||
EM_ASM_INT({
|
||||
abort('Cannot create error type: ' + $0);
|
||||
}, error_type);
|
||||
break;
|
||||
}
|
||||
jerry_value_set_error_flag(&error_ref);
|
||||
return error_ref;
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_external_function(jerry_external_handler_t handler_p) {
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
return __jerry_create_external_function($0);
|
||||
}, handler_p);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_number(double value) {
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
return __jerryRefs.ref($0);
|
||||
}, value);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_number_infinity(bool negative) {
|
||||
if (negative) {
|
||||
return JERRY_CREATE_VALUE(-Infinity);
|
||||
} else {
|
||||
return JERRY_CREATE_VALUE(Infinity);
|
||||
}
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_number_nan(void) {
|
||||
return JERRY_CREATE_VALUE(NaN);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_null(void) {
|
||||
return JERRY_CREATE_VALUE(null);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_object(void) {
|
||||
return JERRY_CREATE_VALUE(new Object());
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_string(const jerry_char_t *str_p) {
|
||||
if (!str_p) {
|
||||
return jerry_create_undefined();
|
||||
}
|
||||
return jerry_create_string_utf8_sz(str_p, strlen((const char *)str_p));
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_string_sz(const jerry_char_t *str_p, jerry_size_t str_size) {
|
||||
return jerry_create_string_utf8_sz(str_p, str_size);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_string_utf8(const jerry_char_t *str_p) {
|
||||
if (!str_p) {
|
||||
return jerry_create_undefined();
|
||||
}
|
||||
return jerry_create_string_utf8_sz(str_p, strlen((const char *)str_p));
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_string_utf8_sz(const jerry_char_t *str_p, jerry_size_t str_size) {
|
||||
if (!str_p) {
|
||||
return jerry_create_undefined();
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
return __jerryRefs.ref(Module.Pointer_stringify($0, $1));
|
||||
}, str_p, str_size);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_create_undefined(void) {
|
||||
return JERRY_CREATE_VALUE(undefined);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// General API Functions of JS Objects
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool jerry_has_property(const jerry_value_t obj_val, const jerry_value_t prop_name_val) {
|
||||
if (!jerry_value_is_object(obj_val) || !jerry_value_is_string(prop_name_val)) {
|
||||
return false;
|
||||
}
|
||||
return (bool)EM_ASM_INT({
|
||||
var obj = __jerryRefs.get($0);
|
||||
var name = __jerryRefs.get($1);
|
||||
return (name in obj);
|
||||
}, obj_val, prop_name_val);
|
||||
}
|
||||
|
||||
bool jerry_has_own_property(const jerry_value_t obj_val, const jerry_value_t prop_name_val) {
|
||||
if (!jerry_value_is_object(obj_val) || !jerry_value_is_string(prop_name_val)) {
|
||||
return false;
|
||||
}
|
||||
return (bool)EM_ASM_INT({
|
||||
var obj = __jerryRefs.get($0);
|
||||
var name = __jerryRefs.get($1);
|
||||
return obj.hasOwnProperty(name);
|
||||
}, obj_val, prop_name_val);
|
||||
}
|
||||
|
||||
bool jerry_delete_property(const jerry_value_t obj_val, const jerry_value_t prop_name_val) {
|
||||
if (!jerry_value_is_object(obj_val) || !jerry_value_is_string(prop_name_val)) {
|
||||
return false;
|
||||
}
|
||||
return (bool)EM_ASM_INT({
|
||||
var obj = __jerryRefs.get($0);
|
||||
var name = __jerryRefs.get($1);
|
||||
try {
|
||||
return delete obj[name];
|
||||
} catch (e) {
|
||||
// In strict mode, delete throws SyntaxError if the property is an
|
||||
// own non-configurable property.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, obj_val, prop_name_val);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_get_property(const jerry_value_t obj_val, const jerry_value_t prop_name_val) {
|
||||
if (!jerry_value_is_object(obj_val) || !jerry_value_is_string(prop_name_val)) {
|
||||
return TYPE_ERROR_ARG;
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
var obj = __jerryRefs.get($0);
|
||||
var name = __jerryRefs.get($1);
|
||||
return __jerryRefs.ref(obj[name]);
|
||||
}, obj_val, prop_name_val);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_get_property_by_index(const jerry_value_t obj_val, uint32_t index) {
|
||||
if (!jerry_value_is_object(obj_val)) {
|
||||
return TYPE_ERROR;
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
var obj = __jerryRefs.get($0);
|
||||
return __jerryRefs.ref(obj[$1]);
|
||||
}, obj_val, index);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_set_property(const jerry_value_t obj_val,
|
||||
const jerry_value_t prop_name_val,
|
||||
const jerry_value_t value_to_set) {
|
||||
if (jerry_value_has_error_flag(value_to_set) ||
|
||||
!jerry_value_is_object(obj_val) ||
|
||||
!jerry_value_is_string(prop_name_val)) {
|
||||
return TYPE_ERROR_ARG;
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
var obj = __jerryRefs.get($0);
|
||||
var name = __jerryRefs.get($1);
|
||||
var to_set = __jerryRefs.get($2);
|
||||
obj[name] = to_set;
|
||||
return __jerryRefs.ref(true);
|
||||
}, obj_val, prop_name_val, value_to_set);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_set_property_by_index(const jerry_value_t obj_val,
|
||||
uint32_t index,
|
||||
const jerry_value_t value_to_set) {
|
||||
if (jerry_value_has_error_flag(value_to_set) ||
|
||||
!jerry_value_is_object(obj_val)) {
|
||||
return TYPE_ERROR_ARG;
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
var obj = __jerryRefs.get($0);
|
||||
var to_set = __jerryRefs.get($2);
|
||||
obj[$1] = to_set;
|
||||
return __jerryRefs.ref(true);
|
||||
}, obj_val, index, value_to_set);
|
||||
}
|
||||
|
||||
void jerry_init_property_descriptor_fields(jerry_property_descriptor_t *prop_desc_p) {
|
||||
*prop_desc_p = (jerry_property_descriptor_t) {
|
||||
.value = jerry_create_undefined(),
|
||||
.getter = jerry_create_undefined(),
|
||||
.setter = jerry_create_undefined(),
|
||||
};
|
||||
}
|
||||
|
||||
jerry_value_t jerry_define_own_property(const jerry_value_t obj_val,
|
||||
const jerry_value_t prop_name_val,
|
||||
const jerry_property_descriptor_t *pdp) {
|
||||
if (!jerry_value_is_object(obj_val) && !jerry_value_is_string(obj_val)) {
|
||||
return TYPE_ERROR_ARG;
|
||||
}
|
||||
if ((pdp->is_writable_defined || pdp->is_value_defined)
|
||||
&& (pdp->is_get_defined || pdp->is_set_defined)) {
|
||||
return TYPE_ERROR_ARG;
|
||||
}
|
||||
if (pdp->is_get_defined && !jerry_value_is_function(pdp->getter)) {
|
||||
return TYPE_ERROR_ARG;
|
||||
}
|
||||
if (pdp->is_set_defined && !jerry_value_is_function(pdp->setter)) {
|
||||
return TYPE_ERROR_ARG;
|
||||
}
|
||||
|
||||
return (jerry_value_t)(EM_ASM_INT({
|
||||
var obj = __jerryRefs.get($12 /* obj_val */);
|
||||
var name = __jerryRefs.get($13 /* prop_name_val */);
|
||||
var desc = {};
|
||||
if ($0 /* is_value_defined */) {
|
||||
desc.value = __jerryRefs.get($9);
|
||||
}
|
||||
if ($1 /* is_get_defined */) {
|
||||
desc.get = __jerryRefs.get($10);
|
||||
}
|
||||
if ($2 /* is_set_defined */) {
|
||||
desc.set = __jerryRefs.get($11);
|
||||
}
|
||||
if ($3 /* is_writable_defined */) {
|
||||
desc.writable = Boolean($4 /* is_writable */);
|
||||
}
|
||||
if ($5 /* is_enumerable_defined */) {
|
||||
desc.enumerable = Boolean($6 /* is_enumerable */);
|
||||
}
|
||||
if ($7 /* is_configurable */) {
|
||||
desc.configurable = Boolean($8 /* is_configurable */);
|
||||
}
|
||||
|
||||
Object.defineProperty(obj, name, desc);
|
||||
return __jerryRefs.ref(Boolean(true));
|
||||
}, pdp->is_value_defined, /* $0 */
|
||||
pdp->is_get_defined, /* $1 */
|
||||
pdp->is_set_defined, /* $2 */
|
||||
pdp->is_writable_defined, /* $3 */
|
||||
pdp->is_writable, /* $4 */
|
||||
pdp->is_enumerable_defined, /* $5 */
|
||||
pdp->is_enumerable, /* $6 */
|
||||
pdp->is_configurable_defined, /* $7 */
|
||||
pdp->is_configurable, /* $8 */
|
||||
pdp->value, /* $9 */
|
||||
pdp->getter, /* $10 */
|
||||
pdp->setter, /* $11 */
|
||||
obj_val, /* $12 */
|
||||
prop_name_val /* $13 */
|
||||
));
|
||||
}
|
||||
|
||||
jerry_value_t emscripten_call_jerry_function(jerry_external_handler_t func_obj_p,
|
||||
const jerry_value_t func_obj_val,
|
||||
const jerry_value_t this_val,
|
||||
const jerry_value_t args_p[],
|
||||
jerry_size_t args_count) {
|
||||
return (func_obj_p)(func_obj_val, this_val, args_p, args_count);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_call_function(const jerry_value_t func_obj_val,
|
||||
const jerry_value_t this_val,
|
||||
const jerry_value_t args_p[],
|
||||
jerry_size_t args_count) {
|
||||
if (!jerry_value_is_function(func_obj_val)) {
|
||||
return TYPE_ERROR_ARG;
|
||||
}
|
||||
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
var func_obj = __jerryRefs.get($0);
|
||||
var this_val = __jerryRefs.get($1);
|
||||
var args = [];
|
||||
for (var i = 0; i < $3; ++i) {
|
||||
args.push(__jerryRefs.get(getValue($2 + i*4, 'i32')));
|
||||
}
|
||||
try {
|
||||
var rv = func_obj.apply(this_val, args);
|
||||
} catch (e) {
|
||||
var error_ref = __jerryRefs.ref(e);
|
||||
__jerryRefs.setError(error_ref, true);
|
||||
return error_ref;
|
||||
}
|
||||
return __jerryRefs.ref(rv);
|
||||
}, func_obj_val, this_val, args_p, args_count);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_construct_object(const jerry_value_t func_obj_val,
|
||||
const jerry_value_t args_p[],
|
||||
jerry_size_t args_count) {
|
||||
if (!jerry_value_is_constructor(func_obj_val)) {
|
||||
return TYPE_ERROR_ARG;
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
var func_obj = __jerryRefs.get($0);
|
||||
var args = [];
|
||||
for (var i = 0; i < $2; ++i) {
|
||||
args.push(__jerryRefs.get(getValue($1 + i*4, 'i32')));
|
||||
}
|
||||
// Call the constructor with new object as `this`
|
||||
var bindArgs = [null].concat(args);
|
||||
var boundConstructor = func_obj.bind.apply(func_obj, bindArgs);
|
||||
var rv = new boundConstructor();
|
||||
return __jerryRefs.ref(rv);
|
||||
}, func_obj_val, args_p, args_count);
|
||||
}
|
||||
|
||||
jerry_size_t jerry_string_to_char_buffer(const jerry_value_t value,
|
||||
jerry_char_t *buffer_p,
|
||||
jerry_size_t buffer_size) {
|
||||
return jerry_string_to_utf8_char_buffer(value, buffer_p, buffer_size);
|
||||
}
|
||||
|
||||
jerry_size_t jerry_object_to_string_to_utf8_char_buffer(const jerry_value_t object,
|
||||
jerry_char_t *buffer_p,
|
||||
jerry_size_t buffer_size) {
|
||||
jerry_value_t str_ref = (jerry_value_t)EM_ASM_INT({
|
||||
var str = __jerryRefs.ref(String(__jerryRefs.get($0)));
|
||||
return str;
|
||||
}, object);
|
||||
jerry_size_t len = jerry_string_to_utf8_char_buffer(str_ref, buffer_p, buffer_size);
|
||||
jerry_release_value(str_ref);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// FIXME: PBL-43551 Propery CESU-8 => UTF-8 conversion.
|
||||
jerry_size_t jerry_object_to_string_to_char_buffer(const jerry_value_t object,
|
||||
jerry_char_t *buffer_p,
|
||||
jerry_size_t buffer_size) {
|
||||
return jerry_object_to_string_to_utf8_char_buffer(object,
|
||||
buffer_p,
|
||||
buffer_size);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_get_object_keys(const jerry_value_t value) {
|
||||
if (!jerry_value_is_object(value)) {
|
||||
return TYPE_ERROR_ARG;
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
return __jerryRefs.ref(Object.keys(__jerryRefs.get($0)));
|
||||
}, value);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_get_prototype(const jerry_value_t value) {
|
||||
if (!jerry_value_is_object(value)) {
|
||||
return TYPE_ERROR_ARG;
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
return __jerryRefs.ref(__jerryRefs.get($0).prototype);
|
||||
}, value);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_set_prototype(const jerry_value_t obj_val, const jerry_value_t proto_obj_val) {
|
||||
return 0; // FIXME: Not sure what to do here
|
||||
}
|
||||
|
||||
bool jerry_get_object_native_handle(const jerry_value_t obj_val, uintptr_t *out_handle_p) {
|
||||
return EM_ASM_INT({
|
||||
var ptr = __jerryRefs.getNativeHandle($0);
|
||||
if (ptr === undefined) {
|
||||
return false;
|
||||
}
|
||||
Module.setValue($1, ptr, '*');
|
||||
return true;
|
||||
}, obj_val, out_handle_p);
|
||||
}
|
||||
|
||||
void jerry_set_object_native_handle(const jerry_value_t obj_val, uintptr_t handle_p,
|
||||
jerry_object_free_callback_t freecb_p) {
|
||||
EM_ASM_INT({
|
||||
__jerryRefs.setNativeHandle($0, $1, $2);
|
||||
}, obj_val, handle_p, freecb_p);
|
||||
}
|
||||
|
||||
void emscripten_call_jerry_object_free_callback(jerry_object_free_callback_t freecb_p,
|
||||
uintptr_t handle_p) {
|
||||
if (freecb_p) {
|
||||
freecb_p(handle_p);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Error flag manipulation functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The error flag is stored alongside the value in __jerryRefs.
|
||||
// This allows for us to keep a valid value, like jerryscript does, and be able
|
||||
// to add / remove a flag specifying whether there was an error or not.
|
||||
|
||||
bool jerry_value_has_error_flag(const jerry_value_t value) {
|
||||
return (bool)(EM_ASM_INT({
|
||||
return __jerryRefs.getError($0);
|
||||
}, value));
|
||||
}
|
||||
|
||||
void jerry_value_clear_error_flag(jerry_value_t *value_p) {
|
||||
EM_ASM_INT({
|
||||
return __jerryRefs.setError($0, false);
|
||||
}, *value_p);
|
||||
}
|
||||
|
||||
void jerry_value_set_error_flag(jerry_value_t *value_p) {
|
||||
EM_ASM_INT({
|
||||
return __jerryRefs.setError($0, true);
|
||||
}, *value_p);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Converters of `jerry_value_t`
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool jerry_value_to_boolean(const jerry_value_t value) {
|
||||
if (jerry_value_has_error_flag(value)) {
|
||||
return false;
|
||||
}
|
||||
return (bool)EM_ASM_INT({
|
||||
return Boolean(__jerryRefs.get($0));
|
||||
}, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
jerry_value_t jerry_value_to_number(const jerry_value_t value) {
|
||||
if (jerry_value_has_error_flag(value)) {
|
||||
return TYPE_ERROR_FLAG;
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
return __jerryRefs.ref(Number(__jerryRefs.get($0)));
|
||||
}, value);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_value_to_object(const jerry_value_t value) {
|
||||
if (jerry_value_has_error_flag(value)) {
|
||||
return TYPE_ERROR_FLAG;
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
return __jerryRefs.ref(new Object(__jerryRefs.get($0)));
|
||||
}, value);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_value_to_primitive(const jerry_value_t value) {
|
||||
if (jerry_value_has_error_flag(value)) {
|
||||
return TYPE_ERROR_FLAG;
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
var val = __jerryRefs.get($0);
|
||||
var rv;
|
||||
if ((typeof val === 'object' && val != null)
|
||||
|| (typeof val === 'function')) {
|
||||
rv = val.valueOf(); // unbox
|
||||
} else {
|
||||
rv = val; // already a primitive
|
||||
}
|
||||
return __jerryRefs.ref(rv);
|
||||
}, value);
|
||||
}
|
||||
|
||||
jerry_value_t jerry_value_to_string(const jerry_value_t value) {
|
||||
if (jerry_value_has_error_flag(value)) {
|
||||
return TYPE_ERROR_FLAG;
|
||||
}
|
||||
return (jerry_value_t)EM_ASM_INT({
|
||||
return __jerryRefs.ref(String(__jerryRefs.get($0)));
|
||||
}, value);
|
||||
}
|
||||
|
||||
int jerry_obj_refcount(jerry_value_t o) {
|
||||
return EM_ASM_INT({
|
||||
try {
|
||||
return __jerryRefs.getRefCount($0);
|
||||
} catch (e) {
|
||||
return 0;
|
||||
}
|
||||
}, o);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void jerry_init(jerry_init_flag_t flags) {
|
||||
EM_ASM(__jerryRefs.reset());
|
||||
}
|
||||
|
||||
void jerry_cleanup(void) {
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue