From 06bbf7f559922e4f667e32be2a347530bc9ec6aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Mon, 10 Jan 2022 16:36:32 +0100 Subject: [PATCH 1/9] Removed 0xd3adc0d3 --- lib/browser/.eslintrc.json | 19 - lib/browser/app.js | 70 - lib/browser/async-open-task.js | 32 - lib/browser/base64.js | 84 -- lib/browser/cache.js | 35 - lib/browser/collections.js | 106 -- lib/browser/constants.js | 61 - lib/browser/credentials.js | 82 -- lib/browser/dictionaries.js | 29 - lib/browser/email-password-auth.js | 99 -- lib/browser/fetch.js | 64 - lib/browser/index.js | 242 ---- lib/browser/lists.js | 47 - lib/browser/objects.js | 98 -- lib/browser/results.js | 48 - lib/browser/rpc.js | 407 ------ lib/browser/session.js | 60 - lib/browser/sets.js | 29 - lib/browser/user.js | 91 -- lib/browser/util.js | 95 -- src/jsc/CMakeLists.txt | 9 - src/jsc/include/JavaScriptCore/JSBase.h | 151 -- src/jsc/include/JavaScriptCore/JSContextRef.h | 158 --- src/jsc/include/JavaScriptCore/JSObjectRef.h | 694 --------- src/jsc/include/JavaScriptCore/JSRetainPtr.h | 208 --- src/jsc/include/JavaScriptCore/JSStringRef.h | 145 -- src/jsc/include/JavaScriptCore/JSValueRef.h | 301 ---- .../JavaScriptCore/WebKitAvailability.h | 67 - src/jsc/jsc_class.hpp | 1195 ---------------- src/jsc/jsc_context.hpp | 33 - src/jsc/jsc_exception.hpp | 34 - src/jsc/jsc_function.hpp | 58 - src/jsc/jsc_init.cpp | 68 - src/jsc/jsc_init.h | 33 - src/jsc/jsc_init.hpp | 35 - src/jsc/jsc_object.hpp | 195 --- src/jsc/jsc_protected.hpp | 174 --- src/jsc/jsc_return_value.hpp | 97 -- src/jsc/jsc_rpc_network_transport.hpp | 79 -- src/jsc/jsc_string.hpp | 90 -- src/jsc/jsc_types.hpp | 64 - src/jsc/jsc_value.cpp | 224 --- src/jsc/jsc_value.hpp | 367 ----- src/jsc/rpc.cpp | 1235 ----------------- src/jsc/rpc.hpp | 40 - 45 files changed, 7552 deletions(-) delete mode 100644 lib/browser/.eslintrc.json delete mode 100644 lib/browser/app.js delete mode 100644 lib/browser/async-open-task.js delete mode 100644 lib/browser/base64.js delete mode 100644 lib/browser/cache.js delete mode 100644 lib/browser/collections.js delete mode 100644 lib/browser/constants.js delete mode 100644 lib/browser/credentials.js delete mode 100644 lib/browser/dictionaries.js delete mode 100644 lib/browser/email-password-auth.js delete mode 100644 lib/browser/fetch.js delete mode 100644 lib/browser/index.js delete mode 100644 lib/browser/lists.js delete mode 100644 lib/browser/objects.js delete mode 100644 lib/browser/results.js delete mode 100644 lib/browser/rpc.js delete mode 100644 lib/browser/session.js delete mode 100644 lib/browser/sets.js delete mode 100644 lib/browser/user.js delete mode 100644 lib/browser/util.js delete mode 100644 src/jsc/CMakeLists.txt delete mode 100644 src/jsc/include/JavaScriptCore/JSBase.h delete mode 100644 src/jsc/include/JavaScriptCore/JSContextRef.h delete mode 100644 src/jsc/include/JavaScriptCore/JSObjectRef.h delete mode 100644 src/jsc/include/JavaScriptCore/JSRetainPtr.h delete mode 100644 src/jsc/include/JavaScriptCore/JSStringRef.h delete mode 100644 src/jsc/include/JavaScriptCore/JSValueRef.h delete mode 100644 src/jsc/include/JavaScriptCore/WebKitAvailability.h delete mode 100644 src/jsc/jsc_class.hpp delete mode 100644 src/jsc/jsc_context.hpp delete mode 100644 src/jsc/jsc_exception.hpp delete mode 100644 src/jsc/jsc_function.hpp delete mode 100644 src/jsc/jsc_init.cpp delete mode 100644 src/jsc/jsc_init.h delete mode 100644 src/jsc/jsc_init.hpp delete mode 100644 src/jsc/jsc_object.hpp delete mode 100644 src/jsc/jsc_protected.hpp delete mode 100644 src/jsc/jsc_return_value.hpp delete mode 100644 src/jsc/jsc_rpc_network_transport.hpp delete mode 100644 src/jsc/jsc_string.hpp delete mode 100644 src/jsc/jsc_types.hpp delete mode 100644 src/jsc/jsc_value.cpp delete mode 100644 src/jsc/jsc_value.hpp delete mode 100644 src/jsc/rpc.cpp delete mode 100644 src/jsc/rpc.hpp diff --git a/lib/browser/.eslintrc.json b/lib/browser/.eslintrc.json deleted file mode 100644 index c27c7a110e..0000000000 --- a/lib/browser/.eslintrc.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "env": { - "worker": true, - "node": false - }, - "globals": { - "global": true - }, - "parserOptions": { - "ecmaFeatures": { - "forOf": false - }, - "sourceType": "module" - }, - "rules": { - "no-console": 0, - "strict": 0 - } -} diff --git a/lib/browser/app.js b/lib/browser/app.js deleted file mode 100644 index 02261b39f2..0000000000 --- a/lib/browser/app.js +++ /dev/null @@ -1,70 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2020 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { keys, objectTypes } from "./constants"; -import { createMethods, getterForProperty } from "./util"; -import { setVersions, createAppRPC } from "./rpc"; -import { promisify } from "../utils"; - -function setupApp(app, info) { - app[keys.id] = info.id; - app[keys.realm] = "(App object)"; - app[keys.type] = objectTypes.APP; -} - -export default class App { - constructor(config) { - let info = createAppRPC(config); - setupApp(this, info); - } - - /** - * Invokes the RPC client to set versions. - * @todo Turn this into a call to the static App._setVersions method if the RPC layer supported invoking remote static methods. - * @param {object} versions An object containing package and platform names and versions. - */ - static _setVersions(versions) { - return setVersions(versions); - } - - logIn(credentials) { - return promisify((cb) => this._logIn(credentials, cb)); - } -} - -createMethods(App.prototype, objectTypes.APP, ["_logIn", "switchUser"], true); - -Object.defineProperties(App.prototype, { - currentUser: { get: getterForProperty("currentUser") }, - allUsers: { get: getterForProperty("allUsers") }, - emailPasswordAuth: { get: getterForProperty("emailPasswordAuth") }, -}); - -export function createApp(realmId, info) { - const appProxy = Object.create(App.prototype); - - // FIXME: This is currently necessary because util/createMethod expects - // the realm id to be present on any object that is used over rpc - appProxy[keys.realm] = "(App object)"; - - appProxy[keys.id] = info.id; - appProxy[keys.type] = objectTypes.APP; - Object.assign(appProxy, info.data); - - return appProxy; -} diff --git a/lib/browser/async-open-task.js b/lib/browser/async-open-task.js deleted file mode 100644 index e420cfb7d0..0000000000 --- a/lib/browser/async-open-task.js +++ /dev/null @@ -1,32 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2019 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { keys, objectTypes } from "./constants"; -import { createMethods } from "./util"; - -export default class AsyncOpenTask {} - -createMethods(AsyncOpenTask.prototype, objectTypes.ASYNCOPENTASK, ["addDownloadNotification", "cancel"]); - -export function createAsyncOpenTask(realmId, info) { - let task = Object.create(AsyncOpenTask.prototype); - task[keys.realm] = "(AsyncOpenTask object)"; - task[keys.id] = info.id; - task[keys.type] = objectTypes.ASYNCOPENTASK; - return task; -} diff --git a/lib/browser/base64.js b/lib/browser/base64.js deleted file mode 100644 index 60fe2bede3..0000000000 --- a/lib/browser/base64.js +++ /dev/null @@ -1,84 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -const CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -const CHAR_MAP = {}; - -Array.from(CHARS, (char, i) => (CHAR_MAP[char] = i)); - -export function decode(base64) { - let length = base64.length; - let byteCount = length * 0.75; - - if (base64[length - 1] === "=") { - byteCount--; - if (base64[length - 2] === "=") { - byteCount--; - } - } - - let buffer = new ArrayBuffer(byteCount); - let bytes = new Uint8Array(buffer); - - for (let i = 0, j = 0; i < length; i += 4) { - let index1 = CHAR_MAP[base64[i]]; - let index2 = CHAR_MAP[base64[i + 1]]; - let index3 = CHAR_MAP[base64[i + 2]]; - let index4 = CHAR_MAP[base64[i + 3]]; - - bytes[j++] = (index1 << 2) + ((index2 & 0x30) >> 4); - bytes[j++] = ((index2 & 0x0f) << 4) + ((index3 & 0x3c) >> 2); - bytes[j++] = ((index3 & 0x03) << 6) + index4; - } - - return buffer; -} - -export function encode(data) { - var byteOffset = 0; - var buffer; - - if (data instanceof ArrayBuffer) { - buffer = data; - } else if (ArrayBuffer.isView(data)) { - buffer = data.buffer; - byteOffset = data.byteOffset; - } else { - throw new TypeError("Can only base64 encode ArrayBuffer and ArrayBufferView objects"); - } - - let byteCount = data.byteLength; - let bytes = new Uint8Array(buffer, byteOffset, byteCount); - let base64 = ""; - - for (let i = 0; i < byteCount; i += 3) { - base64 += CHARS[(bytes[i] & 0xfc) >> 2]; - base64 += CHARS[((bytes[i] & 0x03) << 4) + ((bytes[i + 1] & 0xf0) >> 4)]; - base64 += CHARS[((bytes[i + 1] & 0x0f) << 2) + ((bytes[i + 2] & 0xc0) >> 6)]; - base64 += CHARS[bytes[i + 2] & 0x3f]; - } - - switch (byteCount % 3) { - case 1: - return base64.slice(0, -2) + "=="; - case 2: - return base64.slice(0, -1) + "="; - default: - return base64; - } -} diff --git a/lib/browser/cache.js b/lib/browser/cache.js deleted file mode 100644 index 7a87e9daa4..0000000000 --- a/lib/browser/cache.js +++ /dev/null @@ -1,35 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2020 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -export let propertyCache = {}; - -export function invalidateCache(realmId) { - if (realmId) { - propertyCache[realmId] = {}; - } else { - propertyCache = {}; - } -} - -export function getRealmCache(realmId) { - let realmCache = propertyCache[realmId]; - if (!realmCache) { - realmCache = propertyCache[realmId] = {}; - } - return realmCache; -} diff --git a/lib/browser/collections.js b/lib/browser/collections.js deleted file mode 100644 index 50450b7c0f..0000000000 --- a/lib/browser/collections.js +++ /dev/null @@ -1,106 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { keys } from "./constants"; -import * as util from "./util"; -import * as rpc from "./rpc"; -import { invalidateCache } from "./cache"; - -export default class Collection { - constructor() { - throw new TypeError("Illegal constructor"); - } -} - -function isIndex(propertyName) { - return typeof propertyName === "number" || (typeof propertyName === "string" && /^-?\d+$/.test(propertyName)); -} - -const mutable = Symbol("mutable"); - -const traps = { - get(collection, property) { - if (isIndex(property)) { - return util.getProperty(collection, property); - } - - return Reflect.get(collection, property, collection); - }, - set(collection, property, value) { - if (isIndex(property)) { - if (!collection[mutable]) { - return false; - } - - invalidateCache(collection[keys.realm]); - rpc.setProperty(collection[keys.realm], collection[keys.id], property, value); - return true; - } - - if (!Reflect.set(collection, property, value, collection)) { - throw new TypeError(`Cannot assign to read only property '${property}'`); - } - return true; - }, - ownKeys(collection) { - return Reflect.ownKeys(collection).concat(Array.from({ length: collection.length }, (value, key) => String(key))); - }, - getOwnPropertyDescriptor(collection, property) { - if (isIndex(property)) { - let descriptor = { - enumerable: true, - configurable: true, - writable: collection[mutable], - }; - Reflect.defineProperty(descriptor, "value", { get: () => this.get(collection, property) }); - return descriptor; - } - - return Reflect.getOwnPropertyDescriptor(collection, property); - }, - has(collection, property) { - if (isIndex(property)) { - return true; - } - - return Reflect.has(collection, property); - }, -}; - -export function createCollection(prototype, realmId, info, _mutable) { - let collection = Object.create(prototype); - - Object.defineProperties(collection, { - length: { - get: util.getterForProperty("length"), - }, - type: { - value: info.dataType, - }, - optional: { - value: info.optional, - }, - }); - - collection[keys.realm] = realmId; - collection[keys.id] = info.id; - collection[keys.type] = info.type; - collection[mutable] = _mutable; - - return new Proxy(collection, traps); -} diff --git a/lib/browser/constants.js b/lib/browser/constants.js deleted file mode 100644 index 409cd75647..0000000000 --- a/lib/browser/constants.js +++ /dev/null @@ -1,61 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -export const keys = {}; -export const objectTypes = {}; -export const propTypes = {}; - -["id", "realm", "type"].forEach(function (name) { - keys[name] = Symbol(name); -}); - -[ - "DATA", - "DATE", - "DICT", - "ERROR", - "FUNCTION", - "LIST", - "SET", - "DICTIONARY", - "OBJECT", - "REALM", - "RESULTS", - "USER", - "SESSION", - "ASYNCOPENTASK", - "APP", - "CREDENTIALS", - "FETCHRESPONSEHANDLER", - "UNDEFINED", - "EMAILPASSWORDAUTH", - "EJSON", -].forEach(function (type) { - Object.defineProperty(objectTypes, type, { - value: type.toLowerCase(), - }); -}); - -["BOOL", "INT", "FLOAT", "DOUBLE", "DECIMAL", "STRING", "DATE", "DATA", "OBJECT", "LIST", "OBJECTID"].forEach(function ( - type, -) { - Object.defineProperty(propTypes, type, { - value: type.toLowerCase(), - enumerable: true, - }); -}); diff --git a/lib/browser/credentials.js b/lib/browser/credentials.js deleted file mode 100644 index 51c45e83f5..0000000000 --- a/lib/browser/credentials.js +++ /dev/null @@ -1,82 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2020 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { keys, objectTypes } from "./constants"; -import { - _anonymousRPC, - _facebookRPC, - _functionRPC, - _googleRPC, - _appleRPC, - _emailPasswordRPC, - _userApiKeyRPC, - _serverApiKeyRPC, - _jwtRPC, -} from "./rpc"; - -export default class Credentials { - static anonymous() { - return _anonymousRPC(); - } - - static facebook(token) { - return _facebookRPC(token); - } - - static apple(token) { - return _appleRPC(token); - } - - static emailPassword(email, password) { - return _emailPasswordRPC(email, password); - } - - static userApiKey(user_key) { - return _userApiKeyRPC(user_key); - } - - static function(payload) { - return _functionRPC(payload); - } - - static serverApiKey(server_key) { - return _serverApiKeyRPC(server_key); - } - - static google(authCode) { - return _googleRPC(authCode); - } - - static jwt(token) { - return _jwtRPC(token); - } -} - -export function createCredentials(realmId, info) { - const credentialsProxy = Object.create(Credentials.prototype); - - // FIXME: This is currently necessary because util/createMethod expects - // the realm id to be present on any object that is used over rpc - credentialsProxy[keys.realm] = "(Credentials object)"; - - credentialsProxy[keys.id] = info.id; - credentialsProxy[keys.type] = objectTypes.CREDENTIALS; - Object.assign(credentialsProxy, info.data); - - return credentialsProxy; -} diff --git a/lib/browser/dictionaries.js b/lib/browser/dictionaries.js deleted file mode 100644 index 10ed29c494..0000000000 --- a/lib/browser/dictionaries.js +++ /dev/null @@ -1,29 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2021 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import Collection, { createCollection } from "./collections"; - -export default class Dictionary extends Collection { - constructor() { - throw new Error("Dictionaries are not yet supported in Chrome debugging mode"); - } -} - -export function createDictionary(realmId, info) { - return createCollection(Dictionary.prototype, realmId, info, true); -} diff --git a/lib/browser/email-password-auth.js b/lib/browser/email-password-auth.js deleted file mode 100644 index fb9073f4c0..0000000000 --- a/lib/browser/email-password-auth.js +++ /dev/null @@ -1,99 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2020 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { keys, objectTypes } from "./constants"; -import { createMethods } from "./util"; -import { promisify } from "../utils"; -import { handleDeprecatedPositionalArgs } from "@realm.io/common"; - -// TODO for v11: change all signatures to methodName(argsObject) and remove handleDeprecatedPositionalArgs call -// -// Example post-v11: -// registerUser(argsObject) { -// return promisify((cb) => this._registerUser(argsObject, cb)); -// }, -export class EmailPasswordAuth { - registerUser(...args) { - const { argsObject } = handleDeprecatedPositionalArgs(args, "registerUser", ["email", "password"]); - - return promisify((cb) => this._registerUser(argsObject, cb)); - } - - confirmUser(...args) { - const { argsObject } = handleDeprecatedPositionalArgs(args, "confirmUser", ["token", "tokenId"]); - - return promisify((cb) => this._confirmUser(argsObject, cb)); - } - - resendConfirmationEmail(...args) { - const { argsObject } = handleDeprecatedPositionalArgs(args, "resendConfirmationEmail", ["email"]); - - return promisify((cb) => this._resendConfirmationEmail(argsObject, cb)); - } - - retryCustomConfirmation(...args) { - const { argsObject } = handleDeprecatedPositionalArgs(args, "retryCustomConfirmation", ["email"]); - - return promisify((cb) => this._retryCustomConfirmation(argsObject, cb)); - } - - sendResetPasswordEmail(...args) { - const { argsObject } = handleDeprecatedPositionalArgs(args, "sendResetPasswordEmail", ["email"]); - - return promisify((cb) => this._sendResetPasswordEmail(argsObject, cb)); - } - - resetPassword(...args) { - const { argsObject } = handleDeprecatedPositionalArgs(args, "resetPassword", ["password", "token", "tokenId"]); - - return promisify((cb) => this._resetPassword(argsObject, cb)); - } - - callResetPasswordFunction(...args) { - const { argsObject, restArgs } = handleDeprecatedPositionalArgs( - args, - "callResetPasswordFunction", - ["email", "password"], - true, - ); - - return promisify((cb) => this._callResetPasswordFunction(argsObject, restArgs, cb)); - } -} - -createMethods(EmailPasswordAuth.prototype, objectTypes.EMAILPASSWORDAUTH, [ - "_registerUser", - "_confirmUser", - "_resendConfirmationEmail", - "_retryCustomConfirmation", - "_sendResetPasswordEmail", - "_resetPassword", - "_callResetPasswordFunction", -]); - -export function createEmailPasswordAuth(realmId, info) { - const proxy = Object.create(EmailPasswordAuth.prototype); - - // FIXME: This is currently necessary because util/createMethod expects - // the realm id to be present on any object that is used over rpc - proxy[keys.realm] = "(EmailPasswordAuth object)"; - proxy[keys.id] = info.id; - proxy[keys.type] = objectTypes.EMAILPASSWORDAUTH; - - return proxy; -} diff --git a/lib/browser/fetch.js b/lib/browser/fetch.js deleted file mode 100644 index c51ff671c4..0000000000 --- a/lib/browser/fetch.js +++ /dev/null @@ -1,64 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2020 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { objectTypes } from "./constants"; -import { callMethod, registerTypeConverter } from "./rpc"; - -export function performFetch(request, responseHandler) { - const { url, ...init } = request; - if (typeof url !== "string") { - throw new Error("Expected a URL"); - } - if (typeof responseHandler !== "object") { - throw new Error("Expected a response handler object"); - } - const { onSuccess, onError } = responseHandler; - // Delegate to fetch - fetch(url, init) - .then(async (response) => { - const decodedBody = await response.text(); - // Pull out the headers of the response - const headers = {}; - response.headers.forEach((value, key) => { - headers[key] = value; - }); - return { - statusCode: response.status, - headers, - body: decodedBody, - }; - }) - .then(onSuccess, onError); -} - -function deserializeResponseHandler(realmId, info) { - const { id } = info; - if (typeof id !== "number") { - throw new Error("Expected a nummeric id"); - } - return { - onSuccess: function () { - callMethod(undefined, id, "onSuccess", Array.from(arguments)); - }, - onError: function () { - callMethod(undefined, id, "onError", Array.from(arguments)); - }, - }; -} - -registerTypeConverter(objectTypes.FETCHRESPONSEHANDLER, deserializeResponseHandler); diff --git a/lib/browser/index.js b/lib/browser/index.js deleted file mode 100644 index 41780c0545..0000000000 --- a/lib/browser/index.js +++ /dev/null @@ -1,242 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { NativeModules } from "react-native"; -import { keys, objectTypes } from "./constants"; -import Collection from "./collections"; -import List, { createList } from "./lists"; -import Set, { createSet } from "./sets"; -import Dictionary, { createDictionary } from "./dictionaries"; -import Results, { createResults } from "./results"; -import RealmObject, * as objects from "./objects"; -import User, { createUser } from "./user"; -import { createAsyncOpenTask } from "./async-open-task"; -import App, { createApp } from "./app"; -import Credentials, { createCredentials } from "./credentials"; -import * as rpc from "./rpc"; -import * as util from "./util"; -import { createSession } from "./session"; -import { invalidateCache } from "./cache"; -import { performFetch } from "./fetch"; -import { createEmailPasswordAuth } from "./email-password-auth"; - -const { debugHosts, debugPort } = NativeModules.Realm; - -rpc.registerTypeConverter(objectTypes.LIST, createList); -rpc.registerTypeConverter(objectTypes.SET, createSet); -rpc.registerTypeConverter(objectTypes.DICTIONARY, createDictionary); -rpc.registerTypeConverter(objectTypes.RESULTS, createResults); -rpc.registerTypeConverter(objectTypes.OBJECT, objects.createObject); -rpc.registerTypeConverter(objectTypes.REALM, createRealm); -rpc.registerTypeConverter(objectTypes.USER, createUser); -rpc.registerTypeConverter(objectTypes.SESSION, createSession); -rpc.registerTypeConverter(objectTypes.ASYNCOPENTASK, createAsyncOpenTask); -rpc.registerTypeConverter(objectTypes.APP, createApp); -rpc.registerTypeConverter(objectTypes.CREDENTIALS, createCredentials); -rpc.registerTypeConverter(objectTypes.EMAILPASSWORDAUTH, createEmailPasswordAuth); - -function createRealm(_, info) { - let realm = Object.create(Realm.prototype); - setupRealm(realm, info); - return realm; -} - -function setupRealm(realm, info) { - realm[keys.id] = info.id; - realm[keys.realm] = info.realmId; - realm[keys.type] = objectTypes.REALM; - - ["empty", "schema", "schemaVersion", "isInTransaction", "isClosed"].forEach((name) => { - Object.defineProperty(realm, name, { get: util.getterForProperty(name) }); - }); - for (let key in info.data) { - realm[key] = rpc.deserialize(info.id, info.data[key]); - } -} - -function getObjectType(realm, type) { - if (typeof type == "function") { - return objects.typeForConstructor(realm[keys.realm], type); - } - return type; -} - -export default class Realm { - constructor(config) { - let schemas = typeof config === "object" && config.schema; - let constructors = schemas ? {} : null; - - for (let i = 0, len = schemas ? schemas.length : 0; i < len; i++) { - let item = schemas[i]; - - if (typeof item == "function") { - let schema = item.schema; - if (!schema || typeof schema != "object") { - throw new Error("Realm object constructor must have a 'schema' property."); - } - - let { name, properties } = schema; - if (!name || typeof name != "string") { - throw new Error(`Failed to read ObjectSchema: name must be of type 'string', got (${typeof name})`); - } else if (!properties || typeof properties != "object") { - throw new Error( - `Failed to read ObjectSchema: properties must be of type 'object', got (${typeof properties})`, - ); - } - - schemas.splice(i, 1, schema); - constructors[name] = item; - } - } - - let info = rpc.createRealm(Array.from(arguments)); - setupRealm(this, info); - - // This will create mappings between the id, path, and potential constructors. - objects.registerConstructors(info.realmId, this.path, constructors); - } - - create(type, ...args) { - let method = util.createMethod(objectTypes.REALM, "create", true); - return method.apply(this, [getObjectType(this, type), ...args]); - } - - objects(type, ...args) { - let method = util.createMethod(objectTypes.REALM, "objects"); - return method.apply(this, [getObjectType(this, type), ...args]); - } - - objectForPrimaryKey(type, ...args) { - let method = util.createMethod(objectTypes.REALM, "objectForPrimaryKey"); - return method.apply(this, [getObjectType(this, type), ...args]); - } -} - -// Non-mutating methods: -util.createMethods(Realm.prototype, objectTypes.REALM, [ - "addListener", - "removeListener", - "removeAllListeners", - "writeCopyTo", - "_waitForDownload", -]); - -// Mutating methods: -util.createMethods( - Realm.prototype, - objectTypes.REALM, - [ - "delete", - "deleteModel", - "deleteAll", - "write", - "compact", - "close", - "beginTransaction", - "commitTransaction", - "cancelTransaction", - ], - true, -); - -Object.defineProperties(Realm, { - Collection: { - value: Collection, - }, - List: { - value: List, - }, - Set: { - value: Set, - }, - Dictionary: { - value: Dictionary, - }, - Results: { - value: Results, - }, - Object: { - value: RealmObject, - }, - App: { - value: App, - }, - Credentials: { - value: Credentials, - }, - User: { - value: User, - }, - defaultPath: { - get: util.getterForProperty("defaultPath", false), - set: util.setterForProperty("defaultPath"), - }, - schemaVersion: { - value: function () { - return rpc.callMethod(undefined, Realm[keys.id], "schemaVersion", Array.from(arguments)); - }, - }, - deleteFile: { - value: function () { - return rpc.callMethod(undefined, Realm[keys.id], "deleteFile", Array.from(arguments)); - }, - }, - copyBundledRealmFiles: { - value: function () { - return rpc.callMethod(undefined, Realm[keys.id], "copyBundledRealmFiles", []); - }, - }, - clearTestState: { - value: function () { - objects.clearRegisteredConstructors(); - invalidateCache(); - rpc.clearTestState(); - }, - }, - _asyncOpen: { - value: function (config, callback) { - return rpc.asyncOpenRealm(Realm[keys.id], config, callback); - }, - }, - exists: { - value: function () { - return rpc.callMethod(undefined, Realm[keys.id], "exists", Array.from(arguments)); - }, - }, -}); - -for (let i = 0, len = debugHosts.length; i < len; i++) { - try { - Realm[keys.id] = rpc.createSession(debugHosts[i] + ":" + debugPort, { performFetch }); - break; - } catch (e) { - // Only throw exception after all hosts have been tried. - if (i < len - 1) { - continue; - } - - // Log the original exception for debugging purposes. - console.error(e); - - throw new Error( - "Realm failed to connect to the embedded debug server inside the app. " + - "If attempting to use Chrome debugging from a device, ensure the device is " + - "reachable on the same network as this machine.", - ); - } -} diff --git a/lib/browser/lists.js b/lib/browser/lists.js deleted file mode 100644 index acc5bc2f16..0000000000 --- a/lib/browser/lists.js +++ /dev/null @@ -1,47 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import Collection, { createCollection } from "./collections"; -import { objectTypes } from "./constants"; -import { createMethods } from "./util"; - -export default class List extends Collection {} - -// Non-mutating methods: -createMethods(List.prototype, objectTypes.LIST, [ - "filtered", - "sorted", - "snapshot", - "isValid", - "isEmpty", - "indexOf", - "min", - "max", - "sum", - "avg", - "addListener", - "removeListener", - "removeAllListeners", -]); - -// Mutating methods: -createMethods(List.prototype, objectTypes.LIST, ["pop", "shift", "push", "unshift", "splice"], true); - -export function createList(realmId, info) { - return createCollection(List.prototype, realmId, info, true); -} diff --git a/lib/browser/objects.js b/lib/browser/objects.js deleted file mode 100644 index 015e022962..0000000000 --- a/lib/browser/objects.js +++ /dev/null @@ -1,98 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { keys, objectTypes } from "./constants"; -import { getterForProperty, setterForProperty, createMethods, cacheObject } from "./util"; -import * as rpc from "./rpc"; - -let registeredConstructors = {}; -let registeredRealmPaths = {}; - -export default class RealmObject {} - -// Non-mutating methods: -createMethods(RealmObject.prototype, objectTypes.OBJECT, [ - "isValid", - "objectSchema", - "linkingObjects", - "linkingObjectsCount", - "_objectId", - "_isSameObject", - "addListener", - "removeListener", - "removeAllListeners", - "getPropertyType", -]); - -export function clearRegisteredConstructors() { - registeredConstructors = {}; - registeredRealmPaths = {}; -} - -export function createObject(realmId, info) { - let schema = info.schema; - let realmPath = registeredRealmPaths[realmId]; - let constructor = (registeredConstructors[realmPath] || {})[schema.name]; - let object = Object.create(constructor ? constructor.prototype : RealmObject.prototype); - - object[keys.realm] = realmId; - object[keys.id] = info.id; - object[keys.type] = info.type; - - schema.properties.forEach((name) => { - Object.defineProperty(object, name, { - enumerable: true, - get: getterForProperty(name), - set: setterForProperty(name), - }); - }); - - if (constructor) { - let result = constructor.call(object); - if (result != null && result != object) { - throw new Error("Realm object constructor must not return another value"); - } - } - for (let key in info.cache) { - info.cache[key] = rpc.deserialize(undefined, info.cache[key]); - } - cacheObject(realmId, info.id, info.cache); - - return object; -} - -export function registerConstructors(realmId, realmPath, constructors) { - registeredRealmPaths[realmId] = realmPath; - - if (constructors) { - registeredConstructors[realmPath] = constructors; - } -} - -export function typeForConstructor(realmId, constructor) { - let realmPath = registeredRealmPaths[realmId]; - let constructors = registeredConstructors[realmPath]; - - for (let name in constructors) { - if (constructors[name] == constructor) { - return name; - } - } - - throw new Error("Constructor was not registered in the schema for this Realm"); -} diff --git a/lib/browser/results.js b/lib/browser/results.js deleted file mode 100644 index 5c472032ec..0000000000 --- a/lib/browser/results.js +++ /dev/null @@ -1,48 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import Collection, { createCollection } from "./collections"; -import { objectTypes } from "./constants"; -import { createMethods } from "./util"; - -export default class Results extends Collection {} - -// Non-mutating methods: -createMethods(Results.prototype, objectTypes.RESULTS, [ - "description", - "filtered", - "sorted", - "snapshot", - "isValid", - "isEmpty", - "indexOf", - "min", - "max", - "sum", - "avg", - "addListener", - "removeListener", - "removeAllListeners", -]); - -// Mutating methods: -createMethods(Results.prototype, objectTypes.RESULTS, ["update"], true); - -export function createResults(realmId, info) { - return createCollection(Results.prototype, realmId, info); -} diff --git a/lib/browser/rpc.js b/lib/browser/rpc.js deleted file mode 100644 index d3ee756d08..0000000000 --- a/lib/browser/rpc.js +++ /dev/null @@ -1,407 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { EJSON, ObjectId, Decimal128 } from "bson"; - -import * as base64 from "./base64"; -import { keys, objectTypes } from "./constants"; -import { invalidateCache } from "./cache"; - -const { id: idKey } = keys; -let registeredCallbacks = []; -const typeConverters = {}; - -// Callbacks that are registered initially (currently only refreshAccessToken) will -// carry this symbol so they are not wiped in clearTestState. -const persistentCallback = Symbol("persistentCallback"); - -let XMLHttpRequest = global.originalXMLHttpRequest || global.XMLHttpRequest; -let sessionHost; -let sessionId; - -// Check if XMLHttpRequest has been overridden, and get the native one if that's the case. -if (XMLHttpRequest.__proto__ != global.XMLHttpRequestEventTarget) { - let fakeXMLHttpRequest = XMLHttpRequest; - delete global.XMLHttpRequest; - XMLHttpRequest = global.XMLHttpRequest; - global.XMLHttpRequest = fakeXMLHttpRequest; -} - -registerTypeConverter(objectTypes.DATA, (_, { value }) => base64.decode(value)); -registerTypeConverter(objectTypes.DATE, (_, { value }) => new Date(value)); -registerTypeConverter(objectTypes.EJSON, (_, { value }) => EJSON.deserialize(value)); -registerTypeConverter(objectTypes.DICT, deserializeDict); -registerTypeConverter(objectTypes.ERROR, deserializeError); -registerTypeConverter(objectTypes.FUNCTION, deserializeFunction); - -export function registerTypeConverter(type, handler) { - typeConverters[type] = handler; -} - -function beforeNotify(realm) { - // NOTE: the mere existence of this function is important for read - // isolation even independent of what it does in its body. By having a - // beforenotify listener, we ensure that the RPC server can't proceed in - // notify() to autorefresh until the browser performs a callback poll. - // Without this, the RPC server could autorefresh in between two subsequent - // property reads from the browser. - - // Clear the cache for this Realm, and reenable caching if it was disabled - // by a write transaction. - invalidateCache(realm[keys.realm]); -} - -export function createSession(host, { versions, performFetch }) { - sessionHost = host; - - sessionId = sendRequest( - "create_session", - { - versions, - fetch: serialize(undefined, performFetch), - }, - host, - ); - - return sessionId; -} - -export function createRealm(args) { - if (args) { - args = args.map((arg) => serialize(null, arg)); - } - - return sendRequest("create_realm", { arguments: args, beforeNotify: serialize(null, beforeNotify) }); -} - -export function createAppRPC(config) { - return sendRequest("create_app", { arguments: [serialize(null, config)] }); -} - -export function asyncOpenRealm(id, config, callback) { - return deserialize( - undefined, - sendRequest("call_method", { - id, - name: "_asyncOpen", - arguments: [ - serialize(null, config), - serialize(null, (realm, error) => { - if (realm) { - realm.addListener("beforenotify", beforeNotify); - } - callback(realm, error); - }), - ], - }), - ); -} - -export function setVersions(versions) { - sendRequest("set_versions", { versions: serialize(null, versions) }); -} - -export function _anonymousRPC() { - const result = sendRequest("_anonymous", { arguments: undefined }); - return deserialize(undefined, result); -} - -export function _appleRPC() { - const args = Array.prototype.map.call(arguments, (arg) => serialize(null, arg)); - const result = sendRequest("_apple", { arguments: args }); - return deserialize(undefined, result); -} - -export function _emailPasswordRPC() { - const args = Array.prototype.map.call(arguments, (arg) => serialize(null, arg)); - const result = sendRequest("_emailPassword", { arguments: args }); - return deserialize(undefined, result); -} - -export function _facebookRPC() { - const args = Array.prototype.map.call(arguments, (arg) => serialize(null, arg)); - const result = sendRequest("_facebook", { arguments: args }); - return deserialize(undefined, result); -} - -export function _functionRPC() { - const args = Array.prototype.map.call(arguments, (arg) => serialize(null, arg)); - const result = sendRequest("_function", { arguments: args }); - return deserialize(undefined, result); -} - -export function _googleRPC() { - const args = Array.prototype.map.call(arguments, (arg) => serialize(null, arg)); - const result = sendRequest("_google", { arguments: args }); - return deserialize(undefined, result); -} -export function _userApiKeyRPC() { - const args = Array.prototype.map.call(arguments, (arg) => serialize(null, arg)); - const result = sendRequest("_userAPIKey", { arguments: args }); - return deserialize(undefined, result); -} - -export function _serverApiKeyRPC() { - const args = Array.prototype.map.call(arguments, (arg) => serialize(null, arg)); - const result = sendRequest("_serverAPIKey", { arguments: args }); - return deserialize(undefined, result); -} - -export function _jwtRPC() { - const args = Array.prototype.map.call(arguments, (arg) => serialize(null, arg)); - const result = sendRequest("_jwt", { arguments: args }); - return deserialize(undefined, result); -} - -export function callSyncFunction(name, args) { - args = (args || []).map((arg) => serialize(null, arg)); - let result = sendRequest("call_sync_function", { name, arguments: args }); - return deserialize(undefined, result); -} - -export function callMethod(realmId, id, name, args) { - if (!Array.isArray(args)) { - throw new Error("Expected an array of arguments"); - } - const serializedArgs = args.map((arg) => serialize(realmId, arg)); - const result = sendRequest("call_method", { realmId, id, name, arguments: serializedArgs }); - return deserialize(realmId, result); -} - -export function getObject(realmId, id, name) { - let result = sendRequest("get_object", { realmId, id, name }); - if (!result) { - return result; - } - for (let key in result) { - result[key] = deserialize(realmId, result[key]); - } - return result; -} - -export function getProperty(realmId, id, name) { - let result = sendRequest("get_property", { realmId, id, name }); - return deserialize(realmId, result); -} - -export function setProperty(realmId, id, name, value) { - value = serialize(realmId, value); - sendRequest("set_property", { realmId, id, name, value }); -} - -export function clearTestState() { - sendRequest("clear_test_state"); - - // Clear all registered callbacks that are specific to this session. - registeredCallbacks = registeredCallbacks.filter((cb) => Reflect.has(cb, persistentCallback)); -} - -function registerCallback(callback) { - let key = registeredCallbacks.indexOf(callback); - return key >= 0 ? key : registeredCallbacks.push(callback) - 1; -} - -function serialize(realmId, value) { - if (typeof value == "undefined") { - return { type: objectTypes.UNDEFINED }; - } - if (typeof value == "function") { - return { type: objectTypes.FUNCTION, value: registerCallback(value) }; - } - if (!value || typeof value != "object") { - return { value: value }; - } - - let id = value[idKey]; - if (id) { - return { id }; - } - - if (value instanceof Date) { - return { type: objectTypes.DATE, value: value.getTime() }; - } - - if (Array.isArray(value)) { - let array = value.map((item) => serialize(realmId, item)); - return { value: array }; - } - - if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) { - return { type: objectTypes.DATA, value: base64.encode(value) }; - } - - if (value instanceof ObjectId || value instanceof Decimal128) { - return { - type: objectTypes.EJSON, - value: EJSON.serialize(value, { relaxed: false }), - }; - } - - let keys = Object.keys(value); - let values = keys.map((key) => serialize(realmId, value[key])); - return { type: objectTypes.DICT, keys, values }; -} - -export function deserialize(realmId, info) { - let type = info.type; - let handler = type && typeConverters[type]; - if (handler) { - return handler(realmId, info); - } - - let value = info.value; - if (value && Array.isArray(value)) { - return value.map((item) => deserialize(realmId, item)); - } - - return value; -} - -function deserializeDict(realmId, info) { - let { keys, values } = info; - let object = {}; - - for (let i = 0, len = keys.length; i < len; i++) { - object[keys[i]] = deserialize(realmId, values[i]); - } - - return object; -} - -function deserializeError(realmId, info) { - const { message, stack } = info.error; - const err = new Error(message.value); - err.stack = stack.value; - return err; -} - -function deserializeFunction(realmId, info) { - return registeredCallbacks[info.value]; -} - -function makeRequest(url, data) { - let statusCode; - let responseText; - - // The global __debug__ object is provided by Visual Studio Code. - if (global.__debug__) { - let request = global.__debug__.require("sync-request"); - let response = request("POST", url, { - body: JSON.stringify(data), - headers: { - "Content-Type": "text/plain;charset=UTF-8", - }, - }); - - statusCode = response.statusCode; - responseText = response.body.toString("utf-8"); - } else { - let body = JSON.stringify(data); - let request = new XMLHttpRequest(); - - request.open("POST", url, false); - request.send(body); - - statusCode = request.status; - responseText = request.responseText; - } - - if (statusCode != 200) { - throw new Error(responseText); - } - - return JSON.parse(responseText); -} - -let pollTimeoutId; -let pollTimeout = 10; - -function sendRequest(command, data, host = sessionHost) { - clearTimeout(pollTimeoutId); - try { - if (!host) { - throw new Error("Must first create RPC session with a valid host"); - } - - data = Object.assign({}, data, sessionId ? { sessionId } : null); - - let url = "http://" + host + "/" + command; - let response = makeRequest(url, data); - let callback = response && response.callback; - - // Reset the callback poll interval to 10ms every time we either hit a - // callback or call any other method, and double it each time we poll - // for callbacks and get nothing until it's over a second. - if (callback || command !== "callbacks_poll") { - pollTimeout = 10; - } else if (pollTimeout < 1000) { - pollTimeout *= 2; - } - - if (!response || response.error) { - let error = response && response.error; - - // Remove the type prefix from the error message (e.g. "Error: "). - if (error && typeof error === "string") { - error = error.replace(/^[a-z]+: /i, ""); - } else if (error.type && error.type === "error") { - const err = new Error(error.message.value); - err.stack = error.stack.value; - throw err; - } - - throw new Error(error || `Invalid response for "${command}"`); - } - if (callback != null) { - let result, error, stack; - try { - let realmId = data.realmId; - let thisObject = deserialize(realmId, response.this); - let args = deserialize(realmId, response.arguments); - const fn = registeredCallbacks[callback]; - if (fn) { - result = serialize(realmId, fn.apply(thisObject, args)); - } else { - error = `Unknown callback id: ${callback}`; - } - } catch (e) { - error = e.message || "" + e; - if (e.stack) { - stack = JSON.stringify(e.stack); - } - } - - let callbackCommand = "callback_result"; - if (command === "callbacks_poll" || command === "callback_poll_result") { - callbackCommand = "callback_poll_result"; - } - - return sendRequest(callbackCommand, { - callback, - result, - error, - stack, - callback_call_counter: response.callback_call_counter, - }); - } - - return response.result; - } finally { - pollTimeoutId = setTimeout(() => sendRequest("callbacks_poll"), pollTimeout); - } -} diff --git a/lib/browser/session.js b/lib/browser/session.js deleted file mode 100644 index 3abe50810e..0000000000 --- a/lib/browser/session.js +++ /dev/null @@ -1,60 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { keys, objectTypes } from "./constants"; -import { getterForProperty, createMethods } from "./util"; -import { deserialize } from "./rpc"; - -export default class Session {} - -Object.defineProperties(Session.prototype, { - connectionState: { get: getterForProperty("connectionState", false) }, - state: { get: getterForProperty("state", false) }, - url: { get: getterForProperty("url", false) }, -}); - -createMethods(Session.prototype, objectTypes.SESSION, [ - "_refreshAccessToken", - "_simulateError", - "addProgressNotification", - "removeProgressNotification", - "addConnectionNotification", - "removeConnectionNotification", - "isConnected", - "resume", - "pause", - "_waitForDownloadCompletion", - "_waitForUploadCompletion", -]); - -export function createSession(realmId, info) { - let sessionProxy = Object.create(Session.prototype); - - // FIXME: This is currently necessary because util/createMethod expects - // the realm id to be present on any object that is used over rpc - sessionProxy[keys.realm] = "(Session object)"; - - if (info && info.data && info.data.user) { - sessionProxy[keys.id] = info.id; - sessionProxy[keys.type] = objectTypes.SESSION; - sessionProxy.user = deserialize(realmId, info.data.user); - sessionProxy.config = deserialize(realmId, info.data.config); - } - - return sessionProxy; -} diff --git a/lib/browser/sets.js b/lib/browser/sets.js deleted file mode 100644 index 9fa90547ad..0000000000 --- a/lib/browser/sets.js +++ /dev/null @@ -1,29 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2021 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import Collection, { createCollection } from "./collections"; - -export default class Set extends Collection { - constructor() { - throw new Error("Sets are not yet supported in Chrome debugging mode"); - } -} - -export function createSet(realmId, info) { - return createCollection(Set.prototype, realmId, info, true); -} diff --git a/lib/browser/user.js b/lib/browser/user.js deleted file mode 100644 index a33955f798..0000000000 --- a/lib/browser/user.js +++ /dev/null @@ -1,91 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { EJSON } from "bson"; - -import { keys, objectTypes } from "./constants"; -import { getterForProperty, createMethods } from "./util"; -import { promisify } from "../utils"; - -export default class User { - logOut() { - return promisify((cb) => this._logOut(cb)); - } - - async callFunction(name, args, service) { - const stringifiedArgs = EJSON.stringify(args, { relaxed: false }); - const result = await promisify((cb) => this._callFunction(name, stringifiedArgs, service, cb)); - return EJSON.parse(result); - } - - get functions() { - return new Proxy(this, { - get(target, name, receiver) { - if (typeof name === "string" && name !== "inspect") { - return function (...args) { - return target.callFunction(name, args); - }; - } else { - return Reflect.get(target, name, receiver); - } - }, - }); - } - - get customData() { - return EJSON.parse(this._customData); - } -} - -createMethods(User.prototype, objectTypes.USER, [ - "_logOut", - "_sessionForOnDiskPath", - "_deleteUser", - "_linkCredentials", - "_callFunction", - "_pushRegister", - "_pushDeregister", - "_makeStreamingRequest", - // "_newWatchStream", // TODO expose WatchStream type via RN debug API -]); - -Object.defineProperties(User.prototype, { - id: { get: getterForProperty("id") }, - accessToken: { get: getterForProperty("accessToken") }, - refreshToken: { get: getterForProperty("refreshToken") }, - profile: { get: getterForProperty("profile") }, - identities: { get: getterForProperty("identities") }, - providerType: { get: getterForProperty("providerType") }, - isLoggedIn: { get: getterForProperty("isLoggedIn") }, - state: { get: getterForProperty("state") }, - apiKeys: { get: getterForProperty("apiKeys") }, - deviceId: { get: getterForProperty("deviceId") }, - _customData: { get: getterForProperty("_customData") }, -}); - -export function createUser(realmId, info) { - const userProxy = Object.create(User.prototype); - - // FIXME: This is currently necessary because util/createMethod expects - // the realm id to be present on any object that is used over rpc - userProxy[keys.realm] = "(User object)"; - userProxy[keys.id] = info.id; - userProxy[keys.type] = objectTypes.USER; - - return userProxy; -} diff --git a/lib/browser/util.js b/lib/browser/util.js deleted file mode 100644 index 155581368b..0000000000 --- a/lib/browser/util.js +++ /dev/null @@ -1,95 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -import { keys } from "./constants"; -import * as rpc from "./rpc"; -import { invalidateCache, getRealmCache } from "./cache"; - -export function createMethods(prototype, type, methodNames, mutating) { - let props = {}; - - methodNames.forEach((name) => { - props[name] = { - value: createMethod(type, name, mutating), - }; - }); - - Object.defineProperties(prototype, props); -} - -export function createMethod(type, name, mutating) { - return function () { - let realmId = this[keys.realm]; - let id = this[keys.id]; - - if (!realmId || !id) { - throw new TypeError(`${type}.${name} was called on non-Realm object ${this}!`); - } - if (this[keys.type] !== type) { - throw new TypeError(`${type}.${name} was called on Realm object of type ${this[keys.type]}!`); - } - - if (mutating) { - invalidateCache(realmId); - } - try { - return rpc.callMethod(realmId, id, name, Array.from(arguments)); - } finally { - if (mutating) { - invalidateCache(realmId); - } - } - }; -} - -export function cacheObject(realmId, id, value) { - getRealmCache(realmId)[id] = value; -} - -export function getProperty(obj, name, cache = true) { - let realmId = obj[keys.realm]; - let id = obj[keys.id]; - if (!cache || realmId === undefined) { - return rpc.getProperty(realmId, id, name); - } - - let realmCache = getRealmCache(realmId); - let objCache = realmCache[id]; - if (!objCache) { - objCache = realmCache[id] = rpc.getObject(realmId, id, name); - return objCache[name]; - } - - if (name in objCache) { - return objCache[name]; - } - return (objCache[name] = rpc.getProperty(realmId, id, name)); -} - -export function getterForProperty(name, cache = true) { - return function () { - return getProperty(this, name, cache); - }; -} - -export function setterForProperty(name) { - return function (value) { - invalidateCache(this[keys.realm]); - rpc.setProperty(this[keys.realm], this[keys.id], name, value); - }; -} diff --git a/src/jsc/CMakeLists.txt b/src/jsc/CMakeLists.txt deleted file mode 100644 index 656264d45d..0000000000 --- a/src/jsc/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_library(realm-js-jsc OBJECT - jsc_init.cpp - jsc_value.cpp - rpc.cpp -) - -target_include_directories(realm-js-jsc PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) - -target_link_libraries(realm-js-jsc PUBLIC realm-js-shared) diff --git a/src/jsc/include/JavaScriptCore/JSBase.h b/src/jsc/include/JavaScriptCore/JSBase.h deleted file mode 100644 index 7d0ea3a53d..0000000000 --- a/src/jsc/include/JavaScriptCore/JSBase.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2006 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSBase_h -#define JSBase_h - -#ifndef __cplusplus -#include -#endif - -#ifdef __OBJC__ -#import -#endif - -/* JavaScript engine interface */ - -/*! @typedef JSContextGroupRef A group that associates JavaScript contexts with one another. Contexts in the same group may share and exchange JavaScript objects. */ -typedef const struct OpaqueJSContextGroup* JSContextGroupRef; - -/*! @typedef JSContextRef A JavaScript execution context. Holds the global object and other execution state. */ -typedef const struct OpaqueJSContext* JSContextRef; - -/*! @typedef JSGlobalContextRef A global JavaScript execution context. A JSGlobalContext is a JSContext. */ -typedef struct OpaqueJSContext* JSGlobalContextRef; - -/*! @typedef JSStringRef A UTF16 character buffer. The fundamental string representation in JavaScript. */ -typedef struct OpaqueJSString* JSStringRef; - -/*! @typedef JSClassRef A JavaScript class. Used with JSObjectMake to construct objects with custom behavior. */ -typedef struct OpaqueJSClass* JSClassRef; - -/*! @typedef JSPropertyNameArrayRef An array of JavaScript property names. */ -typedef struct OpaqueJSPropertyNameArray* JSPropertyNameArrayRef; - -/*! @typedef JSPropertyNameAccumulatorRef An ordered set used to collect the names of a JavaScript object's properties. */ -typedef struct OpaqueJSPropertyNameAccumulator* JSPropertyNameAccumulatorRef; - - -/* JavaScript data types */ - -/*! @typedef JSValueRef A JavaScript value. The base type for all JavaScript values, and polymorphic functions on them. */ -typedef const struct OpaqueJSValue* JSValueRef; - -/*! @typedef JSObjectRef A JavaScript object. A JSObject is a JSValue. */ -typedef struct OpaqueJSValue* JSObjectRef; - -/* JavaScript symbol exports */ -/* These rules should stay the same as in WebKit2/Shared/API/c/WKBase.h */ - -#undef JS_EXPORT -#if defined(JS_NO_EXPORT) -#define JS_EXPORT -#elif defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC__) -#define JS_EXPORT __attribute__((visibility("default"))) -#elif defined(WIN32) || defined(_WIN32) || defined(_WIN32_WCE) || defined(__CC_ARM) || defined(__ARMCC__) -#if defined(BUILDING_JavaScriptCore) || defined(STATICALLY_LINKED_WITH_JavaScriptCore) -#define JS_EXPORT __declspec(dllexport) -#else -#define JS_EXPORT __declspec(dllimport) -#endif -#else /* !defined(JS_NO_EXPORT) */ -#define JS_EXPORT -#endif /* defined(JS_NO_EXPORT) */ - -/* JS tests uses WTF but has no config.h, so we need to set the export defines here. */ -#ifndef WTF_EXPORT_PRIVATE -#define WTF_EXPORT_PRIVATE JS_EXPORT -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Script Evaluation */ - -/*! -@function JSEvaluateScript -@abstract Evaluates a string of JavaScript. -@param ctx The execution context to use. -@param script A JSString containing the script to evaluate. -@param thisObject The object to use as "this," or NULL to use the global object as "this." -@param sourceURL A JSString containing a URL for the script's source file. This is used by debuggers and when reporting exceptions. Pass NULL if you do not care to include source file information. -@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions. The value is one-based, so the first line is line 1 and invalid values are clamped to 1. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@result The JSValue that results from evaluating script, or NULL if an exception is thrown. -*/ -JS_EXPORT JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception); - -/*! -@function JSCheckScriptSyntax -@abstract Checks for syntax errors in a string of JavaScript. -@param ctx The execution context to use. -@param script A JSString containing the script to check for syntax errors. -@param sourceURL A JSString containing a URL for the script's source file. This is only used when reporting exceptions. Pass NULL if you do not care to include source file information in exceptions. -@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions. The value is one-based, so the first line is line 1 and invalid values are clamped to 1. -@param exception A pointer to a JSValueRef in which to store a syntax error exception, if any. Pass NULL if you do not care to store a syntax error exception. -@result true if the script is syntactically correct, otherwise false. -*/ -JS_EXPORT bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception); - -/*! -@function JSGarbageCollect -@abstract Performs a JavaScript garbage collection. -@param ctx The execution context to use. -@discussion JavaScript values that are on the machine stack, in a register, - protected by JSValueProtect, set as the global object of an execution context, - or reachable from any such value will not be collected. - - During JavaScript execution, you are not required to call this function; the - JavaScript engine will garbage collect as needed. JavaScript values created - within a context group are automatically destroyed when the last reference - to the context group is released. -*/ -JS_EXPORT void JSGarbageCollect(JSContextRef ctx); - -#ifdef __cplusplus -} -#endif - -/* Enable the Objective-C API for platforms with a modern runtime. */ -#if !defined(JSC_OBJC_API_ENABLED) -#ifndef JSC_OBJC_API_AVAILABLE_MAC_OS_X_1080 -#define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 && !defined(__i386__)) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE))) -#else -#define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 && !defined(__i386__)) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE))) -#endif -#endif - -#endif /* JSBase_h */ diff --git a/src/jsc/include/JavaScriptCore/JSContextRef.h b/src/jsc/include/JavaScriptCore/JSContextRef.h deleted file mode 100644 index cb25c0007d..0000000000 --- a/src/jsc/include/JavaScriptCore/JSContextRef.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2006 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSContextRef_h -#define JSContextRef_h - -#include -#include -#include - -#ifndef __cplusplus -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/*! -@function -@abstract Creates a JavaScript context group. -@discussion A JSContextGroup associates JavaScript contexts with one another. - Contexts in the same group may share and exchange JavaScript objects. Sharing and/or exchanging - JavaScript objects between contexts in different groups will produce undefined behavior. - When objects from the same context group are used in multiple threads, explicit - synchronization is required. -@result The created JSContextGroup. -*/ -JS_EXPORT JSContextGroupRef JSContextGroupCreate() CF_AVAILABLE(10_6, 7_0); - -/*! -@function -@abstract Retains a JavaScript context group. -@param group The JSContextGroup to retain. -@result A JSContextGroup that is the same as group. -*/ -JS_EXPORT JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) CF_AVAILABLE(10_6, 7_0); - -/*! -@function -@abstract Releases a JavaScript context group. -@param group The JSContextGroup to release. -*/ -JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) CF_AVAILABLE(10_6, 7_0); - -/*! -@function -@abstract Creates a global JavaScript execution context. -@discussion JSGlobalContextCreate allocates a global object and populates it with all the - built-in JavaScript objects, such as Object, Function, String, and Array. - - In WebKit version 4.0 and later, the context is created in a unique context group. - Therefore, scripts may execute in it concurrently with scripts executing in other contexts. - However, you may not use values created in the context in other contexts. -@param globalObjectClass The class to use when creating the global object. Pass - NULL to use the default object class. -@result A JSGlobalContext with a global object of class globalObjectClass. -*/ -JS_EXPORT JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) CF_AVAILABLE(10_5, 7_0); - -/*! -@function -@abstract Creates a global JavaScript execution context in the context group provided. -@discussion JSGlobalContextCreateInGroup allocates a global object and populates it with - all the built-in JavaScript objects, such as Object, Function, String, and Array. -@param globalObjectClass The class to use when creating the global object. Pass - NULL to use the default object class. -@param group The context group to use. The created global context retains the group. - Pass NULL to create a unique group for the context. -@result A JSGlobalContext with a global object of class globalObjectClass and a context - group equal to group. -*/ -JS_EXPORT JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) CF_AVAILABLE(10_6, 7_0); - -/*! -@function -@abstract Retains a global JavaScript execution context. -@param ctx The JSGlobalContext to retain. -@result A JSGlobalContext that is the same as ctx. -*/ -JS_EXPORT JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx); - -/*! -@function -@abstract Releases a global JavaScript execution context. -@param ctx The JSGlobalContext to release. -*/ -JS_EXPORT void JSGlobalContextRelease(JSGlobalContextRef ctx); - -/*! -@function -@abstract Gets the global object of a JavaScript execution context. -@param ctx The JSContext whose global object you want to get. -@result ctx's global object. -*/ -JS_EXPORT JSObjectRef JSContextGetGlobalObject(JSContextRef ctx); - -/*! -@function -@abstract Gets the context group to which a JavaScript execution context belongs. -@param ctx The JSContext whose group you want to get. -@result ctx's group. -*/ -JS_EXPORT JSContextGroupRef JSContextGetGroup(JSContextRef ctx) CF_AVAILABLE(10_6, 7_0); - -/*! -@function -@abstract Gets the global context of a JavaScript execution context. -@param ctx The JSContext whose global context you want to get. -@result ctx's global context. -*/ -JS_EXPORT JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx) CF_AVAILABLE(10_7, 7_0); - -/*! -@function -@abstract Gets a copy of the name of a context. -@param ctx The JSGlobalContext whose name you want to get. -@result The name for ctx. -@discussion A JSGlobalContext's name is exposed for remote debugging to make it -easier to identify the context you would like to attach to. -*/ -JS_EXPORT JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx) CF_AVAILABLE(10_10, 8_0); - -/*! -@function -@abstract Sets the remote debugging name for a context. -@param ctx The JSGlobalContext that you want to name. -@param name The remote debugging name to set on ctx. -*/ -JS_EXPORT void JSGlobalContextSetName(JSGlobalContextRef ctx, JSStringRef name) CF_AVAILABLE(10_10, 8_0); - -#ifdef __cplusplus -} -#endif - -#endif /* JSContextRef_h */ diff --git a/src/jsc/include/JavaScriptCore/JSObjectRef.h b/src/jsc/include/JavaScriptCore/JSObjectRef.h deleted file mode 100644 index 754dff3630..0000000000 --- a/src/jsc/include/JavaScriptCore/JSObjectRef.h +++ /dev/null @@ -1,694 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2008 Kelvin W Sherlock (ksherlock@gmail.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSObjectRef_h -#define JSObjectRef_h - -#include -#include -#include - -#ifndef __cplusplus -#include -#endif -#include /* for size_t */ - -#ifdef __cplusplus -extern "C" { -#endif - -/*! -@enum JSPropertyAttribute -@constant kJSPropertyAttributeNone Specifies that a property has no special attributes. -@constant kJSPropertyAttributeReadOnly Specifies that a property is read-only. -@constant kJSPropertyAttributeDontEnum Specifies that a property should not be enumerated by JSPropertyEnumerators and JavaScript for...in loops. -@constant kJSPropertyAttributeDontDelete Specifies that the delete operation should fail on a property. -*/ -enum { - kJSPropertyAttributeNone = 0, - kJSPropertyAttributeReadOnly = 1 << 1, - kJSPropertyAttributeDontEnum = 1 << 2, - kJSPropertyAttributeDontDelete = 1 << 3 -}; - -/*! -@typedef JSPropertyAttributes -@abstract A set of JSPropertyAttributes. Combine multiple attributes by logically ORing them together. -*/ -typedef unsigned JSPropertyAttributes; - -/*! -@enum JSClassAttribute -@constant kJSClassAttributeNone Specifies that a class has no special attributes. -@constant kJSClassAttributeNoAutomaticPrototype Specifies that a class should not automatically generate a shared prototype for its instance objects. Use kJSClassAttributeNoAutomaticPrototype in combination with JSObjectSetPrototype to manage prototypes manually. -*/ -enum { - kJSClassAttributeNone = 0, - kJSClassAttributeNoAutomaticPrototype = 1 << 1 -}; - -/*! -@typedef JSClassAttributes -@abstract A set of JSClassAttributes. Combine multiple attributes by logically ORing them together. -*/ -typedef unsigned JSClassAttributes; - -/*! -@typedef JSObjectInitializeCallback -@abstract The callback invoked when an object is first created. -@param ctx The execution context to use. -@param object The JSObject being created. -@discussion If you named your function Initialize, you would declare it like this: - -void Initialize(JSContextRef ctx, JSObjectRef object); - -Unlike the other object callbacks, the initialize callback is called on the least -derived class (the parent class) first, and the most derived class last. -*/ -typedef void -(*JSObjectInitializeCallback) (JSContextRef ctx, JSObjectRef object); - -/*! -@typedef JSObjectFinalizeCallback -@abstract The callback invoked when an object is finalized (prepared for garbage collection). An object may be finalized on any thread. -@param object The JSObject being finalized. -@discussion If you named your function Finalize, you would declare it like this: - -void Finalize(JSObjectRef object); - -The finalize callback is called on the most derived class first, and the least -derived class (the parent class) last. - -You must not call any function that may cause a garbage collection or an allocation -of a garbage collected object from within a JSObjectFinalizeCallback. This includes -all functions that have a JSContextRef parameter. -*/ -typedef void -(*JSObjectFinalizeCallback) (JSObjectRef object); - -/*! -@typedef JSObjectHasPropertyCallback -@abstract The callback invoked when determining whether an object has a property. -@param ctx The execution context to use. -@param object The JSObject to search for the property. -@param propertyName A JSString containing the name of the property look up. -@result true if object has the property, otherwise false. -@discussion If you named your function HasProperty, you would declare it like this: - -bool HasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName); - -If this function returns false, the hasProperty request forwards to object's statically declared properties, then its parent class chain (which includes the default object class), then its prototype chain. - -This callback enables optimization in cases where only a property's existence needs to be known, not its value, and computing its value would be expensive. - -If this callback is NULL, the getProperty callback will be used to service hasProperty requests. -*/ -typedef bool -(*JSObjectHasPropertyCallback) (JSContextRef ctx, JSObjectRef object, JSStringRef propertyName); - -/*! -@typedef JSObjectGetPropertyCallback -@abstract The callback invoked when getting a property's value. -@param ctx The execution context to use. -@param object The JSObject to search for the property. -@param propertyName A JSString containing the name of the property to get. -@param exception A pointer to a JSValueRef in which to return an exception, if any. -@result The property's value if object has the property, otherwise NULL. -@discussion If you named your function GetProperty, you would declare it like this: - -JSValueRef GetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception); - -If this function returns NULL, the get request forwards to object's statically declared properties, then its parent class chain (which includes the default object class), then its prototype chain. -*/ -typedef JSValueRef -(*JSObjectGetPropertyCallback) (JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception); - -/*! -@typedef JSObjectSetPropertyCallback -@abstract The callback invoked when setting a property's value. -@param ctx The execution context to use. -@param object The JSObject on which to set the property's value. -@param propertyName A JSString containing the name of the property to set. -@param value A JSValue to use as the property's value. -@param exception A pointer to a JSValueRef in which to return an exception, if any. -@result true if the property was set, otherwise false. -@discussion If you named your function SetProperty, you would declare it like this: - -bool SetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception); - -If this function returns false, the set request forwards to object's statically declared properties, then its parent class chain (which includes the default object class). -*/ -typedef bool -(*JSObjectSetPropertyCallback) (JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception); - -/*! -@typedef JSObjectDeletePropertyCallback -@abstract The callback invoked when deleting a property. -@param ctx The execution context to use. -@param object The JSObject in which to delete the property. -@param propertyName A JSString containing the name of the property to delete. -@param exception A pointer to a JSValueRef in which to return an exception, if any. -@result true if propertyName was successfully deleted, otherwise false. -@discussion If you named your function DeleteProperty, you would declare it like this: - -bool DeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception); - -If this function returns false, the delete request forwards to object's statically declared properties, then its parent class chain (which includes the default object class). -*/ -typedef bool -(*JSObjectDeletePropertyCallback) (JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception); - -/*! -@typedef JSObjectGetPropertyNamesCallback -@abstract The callback invoked when collecting the names of an object's properties. -@param ctx The execution context to use. -@param object The JSObject whose property names are being collected. -@param accumulator A JavaScript property name accumulator in which to accumulate the names of object's properties. -@discussion If you named your function GetPropertyNames, you would declare it like this: - -void GetPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames); - -Property name accumulators are used by JSObjectCopyPropertyNames and JavaScript for...in loops. - -Use JSPropertyNameAccumulatorAddName to add property names to accumulator. A class's getPropertyNames callback only needs to provide the names of properties that the class vends through a custom getProperty or setProperty callback. Other properties, including statically declared properties, properties vended by other classes, and properties belonging to object's prototype, are added independently. -*/ -typedef void -(*JSObjectGetPropertyNamesCallback) (JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames); - -/*! -@typedef JSObjectCallAsFunctionCallback -@abstract The callback invoked when an object is called as a function. -@param ctx The execution context to use. -@param function A JSObject that is the function being called. -@param thisObject A JSObject that is the 'this' variable in the function's scope. -@param argumentCount An integer count of the number of arguments in arguments. -@param arguments A JSValue array of the arguments passed to the function. -@param exception A pointer to a JSValueRef in which to return an exception, if any. -@result A JSValue that is the function's return value. -@discussion If you named your function CallAsFunction, you would declare it like this: - -JSValueRef CallAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); - -If your callback were invoked by the JavaScript expression 'myObject.myFunction()', function would be set to myFunction, and thisObject would be set to myObject. - -If this callback is NULL, calling your object as a function will throw an exception. -*/ -typedef JSValueRef -(*JSObjectCallAsFunctionCallback) (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); - -/*! -@typedef JSObjectCallAsConstructorCallback -@abstract The callback invoked when an object is used as a constructor in a 'new' expression. -@param ctx The execution context to use. -@param constructor A JSObject that is the constructor being called. -@param argumentCount An integer count of the number of arguments in arguments. -@param arguments A JSValue array of the arguments passed to the function. -@param exception A pointer to a JSValueRef in which to return an exception, if any. -@result A JSObject that is the constructor's return value. -@discussion If you named your function CallAsConstructor, you would declare it like this: - -JSObjectRef CallAsConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); - -If your callback were invoked by the JavaScript expression 'new myConstructor()', constructor would be set to myConstructor. - -If this callback is NULL, using your object as a constructor in a 'new' expression will throw an exception. -*/ -typedef JSObjectRef -(*JSObjectCallAsConstructorCallback) (JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); - -/*! -@typedef JSObjectHasInstanceCallback -@abstract hasInstance The callback invoked when an object is used as the target of an 'instanceof' expression. -@param ctx The execution context to use. -@param constructor The JSObject that is the target of the 'instanceof' expression. -@param possibleInstance The JSValue being tested to determine if it is an instance of constructor. -@param exception A pointer to a JSValueRef in which to return an exception, if any. -@result true if possibleInstance is an instance of constructor, otherwise false. -@discussion If you named your function HasInstance, you would declare it like this: - -bool HasInstance(JSContextRef ctx, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception); - -If your callback were invoked by the JavaScript expression 'someValue instanceof myObject', constructor would be set to myObject and possibleInstance would be set to someValue. - -If this callback is NULL, 'instanceof' expressions that target your object will return false. - -Standard JavaScript practice calls for objects that implement the callAsConstructor callback to implement the hasInstance callback as well. -*/ -typedef bool -(*JSObjectHasInstanceCallback) (JSContextRef ctx, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception); - -/*! -@typedef JSObjectConvertToTypeCallback -@abstract The callback invoked when converting an object to a particular JavaScript type. -@param ctx The execution context to use. -@param object The JSObject to convert. -@param type A JSType specifying the JavaScript type to convert to. -@param exception A pointer to a JSValueRef in which to return an exception, if any. -@result The objects's converted value, or NULL if the object was not converted. -@discussion If you named your function ConvertToType, you would declare it like this: - -JSValueRef ConvertToType(JSContextRef ctx, JSObjectRef object, JSType type, JSValueRef* exception); - -If this function returns false, the conversion request forwards to object's parent class chain (which includes the default object class). - -This function is only invoked when converting an object to number or string. An object converted to boolean is 'true.' An object converted to object is itself. -*/ -typedef JSValueRef -(*JSObjectConvertToTypeCallback) (JSContextRef ctx, JSObjectRef object, JSType type, JSValueRef* exception); - -/*! -@struct JSStaticValue -@abstract This structure describes a statically declared value property. -@field name A null-terminated UTF8 string containing the property's name. -@field getProperty A JSObjectGetPropertyCallback to invoke when getting the property's value. -@field setProperty A JSObjectSetPropertyCallback to invoke when setting the property's value. May be NULL if the ReadOnly attribute is set. -@field attributes A logically ORed set of JSPropertyAttributes to give to the property. -*/ -typedef struct { - const char* name; - JSObjectGetPropertyCallback getProperty; - JSObjectSetPropertyCallback setProperty; - JSPropertyAttributes attributes; -} JSStaticValue; - -/*! -@struct JSStaticFunction -@abstract This structure describes a statically declared function property. -@field name A null-terminated UTF8 string containing the property's name. -@field callAsFunction A JSObjectCallAsFunctionCallback to invoke when the property is called as a function. -@field attributes A logically ORed set of JSPropertyAttributes to give to the property. -*/ -typedef struct { - const char* name; - JSObjectCallAsFunctionCallback callAsFunction; - JSPropertyAttributes attributes; -} JSStaticFunction; - -/*! -@struct JSClassDefinition -@abstract This structure contains properties and callbacks that define a type of object. All fields other than the version field are optional. Any pointer may be NULL. -@field version The version number of this structure. The current version is 0. -@field attributes A logically ORed set of JSClassAttributes to give to the class. -@field className A null-terminated UTF8 string containing the class's name. -@field parentClass A JSClass to set as the class's parent class. Pass NULL use the default object class. -@field staticValues A JSStaticValue array containing the class's statically declared value properties. Pass NULL to specify no statically declared value properties. The array must be terminated by a JSStaticValue whose name field is NULL. -@field staticFunctions A JSStaticFunction array containing the class's statically declared function properties. Pass NULL to specify no statically declared function properties. The array must be terminated by a JSStaticFunction whose name field is NULL. -@field initialize The callback invoked when an object is first created. Use this callback to initialize the object. -@field finalize The callback invoked when an object is finalized (prepared for garbage collection). Use this callback to release resources allocated for the object, and perform other cleanup. -@field hasProperty The callback invoked when determining whether an object has a property. If this field is NULL, getProperty is called instead. The hasProperty callback enables optimization in cases where only a property's existence needs to be known, not its value, and computing its value is expensive. -@field getProperty The callback invoked when getting a property's value. -@field setProperty The callback invoked when setting a property's value. -@field deleteProperty The callback invoked when deleting a property. -@field getPropertyNames The callback invoked when collecting the names of an object's properties. -@field callAsFunction The callback invoked when an object is called as a function. -@field hasInstance The callback invoked when an object is used as the target of an 'instanceof' expression. -@field callAsConstructor The callback invoked when an object is used as a constructor in a 'new' expression. -@field convertToType The callback invoked when converting an object to a particular JavaScript type. -@discussion The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties. Statically declared properties autmatically service requests like getProperty, setProperty, and getPropertyNames. Property access callbacks are required only to implement unusual properties, like array indexes, whose names are not known at compile-time. - -If you named your getter function "GetX" and your setter function "SetX", you would declare a JSStaticValue array containing "X" like this: - -JSStaticValue StaticValueArray[] = { - { "X", GetX, SetX, kJSPropertyAttributeNone }, - { 0, 0, 0, 0 } -}; - -Standard JavaScript practice calls for storing function objects in prototypes, so they can be shared. The default JSClass created by JSClassCreate follows this idiom, instantiating objects with a shared, automatically generating prototype containing the class's function objects. The kJSClassAttributeNoAutomaticPrototype attribute specifies that a JSClass should not automatically generate such a prototype. The resulting JSClass instantiates objects with the default object prototype, and gives each instance object its own copy of the class's function objects. - -A NULL callback specifies that the default object callback should substitute, except in the case of hasProperty, where it specifies that getProperty should substitute. -*/ -typedef struct { - int version; /* current (and only) version is 0 */ - JSClassAttributes attributes; - - const char* className; - JSClassRef parentClass; - - const JSStaticValue* staticValues; - const JSStaticFunction* staticFunctions; - - JSObjectInitializeCallback initialize; - JSObjectFinalizeCallback finalize; - JSObjectHasPropertyCallback hasProperty; - JSObjectGetPropertyCallback getProperty; - JSObjectSetPropertyCallback setProperty; - JSObjectDeletePropertyCallback deleteProperty; - JSObjectGetPropertyNamesCallback getPropertyNames; - JSObjectCallAsFunctionCallback callAsFunction; - JSObjectCallAsConstructorCallback callAsConstructor; - JSObjectHasInstanceCallback hasInstance; - JSObjectConvertToTypeCallback convertToType; -} JSClassDefinition; - -/*! -@const kJSClassDefinitionEmpty -@abstract A JSClassDefinition structure of the current version, filled with NULL pointers and having no attributes. -@discussion Use this constant as a convenience when creating class definitions. For example, to create a class definition with only a finalize method: - -JSClassDefinition definition = kJSClassDefinitionEmpty; -definition.finalize = Finalize; -*/ -JS_EXPORT extern const JSClassDefinition kJSClassDefinitionEmpty; - -/*! -@function -@abstract Creates a JavaScript class suitable for use with JSObjectMake. -@param definition A JSClassDefinition that defines the class. -@result A JSClass with the given definition. Ownership follows the Create Rule. -*/ -JS_EXPORT JSClassRef JSClassCreate(const JSClassDefinition* definition); - -/*! -@function -@abstract Retains a JavaScript class. -@param jsClass The JSClass to retain. -@result A JSClass that is the same as jsClass. -*/ -JS_EXPORT JSClassRef JSClassRetain(JSClassRef jsClass); - -/*! -@function -@abstract Releases a JavaScript class. -@param jsClass The JSClass to release. -*/ -JS_EXPORT void JSClassRelease(JSClassRef jsClass); - -/*! -@function -@abstract Creates a JavaScript object. -@param ctx The execution context to use. -@param jsClass The JSClass to assign to the object. Pass NULL to use the default object class. -@param data A void* to set as the object's private data. Pass NULL to specify no private data. -@result A JSObject with the given class and private data. -@discussion The default object class does not allocate storage for private data, so you must provide a non-NULL jsClass to JSObjectMake if you want your object to be able to store private data. - -data is set on the created object before the intialize methods in its class chain are called. This enables the initialize methods to retrieve and manipulate data through JSObjectGetPrivate. -*/ -JS_EXPORT JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data); - -/*! -@function -@abstract Convenience method for creating a JavaScript function with a given callback as its implementation. -@param ctx The execution context to use. -@param name A JSString containing the function's name. This will be used when converting the function to string. Pass NULL to create an anonymous function. -@param callAsFunction The JSObjectCallAsFunctionCallback to invoke when the function is called. -@result A JSObject that is a function. The object's prototype will be the default function prototype. -*/ -JS_EXPORT JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction); - -/*! -@function -@abstract Convenience method for creating a JavaScript constructor. -@param ctx The execution context to use. -@param jsClass A JSClass that is the class your constructor will assign to the objects its constructs. jsClass will be used to set the constructor's .prototype property, and to evaluate 'instanceof' expressions. Pass NULL to use the default object class. -@param callAsConstructor A JSObjectCallAsConstructorCallback to invoke when your constructor is used in a 'new' expression. Pass NULL to use the default object constructor. -@result A JSObject that is a constructor. The object's prototype will be the default object prototype. -@discussion The default object constructor takes no arguments and constructs an object of class jsClass with no private data. -*/ -JS_EXPORT JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor); - -/*! - @function - @abstract Creates a JavaScript Array object. - @param ctx The execution context to use. - @param argumentCount An integer count of the number of arguments in arguments. - @param arguments A JSValue array of data to populate the Array with. Pass NULL if argumentCount is 0. - @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. - @result A JSObject that is an Array. - @discussion The behavior of this function does not exactly match the behavior of the built-in Array constructor. Specifically, if one argument - is supplied, this function returns an array with one element. - */ -JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0); - -/*! - @function - @abstract Creates a JavaScript Date object, as if by invoking the built-in Date constructor. - @param ctx The execution context to use. - @param argumentCount An integer count of the number of arguments in arguments. - @param arguments A JSValue array of arguments to pass to the Date Constructor. Pass NULL if argumentCount is 0. - @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. - @result A JSObject that is a Date. - */ -JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0); - -/*! - @function - @abstract Creates a JavaScript Error object, as if by invoking the built-in Error constructor. - @param ctx The execution context to use. - @param argumentCount An integer count of the number of arguments in arguments. - @param arguments A JSValue array of arguments to pass to the Error Constructor. Pass NULL if argumentCount is 0. - @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. - @result A JSObject that is a Error. - */ -JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0); - -/*! - @function - @abstract Creates a JavaScript RegExp object, as if by invoking the built-in RegExp constructor. - @param ctx The execution context to use. - @param argumentCount An integer count of the number of arguments in arguments. - @param arguments A JSValue array of arguments to pass to the RegExp Constructor. Pass NULL if argumentCount is 0. - @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. - @result A JSObject that is a RegExp. - */ -JS_EXPORT JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) CF_AVAILABLE(10_6, 7_0); - -/*! -@function -@abstract Creates a function with a given script as its body. -@param ctx The execution context to use. -@param name A JSString containing the function's name. This will be used when converting the function to string. Pass NULL to create an anonymous function. -@param parameterCount An integer count of the number of parameter names in parameterNames. -@param parameterNames A JSString array containing the names of the function's parameters. Pass NULL if parameterCount is 0. -@param body A JSString containing the script to use as the function's body. -@param sourceURL A JSString containing a URL for the script's source file. This is only used when reporting exceptions. Pass NULL if you do not care to include source file information in exceptions. -@param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions. The value is one-based, so the first line is line 1 and invalid values are clamped to 1. -@param exception A pointer to a JSValueRef in which to store a syntax error exception, if any. Pass NULL if you do not care to store a syntax error exception. -@result A JSObject that is a function, or NULL if either body or parameterNames contains a syntax error. The object's prototype will be the default function prototype. -@discussion Use this method when you want to execute a script repeatedly, to avoid the cost of re-parsing the script before each execution. -*/ -JS_EXPORT JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception); - -/*! -@function -@abstract Gets an object's prototype. -@param ctx The execution context to use. -@param object A JSObject whose prototype you want to get. -@result A JSValue that is the object's prototype. -*/ -JS_EXPORT JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object); - -/*! -@function -@abstract Sets an object's prototype. -@param ctx The execution context to use. -@param object The JSObject whose prototype you want to set. -@param value A JSValue to set as the object's prototype. -*/ -JS_EXPORT void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value); - -/*! -@function -@abstract Tests whether an object has a given property. -@param object The JSObject to test. -@param propertyName A JSString containing the property's name. -@result true if the object has a property whose name matches propertyName, otherwise false. -*/ -JS_EXPORT bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName); - -/*! -@function -@abstract Gets a property from an object. -@param ctx The execution context to use. -@param object The JSObject whose property you want to get. -@param propertyName A JSString containing the property's name. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@result The property's value if object has the property, otherwise the undefined value. -*/ -JS_EXPORT JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception); - -/*! -@function -@abstract Sets a property on an object. -@param ctx The execution context to use. -@param object The JSObject whose property you want to set. -@param propertyName A JSString containing the property's name. -@param value A JSValue to use as the property's value. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@param attributes A logically ORed set of JSPropertyAttributes to give to the property. -*/ -JS_EXPORT void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception); - -/*! -@function -@abstract Deletes a property from an object. -@param ctx The execution context to use. -@param object The JSObject whose property you want to delete. -@param propertyName A JSString containing the property's name. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@result true if the delete operation succeeds, otherwise false (for example, if the property has the kJSPropertyAttributeDontDelete attribute set). -*/ -JS_EXPORT bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception); - -/*! -@function -@abstract Gets a property from an object by numeric index. -@param ctx The execution context to use. -@param object The JSObject whose property you want to get. -@param propertyIndex An integer value that is the property's name. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@result The property's value if object has the property, otherwise the undefined value. -@discussion Calling JSObjectGetPropertyAtIndex is equivalent to calling JSObjectGetProperty with a string containing propertyIndex, but JSObjectGetPropertyAtIndex provides optimized access to numeric properties. -*/ -JS_EXPORT JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception); - -/*! -@function -@abstract Sets a property on an object by numeric index. -@param ctx The execution context to use. -@param object The JSObject whose property you want to set. -@param propertyIndex The property's name as a number. -@param value A JSValue to use as the property's value. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@discussion Calling JSObjectSetPropertyAtIndex is equivalent to calling JSObjectSetProperty with a string containing propertyIndex, but JSObjectSetPropertyAtIndex provides optimized access to numeric properties. -*/ -JS_EXPORT void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception); - -/*! -@function -@abstract Gets an object's private data. -@param object A JSObject whose private data you want to get. -@result A void* that is the object's private data, if the object has private data, otherwise NULL. -*/ -JS_EXPORT void* JSObjectGetPrivate(JSObjectRef object); - -/*! -@function -@abstract Sets a pointer to private data on an object. -@param object The JSObject whose private data you want to set. -@param data A void* to set as the object's private data. -@result true if object can store private data, otherwise false. -@discussion The default object class does not allocate storage for private data. Only objects created with a non-NULL JSClass can store private data. -*/ -JS_EXPORT bool JSObjectSetPrivate(JSObjectRef object, void* data); - -/*! -@function -@abstract Tests whether an object can be called as a function. -@param ctx The execution context to use. -@param object The JSObject to test. -@result true if the object can be called as a function, otherwise false. -*/ -JS_EXPORT bool JSObjectIsFunction(JSContextRef ctx, JSObjectRef object); - -/*! -@function -@abstract Calls an object as a function. -@param ctx The execution context to use. -@param object The JSObject to call as a function. -@param thisObject The object to use as "this," or NULL to use the global object as "this." -@param argumentCount An integer count of the number of arguments in arguments. -@param arguments A JSValue array of arguments to pass to the function. Pass NULL if argumentCount is 0. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@result The JSValue that results from calling object as a function, or NULL if an exception is thrown or object is not a function. -*/ -JS_EXPORT JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); - -/*! -@function -@abstract Tests whether an object can be called as a constructor. -@param ctx The execution context to use. -@param object The JSObject to test. -@result true if the object can be called as a constructor, otherwise false. -*/ -JS_EXPORT bool JSObjectIsConstructor(JSContextRef ctx, JSObjectRef object); - -/*! -@function -@abstract Calls an object as a constructor. -@param ctx The execution context to use. -@param object The JSObject to call as a constructor. -@param argumentCount An integer count of the number of arguments in arguments. -@param arguments A JSValue array of arguments to pass to the constructor. Pass NULL if argumentCount is 0. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@result The JSObject that results from calling object as a constructor, or NULL if an exception is thrown or object is not a constructor. -*/ -JS_EXPORT JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); - -/*! -@function -@abstract Gets the names of an object's enumerable properties. -@param ctx The execution context to use. -@param object The object whose property names you want to get. -@result A JSPropertyNameArray containing the names object's enumerable properties. Ownership follows the Create Rule. -*/ -JS_EXPORT JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object); - -/*! -@function -@abstract Retains a JavaScript property name array. -@param array The JSPropertyNameArray to retain. -@result A JSPropertyNameArray that is the same as array. -*/ -JS_EXPORT JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array); - -/*! -@function -@abstract Releases a JavaScript property name array. -@param array The JSPropetyNameArray to release. -*/ -JS_EXPORT void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array); - -/*! -@function -@abstract Gets a count of the number of items in a JavaScript property name array. -@param array The array from which to retrieve the count. -@result An integer count of the number of names in array. -*/ -JS_EXPORT size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array); - -/*! -@function -@abstract Gets a property name at a given index in a JavaScript property name array. -@param array The array from which to retrieve the property name. -@param index The index of the property name to retrieve. -@result A JSStringRef containing the property name. -*/ -JS_EXPORT JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index); - -/*! -@function -@abstract Adds a property name to a JavaScript property name accumulator. -@param accumulator The accumulator object to which to add the property name. -@param propertyName The property name to add. -*/ -JS_EXPORT void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef accumulator, JSStringRef propertyName); - -#ifdef __cplusplus -} -#endif - -#endif /* JSObjectRef_h */ diff --git a/src/jsc/include/JavaScriptCore/JSRetainPtr.h b/src/jsc/include/JavaScriptCore/JSRetainPtr.h deleted file mode 100644 index f23e32fcb7..0000000000 --- a/src/jsc/include/JavaScriptCore/JSRetainPtr.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSRetainPtr_h -#define JSRetainPtr_h - -#include -#include -#include - -inline void JSRetain(JSStringRef string) { JSStringRetain(string); } -inline void JSRelease(JSStringRef string) { JSStringRelease(string); } -inline void JSRetain(JSGlobalContextRef context) { JSGlobalContextRetain(context); } -inline void JSRelease(JSGlobalContextRef context) { JSGlobalContextRelease(context); } - -enum AdoptTag { Adopt }; - -template class JSRetainPtr { -public: - JSRetainPtr() : m_ptr(0) { } - JSRetainPtr(T ptr) : m_ptr(ptr) { if (ptr) JSRetain(ptr); } - JSRetainPtr(AdoptTag, T ptr) : m_ptr(ptr) { } - JSRetainPtr(const JSRetainPtr&); - template JSRetainPtr(const JSRetainPtr&); - ~JSRetainPtr(); - - T get() const { return m_ptr; } - - void clear(); - T leakRef(); - - T operator->() const { return m_ptr; } - - bool operator!() const { return !m_ptr; } - - // This conversion operator allows implicit conversion to bool but not to other integer types. - typedef T JSRetainPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return m_ptr ? &JSRetainPtr::m_ptr : 0; } - - JSRetainPtr& operator=(const JSRetainPtr&); - template JSRetainPtr& operator=(const JSRetainPtr&); - JSRetainPtr& operator=(T); - template JSRetainPtr& operator=(U*); - - void adopt(T); - - void swap(JSRetainPtr&); - -private: - T m_ptr; -}; - -template inline JSRetainPtr::JSRetainPtr(const JSRetainPtr& o) - : m_ptr(o.m_ptr) -{ - if (m_ptr) - JSRetain(m_ptr); -} - -template template inline JSRetainPtr::JSRetainPtr(const JSRetainPtr& o) - : m_ptr(o.get()) -{ - if (m_ptr) - JSRetain(m_ptr); -} - -template inline JSRetainPtr::~JSRetainPtr() -{ - if (m_ptr) - JSRelease(m_ptr); -} - -template inline void JSRetainPtr::clear() -{ - if (T ptr = m_ptr) { - m_ptr = 0; - JSRelease(ptr); - } -} - -template inline T JSRetainPtr::leakRef() -{ - T ptr = m_ptr; - m_ptr = 0; - return ptr; -} - -template inline JSRetainPtr& JSRetainPtr::operator=(const JSRetainPtr& o) -{ - T optr = o.get(); - if (optr) - JSRetain(optr); - T ptr = m_ptr; - m_ptr = optr; - if (ptr) - JSRelease(ptr); - return *this; -} - -template template inline JSRetainPtr& JSRetainPtr::operator=(const JSRetainPtr& o) -{ - T optr = o.get(); - if (optr) - JSRetain(optr); - T ptr = m_ptr; - m_ptr = optr; - if (ptr) - JSRelease(ptr); - return *this; -} - -template inline JSRetainPtr& JSRetainPtr::operator=(T optr) -{ - if (optr) - JSRetain(optr); - T ptr = m_ptr; - m_ptr = optr; - if (ptr) - JSRelease(ptr); - return *this; -} - -template inline void JSRetainPtr::adopt(T optr) -{ - T ptr = m_ptr; - m_ptr = optr; - if (ptr) - JSRelease(ptr); -} - -template template inline JSRetainPtr& JSRetainPtr::operator=(U* optr) -{ - if (optr) - JSRetain(optr); - T ptr = m_ptr; - m_ptr = optr; - if (ptr) - JSRelease(ptr); - return *this; -} - -template inline void JSRetainPtr::swap(JSRetainPtr& o) -{ - std::swap(m_ptr, o.m_ptr); -} - -template inline void swap(JSRetainPtr& a, JSRetainPtr& b) -{ - a.swap(b); -} - -template inline bool operator==(const JSRetainPtr& a, const JSRetainPtr& b) -{ - return a.get() == b.get(); -} - -template inline bool operator==(const JSRetainPtr& a, U* b) -{ - return a.get() == b; -} - -template inline bool operator==(T* a, const JSRetainPtr& b) -{ - return a == b.get(); -} - -template inline bool operator!=(const JSRetainPtr& a, const JSRetainPtr& b) -{ - return a.get() != b.get(); -} - -template inline bool operator!=(const JSRetainPtr& a, U* b) -{ - return a.get() != b; -} - -template inline bool operator!=(T* a, const JSRetainPtr& b) -{ - return a != b.get(); -} - - -#endif // JSRetainPtr_h diff --git a/src/jsc/include/JavaScriptCore/JSStringRef.h b/src/jsc/include/JavaScriptCore/JSStringRef.h deleted file mode 100644 index 6f45fcbd83..0000000000 --- a/src/jsc/include/JavaScriptCore/JSStringRef.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2006 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSStringRef_h -#define JSStringRef_h - -#include - -#ifndef __cplusplus -#include -#endif -#include /* for size_t */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(WIN32) && !defined(_WIN32) \ - && !((defined(__CC_ARM) || defined(__ARMCC__)) && !defined(__linux__)) /* RVCT */ -/*! -@typedef JSChar -@abstract A Unicode character. -*/ - typedef unsigned short JSChar; -#else - typedef wchar_t JSChar; -#endif - -/*! -@function -@abstract Creates a JavaScript string from a buffer of Unicode characters. -@param chars The buffer of Unicode characters to copy into the new JSString. -@param numChars The number of characters to copy from the buffer pointed to by chars. -@result A JSString containing chars. Ownership follows the Create Rule. -*/ -JS_EXPORT JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars); -/*! -@function -@abstract Creates a JavaScript string from a null-terminated UTF8 string. -@param string The null-terminated UTF8 string to copy into the new JSString. -@result A JSString containing string. Ownership follows the Create Rule. -*/ -JS_EXPORT JSStringRef JSStringCreateWithUTF8CString(const char* string); - -/*! -@function -@abstract Retains a JavaScript string. -@param string The JSString to retain. -@result A JSString that is the same as string. -*/ -JS_EXPORT JSStringRef JSStringRetain(JSStringRef string); -/*! -@function -@abstract Releases a JavaScript string. -@param string The JSString to release. -*/ -JS_EXPORT void JSStringRelease(JSStringRef string); - -/*! -@function -@abstract Returns the number of Unicode characters in a JavaScript string. -@param string The JSString whose length (in Unicode characters) you want to know. -@result The number of Unicode characters stored in string. -*/ -JS_EXPORT size_t JSStringGetLength(JSStringRef string); -/*! -@function -@abstract Returns a pointer to the Unicode character buffer that - serves as the backing store for a JavaScript string. -@param string The JSString whose backing store you want to access. -@result A pointer to the Unicode character buffer that serves as string's - backing store, which will be deallocated when string is deallocated. -*/ -JS_EXPORT const JSChar* JSStringGetCharactersPtr(JSStringRef string); - -/*! -@function -@abstract Returns the maximum number of bytes a JavaScript string will - take up if converted into a null-terminated UTF8 string. -@param string The JSString whose maximum converted size (in bytes) you - want to know. -@result The maximum number of bytes that could be required to convert string into a - null-terminated UTF8 string. The number of bytes that the conversion actually ends - up requiring could be less than this, but never more. -*/ -JS_EXPORT size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string); -/*! -@function -@abstract Converts a JavaScript string into a null-terminated UTF8 string, - and copies the result into an external byte buffer. -@param string The source JSString. -@param buffer The destination byte buffer into which to copy a null-terminated - UTF8 representation of string. On return, buffer contains a UTF8 string - representation of string. If bufferSize is too small, buffer will contain only - partial results. If buffer is not at least bufferSize bytes in size, - behavior is undefined. -@param bufferSize The size of the external buffer in bytes. -@result The number of bytes written into buffer (including the null-terminator byte). -*/ -JS_EXPORT size_t JSStringGetUTF8CString(JSStringRef string, char* buffer, size_t bufferSize); - -/*! -@function -@abstract Tests whether two JavaScript strings match. -@param a The first JSString to test. -@param b The second JSString to test. -@result true if the two strings match, otherwise false. -*/ -JS_EXPORT bool JSStringIsEqual(JSStringRef a, JSStringRef b); -/*! -@function -@abstract Tests whether a JavaScript string matches a null-terminated UTF8 string. -@param a The JSString to test. -@param b The null-terminated UTF8 string to test. -@result true if the two strings match, otherwise false. -*/ -JS_EXPORT bool JSStringIsEqualToUTF8CString(JSStringRef a, const char* b); - -#ifdef __cplusplus -} -#endif - -#endif /* JSStringRef_h */ diff --git a/src/jsc/include/JavaScriptCore/JSValueRef.h b/src/jsc/include/JavaScriptCore/JSValueRef.h deleted file mode 100644 index 538e6e0deb..0000000000 --- a/src/jsc/include/JavaScriptCore/JSValueRef.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (C) 2006 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSValueRef_h -#define JSValueRef_h - -#include -#include - -#ifndef __cplusplus -#include -#endif - -/*! -@enum JSType -@abstract A constant identifying the type of a JSValue. -@constant kJSTypeUndefined The unique undefined value. -@constant kJSTypeNull The unique null value. -@constant kJSTypeBoolean A primitive boolean value, one of true or false. -@constant kJSTypeNumber A primitive number value. -@constant kJSTypeString A primitive string value. -@constant kJSTypeObject An object value (meaning that this JSValueRef is a JSObjectRef). -*/ -typedef enum { - kJSTypeUndefined, - kJSTypeNull, - kJSTypeBoolean, - kJSTypeNumber, - kJSTypeString, - kJSTypeObject -} JSType; - -#ifdef __cplusplus -extern "C" { -#endif - -/*! -@function -@abstract Returns a JavaScript value's type. -@param ctx The execution context to use. -@param value The JSValue whose type you want to obtain. -@result A value of type JSType that identifies value's type. -*/ -JS_EXPORT JSType JSValueGetType(JSContextRef ctx, JSValueRef); - -/*! -@function -@abstract Tests whether a JavaScript value's type is the undefined type. -@param ctx The execution context to use. -@param value The JSValue to test. -@result true if value's type is the undefined type, otherwise false. -*/ -JS_EXPORT bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value); - -/*! -@function -@abstract Tests whether a JavaScript value's type is the null type. -@param ctx The execution context to use. -@param value The JSValue to test. -@result true if value's type is the null type, otherwise false. -*/ -JS_EXPORT bool JSValueIsNull(JSContextRef ctx, JSValueRef value); - -/*! -@function -@abstract Tests whether a JavaScript value's type is the boolean type. -@param ctx The execution context to use. -@param value The JSValue to test. -@result true if value's type is the boolean type, otherwise false. -*/ -JS_EXPORT bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value); - -/*! -@function -@abstract Tests whether a JavaScript value's type is the number type. -@param ctx The execution context to use. -@param value The JSValue to test. -@result true if value's type is the number type, otherwise false. -*/ -JS_EXPORT bool JSValueIsNumber(JSContextRef ctx, JSValueRef value); - -/*! -@function -@abstract Tests whether a JavaScript value's type is the string type. -@param ctx The execution context to use. -@param value The JSValue to test. -@result true if value's type is the string type, otherwise false. -*/ -JS_EXPORT bool JSValueIsString(JSContextRef ctx, JSValueRef value); - -/*! -@function -@abstract Tests whether a JavaScript value's type is the object type. -@param ctx The execution context to use. -@param value The JSValue to test. -@result true if value's type is the object type, otherwise false. -*/ -JS_EXPORT bool JSValueIsObject(JSContextRef ctx, JSValueRef value); - -/*! -@function -@abstract Tests whether a JavaScript value is an object with a given class in its class chain. -@param ctx The execution context to use. -@param value The JSValue to test. -@param jsClass The JSClass to test against. -@result true if value is an object and has jsClass in its class chain, otherwise false. -*/ -JS_EXPORT bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass); - -/* Comparing values */ - -/*! -@function -@abstract Tests whether two JavaScript values are equal, as compared by the JS == operator. -@param ctx The execution context to use. -@param a The first value to test. -@param b The second value to test. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@result true if the two values are equal, false if they are not equal or an exception is thrown. -*/ -JS_EXPORT bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception); - -/*! -@function -@abstract Tests whether two JavaScript values are strict equal, as compared by the JS === operator. -@param ctx The execution context to use. -@param a The first value to test. -@param b The second value to test. -@result true if the two values are strict equal, otherwise false. -*/ -JS_EXPORT bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b); - -/*! -@function -@abstract Tests whether a JavaScript value is an object constructed by a given constructor, as compared by the JS instanceof operator. -@param ctx The execution context to use. -@param value The JSValue to test. -@param constructor The constructor to test against. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@result true if value is an object constructed by constructor, as compared by the JS instanceof operator, otherwise false. -*/ -JS_EXPORT bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception); - -/* Creating values */ - -/*! -@function -@abstract Creates a JavaScript value of the undefined type. -@param ctx The execution context to use. -@result The unique undefined value. -*/ -JS_EXPORT JSValueRef JSValueMakeUndefined(JSContextRef ctx); - -/*! -@function -@abstract Creates a JavaScript value of the null type. -@param ctx The execution context to use. -@result The unique null value. -*/ -JS_EXPORT JSValueRef JSValueMakeNull(JSContextRef ctx); - -/*! -@function -@abstract Creates a JavaScript value of the boolean type. -@param ctx The execution context to use. -@param boolean The bool to assign to the newly created JSValue. -@result A JSValue of the boolean type, representing the value of boolean. -*/ -JS_EXPORT JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool boolean); - -/*! -@function -@abstract Creates a JavaScript value of the number type. -@param ctx The execution context to use. -@param number The double to assign to the newly created JSValue. -@result A JSValue of the number type, representing the value of number. -*/ -JS_EXPORT JSValueRef JSValueMakeNumber(JSContextRef ctx, double number); - -/*! -@function -@abstract Creates a JavaScript value of the string type. -@param ctx The execution context to use. -@param string The JSString to assign to the newly created JSValue. The - newly created JSValue retains string, and releases it upon garbage collection. -@result A JSValue of the string type, representing the value of string. -*/ -JS_EXPORT JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string); - -/* Converting to and from JSON formatted strings */ - -/*! - @function - @abstract Creates a JavaScript value from a JSON formatted string. - @param ctx The execution context to use. - @param string The JSString containing the JSON string to be parsed. - @result A JSValue containing the parsed value, or NULL if the input is invalid. - */ -JS_EXPORT JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) CF_AVAILABLE(10_7, 7_0); - -/*! - @function - @abstract Creates a JavaScript string containing the JSON serialized representation of a JS value. - @param ctx The execution context to use. - @param value The value to serialize. - @param indent The number of spaces to indent when nesting. If 0, the resulting JSON will not contains newlines. The size of the indent is clamped to 10 spaces. - @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. - @result A JSString with the result of serialization, or NULL if an exception is thrown. - */ -JS_EXPORT JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef value, unsigned indent, JSValueRef* exception) CF_AVAILABLE(10_7, 7_0); - -/* Converting to primitive values */ - -/*! -@function -@abstract Converts a JavaScript value to boolean and returns the resulting boolean. -@param ctx The execution context to use. -@param value The JSValue to convert. -@result The boolean result of conversion. -*/ -JS_EXPORT bool JSValueToBoolean(JSContextRef ctx, JSValueRef value); - -/*! -@function -@abstract Converts a JavaScript value to number and returns the resulting number. -@param ctx The execution context to use. -@param value The JSValue to convert. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@result The numeric result of conversion, or NaN if an exception is thrown. -*/ -JS_EXPORT double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception); - -/*! -@function -@abstract Converts a JavaScript value to string and copies the result into a JavaScript string. -@param ctx The execution context to use. -@param value The JSValue to convert. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@result A JSString with the result of conversion, or NULL if an exception is thrown. Ownership follows the Create Rule. -*/ -JS_EXPORT JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception); - -/*! -@function -@abstract Converts a JavaScript value to object and returns the resulting object. -@param ctx The execution context to use. -@param value The JSValue to convert. -@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception. -@result The JSObject result of conversion, or NULL if an exception is thrown. -*/ -JS_EXPORT JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception); - -/* Garbage collection */ -/*! -@function -@abstract Protects a JavaScript value from garbage collection. -@param ctx The execution context to use. -@param value The JSValue to protect. -@discussion Use this method when you want to store a JSValue in a global or on the heap, where the garbage collector will not be able to discover your reference to it. - -A value may be protected multiple times and must be unprotected an equal number of times before becoming eligible for garbage collection. -*/ -JS_EXPORT void JSValueProtect(JSContextRef ctx, JSValueRef value); - -/*! -@function -@abstract Unprotects a JavaScript value from garbage collection. -@param ctx The execution context to use. -@param value The JSValue to unprotect. -@discussion A value may be protected multiple times and must be unprotected an - equal number of times before becoming eligible for garbage collection. -*/ -JS_EXPORT void JSValueUnprotect(JSContextRef ctx, JSValueRef value); - -#ifdef __cplusplus -} -#endif - -#endif /* JSValueRef_h */ diff --git a/src/jsc/include/JavaScriptCore/WebKitAvailability.h b/src/jsc/include/JavaScriptCore/WebKitAvailability.h deleted file mode 100644 index 24695ed9a8..0000000000 --- a/src/jsc/include/JavaScriptCore/WebKitAvailability.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2008, 2009, 2010, 2014 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __WebKitAvailability__ -#define __WebKitAvailability__ - -#ifdef __APPLE__ - -#include -#include - -#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED <= 1090 -/* To support availability macros that mention newer OS X versions when building on older OS X versions, - we provide our own definitions of the underlying macros that the availability macros expand to. We're - free to expand the macros as no-ops since frameworks built on older OS X versions only ship bundled with - an application rather than as part of the system. -*/ - -#ifndef __NSi_10_10 -#define __NSi_10_10 introduced=10.0 -#endif - -#ifndef __AVAILABILITY_INTERNAL__MAC_10_9 -#define __AVAILABILITY_INTERNAL__MAC_10_9 -#endif - -#ifndef __AVAILABILITY_INTERNAL__MAC_10_10 -#define __AVAILABILITY_INTERNAL__MAC_10_10 -#endif - -#ifndef AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER -#define AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER -#endif - -#ifndef AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER -#define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER -#endif - -#endif /* __MAC_OS_X_VERSION_MIN_REQUIRED <= 1090 */ - -#else -#define CF_AVAILABLE(_mac, _ios) -#endif - -#endif /* __WebKitAvailability__ */ diff --git a/src/jsc/jsc_class.hpp b/src/jsc/jsc_class.hpp deleted file mode 100644 index 984bf55454..0000000000 --- a/src/jsc/jsc_class.hpp +++ /dev/null @@ -1,1195 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "jsc_types.hpp" - -#include "js_class.hpp" -#include "js_util.hpp" - -namespace realm { -namespace js { -template -struct RealmObjectClass; -} -namespace node { -struct Types; -} -} // namespace realm - -namespace realm { -namespace jsc { - -extern js::Protected ObjectDefineProperty; -extern js::Protected FunctionPrototype; -extern js::Protected RealmObjectClassConstructor; -extern js::Protected RealmObjectClassConstructorPrototype; - -static inline void jsc_class_init(JSContextRef ctx, JSObjectRef globalObject) -{ - // handle ReactNative app refresh by reseting the cached constructor values - if (RealmObjectClassConstructor) { - RealmObjectClassConstructor = js::Protected(); - } - - if (RealmObjectClassConstructorPrototype) { - RealmObjectClassConstructorPrototype = js::Protected(); - } - - JSValueRef value = nullptr; - value = jsc::Object::get_property(ctx, globalObject, "Object"); - JSObjectRef objectClass = jsc::Value::to_object(ctx, value); - - value = jsc::Object::get_property(ctx, objectClass, "defineProperty"); - ObjectDefineProperty = js::Protected(ctx, Value::to_object(ctx, value)); - - value = jsc::Object::get_property(ctx, globalObject, "Function"); - JSObjectRef globalFunction = jsc::Value::to_object(ctx, value); - value = jsc::Object::get_property(ctx, globalFunction, "prototype"); - FunctionPrototype = js::Protected(ctx, Value::to_object(ctx, value)); -} - -template -using ClassDefinition = js::ClassDefinition; - -using ConstructorType = js::ConstructorType; -using ArgumentsMethodType = js::ArgumentsMethodType; -using Arguments = js::Arguments; -using PropertyType = js::PropertyType; -using IndexPropertyType = js::IndexPropertyType; -using StringPropertyType = js::StringPropertyType; -using MethodMap = js::MethodMap; -using PropertyMap = js::PropertyMap; - -struct SchemaObjectType { - JSObjectRef constructor; -}; - -template -class ObjectWrap { - using Internal = typename ClassType::Internal; - using ParentClassType = typename ClassType::Parent; - -public: - static JSObjectRef create_instance(JSContextRef ctx, Internal* internal = nullptr) - { - return JSObjectMake(ctx, get_class(), new ObjectWrap(internal)); - } - - static JSObjectRef create_instance_by_schema(JSContextRef ctx, const realm::ObjectSchema& schema, - typename ClassType::Internal* internal = nullptr) - { - JSObjectRef constructor = nullptr; - return create_instance_by_schema(ctx, constructor, schema, internal); - } - static JSObjectRef create_instance_by_schema(JSContextRef ctx, JSObjectRef& constructor, - const realm::ObjectSchema& schema, - typename ClassType::Internal* internal = nullptr); - - static JSObjectRef create_constructor(JSContextRef ctx) - { - bool isRealmObjectClass = std::is_same>::value; - if (isRealmObjectClass) { - if (RealmObjectClassConstructor) { - return RealmObjectClassConstructor; - } - - JSObjectRef constructor = JSObjectMake(ctx, get_constructor_class(ctx), nullptr); - RealmObjectClassConstructor = js::Protected(ctx, constructor); - - JSValueRef value = Object::get_property(ctx, RealmObjectClassConstructor, "prototype"); - RealmObjectClassConstructorPrototype = js::Protected(ctx, Value::to_object(ctx, value)); - - return RealmObjectClassConstructor; - } - - return JSObjectMake(ctx, get_constructor_class(ctx), nullptr); - } - - static JSClassRef get_class() - { - if (m_Class != nullptr) { - return m_Class; - } - - JSClassRef js_class = create_class(); - m_Class = JSClassRetain(js_class); - return m_Class; - } - - static JSClassRef get_constructor_class(JSContextRef ctx) - { - if (m_constructorClass != nullptr) { - return m_constructorClass; - } - - JSClassRef js_class = create_constructor_class(); - m_constructorClass = JSClassRetain(js_class); - return m_constructorClass; - } - - static bool has_instance(JSContextRef ctx, JSValueRef value); - - ObjectWrap& operator=(Internal* object) - { - if (m_object.get() != object) { - m_object = std::unique_ptr(object); - } - return *this; - } - - static Internal* get_internal(JSContextRef ctx, const JSObjectRef& object); - - static void on_context_destroy(JSContextRef ctx, std::string realmPath); - -private: - static ClassType s_class; - static std::unordered_map*> s_schemaObjectTypes; - - std::unique_ptr m_object; - - static JSClassRef m_constructorClass; - static JSClassRef m_Class; - static JSClassRef m_internalValueClass; - static JSClassRef m_getterAccessorClass; - static JSClassRef m_setterAccessorClass; - static JSClassRef m_NativePropertyGetterClass; - - ObjectWrap(Internal* object = nullptr) - : m_object(object) - { - } - - static JSClassRef create_constructor_class(); - static JSClassRef create_class(); - - static std::vector get_methods(const MethodMap&); - static std::vector get_properties(const PropertyMap&); - - static JSValueRef call(JSContextRef, JSObjectRef, JSObjectRef, size_t, const JSValueRef[], JSValueRef*); - static JSObjectRef construct(JSContextRef, JSObjectRef, size_t, const JSValueRef[], JSValueRef*); - static void initialize_constructor(JSContextRef, JSObjectRef); - static void finalize(JSObjectRef); - static void get_property_names(JSContextRef, JSObjectRef, JSPropertyNameAccumulatorRef); - static JSValueRef get_property(JSContextRef, JSObjectRef, JSStringRef, JSValueRef*); - static bool set_property(JSContextRef, JSObjectRef, JSStringRef, JSValueRef, JSValueRef*); - - static bool has_instance(JSContextRef ctx, JSObjectRef constructor, JSValueRef value, JSValueRef* exception); - - static bool set_readonly_property(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef value, - JSValueRef* exception) - { - *exception = Exception::value(ctx, std::string("Cannot assign to read only property '") + - std::string(String(property)) + "'"); - return false; - } - - static void set_internal_property(JSContextRef ctx, JSObjectRef& instance, - typename ClassType::Internal* internal); - - static void define_schema_properties(JSContextRef ctx, JSObjectRef constructorPrototype, - const realm::ObjectSchema& schema, bool redefine); - static void define_accessor_for_schema_property(JSContextRef ctx, JSObjectRef& target, jsc::String* name); - static void define_native_property_accessor(JSContextRef ctx, JSObjectRef& target, jsc::String* name, - JSObjectGetPropertyCallback getCallback); - static JSValueRef native_property_getter_callback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, - size_t argumentCount, const JSValueRef arguments[], - JSValueRef* exception); - static JSValueRef accessor_getter(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argc, - const JSValueRef arguments[], JSValueRef* exception); - static JSValueRef accessor_setter(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argc, - const JSValueRef arguments[], JSValueRef* exception); -}; - -template <> -class ObjectWrap { -public: - using Internal = void; - - static JSClassRef get_class() - { - return nullptr; - } -}; - -// The static class variable must be defined as well. -template -ClassType ObjectWrap::s_class; - -template -std::unordered_map*> - ObjectWrap::s_schemaObjectTypes; - -template -JSClassRef ObjectWrap::m_getterAccessorClass = nullptr; - -template -JSClassRef ObjectWrap::m_setterAccessorClass = nullptr; - -template -JSClassRef ObjectWrap::m_NativePropertyGetterClass = nullptr; - -template -JSClassRef ObjectWrap::m_internalValueClass = nullptr; - -template -JSClassRef ObjectWrap::m_Class = nullptr; - -template -JSClassRef ObjectWrap::m_constructorClass = nullptr; - -template -inline JSClassRef ObjectWrap::create_class() -{ - JSClassDefinition definition = kJSClassDefinitionEmpty; - std::vector methods; - std::vector properties; - - definition.parentClass = ObjectWrap::get_class(); - definition.className = s_class.name.c_str(); - definition.finalize = finalize; - - if (!s_class.methods.empty()) { - methods = get_methods(s_class.methods); - definition.staticFunctions = methods.data(); - } - if (!s_class.properties.empty()) { - properties = get_properties(s_class.properties); - definition.staticValues = properties.data(); - } - - if (s_class.index_accessor.getter || s_class.string_accessor.getter) { - definition.getProperty = get_property; - definition.setProperty = set_property; - } - else if (s_class.index_accessor.setter || s_class.string_accessor.setter) { - definition.setProperty = set_property; - } - - if (s_class.index_accessor.getter || s_class.string_accessor.enumerator) { - definition.getPropertyNames = get_property_names; - } - - return JSClassCreate(&definition); -} - -template -inline JSClassRef ObjectWrap::create_constructor_class() -{ - JSClassDefinition definition = kJSClassDefinitionEmpty; - std::vector methods; - std::vector properties; - - definition.attributes = kJSClassAttributeNoAutomaticPrototype; - definition.className = "Function"; - definition.initialize = initialize_constructor; - definition.hasInstance = has_instance; - - // This must be set for `typeof constructor` to be 'function'. - definition.callAsFunction = call; - - if (reinterpret_cast(s_class.constructor)) { - definition.callAsConstructor = construct; - } - if (!s_class.static_methods.empty()) { - methods = get_methods(s_class.static_methods); - definition.staticFunctions = methods.data(); - } - if (!s_class.static_properties.empty()) { - properties = get_properties(s_class.static_properties); - definition.staticValues = properties.data(); - } - - bool isRealmObjectClass = std::is_same>::value; - if (isRealmObjectClass) { - if (m_internalValueClass == nullptr) { - JSClassDefinition internalValueClassDefinition = kJSClassDefinitionEmpty; - internalValueClassDefinition.className = "Internal"; - internalValueClassDefinition.finalize = finalize; - m_internalValueClass = JSClassCreate(&internalValueClassDefinition); - m_internalValueClass = JSClassRetain(m_internalValueClass); - } - - if (m_getterAccessorClass == nullptr) { - JSClassDefinition definition = kJSClassDefinitionEmpty; - definition.callAsFunction = accessor_getter; - m_getterAccessorClass = JSClassCreate(&definition); - m_getterAccessorClass = JSClassRetain(m_getterAccessorClass); - } - - if (m_setterAccessorClass == nullptr) { - JSClassDefinition definition = kJSClassDefinitionEmpty; - definition.callAsFunction = accessor_setter; - m_setterAccessorClass = JSClassCreate(&definition); - m_setterAccessorClass = JSClassRetain(m_setterAccessorClass); - } - - if (m_NativePropertyGetterClass == nullptr) { - JSClassDefinition definition = kJSClassDefinitionEmpty; - definition.callAsFunction = native_property_getter_callback; - m_NativePropertyGetterClass = JSClassCreate(&definition); - m_NativePropertyGetterClass = JSClassRetain(m_NativePropertyGetterClass); - } - } - - return JSClassCreate(&definition); -} - -template -inline std::vector ObjectWrap::get_methods(const MethodMap& methods) -{ - std::vector functions; - functions.reserve(methods.size() + 1); - - JSPropertyAttributes attributes = - kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete; - size_t index = 0; - - for (auto& pair : methods) { - functions[index++] = {pair.first.c_str(), pair.second, attributes}; - } - - functions[index] = {0}; - return functions; -} - -template -inline std::vector ObjectWrap::get_properties(const PropertyMap& properties) -{ - std::vector values; - values.reserve(properties.size() + 1); - - JSPropertyAttributes attributes = kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete; - size_t index = 0; - - for (auto& pair : properties) { - auto& prop = pair.second; - values[index++] = {pair.first.c_str(), prop.getter, prop.setter ?: set_readonly_property, attributes}; - } - - values[index] = {0}; - return values; -} - -template -inline void ObjectWrap::on_context_destroy(JSContextRef ctx, std::string realmPath) -{ - std::unordered_map* schemaObjects = nullptr; - if (!s_schemaObjectTypes.count(realmPath)) { - return; - } - - schemaObjects = s_schemaObjectTypes.at(realmPath); - for (auto it = schemaObjects->begin(); it != schemaObjects->end(); ++it) { - JSValueUnprotect(ctx, it->second->constructor); - it->second->constructor = nullptr; - SchemaObjectType* schemaObjecttype = it->second; - delete schemaObjecttype; - } - s_schemaObjectTypes.erase(realmPath); - - delete schemaObjects; -} - -template -inline JSValueRef ObjectWrap::accessor_getter(JSContextRef ctx, JSObjectRef function, - JSObjectRef this_object, size_t argc, - const JSValueRef arguments[], JSValueRef* exception) -{ - bool isRealmObjectClass = std::is_same>::value; - REALM_ASSERT(isRealmObjectClass); - - void* data = JSObjectGetPrivate(function); - jsc::String* propertyName = (jsc::String*)data; -#ifdef DEBUG - std::string debugName = *propertyName; -#endif - - return s_class.string_accessor.getter(ctx, this_object, *propertyName, exception); -} - -template -inline JSValueRef ObjectWrap::accessor_setter(JSContextRef ctx, JSObjectRef function, - JSObjectRef this_object, size_t argc, - const JSValueRef arguments[], JSValueRef* exception) -{ - bool isRealmObjectClass = std::is_same>::value; - REALM_ASSERT(isRealmObjectClass); - - void* data = JSObjectGetPrivate(function); - jsc::String* propertyName = (jsc::String*)data; -#ifdef DEBUG - std::string debugName = *propertyName; -#endif - - bool result = s_class.string_accessor.setter(ctx, this_object, *propertyName, arguments[0], exception); - return Value::from_boolean(ctx, result); -} - -template -inline JSValueRef ObjectWrap::native_property_getter_callback(JSContextRef ctx, JSObjectRef function, - JSObjectRef thisObject, size_t argumentCount, - const JSValueRef arguments[], - JSValueRef* exception) -{ - bool isRealmObjectClass = std::is_same>::value; - REALM_ASSERT(isRealmObjectClass); - - JSValueRef error = nullptr; - - void* data = JSObjectGetPrivate(function); - JSValueRef value = JSObjectGetProperty(ctx, function, JSStringCreateWithUTF8CString("propertyName"), &error); - if (error) { - *exception = error; - return nullptr; - } - jsc::String propertyName = Value::to_string(ctx, value); -#ifdef DEBUG - std::string debugName = propertyName; -#endif - - JSObjectGetPropertyCallback getterCallback = (JSObjectGetPropertyCallback)data; - - JSValueRef result = getterCallback(ctx, thisObject, propertyName, &error); - if (error) { - *exception = error; - return nullptr; - } - - return result; -} - -template -void ObjectWrap::define_accessor_for_schema_property(JSContextRef ctx, JSObjectRef& target, - jsc::String* name) -{ - JSObjectRef descriptor = Object::create_empty(ctx); - JSValueRef exception = nullptr; - - // create an object with attached function callback. This is to be able to set private data on the function. - // Use this function as the 'get' function in the property descriptor - // set the property name as private data. In the future this could be the realm::Property or the table index to - // speed up the get operation - JSObjectRef getter = JSObjectMake(ctx, m_getterAccessorClass, name); - JSObjectSetPrototype(ctx, getter, FunctionPrototype); - - JSObjectSetProperty(ctx, descriptor, JSStringCreateWithUTF8CString("get"), getter, kJSPropertyAttributeReadOnly, - &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - JSObjectRef setter = JSObjectMake(ctx, m_setterAccessorClass, name); - JSObjectSetProperty(ctx, descriptor, JSStringCreateWithUTF8CString("set"), setter, kJSPropertyAttributeReadOnly, - &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - JSObjectSetProperty(ctx, descriptor, JSStringCreateWithUTF8CString("enumerable"), Value::from_boolean(ctx, true), - kJSPropertyAttributeReadOnly, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - // call Object.defineProperty - JSValueRef arguments[] = {target, Value::from_string(ctx, *name), descriptor}; - Function::call(ctx, ObjectDefineProperty, nullptr /*this*/, 3, arguments); -} - -template -void ObjectWrap::define_native_property_accessor(JSContextRef ctx, JSObjectRef& target, jsc::String* name, - JSObjectGetPropertyCallback getCallback) -{ - - JSObjectRef descriptor = Object::create_empty(ctx); - JSValueRef exception = nullptr; - - JSObjectRef getter = JSObjectMake(ctx, m_NativePropertyGetterClass, (void*)getCallback); - JSObjectSetPrototype(ctx, getter, FunctionPrototype); - JSObjectSetProperty(ctx, getter, JSStringCreateWithUTF8CString("propertyName"), Value::from_string(ctx, *name), - kJSPropertyAttributeReadOnly, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - JSObjectSetProperty(ctx, descriptor, JSStringCreateWithUTF8CString("get"), getter, kJSPropertyAttributeReadOnly, - &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - - // call Object.defineProperty - JSValueRef arguments[] = {target, Value::from_string(ctx, *name), descriptor}; - Function::call(ctx, ObjectDefineProperty, nullptr /*this*/, 3, arguments); -} - -// A cache for property names. The pair is property name and a node::String* to the same string representation. -// The cache is persisted throughout the process life time to preseve property names between constructor cache -// invalidations (on_destory_context is called) Since RealmObjectClass instances may be used after context is -// destroyed, their property names should be valid -static std::unordered_map propertyNamesCache; - -static jsc::String* get_cached_property_name(const std::string& name) -{ - if (propertyNamesCache.count(name)) { - jsc::String* cachedName = propertyNamesCache.at(name); - return cachedName; - } - - jsc::String* result = new jsc::String(name); - propertyNamesCache.emplace(name, result); - return result; -} - -static void define_function_property(JSContextRef ctx, JSObjectRef& target, const char* name, - const JSObjectCallAsFunctionCallback& callback) -{ - JSObjectRef descriptor = Object::create_empty(ctx); - - JSObjectRef functionValue = JSObjectMakeFunctionWithCallback(ctx, JSStringCreateWithUTF8CString(name), callback); - - JSValueRef exception = nullptr; - JSObjectSetProperty(ctx, descriptor, JSStringCreateWithUTF8CString("value"), functionValue, - kJSPropertyAttributeNone, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - JSObjectSetProperty(ctx, descriptor, JSStringCreateWithUTF8CString("writable"), Value::from_boolean(ctx, true), - kJSPropertyAttributeNone, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - JSObjectSetProperty(ctx, descriptor, JSStringCreateWithUTF8CString("configurable"), - Value::from_boolean(ctx, true), kJSPropertyAttributeNone, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - JSValueRef arguments[] = {target, Value::from_string(ctx, name), descriptor}; - Function::call(ctx, ObjectDefineProperty, nullptr /*this*/, 3, arguments); -} - -static inline void remove_schema_object(JSContextRef ctx, - std::unordered_map* schemaObjects, - const std::string& schemaName) -{ - bool schemaExists = schemaObjects->count(schemaName); - if (!schemaExists) { - return; - } - - SchemaObjectType* schemaObjectType = schemaObjects->at(schemaName); - schemaObjects->erase(schemaName); - JSValueUnprotect(ctx, schemaObjectType->constructor); - delete schemaObjectType; -} - -template -typename ClassType::Internal* ObjectWrap::get_internal(JSContextRef ctx, const JSObjectRef& object) -{ - JSObjectRef instance = object; - bool isRealmObjectClass = std::is_same>::value; - if (isRealmObjectClass) { - const jsc::String* externalName = get_cached_property_name("_external"); - JSValueRef value = Object::get_property(ctx, object, *externalName); - if (Value::is_undefined(ctx, value)) { - return nullptr; - } - - instance = Value::to_object(ctx, value); - } - - ObjectWrap* realmObjectInstance = static_cast*>(JSObjectGetPrivate(instance)); - return realmObjectInstance->m_object.get(); -} - -template -void ObjectWrap::set_internal_property(JSContextRef ctx, JSObjectRef& instance, - typename ClassType::Internal* internal) -{ - // create a JS object that has a finializer to delete the internal reference - JSObjectRef internalObject = JSObjectMake(ctx, m_internalValueClass, new ObjectWrap(internal)); - - const jsc::String* externalName = get_cached_property_name("_external"); - auto attributes = realm::js::PropertyAttributes::ReadOnly | realm::js::PropertyAttributes::DontDelete | - realm::js::PropertyAttributes::DontEnum; - Object::set_property(ctx, instance, *externalName, internalObject, attributes); -} - -static inline JSObjectRef try_get_prototype(JSContextRef ctx, JSObjectRef object) -{ - JSValueRef exception = nullptr; - JSValueRef protoValue = JSObjectGetPrototype(ctx, object); - if (JSValueIsNull(ctx, protoValue)) { - return nullptr; - } - - JSObjectRef proto = JSValueToObject(ctx, protoValue, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - return proto; -} - -// This is called from realm's abstraction layer and by JSValueIsInstanceOfConstructor -template -bool ObjectWrap::has_instance(JSContextRef ctx, JSValueRef value) -{ - bool isRealmObjectClass = std::is_same>::value; - if (isRealmObjectClass) { - // Can't use JSValueIsObjectOfClass for RealmObjectClass instances created from a user defined constructor in - // the schema. Can't use JSValueIsInstanceOfConstructor with the RealmObjectClass constructor since it will - // recursively call this method again Check if the object has RealmObjectClassConstructorPrototype in its - // proto chain (the definition of JS 'instanceof') - if (!JSValueIsObject(ctx, value)) { - return false; - } - - JSValueRef error = nullptr; - JSObjectRef object = JSValueToObject(ctx, value, &error); - if (error) { - // do not throw exceptions in 'instanceof' calls - return false; - } - - // search for RealmObjectClassConstructor on the prototype chain of the object - JSObjectRef proto = try_get_prototype(ctx, object); - while (proto != nullptr && !JSValueIsNull(ctx, proto)) { - if (JSValueIsStrictEqual(ctx, proto, RealmObjectClassConstructorPrototype)) { - return true; - } - - proto = try_get_prototype(ctx, proto); - } - - // handle RealmObjects using user defined ctors without extending RealmObject. - // In this case we just check for existing internal value to identify RealmObject instances - auto internal = ObjectWrap::get_internal(ctx, object); - if (internal != nullptr) { - return true; - } - - // if there is no RealmObjectClass on the prototype chain and the object does not have existing internal value - // then this is not an RealmObject instance - return false; - } - - return JSValueIsObjectOfClass(ctx, value, get_class()); -} - -// JavaScriptCore calls this private method when doing 'instanceof' from JS -template -bool ObjectWrap::has_instance(JSContextRef ctx, JSObjectRef constructor, JSValueRef value, - JSValueRef* exception) -{ - return has_instance(ctx, value); -} - -template -inline void ObjectWrap::define_schema_properties(JSContextRef ctx, JSObjectRef constructorPrototype, - const realm::ObjectSchema& schema, bool redefine) -{ - // get all properties from the schema - for (auto& property : schema.persisted_properties) { - std::string propName = property.public_name.empty() ? property.name : property.public_name; - if (redefine || - !JSObjectHasProperty(ctx, constructorPrototype, JSStringCreateWithUTF8CString(propName.c_str()))) { - jsc::String* name = get_cached_property_name(propName); - define_accessor_for_schema_property(ctx, constructorPrototype, name); - } - } - - for (auto& property : schema.computed_properties) { - std::string propName = property.public_name.empty() ? property.name : property.public_name; - if (redefine || - !JSObjectHasProperty(ctx, constructorPrototype, JSStringCreateWithUTF8CString(propName.c_str()))) { - jsc::String* name = get_cached_property_name(propName); - define_accessor_for_schema_property(ctx, constructorPrototype, name); - } - } -} - -template -inline JSObjectRef ObjectWrap::create_instance_by_schema(JSContextRef ctx, JSObjectRef& constructor, - const realm::ObjectSchema& schema, - typename ClassType::Internal* internal) -{ - bool isRealmObjectClass = std::is_same>::value; - if (!isRealmObjectClass) { - JSValueRef exception = - jsc::Exception::value(ctx, "Creating instances by schema is supported for RealmObjectClass only"); - throw jsc::Exception(ctx, exception); - } - - if (isRealmObjectClass && !internal) { - JSValueRef exception = jsc::Exception::value( - ctx, "RealmObjectClass requires an internal realm object when creating instances by schema"); - throw jsc::Exception(ctx, exception); - } - - JSObjectRef instance; - JSValueRef value; - - auto config = internal->realm()->config(); - std::string path = config.path; - auto version = internal->realm()->schema_version(); - std::string schemaName = schema.name + ":" + util::to_string(version); - - std::unordered_map* schemaObjects = nullptr; - if (!s_schemaObjectTypes.count(path)) { - schemaObjects = new std::unordered_map(); - s_schemaObjectTypes.emplace(path, schemaObjects); - } - else { - schemaObjects = s_schemaObjectTypes.at(path); - } - - JSObjectRef schemaObjectConstructor; - SchemaObjectType* schemaObjectType; - JSObjectRef constructorPrototype; - - // if we are creating a RealmObject from schema with no user defined constructor - if (constructor == nullptr) { - if (!schemaObjects->count(schemaName)) { - - JSClassDefinition definition = kJSClassDefinitionEmpty; - definition.className = schema.name.c_str(); - JSClassRef schemaClass = JSClassCreate(&definition); - schemaObjectConstructor = JSObjectMakeConstructor(ctx, schemaClass, nullptr); - value = Object::get_property(ctx, schemaObjectConstructor, "prototype"); - constructorPrototype = Value::to_object(ctx, value); - - JSObjectSetPrototype(ctx, constructorPrototype, RealmObjectClassConstructorPrototype); - JSObjectSetPrototype(ctx, schemaObjectConstructor, RealmObjectClassConstructor); - - define_schema_properties(ctx, constructorPrototype, schema, true); - - schemaObjectType = new SchemaObjectType(); - schemaObjects->emplace(schemaName, schemaObjectType); - JSValueProtect(ctx, schemaObjectConstructor); - schemaObjectType->constructor = schemaObjectConstructor; - } - else { - // hot path. The constructor for this schema object is already cached. - schemaObjectType = schemaObjects->at(schemaName); - schemaObjectConstructor = schemaObjectType->constructor; - } - - instance = Function::construct(ctx, schemaObjectConstructor, 0, {}); - - // save the internal object on the instance - set_internal_property(ctx, instance, internal); - - return instance; - } - else { - // creating a RealmObject with user defined constructor - bool schemaExists = schemaObjects->count(schemaName); - if (schemaExists) { - schemaObjectType = schemaObjects->at(schemaName); - schemaObjectConstructor = schemaObjectType->constructor; - - // check if constructors have changed for the same schema object and name - if (!JSValueIsStrictEqual(ctx, schemaObjectConstructor, constructor)) { - schemaExists = false; - remove_schema_object(ctx, schemaObjects, schemaName); - } - } - - // hot path. The constructor for this schema object is already cached. use it and return a new instance - if (schemaExists) { - schemaObjectType = schemaObjects->at(schemaName); - schemaObjectConstructor = schemaObjectType->constructor; - - instance = Function::construct(ctx, schemaObjectConstructor, 0, {}); - set_internal_property(ctx, instance, internal); - return instance; - } - - schemaObjectConstructor = constructor; - value = Object::get_property(ctx, constructor, "prototype"); - constructorPrototype = Value::to_object(ctx, value); - - define_schema_properties(ctx, constructorPrototype, schema, false); - - JSValueRef exception = nullptr; - bool isInstanceOfRealmObjectClass = - JSValueIsInstanceOfConstructor(ctx, constructorPrototype, RealmObjectClassConstructor, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - // Skip if the user defined constructor inherited the RealmObjectClass. All RealmObjectClass members are - // available already. - if (!isInstanceOfRealmObjectClass) { - // setup all RealmObjectClass methods to the prototype of the object - for (auto& pair : s_class.methods) { - // don't redefine if exists - if (!JSObjectHasProperty(ctx, constructorPrototype, - JSStringCreateWithUTF8CString(pair.first.c_str()))) { - define_function_property(ctx, constructorPrototype, pair.first.c_str(), pair.second); - } - } - - for (auto& pair : s_class.properties) { - // don't redefine if exists - if (!JSObjectHasProperty(ctx, constructorPrototype, - JSStringCreateWithUTF8CString(pair.first.c_str()))) { - jsc::String* name = get_cached_property_name(pair.first); - JSObjectGetPropertyCallback getterCallback = pair.second.getter; - define_native_property_accessor(ctx, constructorPrototype, name, getterCallback); - } - } - } - - // create the instance - instance = Function::construct(ctx, schemaObjectConstructor, 0, {}); - bool instanceOfSchemaConstructor = - JSValueIsInstanceOfConstructor(ctx, instance, schemaObjectConstructor, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - if (!instanceOfSchemaConstructor) { - throw jsc::Exception(ctx, "Realm object constructor must not return another value"); - } - - // save the internal object on the instance - set_internal_property(ctx, instance, internal); - - schemaObjectType = new SchemaObjectType(); - schemaObjects->emplace(schemaName, schemaObjectType); - JSValueProtect(ctx, schemaObjectConstructor); - schemaObjectType->constructor = schemaObjectConstructor; - - return instance; - } -} - -template -inline JSValueRef ObjectWrap::call(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, - size_t argc, const JSValueRef arguments[], JSValueRef* exception) -{ - // This should only be called as a super() call in the constructor of a subclass. - if (!has_instance(ctx, this_object)) { - *exception = jsc::Exception::value(ctx, s_class.name + " cannot be called as a function"); - return nullptr; - } - - // Classes without a constructor should still be subclassable. - if (reinterpret_cast(s_class.constructor)) { - jsc::Arguments args{ctx, argc, arguments}; - try { - s_class.constructor(ctx, this_object, args); - } - catch (std::exception& e) { - *exception = jsc::Exception::value(ctx, e); - return nullptr; - } - } - - return JSValueMakeUndefined(ctx); -} - -template -inline JSObjectRef ObjectWrap::construct(JSContextRef ctx, JSObjectRef constructor, size_t argc, - const JSValueRef arguments[], JSValueRef* exception) -{ - if (!reinterpret_cast(s_class.constructor)) { - *exception = jsc::Exception::value(ctx, s_class.name + " is not a constructor"); - return nullptr; - } - - JSObjectRef this_object = create_instance(ctx); - jsc::Arguments args{ctx, argc, arguments}; - try { - s_class.constructor(ctx, this_object, args); - } - catch (std::exception& e) { - *exception = jsc::Exception::value(ctx, e); - return nullptr; - } - return this_object; -} - -template -inline void ObjectWrap::initialize_constructor(JSContextRef ctx, JSObjectRef constructor) -{ - static const String prototype_string = "prototype"; - - // Set the prototype of the constructor to be Function.prototype. - Object::set_prototype(ctx, constructor, - Object::get_prototype(ctx, JSObjectMakeFunctionWithCallback(ctx, nullptr, call))); - - // Set the constructor prototype to be the prototype generated from the instance JSClassRef. - JSObjectRef prototype = - Object::validated_get_object(ctx, JSObjectMakeConstructor(ctx, get_class(), construct), prototype_string); - Object::set_property(ctx, constructor, prototype_string, prototype, js::ReadOnly | js::DontEnum | js::DontDelete); -} - -template -inline void ObjectWrap::finalize(JSObjectRef object) -{ - // This is called for the most derived class before superclasses. - if (auto wrap = static_cast*>(JSObjectGetPrivate(object))) { - delete wrap; - JSObjectSetPrivate(object, nullptr); - } -} - -template -inline void ObjectWrap::get_property_names(JSContextRef ctx, JSObjectRef object, - JSPropertyNameAccumulatorRef accumulator) -{ - if (s_class.index_accessor.getter) { - try { - uint32_t length = Object::validated_get_length(ctx, object); - char string[32]; - for (uint32_t i = 0; i < length; i++) { - sprintf(string, "%u", i); - JSPropertyNameAccumulatorAddName(accumulator, jsc::String(string)); - } - } - catch (std::exception&) { - // Enumerating properties should never throw an exception into JS. - } - } - if (auto string_enumerator = s_class.string_accessor.enumerator) { - string_enumerator(ctx, object, accumulator); - } -} - -static inline bool try_get_int(JSStringRef property, int64_t& value) -{ - value = 0; - auto str = JSStringGetCharactersPtr(property); - auto end = str + JSStringGetLength(property); - while (str != end && iswspace(*str)) { - ++str; - } - bool negative = false; - if (str != end && *str == '-') { - negative = true; - ++str; - } - while (str != end && *str >= '0' && *str <= '9') { - if (util::int_multiply_with_overflow_detect(value, 10)) { - return false; - } - value += *str - '0'; - ++str; - } - if (negative) { - value *= -1; - } - return str == end; -} - -template -inline JSValueRef ObjectWrap::get_property(JSContextRef ctx, JSObjectRef object, JSStringRef property, - JSValueRef* exception) -{ - if (JSStringGetLength(property) == 0) { - return Value::from_undefined(ctx); - } - - if (auto index_getter = s_class.index_accessor.getter) { - int64_t num; - if (try_get_int(property, num)) { - uint32_t index; - if (num < 0 || util::int_cast_with_overflow_detect(num, index)) { - // Out-of-bounds index getters should just return undefined in JS. - return Value::from_undefined(ctx); - } - - return index_getter(ctx, object, index, exception); - } - } - - if (auto string_getter = s_class.string_accessor.getter) { - return string_getter(ctx, object, property, exception); - } - - return nullptr; -} - -template -inline bool ObjectWrap::set_property(JSContextRef ctx, JSObjectRef object, JSStringRef property, - JSValueRef value, JSValueRef* exception) -{ - if (JSStringGetLength(property) == 0) { - return false; - } - - auto index_setter = s_class.index_accessor.setter; - - if (index_setter || s_class.index_accessor.getter) { - int64_t num; - if (try_get_int(property, num)) { - if (num < 0) { - *exception = Exception::value(ctx, util::format("Index %1 cannot be less than zero.", num)); - return false; - } - - int32_t index; - if (util::int_cast_with_overflow_detect(num, index)) { - *exception = Exception::value(ctx, util::format("Index %1 cannot be greater than %2.", num, - std::numeric_limits::max())); - return false; - } - - if (index_setter) { - return index_setter(ctx, object, index, value, exception); - } - - *exception = Exception::value(ctx, util::format("Cannot assign to read only index %1", index)); - return false; - } - } - - if (auto string_setter = s_class.string_accessor.setter) { - return string_setter(ctx, object, property, value, exception); - } - - return false; -} - -} // namespace jsc - -namespace js { - -template -class ObjectWrap : public jsc::ObjectWrap { -}; - -template -JSValueRef wrap(JSContextRef ctx, JSObjectRef, JSObjectRef this_object, size_t argc, const JSValueRef arguments[], - JSValueRef* exception) -{ - jsc::Arguments args{ctx, argc, arguments}; - jsc::ReturnValue return_value(ctx); - try { - F(ctx, this_object, args, return_value); - return return_value; - } - catch (std::exception& e) { - *exception = jsc::Exception::value(ctx, e); - return nullptr; - } -} - -template -JSValueRef wrap(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception) -{ - jsc::ReturnValue return_value(ctx); - try { - F(ctx, object, return_value); - return return_value; - } - catch (std::exception& e) { - *exception = jsc::Exception::value(ctx, e); - return nullptr; - } -} - -template -bool wrap(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef* exception) -{ - try { - F(ctx, object, value); - return true; - } - catch (std::exception& e) { - *exception = jsc::Exception::value(ctx, e); - return false; - } -} - -template -JSValueRef wrap(JSContextRef ctx, JSObjectRef object, uint32_t index, JSValueRef* exception) -{ - jsc::ReturnValue return_value(ctx); - try { - F(ctx, object, index, return_value); - return return_value; - } - catch (std::out_of_range&) { - // Out-of-bounds index getters should just return undefined in JS. - return jsc::Value::from_undefined(ctx); - } - catch (std::exception& e) { - *exception = jsc::Exception::value(ctx, e); - return nullptr; - } -} - -template -bool wrap(JSContextRef ctx, JSObjectRef object, uint32_t index, JSValueRef value, JSValueRef* exception) -{ - try { - return F(ctx, object, index, value); - } - catch (std::exception& e) { - *exception = jsc::Exception::value(ctx, e); - return false; - } -} - -template -JSValueRef wrap(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception) -{ - jsc::ReturnValue return_value(ctx); - try { - F(ctx, object, property, return_value); - return return_value; - } - catch (std::exception& e) { - *exception = jsc::Exception::value(ctx, e); - return nullptr; - } -} - -template -bool wrap(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef* exception) -{ - try { - return F(ctx, object, property, value); - } - catch (std::exception& e) { - *exception = jsc::Exception::value(ctx, e); - return false; - } -} - -template -void wrap(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef accumulator) -{ - auto names = F(ctx, object); - for (auto& name : names) { - JSPropertyNameAccumulatorAddName(accumulator, name); - } -} - -} // namespace js -} // namespace realm diff --git a/src/jsc/jsc_context.hpp b/src/jsc/jsc_context.hpp deleted file mode 100644 index d73f5eb3a7..0000000000 --- a/src/jsc/jsc_context.hpp +++ /dev/null @@ -1,33 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "jsc_types.hpp" - -namespace realm { -namespace js { - -template <> -inline JSGlobalContextRef jsc::Context::get_global_context(JSContextRef ctx) -{ - return JSContextGetGlobalContext(ctx); -} - -} // namespace js -} // namespace realm diff --git a/src/jsc/jsc_exception.hpp b/src/jsc/jsc_exception.hpp deleted file mode 100644 index 51757ecce8..0000000000 --- a/src/jsc/jsc_exception.hpp +++ /dev/null @@ -1,34 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "jsc_types.hpp" - -namespace realm { -namespace js { - -template <> -inline JSValueRef jsc::Exception::value(JSContextRef ctx, const std::string& message) -{ - JSValueRef value = jsc::Value::from_string(ctx, message); - return JSObjectMakeError(ctx, 1, &value, NULL); -} - -} // namespace js -} // namespace realm diff --git a/src/jsc/jsc_function.hpp b/src/jsc/jsc_function.hpp deleted file mode 100644 index d2f99d5c1e..0000000000 --- a/src/jsc/jsc_function.hpp +++ /dev/null @@ -1,58 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "jsc_types.hpp" - -namespace realm { -namespace js { - -template <> -inline JSValueRef jsc::Function::call(JSContextRef ctx, const JSObjectRef& function, const JSObjectRef& this_object, - size_t argc, const JSValueRef arguments[]) -{ - JSValueRef exception = nullptr; - JSValueRef result = JSObjectCallAsFunction(ctx, function, this_object, argc, arguments, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - return result; -} - -template <> -inline JSValueRef jsc::Function::callback(JSContextRef ctx, const JSObjectRef& function, - const JSObjectRef& this_object, size_t argc, const JSValueRef arguments[]) -{ - return jsc::Function::call(ctx, function, this_object, argc, arguments); -} - -template <> -inline JSObjectRef jsc::Function::construct(JSContextRef ctx, const JSObjectRef& function, size_t argc, - const JSValueRef arguments[]) -{ - JSValueRef exception = nullptr; - JSObjectRef result = JSObjectCallAsConstructor(ctx, function, argc, arguments, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - return result; -} - -} // namespace js -} // namespace realm diff --git a/src/jsc/jsc_init.cpp b/src/jsc/jsc_init.cpp deleted file mode 100644 index ba290616b7..0000000000 --- a/src/jsc/jsc_init.cpp +++ /dev/null @@ -1,68 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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 -#include - -#include -#include - -#include "jsc_init.hpp" -#include "platform.hpp" -namespace realm { -namespace jsc { -js::Protected ObjectDefineProperty; -js::Protected FunctionPrototype; -js::Protected RealmObjectClassConstructor; -js::Protected RealmObjectClassConstructorPrototype; -} // namespace jsc -} // namespace realm - -extern "C" { - -using namespace realm; -using namespace realm::jsc; - -JSObjectRef RJSConstructorCreate(JSContextRef ctx) -{ - return js::RealmClass::create_constructor(ctx); -} - -void RJSInitializeInContext(JSContextRef ctx) -{ - static const jsc::String realm_string = "Realm"; - - JSObjectRef global_object = JSContextGetGlobalObject(ctx); - - jsc_class_init(ctx, global_object); - - JSObjectRef realm_constructor = RJSConstructorCreate(ctx); - - jsc::Object::set_property(ctx, global_object, realm_string, realm_constructor, - js::ReadOnly | js::DontEnum | js::DontDelete); -} - -void RJSInvalidateCaches() -{ - // Close all cached Realms - realm::_impl::RealmCoordinator::clear_all_caches(); - // Clear the Object Store App cache, to prevent instances from using a context that was released - realm::app::App::clear_cached_apps(); -} - -} // extern "C" diff --git a/src/jsc/jsc_init.h b/src/jsc/jsc_init.h deleted file mode 100644 index 8521abef9d..0000000000 --- a/src/jsc/jsc_init.h +++ /dev/null @@ -1,33 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -JSObjectRef RJSConstructorCreate(JSContextRef ctx); -void RJSInitializeInContext(JSContextRef ctx); -void RJSInvalidateCaches(); - -#ifdef __cplusplus -} -#endif diff --git a/src/jsc/jsc_init.hpp b/src/jsc/jsc_init.hpp deleted file mode 100644 index 671120fa02..0000000000 --- a/src/jsc/jsc_init.hpp +++ /dev/null @@ -1,35 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "jsc_init.h" -#include "jsc_string.hpp" -#include "jsc_protected.hpp" -#include "jsc_context.hpp" -#include "jsc_value.hpp" -#include "jsc_object.hpp" -#include "jsc_function.hpp" -#include "jsc_exception.hpp" -#include "jsc_return_value.hpp" -#include "jsc_class.hpp" - -// FIXME: js_object_accessor.hpp includes js_list.hpp which includes js_object_accessor.hpp. -#include "js_object_accessor.hpp" - -#include "js_realm.hpp" diff --git a/src/jsc/jsc_object.hpp b/src/jsc/jsc_object.hpp deleted file mode 100644 index 319d280aa0..0000000000 --- a/src/jsc/jsc_object.hpp +++ /dev/null @@ -1,195 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "jsc_types.hpp" - -namespace realm { -namespace js { - -template <> -inline JSValueRef jsc::Object::get_property(JSContextRef ctx, const JSObjectRef& object, const jsc::String& key) -{ - JSValueRef exception = nullptr; - JSValueRef value = JSObjectGetProperty(ctx, object, key, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - return value; -} - -template <> -inline JSValueRef jsc::Object::get_property(JSContextRef ctx, const JSObjectRef& object, StringData key) -{ - return get_property(ctx, object, jsc::String(key)); -} - -template <> -inline JSValueRef jsc::Object::get_property(JSContextRef ctx, const JSObjectRef& object, uint32_t index) -{ - JSValueRef exception = nullptr; - JSValueRef value = JSObjectGetPropertyAtIndex(ctx, object, index, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - return value; -} - -template <> -inline void jsc::Object::set_property(JSContextRef ctx, JSObjectRef& object, const jsc::String& key, - const JSValueRef& value, PropertyAttributes attributes) -{ - JSValueRef exception = nullptr; - JSObjectSetProperty(ctx, object, key, value, attributes << 1, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } -} - -template <> -inline void jsc::Object::set_property(JSContextRef ctx, JSObjectRef& object, uint32_t index, const JSValueRef& value) -{ - JSValueRef exception = nullptr; - JSObjectSetPropertyAtIndex(ctx, object, index, value, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } -} - -template <> -inline std::vector jsc::Object::get_property_names(JSContextRef ctx, const JSObjectRef& object) -{ - JSPropertyNameArrayRef property_names = JSObjectCopyPropertyNames(ctx, object); - size_t property_count = JSPropertyNameArrayGetCount(property_names); - - std::vector names; - names.reserve(property_count); - - for (size_t i = 0; i < property_count; i++) { - names.push_back(JSPropertyNameArrayGetNameAtIndex(property_names, i)); - } - - JSPropertyNameArrayRelease(property_names); - return names; -} - -template <> -inline JSValueRef jsc::Object::get_prototype(JSContextRef ctx, const JSObjectRef& object) -{ - return JSObjectGetPrototype(ctx, object); -} - -template <> -inline void jsc::Object::set_prototype(JSContextRef ctx, const JSObjectRef& object, const JSValueRef& prototype) -{ - JSObjectSetPrototype(ctx, object, prototype); -} - -template <> -inline JSObjectRef jsc::Object::create_empty(JSContextRef ctx) -{ - return JSObjectMake(ctx, nullptr, nullptr); -} - -template <> -inline JSObjectRef jsc::Object::create_array(JSContextRef ctx, uint32_t length, const JSValueRef values[]) -{ - JSValueRef exception = nullptr; - JSObjectRef array = JSObjectMakeArray(ctx, length, values, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - return array; -} - -template <> -inline JSObjectRef jsc::Object::create_date(JSContextRef ctx, double time) -{ - JSValueRef number = jsc::Value::from_number(ctx, time); - return JSObjectMakeDate(ctx, 1, &number, nullptr); -} - -template <> -template -inline JSObjectRef jsc::Object::create_instance(JSContextRef ctx, typename ClassType::Internal* internal) -{ - return jsc::ObjectWrap::create_instance(ctx, internal); -} - -template <> -template -inline JSObjectRef jsc::Object::create_instance_by_schema(JSContextRef ctx, JSObjectRef& constructor, - const realm::ObjectSchema& schema, - typename ClassType::Internal* internal) -{ - return jsc::ObjectWrap::create_instance_by_schema(ctx, constructor, schema, internal); -} - -template <> -template -inline JSObjectRef jsc::Object::create_instance_by_schema(JSContextRef ctx, const realm::ObjectSchema& schema, - typename ClassType::Internal* internal) -{ - return jsc::ObjectWrap::create_instance_by_schema(ctx, schema, internal); -} - -template -inline void on_context_destroy(JSContextRef ctx, std::string realmPath) -{ - jsc::ObjectWrap::on_context_destroy(ctx, realmPath); -} - -template <> -template -inline bool jsc::Object::is_instance(JSContextRef ctx, const JSObjectRef& object) -{ - return jsc::ObjectWrap::has_instance(ctx, object); -} - -template <> -template -inline typename ClassType::Internal* jsc::Object::get_internal(JSContextRef ctx, const JSObjectRef& object) -{ - return jsc::ObjectWrap::get_internal(ctx, object); -} - -template <> -template -inline void jsc::Object::set_internal(JSContextRef ctx, const JSObjectRef& object, typename ClassType::Internal* ptr) -{ - auto wrap = static_cast*>(JSObjectGetPrivate(object)); - *wrap = ptr; -} - -template <> -inline void jsc::Object::set_global(JSContextRef ctx, const jsc::String& key, const JSValueRef& value) -{ - JSObjectRef global_object = JSContextGetGlobalObject(ctx); - jsc::Object::set_property(ctx, global_object, key, value, js::ReadOnly | js::DontEnum | js::DontDelete); -} - -template <> -inline JSValueRef jsc::Object::get_global(JSContextRef ctx, const jsc::String& key) -{ - JSObjectRef global_object = JSContextGetGlobalObject(ctx); - return jsc::Object::get_property(ctx, global_object, key); -} - -} // namespace js -} // namespace realm diff --git a/src/jsc/jsc_protected.hpp b/src/jsc/jsc_protected.hpp deleted file mode 100644 index 2e345b9403..0000000000 --- a/src/jsc/jsc_protected.hpp +++ /dev/null @@ -1,174 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "jsc_types.hpp" - -namespace realm { -namespace js { - -template <> -class Protected { - JSGlobalContextRef m_context; - -public: - Protected() - : m_context(nullptr) - { - } - Protected(const Protected& other) - : Protected(other.m_context) - { - } - Protected(Protected&& other) - : m_context(other.m_context) - { - other.m_context = nullptr; - } - explicit Protected(JSGlobalContextRef ctx) - : m_context(ctx) - { - JSGlobalContextRetain(m_context); - } - ~Protected() - { - if (m_context) { - JSGlobalContextRelease(m_context); - } - } - operator JSGlobalContextRef() const - { - return m_context; - } - operator bool() const - { - return m_context != nullptr; - } - - struct Comparator { - bool operator()(const Protected& a, const Protected& b) const - { - return a.m_context == b.m_context; - } - }; -}; - -template <> -class Protected { -protected: - JSGlobalContextRef m_context = nullptr; - JSValueRef m_value = nullptr; - -public: - Protected() {} - - Protected(const Protected& other) - : Protected(other.m_context, other.m_value) - { - } - - Protected(Protected&& other) - : m_context(other.m_context) - , m_value(other.m_value) - { - other.m_context = nullptr; - other.m_value = nullptr; - } - - Protected(JSContextRef ctx, JSValueRef value) - : m_context(JSContextGetGlobalContext(ctx)) - , m_value(value) - { - JSGlobalContextRetain(m_context); - JSValueProtect(m_context, m_value); - } - - ~Protected() - { - if (m_value) { - JSValueUnprotect(m_context, m_value); - } - - if (m_context) { - JSGlobalContextRelease(m_context); - } - } - operator JSValueRef() const - { - return m_value; - } - operator bool() const - { - return m_value != nullptr; - } - - struct Comparator { - bool operator()(const Protected& a, const Protected& b) const - { - if (a.m_context != b.m_context) { - return false; - } - return JSValueIsStrictEqual(a.m_context, a.m_value, b.m_value); - } - }; - - Protected& operator=(Protected other) - { - std::swap(m_context, other.m_context); - std::swap(m_value, other.m_value); - return *this; - } -}; - -template <> -class Protected : public Protected { -public: - Protected() - : Protected() - { - } - Protected(const Protected& other) - : Protected(other) - { - } - Protected(Protected&& other) - : Protected(std::move(other)) - { - } - Protected(JSContextRef ctx, JSObjectRef value) - : Protected(ctx, value) - { - } - - operator JSObjectRef() const - { - JSValueRef value = static_cast(*this); - return (JSObjectRef)value; - } - - Protected& operator=(Protected other) - { - std::swap(m_context, other.m_context); - std::swap(m_value, other.m_value); - return *this; - } -}; - -} // namespace js -} // namespace realm diff --git a/src/jsc/jsc_return_value.hpp b/src/jsc/jsc_return_value.hpp deleted file mode 100644 index 3653dd90d7..0000000000 --- a/src/jsc/jsc_return_value.hpp +++ /dev/null @@ -1,97 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "jsc_types.hpp" -#include "jsc_string.hpp" - -namespace realm { -namespace js { - -template <> -class ReturnValue { - const JSContextRef m_context; - JSValueRef m_value = nullptr; - -public: - ReturnValue(JSContextRef ctx) - : m_context(ctx) - { - } - - void set(const JSValueRef& value) - { - m_value = value; - } - void set(const std::string& string) - { - m_value = JSValueMakeString(m_context, jsc::String(string)); - } - void set(const char* string) - { - m_value = JSValueMakeString(m_context, jsc::String(string)); - } - void set(bool boolean) - { - m_value = JSValueMakeBoolean(m_context, boolean); - } - void set(double number) - { - m_value = JSValueMakeNumber(m_context, number); - } - void set(int32_t number) - { - m_value = JSValueMakeNumber(m_context, number); - } - void set(uint32_t number) - { - m_value = JSValueMakeNumber(m_context, number); - } - void set(realm::Mixed mixed) - { - m_value = Value::from_mixed(m_context, nullptr, mixed); - } - void set_null() - { - m_value = JSValueMakeNull(m_context); - } - void set_undefined() - { - m_value = JSValueMakeUndefined(m_context); - } - - template - void set(const util::Optional& value) - { - if (value) { - set(*value); - } - else { - set_undefined(); - } - } - - operator JSValueRef() const - { - return m_value; - } -}; - -} // namespace js -} // namespace realm diff --git a/src/jsc/jsc_rpc_network_transport.hpp b/src/jsc/jsc_rpc_network_transport.hpp deleted file mode 100644 index 9555e5405b..0000000000 --- a/src/jsc/jsc_rpc_network_transport.hpp +++ /dev/null @@ -1,79 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2020 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include -#include -#include "js_types.hpp" -#include "js_network_transport.hpp" - -namespace realm { -namespace rpc { - -/* -struct RPCFetchRef { - static JSValueRef value; -}; -*/ - -/** - * Provides an implementation of GenericNetworkTransport for use when the library is loaded in a runtime which doesn't - * provide the APIs required to perform network requests directly. Instead it uses the RPC server to ask the RPC - * client to perform network requests on its behalf. - */ -struct RPCNetworkTransport : public app::GenericNetworkTransport { - using T = jsc::Types; - using ContextType = typename T::Context; - using FunctionType = typename T::Function; - using ObjectType = typename T::Object; - using ValueType = typename T::Value; - using String = js::String; - using Object = js::Object; - using Value = js::Value; - using Function = js::Function; - - using SendRequestHandler = void(ContextType m_ctx, const app::Request request, - std::function completion_callback); - - static inline js::Protected fetch_function; - - RPCNetworkTransport(ContextType ctx) - : m_ctx(ctx) - { - } - - void send_request_to_server(const app::Request request, - std::function completion_callback) override - { - // Build up a JS request object - auto request_object = js::JavaScriptNetworkTransport::makeRequest(m_ctx, request); - // Ask the RPC layer to enqueue a call to the client-side fetch function - Function::call(m_ctx, fetch_function, nullptr, - { - request_object, - js::ResponseHandlerClass::create_instance(m_ctx, std::move(completion_callback)), - }); - } - -private: - ContextType m_ctx; -}; - -} // namespace rpc -} // namespace realm diff --git a/src/jsc/jsc_string.hpp b/src/jsc/jsc_string.hpp deleted file mode 100644 index f448096f17..0000000000 --- a/src/jsc/jsc_string.hpp +++ /dev/null @@ -1,90 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "jsc_types.hpp" - -namespace realm { -namespace js { - -template <> -class String { - using StringType = String; - - JSStringRef m_str; - -public: - static bson::Bson to_bson(StringType stringified_ejson) - { - return bson::parse(std::string(stringified_ejson)); - } - - static String from_bson(const bson::Bson& bson) - { - return String(bson.to_string()); - } - - String(const char* s) - : m_str(JSStringCreateWithUTF8CString(s)) - { - } - String(const JSStringRef& s) - : m_str(JSStringRetain(s)) - { - } - String(StringData str) - : String(str.data()) - { - } - String(const std::string& str) - : String(str.c_str()) - { - } - String(const StringType& o) - : String(o.m_str) - { - } - String(StringType&& o) - : m_str(o.m_str) - { - o.m_str = nullptr; - } - ~String() - { - if (m_str) { - JSStringRelease(m_str); - } - } - - operator JSStringRef() const - { - return m_str; - } - operator std::string() const - { - size_t max_size = JSStringGetMaximumUTF8CStringSize(m_str); - std::string string; - string.resize(max_size); - string.resize(JSStringGetUTF8CString(m_str, &string[0], max_size) - 1); - return string; - } -}; - -} // namespace js -} // namespace realm diff --git a/src/jsc/jsc_types.hpp b/src/jsc/jsc_types.hpp deleted file mode 100644 index 3aedaee329..0000000000 --- a/src/jsc/jsc_types.hpp +++ /dev/null @@ -1,64 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include -#include -#include - -#define HANDLESCOPE(context) - -#include "js_types.hpp" - - -namespace realm { -namespace jsc { - -struct Types { - using Context = JSContextRef; - using GlobalContext = JSGlobalContextRef; - using Value = JSValueRef; - using Object = JSObjectRef; - using String = JSStringRef; - using Function = JSObjectRef; - - using ConstructorCallback = JSObjectCallAsConstructorCallback; - using FunctionCallback = JSObjectCallAsFunctionCallback; - using PropertyGetterCallback = JSObjectGetPropertyCallback; - using PropertySetterCallback = JSObjectSetPropertyCallback; - using IndexPropertyGetterCallback = JSValueRef (*)(JSContextRef, JSObjectRef, uint32_t, JSValueRef*); - using IndexPropertySetterCallback = bool (*)(JSContextRef, JSObjectRef, uint32_t, JSValueRef, JSValueRef*); - using StringPropertyGetterCallback = JSObjectGetPropertyCallback; - using StringPropertySetterCallback = JSObjectSetPropertyCallback; - using StringPropertyEnumeratorCallback = JSObjectGetPropertyNamesCallback; -}; - -template -class ObjectWrap; - -using String = js::String; -using Context = js::Context; -using Value = js::Value; -using Function = js::Function; -using Object = js::Object; -using Exception = js::Exception; -using ReturnValue = js::ReturnValue; - -} // namespace jsc -} // namespace realm diff --git a/src/jsc/jsc_value.cpp b/src/jsc/jsc_value.cpp deleted file mode 100644 index 50623d190c..0000000000 --- a/src/jsc/jsc_value.cpp +++ /dev/null @@ -1,224 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2017 Realm Inc. -// -// 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 "jsc_value.hpp" - -#include "jsc_function.hpp" -#include "jsc_object.hpp" - -namespace realm { -namespace js { - -template <> -bool jsc::Value::is_binary(JSContextRef ctx, const JSValueRef& value) -{ - static jsc::String s_array_buffer = "ArrayBuffer"; - static jsc::String s_is_view = "isView"; - - JSObjectRef global_object = JSContextGetGlobalObject(ctx); - JSObjectRef array_buffer_constructor = jsc::Object::validated_get_constructor(ctx, global_object, s_array_buffer); - - // Value should either be an ArrayBuffer or ArrayBufferView (i.e. TypedArray or DataView). - if (JSValueIsInstanceOfConstructor(ctx, value, array_buffer_constructor, nullptr)) { - return true; - } - if (JSObjectRef object = JSValueToObject(ctx, value, nullptr)) { - // Check if value is an ArrayBufferView by calling ArrayBuffer.isView(val). - JSValueRef is_view = jsc::Object::call_method(ctx, array_buffer_constructor, s_is_view, 1, &object); - - return jsc::Value::to_boolean(ctx, is_view); - } - return false; -} - -template <> -JSValueRef jsc::Value::from_nonnull_binary(JSContextRef ctx, BinaryData data) -{ - static jsc::String s_buffer = "buffer"; - static jsc::String s_uint8_array = "Uint8Array"; - - size_t byte_count = data.size(); - JSValueRef byte_count_value = jsc::Value::from_number(ctx, byte_count); - JSObjectRef uint8_array_constructor = - jsc::Object::validated_get_constructor(ctx, JSContextGetGlobalObject(ctx), s_uint8_array); - JSObjectRef uint8_array = jsc::Function::construct(ctx, uint8_array_constructor, 1, &byte_count_value); - - for (uint32_t i = 0; i < byte_count; i++) { - JSValueRef num = jsc::Value::from_number(ctx, data[i]); - jsc::Object::set_property(ctx, uint8_array, i, num); - } - - return jsc::Object::validated_get_object(ctx, uint8_array, s_buffer); -} - -template <> -JSValueRef jsc::Value::from_decimal128(JSContextRef ctx, const Decimal128& value) -{ - static jsc::String s_realm = "Realm"; - static jsc::String s_decimal = "_Decimal128"; - static jsc::String s_from_string = "fromString"; - - if (value.is_null()) { - return JSValueMakeNull(ctx); - } - - JSObjectRef global_object = JSContextGetGlobalObject(ctx); - JSObjectRef realm_constructor = jsc::Object::validated_get_constructor(ctx, global_object, s_realm); - JSObjectRef decimal_constructor = jsc::Object::validated_get_constructor(ctx, realm_constructor, s_decimal); - - std::array args = {{jsc::Value::from_nonnull_string(ctx, jsc::String(value.to_string()))}}; - - return jsc::Object::call_method(ctx, decimal_constructor, s_from_string, args.size(), args.data()); -} - -template <> -JSValueRef jsc::Value::from_object_id(JSContextRef ctx, const ObjectId& value) -{ - static jsc::String s_realm = "Realm"; - static jsc::String s_object_id = "_ObjectId"; - - JSObjectRef global_object = JSContextGetGlobalObject(ctx); - JSObjectRef realm_constructor = jsc::Object::validated_get_constructor(ctx, global_object, s_realm); - JSObjectRef object_id_constructor = jsc::Object::validated_get_constructor(ctx, realm_constructor, s_object_id); - - std::array args{{jsc::Value::from_nonnull_string(ctx, jsc::String(value.to_string()))}}; - return jsc::Function::construct(ctx, object_id_constructor, args.size(), args.data()); -} - -template <> -JSValueRef jsc::Value::from_uuid(JSContextRef ctx, const UUID& value) -{ - static jsc::String s_realm = "Realm"; - static jsc::String s_uuid = "_UUID"; - - JSObjectRef global_object = JSContextGetGlobalObject(ctx); - JSObjectRef realm_constructor = jsc::Object::validated_get_constructor(ctx, global_object, s_realm); - JSObjectRef uuid_constructor = jsc::Object::validated_get_constructor(ctx, realm_constructor, s_uuid); - - std::array args{{jsc::Value::from_nonnull_string(ctx, jsc::String(value.to_string()))}}; - return jsc::Function::construct(ctx, uuid_constructor, args.size(), args.data()); -} - -template <> -OwnedBinaryData jsc::Value::to_binary(JSContextRef ctx, const JSValueRef& value) -{ - static jsc::String s_array_buffer = "ArrayBuffer"; - static jsc::String s_buffer = "buffer"; - static jsc::String s_byte_length = "byteLength"; - static jsc::String s_byte_offset = "byteOffset"; - static jsc::String s_is_view = "isView"; - static jsc::String s_uint8_array = "Uint8Array"; - - JSObjectRef global_object = JSContextGetGlobalObject(ctx); - JSObjectRef array_buffer_constructor = jsc::Object::validated_get_constructor(ctx, global_object, s_array_buffer); - JSObjectRef uint8_array_constructor = jsc::Object::validated_get_constructor(ctx, global_object, s_uint8_array); - JSValueRef uint8_array_arguments[3]; - uint32_t uint8_array_argc = 0; - - // Value should either be an ArrayBuffer or ArrayBufferView (i.e. TypedArray or DataView). - if (JSValueIsInstanceOfConstructor(ctx, value, array_buffer_constructor, nullptr)) { - uint8_array_arguments[0] = value; - uint8_array_argc = 1; - } - else if (JSObjectRef object = JSValueToObject(ctx, value, nullptr)) { - // Check if value is an ArrayBufferView by calling ArrayBuffer.isView(val). - JSValueRef is_view = jsc::Object::call_method(ctx, array_buffer_constructor, s_is_view, 1, &object); - - if (jsc::Value::to_boolean(ctx, is_view)) { - uint8_array_arguments[0] = jsc::Object::validated_get_object(ctx, object, s_buffer); - uint8_array_arguments[1] = jsc::Object::get_property(ctx, object, s_byte_offset); - uint8_array_arguments[2] = jsc::Object::get_property(ctx, object, s_byte_length); - uint8_array_argc = 3; - } - } - - if (!uint8_array_argc) { - throw std::runtime_error("Can only convert ArrayBuffer and TypedArray objects to binary"); - } - - JSObjectRef uint8_array = - jsc::Function::construct(ctx, uint8_array_constructor, uint8_array_argc, uint8_array_arguments); - uint32_t byte_count = jsc::Object::validated_get_length(ctx, uint8_array); - auto buffer = std::make_unique(byte_count); - - for (uint32_t i = 0; i < byte_count; i++) { - JSValueRef byteValue = jsc::Object::get_property(ctx, uint8_array, i); - buffer[i] = jsc::Value::to_number(ctx, byteValue); - } - - return OwnedBinaryData(std::move(buffer), byte_count); -} - -template <> -Decimal128 jsc::Value::to_decimal128(JSContextRef ctx, const JSValueRef& value) -{ - auto object = to_object(ctx, value); - // EJSON input supported (in RN only) for enabling debugging of synced realms. - auto ejson_property = jsc::Object::get_property(ctx, object, "$numberDecimal"); - - if (is_undefined(ctx, ejson_property)) { - static jsc::String s_to_string = "toString"; - JSValueRef args[] = {}; - JSValueRef as_string = jsc::Object::call_method(ctx, to_object(ctx, value), s_to_string, 0, args); - std::string str = to_string(ctx, as_string); - return Decimal128(StringData(str)); - } - else { - std::string str = to_string(ctx, ejson_property); - return Decimal128(StringData(str)); - } -} - -template <> -ObjectId jsc::Value::to_object_id(JSContextRef ctx, const JSValueRef& value) -{ - auto object = to_object(ctx, value); - // EJSON input supported (in RN only) for enabling debugging of synced realms. - auto ejson_property = jsc::Object::get_property(ctx, object, "$oid"); - - if (is_undefined(ctx, ejson_property)) { - static jsc::String s_to_hex_string = "toHexString"; - JSValueRef args[] = {}; - JSValueRef as_string = jsc::Object::call_method(ctx, to_object(ctx, value), s_to_hex_string, 0, args); - return ObjectId(std::string(to_string(ctx, as_string)).c_str()); - } - else { - return ObjectId(std::string(to_string(ctx, ejson_property)).c_str()); - } -} - -template <> -UUID jsc::Value::to_uuid(JSContextRef ctx, const JSValueRef& value) -{ - auto object = to_object(ctx, value); - // EJSON input supported (in RN only) for enabling debugging of synced realms. - auto ejson_property = jsc::Object::get_property(ctx, object, "$uuid"); - - if (is_undefined(ctx, ejson_property)) { - static jsc::String s_to_hex_string = "toHexString"; - JSValueRef args[] = {}; - JSValueRef as_string = jsc::Object::call_method(ctx, to_object(ctx, value), s_to_hex_string, 0, args); - return UUID(std::string(to_string(ctx, as_string)).c_str()); - } - else { - return UUID(std::string(to_string(ctx, ejson_property)).c_str()); - } -} - -} // namespace js -} // namespace realm diff --git a/src/jsc/jsc_value.hpp b/src/jsc/jsc_value.hpp deleted file mode 100644 index 369c05bf88..0000000000 --- a/src/jsc/jsc_value.hpp +++ /dev/null @@ -1,367 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "jsc_protected.hpp" -#include "jsc_types.hpp" -#include "jsc_string.hpp" - -namespace realm { -namespace js { - -static inline bool is_object_of_type(JSContextRef ctx, JSValueRef value, jsc::String type) -{ - JSObjectRef global_object = JSContextGetGlobalObject(ctx); - JSValueRef exception = nullptr; - JSValueRef constructor = JSObjectGetProperty(ctx, global_object, type, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - bool result = JSValueIsInstanceOfConstructor(ctx, value, jsc::Value::validated_to_constructor(ctx, constructor), - &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - - return result; -} - -template <> -inline const char* jsc::Value::typeof(JSContextRef ctx, const JSValueRef& value) -{ - switch (JSValueGetType(ctx, value)) { - case kJSTypeNull: - return "null"; - case kJSTypeNumber: - return "number"; - case kJSTypeObject: - return "object"; - case kJSTypeString: - return "string"; - case kJSTypeBoolean: - return "boolean"; - case kJSTypeUndefined: - return "undefined"; -#if defined __IPHONE_12_2 || defined __MAC_10_14_4 - case kJSTypeSymbol: - return "symbol"; -#endif - } -} - -template <> -inline bool jsc::Value::is_array(JSContextRef ctx, const JSValueRef& value) -{ - // JSValueIsArray() is not available until iOS 9. - static const jsc::String type = "Array"; - return is_object_of_type(ctx, value, type); -} - -template <> -inline bool jsc::Value::is_array_buffer(JSContextRef ctx, const JSValueRef& value) -{ - static const jsc::String type = "ArrayBuffer"; - return is_object_of_type(ctx, value, type); -} - -template <> -inline bool jsc::Value::is_date(JSContextRef ctx, const JSValueRef& value) -{ - static const jsc::String type = "Date"; - return is_object_of_type(ctx, value, type); -} - -template <> -inline bool jsc::Value::is_boolean(JSContextRef ctx, const JSValueRef& value) -{ - return JSValueIsBoolean(ctx, value); -} - -template <> -inline bool jsc::Value::is_constructor(JSContextRef ctx, const JSValueRef& value) -{ - return JSValueIsObject(ctx, value) && JSObjectIsConstructor(ctx, (JSObjectRef)value); -} - -template <> -inline bool jsc::Value::is_error(JSContextRef ctx, const JSValueRef& value) -{ - static const jsc::String type = "Error"; - return is_object_of_type(ctx, value, type); -} - -template <> -inline bool jsc::Value::is_function(JSContextRef ctx, const JSValueRef& value) -{ - return JSValueIsObject(ctx, value) && JSObjectIsFunction(ctx, (JSObjectRef)value); -} - -template <> -inline bool jsc::Value::is_null(JSContextRef ctx, const JSValueRef& value) -{ - return JSValueIsNull(ctx, value); -} - -template <> -inline bool jsc::Value::is_number(JSContextRef ctx, const JSValueRef& value) -{ - return JSValueIsNumber(ctx, value); -} - -template <> -inline bool jsc::Value::is_object(JSContextRef ctx, const JSValueRef& value) -{ - return JSValueIsObject(ctx, value); -} - -template <> -inline bool jsc::Value::is_string(JSContextRef ctx, const JSValueRef& value) -{ - return JSValueIsString(ctx, value); -} - -template <> -bool jsc::Value::is_binary(JSContextRef ctx, const JSValueRef& value); - -template <> -inline bool jsc::Value::is_undefined(JSContextRef ctx, const JSValueRef& value) -{ - return JSValueIsUndefined(ctx, value); -} - -template <> -inline bool jsc::Value::is_valid(const JSValueRef& value) -{ - return value != nullptr; -} - -inline bool is_bson_type(JSContextRef ctx, const JSValueRef& value, std::string type) -{ - if (JSValueIsNull(ctx, value) || JSValueIsUndefined(ctx, value) || !JSValueIsObject(ctx, value)) { - return false; - } - - - JSValueRef error = nullptr; - JSObjectRef object = JSValueToObject(ctx, value, &error); - if (error) { - throw jsc::Exception(ctx, error); - } - - JSValueRef bson_type = JSObjectGetProperty(ctx, object, JSStringCreateWithUTF8CString("_bsontype"), &error); - if (error) { - throw jsc::Exception(ctx, error); - } - - if (JSValueIsUndefined(ctx, value)) { - return false; - } - - jsc::String bson_type_value = JSValueToStringCopy(ctx, bson_type, &error); - // Since the string's retain value is +2 here, we need to manually release it before returning. - JSStringRelease(bson_type_value); - if (error) { - throw jsc::Exception(ctx, error); - } - - return (std::string)bson_type_value == type; -} - -/** - * Checks if a `value` is an EJSON representation of a particular type (determined by the existance of a particular - * property). - */ -inline bool is_ejson_type(JSContextRef ctx, const JSValueRef& value, std::string property_name) -{ - if (JSValueIsNull(ctx, value) || JSValueIsUndefined(ctx, value) || !JSValueIsObject(ctx, value)) { - return false; - } - - JSValueRef error = nullptr; - JSObjectRef object = JSValueToObject(ctx, value, &error); - if (error) { - throw jsc::Exception(ctx, error); - } - - JSStringRef property_name_string = JSStringCreateWithUTF8CString(property_name.c_str()); - auto property = JSObjectGetProperty(ctx, object, property_name_string, &error); - if (error) { - throw jsc::Exception(ctx, error); - } - - return JSValueIsUndefined(ctx, property) == false; -} - -template <> -inline bool jsc::Value::is_decimal128(JSContextRef ctx, const JSValueRef& value) -{ - return is_bson_type(ctx, value, "Decimal128") || is_ejson_type(ctx, value, "$numberDecimal"); -} - -template <> -inline bool jsc::Value::is_object_id(JSContextRef ctx, const JSValueRef& value) -{ - return is_bson_type(ctx, value, "ObjectID") || is_ejson_type(ctx, value, "$oid"); -} - -template <> -inline bool jsc::Value::is_uuid(JSContextRef ctx, const JSValueRef& value) -{ - // TODO: is_ejson_type won't work for binary EJSON - return is_bson_type(ctx, value, "UUID") || is_ejson_type(ctx, value, "$uuid"); -} - -template <> -inline JSValueRef jsc::Value::from_boolean(JSContextRef ctx, bool boolean) -{ - return JSValueMakeBoolean(ctx, boolean); -} - -template <> -inline JSValueRef jsc::Value::from_null(JSContextRef ctx) -{ - return JSValueMakeNull(ctx); -} - -template <> -inline JSValueRef jsc::Value::from_number(JSContextRef ctx, double number) -{ - return JSValueMakeNumber(ctx, number); -} - -template <> -inline JSValueRef jsc::Value::from_nonnull_string(JSContextRef ctx, const jsc::String& string) -{ - return JSValueMakeString(ctx, string); -} - -template <> -inline JSValueRef jsc::Value::from_undefined(JSContextRef ctx) -{ - return JSValueMakeUndefined(ctx); -} - -template <> -JSValueRef jsc::Value::from_nonnull_binary(JSContextRef ctx, BinaryData data); - -template <> -JSValueRef jsc::Value::from_decimal128(JSContextRef ctx, const Decimal128& value); - -template <> -JSValueRef jsc::Value::from_object_id(JSContextRef ctx, const ObjectId& value); - -template <> -JSValueRef jsc::Value::from_uuid(JSContextRef ctx, const UUID& value); - -template <> -inline bool jsc::Value::to_boolean(JSContextRef ctx, const JSValueRef& value) -{ - return JSValueToBoolean(ctx, value); -} -template <> -inline jsc::String jsc::Value::to_string(JSContextRef ctx, const JSValueRef& value) -{ - JSValueRef exception = nullptr; - jsc::String string = JSValueToStringCopy(ctx, value, &exception); - - // Since the string's retain value is +2 here, we need to manually release it before returning. - JSStringRelease(string); - - if (exception) { - throw jsc::Exception(ctx, exception); - } - return string; -} - -template <> -inline double jsc::Value::to_number(JSContextRef ctx, const JSValueRef& value) -{ - JSValueRef exception = nullptr; - double number = JSValueToNumber(ctx, value, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - if (isnan(number)) { - throw std::invalid_argument( - util::format("Value '%1' not convertible to a number.", (std::string)to_string(ctx, value))); - } - return number; -} - - -template <> -inline JSObjectRef jsc::Value::to_object(JSContextRef ctx, const JSValueRef& value) -{ - JSValueRef exception = nullptr; - JSObjectRef object = JSValueToObject(ctx, value, &exception); - if (exception) { - throw jsc::Exception(ctx, exception); - } - return object; -} - -template <> -inline JSObjectRef jsc::Value::to_array(JSContextRef ctx, const JSValueRef& value) -{ - return to_object(ctx, value); -} - -template <> -inline JSObjectRef jsc::Value::to_constructor(JSContextRef ctx, const JSValueRef& value) -{ - return to_object(ctx, value); -} - -template <> -inline JSObjectRef jsc::Value::to_date(JSContextRef ctx, const JSValueRef& value) -{ - if (JSValueIsString(ctx, value)) { - JSValueRef error; - std::array args{value}; - if (JSObjectRef result = JSObjectMakeDate(ctx, args.size(), args.data(), &error)) { - return result; - } - else { - throw jsc::Exception(ctx, error); - } - } - return to_object(ctx, value); -} - -template <> -inline JSObjectRef jsc::Value::to_function(JSContextRef ctx, const JSValueRef& value) -{ - return to_object(ctx, value); -} - -template <> -OwnedBinaryData jsc::Value::to_binary(JSContextRef ctx, const JSValueRef& value); - -template <> -Decimal128 jsc::Value::to_decimal128(JSContextRef ctx, const JSValueRef& value); - -template <> -ObjectId jsc::Value::to_object_id(JSContextRef ctx, const JSValueRef& value); - -template <> -UUID jsc::Value::to_uuid(JSContextRef ctx, const JSValueRef& value); - -} // namespace js -} // namespace realm diff --git a/src/jsc/rpc.cpp b/src/jsc/rpc.cpp deleted file mode 100644 index 9940ea3011..0000000000 --- a/src/jsc/rpc.cpp +++ /dev/null @@ -1,1235 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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 -#include -#include -#include -#include -#include - -#include "rpc.hpp" -#include "jsc_init.hpp" - -#include -#include -#include -#include -#include "jsc_rpc_network_transport.hpp" -#include "js_app.hpp" - -#include "concurrent_deque.hpp" -#include -#include "jsc_types.hpp" -#include "jsc_protected.hpp" -#include "js_network_transport.hpp" - -using namespace realm; -using namespace realm::rpc; - -using json = nlohmann::json; - -using RPCObjectID = u_int64_t; -using RPCRequest = std::function; -using NetworkTransport = js::JavaScriptNetworkTransport; -using NetworkTransportFactory = typename NetworkTransport::NetworkTransportFactory; - -using Value = js::Value; -using Accessor = realm::js::NativeAccessor; -using AppClass = js::AppClass; - -namespace realm::rpc { - -class RPCWorker { -public: - RPCWorker(); - ~RPCWorker(); - - template - json add_task(Fn&&); - void invoke_callback(json); - json resolve_callback(json args); - std::future add_promise(); - - bool try_run_task(); - void stop(); - json try_pop_callback(); - bool should_stop(); - -private: - bool m_stop = false; - int m_depth = 0; -#if __APPLE__ - std::thread m_thread; - CFRunLoopRef m_loop; -#endif - ConcurrentDeque> m_tasks; - ConcurrentDeque> m_promises; - ConcurrentDeque m_callbacks; -}; - -class RPCServerImpl { -public: - RPCServerImpl(); - ~RPCServerImpl(); - json perform_request(std::string const& name, json&& args); - bool try_run_task(); - -private: - JSGlobalContextRef m_context; - std::mutex m_request_mutex; - std::map m_requests; - std::map> m_objects; - std::map> m_callbacks; - // The key here is the same as the value in m_callbacks. We use the raw pointer as a key here, - // because protecting the value in m_callbacks pins the function object and prevents it from being moved - // by the garbage collector upon compaction. - std::map m_callback_ids; - RPCObjectID m_session_id; - RPCWorker m_worker; - u_int64_t m_callback_call_counter; - uint64_t m_reset_counter = 0; - - std::mutex m_pending_callbacks_mutex; - std::map, std::promise> m_pending_callbacks; - - NetworkTransportFactory previous_transport_generator; - - static JSValueRef run_callback(JSContextRef, JSObjectRef, JSObjectRef, size_t, const JSValueRef[], - JSValueRef* exception); - - RPCObjectID store_object(JSObjectRef object); - JSObjectRef get_object(RPCObjectID) const; - JSObjectRef get_realm_constructor() const; - - json serialize_json_value(JSValueRef value); - JSValueRef deserialize_json_value(const json dict); -}; - -} // namespace realm::rpc - -namespace { -static const char* const RealmObjectTypesData = "data"; -static const char* const RealmObjectTypesDate = "date"; -static const char* const RealmObjectTypesDictionary = "dict"; -static const char* const RealmObjectTypesFunction = "function"; -static const char* const RealmObjectTypesList = "list"; -static const char* const RealmObjectTypesObject = "object"; -static const char* const RealmObjectTypesResults = "results"; -static const char* const RealmObjectTypesRealm = "realm"; -static const char* const RealmObjectTypesUser = "user"; -static const char* const RealmObjectTypesSession = "session"; -static const char* const RealmObjectTypesAsyncOpenTask = "asyncopentask"; -static const char* const RealmObjectTypesApp = "app"; -static const char* const RealmObjectTypesCredentials = "credentials"; -static const char* const RealmObjectTypesUndefined = "undefined"; -static const char* const RealmObjectTypesError = "error"; -static const char* const RealmObjectTypesFetchResponseHandler = "fetchresponsehandler"; -static const char* const RealmObjectTypesEmailPasswordAuth = "emailpasswordauth"; -static const char* const RealmObjectTypesEJSON = "ejson"; - -json serialize_object_schema(const realm::ObjectSchema& object_schema) -{ - std::vector properties; - - for (auto& prop : object_schema.persisted_properties) { - properties.push_back(prop.public_name.empty() ? prop.name : prop.public_name); - } - - for (auto& prop : object_schema.computed_properties) { - properties.push_back(prop.public_name.empty() ? prop.name : prop.public_name); - } - - return { - {"name", object_schema.name}, - {"properties", properties}, - }; -} - -template -json get_type(Container const& c) -{ - auto type = c.get_type(); - if (type == realm::PropertyType::Object) { - return serialize_object_schema(c.get_object_schema()); - } - return {{"type", js::local_string_for_property_type(type)}, {"optional", is_nullable(type)}}; -} - -RPCServerImpl*& get_rpc_server(JSGlobalContextRef ctx) -{ - static std::map s_map; - return s_map[ctx]; -} -} // namespace - -#ifdef __APPLE__ -void runLoopFunc(CFRunLoopRef loop, RPCWorker* rpcWorker) -{ - CFRunLoopPerformBlock(loop, kCFRunLoopDefaultMode, ^{ - rpcWorker->try_run_task(); - if (rpcWorker->should_stop()) { - CFRunLoopStop(CFRunLoopGetCurrent()); - } - else { - runLoopFunc(loop, rpcWorker); - } - }); - CFRunLoopWakeUp(loop); -} -#endif - -RPCWorker::RPCWorker() -{ -#ifdef __APPLE__ - m_thread = std::thread([this]() { - m_loop = CFRunLoopGetCurrent(); - runLoopFunc(m_loop, this); - CFRunLoopRun(); - }); -#endif -} - -RPCWorker::~RPCWorker() -{ - stop(); -} - -template -json RPCWorker::add_task(Fn&& fn) -{ - std::promise p; - auto future = p.get_future(); - m_promises.push_back(std::move(p)); - m_tasks.push_back([this, fn = std::move(fn)] { - auto result = fn(); - m_promises.pop_back().set_value(std::move(result)); - }); - return future.get(); -} - -void RPCWorker::invoke_callback(json callback) -{ - m_tasks.push_back([=, callback = std::move(callback)]() mutable { - if (m_depth == 1) { - // The callback was invoked directly from the event loop. Push it - // onto the queue of callbacks to be processed by /callbacks_poll - m_callbacks.push_back(std::move(callback)); - } - else if (auto promise = m_promises.try_pop_back(0)) { - // The callback was invoked from within a call to something else, - // and there's someone waiting for its result. - promise->set_value(std::move(callback)); - } - else { - // The callback was invoked from within a call to something else, - // but there's no one waiting for the result. Shouldn't be possible? - m_callbacks.push_back(std::move(callback)); - } - }); -} - -std::future RPCWorker::add_promise() -{ - std::promise p; - auto future = p.get_future(); - m_promises.push_back(std::move(p)); - return future; -} - -json RPCWorker::try_pop_callback() -{ - auto cb = m_callbacks.try_pop_back(0); - return cb ? *cb : json::object(); -} - -bool RPCWorker::try_run_task() -{ - if (m_stop) { - return true; - } - - // Use a 10 millisecond timeout to keep this thread unblocked. - if (auto task = m_tasks.try_pop_back(10)) { - ++m_depth; - (*task)(); - --m_depth; - return m_stop; - } - return false; -} - -bool RPCWorker::should_stop() -{ - return m_stop; -} - -void RPCWorker::stop() -{ - if (!m_stop) { - m_stop = true; -#if __APPLE__ - m_thread.join(); - m_loop = nullptr; -#endif - } -} - -static json read_object_properties(Object& object) -{ - json cache; - if (!object.is_valid()) { - return cache; - } - - // Send the values of the primitive and short string properties directly - // as the overhead of doing so is tiny compared to even a single RPC request - auto& object_schema = object.get_object_schema(); - auto obj = object.obj(); - for (auto& property : object_schema.persisted_properties) { - if (is_array(property.type)) { - continue; - } - if (is_nullable(property.type) && obj.is_null(property.column_key)) { - cache[property.name] = {{"value", json(nullptr)}}; - continue; - } - auto cache_value = [&](auto&& v) { - cache[property.name] = {{"value", v}}; - }; - switch (property.type & ~PropertyType::Flags) { - case PropertyType::Bool: - cache_value(obj.get(property.column_key)); - break; - case PropertyType::Int: - cache_value(obj.get(property.column_key)); - break; - case PropertyType::Float: - cache_value(obj.get(property.column_key)); - break; - case PropertyType::Double: - cache_value(obj.get(property.column_key)); - break; - case PropertyType::Date: { - auto ts = obj.get(property.column_key); - cache[property.name] = { - {"type", RealmObjectTypesDate}, - {"value", ts.get_seconds() * 1000.0 + ts.get_nanoseconds() / 1000000.0}, - }; - break; - } break; - case PropertyType::String: { - auto str = obj.get(property.column_key); - // A completely abitrary upper limit on how big of a string we'll pre-cache - if (str.size() < 100) { - cache_value(str); - } - break; - } - case PropertyType::Decimal: - cache[property.name] = { - {"type", RealmObjectTypesEJSON}, - {"value", {"$numberDecimal", obj.get(property.column_key).to_string()}}, - }; - break; - case PropertyType::ObjectId: - cache[property.name] = { - {"type", RealmObjectTypesEJSON}, - {"value", {"$oid", obj.get(property.column_key).to_string()}}, - }; - break; - case PropertyType::Data: - case PropertyType::Object: - break; - default: - REALM_UNREACHABLE(); - } - } - return cache; -} - -RPCServerImpl::RPCServerImpl() -{ - m_context = JSGlobalContextCreate(NULL); - get_rpc_server(m_context) = this; - m_callback_call_counter = 1; - - // Make the App use the RPC Network Transport from now on - previous_transport_generator = AppClass::transport_generator; - AppClass::transport_generator = - [](jsc::Types::Context ctx, - NetworkTransport::Dispatcher dispatcher) -> std::unique_ptr { - (void)dispatcher; // We don't need to use the dispatcher because JSC separately guarantees thread-safety. - return std::make_unique(ctx); - }; - - // JavaScriptCore crashes when trying to walk up the native stack to print the stacktrace. - // FIXME: Avoid having to do this! - static void (*setIncludesNativeCallStack)(JSGlobalContextRef, bool) = (void (*)(JSGlobalContextRef, bool))dlsym( - RTLD_DEFAULT, "JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions"); - if (setIncludesNativeCallStack) { - setIncludesNativeCallStack(m_context, false); - } - - m_requests["/create_session"] = [this](const json dict) { - RJSInitializeInContext(m_context); - - jsc::String realm_string = "Realm"; - JSObjectRef realm_constructor = - jsc::Object::validated_get_constructor(m_context, JSContextGetGlobalObject(m_context), realm_string); - - // Enable the RCP network transport to issue calls to the remote fetch function - jsc::Types::Function fetch_function = - Value::validated_to_function(m_context, deserialize_json_value(dict["fetch"]), "fetch"); - RPCNetworkTransport::fetch_function = js::Protected(m_context, fetch_function); - - m_session_id = store_object(realm_constructor); - return (json){{"result", m_session_id}}; - }; - m_requests["/create_realm"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef realm_object = jsc::Function::construct(m_context, realm_constructor, arg_count, arg_values); - - JSObjectRef add_listener_method = - (JSObjectRef)jsc::Object::get_property(m_context, realm_object, "addListener"); - JSValueRef listener_args[] = {jsc::Value::from_string(m_context, "beforenotify"), - deserialize_json_value(dict["beforeNotify"])}; - jsc::Function::call(m_context, add_listener_method, realm_object, 2, listener_args); - - return (json){{"result", serialize_json_value(realm_object)}}; - }; - m_requests["/create_app"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - JSObjectRef app_constructor = (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "App"); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef app_object = jsc::Function::construct(m_context, app_constructor, arg_count, arg_values); - return (json){{"result", serialize_json_value(app_object)}}; - }; - m_requests["/create_user"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - - JSObjectRef sync_constructor = (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Sync"); - JSObjectRef user_constructor = (JSObjectRef)jsc::Object::get_property(m_context, sync_constructor, "User"); - JSObjectRef create_user_method = - (JSObjectRef)jsc::Object::get_property(m_context, user_constructor, "createUser"); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef user_object = - (JSObjectRef)jsc::Function::call(m_context, create_user_method, arg_count, arg_values); - return (json){{"result", serialize_json_value(user_object)}}; - }; - m_requests["/call_sync_function"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - JSObjectRef sync_constructor = (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Sync"); - - std::string name = dict["name"]; - JSObjectRef method = (JSObjectRef)jsc::Object::get_property(m_context, sync_constructor, name); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - auto result = jsc::Function::call(m_context, method, arg_count, arg_values); - return (json){{"result", serialize_json_value(result)}}; - }; - m_requests["/_asyncOpen"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - - JSObjectRef _asyncOpen_method = - (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "_asyncOpen"); - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - auto result = jsc::Function::call(m_context, _asyncOpen_method, arg_count, arg_values); - return (json){{"result", serialize_json_value(result)}}; - }; - m_requests["/call_method"] = [this](const json dict) { - JSObjectRef object = get_object(dict["id"].get()); - std::string method_string = dict["name"].get(); - JSObjectRef function = jsc::Object::validated_get_function(m_context, object, method_string); - - json args = dict["arguments"]; - size_t arg_count = args.size(); - JSValueRef arg_values[arg_count]; - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSValueRef result = jsc::Function::call(m_context, function, object, arg_count, arg_values); - return (json){{"result", serialize_json_value(result)}}; - }; - m_requests["/get_object"] = [this](const json dict) -> json { - RPCObjectID oid = dict["id"].get(); - json name = dict["name"]; - JSObjectRef object = get_object(oid); - if (!object) { - return {{"result", nullptr}}; - } - - json result; - if (jsc::Object::is_instance>(m_context, object)) { - auto obj = jsc::Object::get_internal>(m_context, object); - result = read_object_properties(*obj); - } - if (result.find(name) == result.end()) { - if (name.is_number()) { - auto key = name.get(); - result[key] = serialize_json_value(jsc::Object::get_property(m_context, object, key)); - } - else { - auto key = name.get(); - result[key] = serialize_json_value(jsc::Object::get_property(m_context, object, key)); - } - } - return {{"result", result}}; - }; - m_requests["/get_property"] = [this](const json dict) { - RPCObjectID oid = dict["id"].get(); - json name = dict["name"]; - - JSValueRef value; - if (JSObjectRef object = get_object(oid)) { - if (name.is_number()) { - value = jsc::Object::get_property(m_context, object, name.get()); - } - else { - value = jsc::Object::get_property(m_context, object, name.get()); - } - } - else { - value = jsc::Value::from_null(m_context); - } - - return (json){{"result", serialize_json_value(value)}}; - }; - m_requests["/set_property"] = [this](const json dict) { - RPCObjectID oid = dict["id"].get(); - json name = dict["name"]; - JSValueRef value = deserialize_json_value(dict["value"]); - - if (name.is_number()) { - jsc::Object::set_property(m_context, get_object(oid), name.get(), value); - } - else { - jsc::Object::set_property(m_context, get_object(oid), name.get(), value); - } - - return json::object(); - }; - m_requests["/dispose_object"] = [this](const json dict) { - RPCObjectID oid = dict["id"].get(); - m_objects.erase(oid); - return json::object(); - }; - m_requests["/clear_test_state"] = [this](const json dict) { - // The session ID points to the Realm constructor object, which should remain. - auto realm_constructor = m_objects[m_session_id]; - m_objects.clear(); - - if (realm_constructor) { - m_objects.emplace(m_session_id, realm_constructor); - } - - // The JS side of things only gives us the fetch function callback - // when creating a session so we need to hold onto it. - auto fetch_function = m_callbacks[0]; - - m_callbacks.clear(); - m_callback_ids.clear(); - m_callbacks[0] = fetch_function; - m_callback_ids[fetch_function] = 0; - ++m_reset_counter; - JSGarbageCollect(m_context); - js::clear_test_state(); - - return json::object(); - }; - m_requests["/set_versions"] = [this](const json dict) { - JSObjectRef versions = - jsc::Value::validated_to_object(m_context, deserialize_json_value(dict["versions"]), "versions"); - AppClass::package_version = jsc::Object::validated_get_string(m_context, versions, "packageVersion"); - AppClass::platform_context = jsc::Object::validated_get_string(m_context, versions, "platformContext"); - AppClass::platform_os = jsc::Object::validated_get_string(m_context, versions, "platformOs"); - AppClass::platform_version = jsc::Object::validated_get_string(m_context, versions, "platformVersion"); - return json::object(); - }; - m_requests["/_anonymous"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - JSObjectRef credentials_constructor = - (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Credentials"); - JSObjectRef anonymous_method = - (JSObjectRef)jsc::Object::get_property(m_context, credentials_constructor, "anonymous"); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); // should be zero - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef credentials_object = - (JSObjectRef)jsc::Function::call(m_context, anonymous_method, arg_count, arg_values); - return (json){{"result", serialize_json_value(credentials_object)}}; - }; - m_requests["/_facebook"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - JSObjectRef credentials_constructor = - (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Credentials"); - JSObjectRef facebook_method = - (JSObjectRef)jsc::Object::get_property(m_context, credentials_constructor, "facebook"); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); // should be one - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef credentials_object = - (JSObjectRef)jsc::Function::call(m_context, facebook_method, arg_count, arg_values); - return (json){{"result", serialize_json_value(credentials_object)}}; - }; - m_requests["/_apple"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - JSObjectRef credentials_constructor = - (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Credentials"); - JSObjectRef apple_method = - (JSObjectRef)jsc::Object::get_property(m_context, credentials_constructor, "apple"); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); // should be one - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef credentials_object = - (JSObjectRef)jsc::Function::call(m_context, apple_method, arg_count, arg_values); - return (json){{"result", serialize_json_value(credentials_object)}}; - }; - m_requests["/_emailPassword"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - JSObjectRef credentials_constructor = - (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Credentials"); - JSObjectRef email_password_method = - (JSObjectRef)jsc::Object::get_property(m_context, credentials_constructor, "emailPassword"); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); // should be two - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef credentials_object = - (JSObjectRef)jsc::Function::call(m_context, email_password_method, arg_count, arg_values); - return (json){{"result", serialize_json_value(credentials_object)}}; - }; - m_requests["/_function"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - JSObjectRef credentials_constructor = - (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Credentials"); - JSObjectRef function_method = - (JSObjectRef)jsc::Object::get_property(m_context, credentials_constructor, "function"); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); // should be one - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef credentials_object = - (JSObjectRef)jsc::Function::call(m_context, function_method, arg_count, arg_values); - return (json){{"result", serialize_json_value(credentials_object)}}; - }; - m_requests["/_google"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - JSObjectRef credentials_constructor = - (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Credentials"); - JSObjectRef google_method = - (JSObjectRef)jsc::Object::get_property(m_context, credentials_constructor, "google"); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); // should be one - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef credentials_object = - (JSObjectRef)jsc::Function::call(m_context, google_method, arg_count, arg_values); - return (json){{"result", serialize_json_value(credentials_object)}}; - }; - m_requests["/_userApiKey"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - JSObjectRef credentials_constructor = - (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Credentials"); - JSObjectRef user_api_key_method = - (JSObjectRef)jsc::Object::get_property(m_context, credentials_constructor, "userApiKey"); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); // should be one - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef credentials_object = - (JSObjectRef)jsc::Function::call(m_context, user_api_key_method, arg_count, arg_values); - return (json){{"result", serialize_json_value(credentials_object)}}; - }; - m_requests["/_serverApiKey"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - JSObjectRef credentials_constructor = - (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Credentials"); - JSObjectRef server_api_key_method = - (JSObjectRef)jsc::Object::get_property(m_context, credentials_constructor, "serverApiKey"); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); // should be one - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef credentials_object = - (JSObjectRef)jsc::Function::call(m_context, server_api_key_method, arg_count, arg_values); - return (json){{"result", serialize_json_value(credentials_object)}}; - }; - m_requests["/_jwt"] = [this](const json dict) { - JSObjectRef realm_constructor = get_realm_constructor(); - JSObjectRef credentials_constructor = - (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Credentials"); - JSObjectRef jwt_method = (JSObjectRef)jsc::Object::get_property(m_context, credentials_constructor, "jwt"); - - json::array_t args = dict["arguments"]; - size_t arg_count = args.size(); // should be one - JSValueRef arg_values[arg_count]; - - for (size_t i = 0; i < arg_count; i++) { - arg_values[i] = deserialize_json_value(args[i]); - } - - JSObjectRef credentials_object = - (JSObjectRef)jsc::Function::call(m_context, jwt_method, arg_count, arg_values); - return (json){{"result", serialize_json_value(credentials_object)}}; - }; -} - -RPCServerImpl::~RPCServerImpl() -{ - m_worker.stop(); - - // The protected values should be unprotected before releasing the context. - m_objects.clear(); - m_callbacks.clear(); - - // Restore the previous transport generator - AppClass::transport_generator = previous_transport_generator; - - get_rpc_server(m_context) = nullptr; - JSGlobalContextRelease(m_context); -} - -/** - * Asks the client to execute a callback and awaits the result. - */ -JSValueRef RPCServerImpl::run_callback(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argc, - const JSValueRef arguments[], JSValueRef* exception) -{ - RPCServerImpl* server = get_rpc_server(JSContextGetGlobalContext(ctx)); - if (!server) { - return JSValueMakeUndefined(ctx); - } - - u_int64_t counter = server->m_callback_call_counter++; - // The first argument was curried to be the callback id. - auto it = server->m_callback_ids.find(function); - if (it == server->m_callback_ids.end()) { - // Callback will no longer exist if it was pending while clearTestState() - // was called. Just return undefined when that happens. - return JSValueMakeUndefined(ctx); - } - RPCObjectID callback_id = it->second; - JSObjectRef arguments_array = jsc::Object::create_array(ctx, uint32_t(argc), arguments); - json arguments_json = server->serialize_json_value(arguments_array); - json this_json = server->serialize_json_value(this_object); - - std::future future; - { - std::lock_guard lock(server->m_pending_callbacks_mutex); - future = server->m_pending_callbacks[{callback_id, counter}].get_future(); - } - - // The next task on the stack will instruct the JS to run this callback. - // This captures references since it will be executed before exiting this function. - server->m_worker.invoke_callback({{"callback", callback_id}, - {"this", this_json}, - {"arguments", arguments_json}, - {"callback_call_counter", counter}}); - - uint64_t reset_counter = server->m_reset_counter; - while (!server->try_run_task() && future.wait_for(std::chrono::microseconds(100)) != std::future_status::ready && - reset_counter == server->m_reset_counter) - ; - - if (reset_counter != server->m_reset_counter) { - // clearTestState() was called while the callback was pending - return JSValueMakeUndefined(ctx); - } - - json results = future.get(); - // The callback id should be identical! - assert(callback_id == results["callback"].get()); - - json error = results["error"]; - if (!error.is_null()) { - JSStringRef message = JSStringCreateWithUTF8CString(error.get().c_str()); - JSValueRef arguments[]{JSValueMakeString(ctx, message)}; - JSStringRelease(message); - JSObjectRef error = JSObjectMakeError(ctx, 1, arguments, nullptr); - *exception = error; - - json stack = results["stack"]; - if (stack.is_string()) { - JSStringRef stack_json = JSStringCreateWithUTF8CString(stack.get().c_str()); - JSValueRef array = JSValueMakeFromJSONString(ctx, stack_json); - JSStringRelease(stack_json); - JSStringRef key = JSStringCreateWithUTF8CString("stack"); - JSObjectSetProperty(ctx, error, key, array, 0, nullptr); - JSStringRelease(key); - } - return nullptr; - } - - return server->deserialize_json_value(results["result"]); -} - -json RPCServerImpl::perform_request(std::string const& name, json&& args) -{ - std::lock_guard lock(m_request_mutex); - - // Only create_session is allowed without the correct session id (since it creates the session id). - if (name != "/create_session" && m_session_id != args["sessionId"].get()) { - return {{"error", "Invalid session ID"}}; - } - - auto resolve_callback = [&] { - auto callback_id = args["callback"].get(); - auto callback_counter = args["callback_call_counter"].get(); - std::lock_guard lock(m_pending_callbacks_mutex); - auto cb = m_pending_callbacks.find({callback_id, callback_counter}); - if (cb != m_pending_callbacks.end()) { - cb->second.set_value(args); - m_pending_callbacks.erase(cb); - } - }; - - // The callback_result message contains the return value (or exception) of a callback ran by run_callback(). - if (name == "/callback_result") { - std::future result = m_worker.add_promise(); - resolve_callback(); - return result.get(); - } - if (name == "/callback_poll_result") { - resolve_callback(); - return m_worker.try_pop_callback(); - } - if (name == "/callbacks_poll") { - return m_worker.try_pop_callback(); - } - - RPCRequest* action = &m_requests[name]; - REALM_ASSERT_RELEASE(action && *action); - - return m_worker.add_task([=] { - try { - return (*action)(args); - } - catch (jsc::Exception const& ex) { - json exceptionAsJson = nullptr; - try { - exceptionAsJson = serialize_json_value(ex); - } - catch (...) { - exceptionAsJson = { - {"error", - "An exception occured while processing the request. Could not serialize the exception as JSON"}}; - } - return (json){ - {"error", exceptionAsJson}, - {"message", ex.what()}, - }; - } - catch (std::exception const& exception) { - return (json){{"error", exception.what()}}; - } - }); -} - -bool RPCServerImpl::try_run_task() -{ - return m_worker.try_run_task(); -} - -RPCObjectID RPCServerImpl::store_object(JSObjectRef object) -{ - static RPCObjectID s_next_id = 1; - - RPCObjectID next_id = s_next_id++; - m_objects.emplace(next_id, js::Protected(m_context, object)); - return next_id; -} - -JSObjectRef RPCServerImpl::get_object(RPCObjectID oid) const -{ - auto it = m_objects.find(oid); - return it == m_objects.end() ? nullptr : static_cast(it->second); -} - -JSObjectRef RPCServerImpl::get_realm_constructor() const -{ - JSObjectRef realm_constructor = m_session_id ? JSObjectRef(get_object(m_session_id)) : NULL; - if (!realm_constructor) { - throw std::runtime_error("Realm constructor not found!"); - } - return realm_constructor; -} - -json RPCServerImpl::serialize_json_value(JSValueRef js_value) -{ - switch (JSValueGetType(m_context, js_value)) { - case kJSTypeUndefined: - return json::object(); - case kJSTypeNull: - return {{"value", json(nullptr)}}; - case kJSTypeBoolean: - return {{"value", jsc::Value::to_boolean(m_context, js_value)}}; - case kJSTypeNumber: - return {{"value", jsc::Value::to_number(m_context, js_value)}}; - case kJSTypeString: - return {{"value", jsc::Value::to_string(m_context, js_value)}}; - case kJSTypeObject: - break; -#if defined __IPHONE_12_2 || defined __MAC_10_14_4 - case kJSTypeSymbol: - break; -#endif - } - - JSObjectRef js_object = jsc::Value::validated_to_object(m_context, js_value); - - if (jsc::Object::is_instance>(m_context, js_object)) { - auto object = jsc::Object::get_internal>(m_context, js_object); - return {{"type", RealmObjectTypesObject}, - {"id", store_object(js_object)}, - {"schema", serialize_object_schema(object->get_object_schema())}, - {"cache", read_object_properties(*object)}}; - } - else if (jsc::Object::is_instance>(m_context, js_object)) { - auto list = jsc::Object::get_internal>(m_context, js_object); - return { - {"type", RealmObjectTypesList}, - {"id", store_object(js_object)}, - {"dataType", js::local_string_for_property_type(list->get_type() & ~realm::PropertyType::Flags)}, - {"optional", is_nullable(list->get_type())}, - }; - } - else if (jsc::Object::is_instance>(m_context, js_object)) { - auto results = jsc::Object::get_internal>(m_context, js_object); - return { - {"type", RealmObjectTypesResults}, - {"id", store_object(js_object)}, - {"dataType", js::local_string_for_property_type(results->get_type() & ~realm::PropertyType::Flags)}, - {"optional", is_nullable(results->get_type())}, - }; - } - else if (jsc::Object::is_instance>(m_context, js_object)) { - auto realm = jsc::Object::get_internal>(m_context, js_object); - json realm_dict{ - {"_isPartialRealm", - serialize_json_value(jsc::Object::get_property(m_context, js_object, "_isPartialRealm"))}, - {"inMemory", serialize_json_value(jsc::Object::get_property(m_context, js_object, "inMemory"))}, - {"path", serialize_json_value(jsc::Object::get_property(m_context, js_object, "path"))}, - {"readOnly", serialize_json_value(jsc::Object::get_property(m_context, js_object, "readOnly"))}, - {"syncSession", serialize_json_value(jsc::Object::get_property(m_context, js_object, "syncSession"))}, - }; - return {{"type", RealmObjectTypesRealm}, - {"id", store_object(js_object)}, - {"realmId", (uintptr_t)realm->get()}, - {"data", realm_dict}}; - } -#if REALM_ENABLE_SYNC - else if (jsc::Object::is_instance>(m_context, js_object)) { - return { - {"type", RealmObjectTypesUser}, - {"id", store_object(js_object)}, - }; - } - else if (jsc::Object::is_instance>(m_context, js_object)) { - json session_dict{ - {"user", serialize_json_value(jsc::Object::get_property(m_context, js_object, "user"))}, - {"config", serialize_json_value(jsc::Object::get_property(m_context, js_object, "config"))}, - }; - return {{"type", RealmObjectTypesSession}, {"id", store_object(js_object)}, {"data", session_dict}}; - } - else if (jsc::Object::is_instance>(m_context, js_object)) { - return { - {"type", RealmObjectTypesAsyncOpenTask}, - {"id", store_object(js_object)}, - }; - } - else if (jsc::Object::is_instance>(m_context, js_object)) { - return { - {"type", RealmObjectTypesApp}, - {"id", store_object(js_object)}, - }; - } - else if (jsc::Object::is_instance>(m_context, js_object)) { - return { - {"type", RealmObjectTypesCredentials}, - {"id", store_object(js_object)}, - }; - } - else if (jsc::Object::is_instance>(m_context, js_object)) { - return { - {"type", RealmObjectTypesFetchResponseHandler}, - {"id", store_object(js_object)}, - }; - } - else if (jsc::Object::is_instance>(m_context, js_object)) { - return { - {"type", RealmObjectTypesEmailPasswordAuth}, - {"id", store_object(js_object)}, - }; - } -#endif - else if (jsc::Value::is_array(m_context, js_object)) { - uint32_t length = jsc::Object::validated_get_length(m_context, js_object); - std::vector array; - for (uint32_t i = 0; i < length; i++) { - array.push_back(serialize_json_value(jsc::Object::get_property(m_context, js_object, i))); - } - return {{"value", array}}; - } - else if (jsc::Value::is_binary(m_context, js_object)) { - auto data = jsc::Value::to_binary(m_context, js_object); - - std::string encoded; - encoded.reserve(realm::util::base64_encoded_size(data.size())); - encoded.resize(realm::util::base64_encode(data.data(), data.size(), encoded.data(), encoded.capacity())); - - return { - {"type", RealmObjectTypesData}, - {"value", encoded}, - }; - } - else if (jsc::Value::is_date(m_context, js_object)) { - return { - {"type", RealmObjectTypesDate}, - {"value", jsc::Value::to_number(m_context, js_object)}, - }; - } - else if (jsc::Value::is_error(m_context, js_object)) { - return { - {"type", RealmObjectTypesError}, - {"message", serialize_json_value(jsc::Object::get_property(m_context, js_object, "message"))}, - {"stack", serialize_json_value(jsc::Object::get_property(m_context, js_object, "stack"))}, - }; - } - else if (jsc::Value::is_function(m_context, js_object)) { - auto it = m_callback_ids.find(js_object); - if (it != m_callback_ids.end()) { - return {{"type", RealmObjectTypesFunction}, {"value", it->second}}; - } - else { - return {{"type", RealmObjectTypesFunction}, {"value", it->second}}; - } - return json::object(); - } - else { - // Serialize this JS object as a plain object since it doesn't match any known types above. - std::vector keys; - std::vector values; - - // Use the enumarable properties - std::vector js_keys = jsc::Object::get_property_names(m_context, js_object); - for (auto& js_key : js_keys) { - JSValueRef js_value = jsc::Object::get_property(m_context, js_object, js_key); - keys.push_back(js_key); - values.push_back(serialize_json_value(js_value)); - } - - return { - {"type", RealmObjectTypesDictionary}, - {"keys", keys}, - {"values", values}, - }; - } - assert(0); -} - -JSValueRef RPCServerImpl::deserialize_json_value(const json dict) -{ - json oid = dict.value("id", json()); - if (oid.is_number()) { - return m_objects[oid.get()]; - } - - json value = dict.value("value", json()); - json type = dict.value("type", json()); - - if (type.is_string()) { - std::string type_string = type.get(); - - if (type_string == RealmObjectTypesFunction) { - RPCObjectID callback_id = value.get(); - - if (!m_callbacks.count(callback_id)) { - JSObjectRef callback = JSObjectMakeFunctionWithCallback(m_context, nullptr, run_callback); - m_callbacks.emplace(callback_id, js::Protected(m_context, callback)); - m_callback_ids.emplace(callback, callback_id); - } - - return m_callbacks.at(callback_id); - } - else if (type_string == RealmObjectTypesDictionary) { - JSObjectRef js_object = jsc::Object::create_empty(m_context); - json keys = dict["keys"]; - json values = dict["values"]; - size_t count = keys.size(); - - for (size_t i = 0; i < count; i++) { - std::string js_key = keys.at(i); - JSValueRef js_value = deserialize_json_value(values.at(i)); - jsc::Object::set_property(m_context, js_object, js_key, js_value); - } - - return js_object; - } - else if (type_string == RealmObjectTypesData) { - auto bytes = realm::util::base64_decode_to_vector(value.get()); - if (!bytes) { - throw std::runtime_error("Failed to decode base64 encoded data"); - } - return jsc::Value::from_binary(m_context, realm::BinaryData(bytes->data(), bytes->size())); - } - else if (type_string == RealmObjectTypesDate) { - return jsc::Object::create_date(m_context, value.get()); - } - else if (type_string == RealmObjectTypesUndefined) { - return jsc::Value::from_undefined(m_context); - } - else if (type_string == RealmObjectTypesEJSON) { - JSObjectRef js_object = jsc::Object::create_empty(m_context); - for (auto& el : value.items()) { - auto el_value = jsc::Value::from_string(m_context, el.value().get()); - jsc::Object::set_property(m_context, js_object, el.key(), el_value); - } - return js_object; - } - assert(0); - } - - if (value.is_null()) { - return jsc::Value::from_null(m_context); - } - else if (value.is_boolean()) { - return jsc::Value::from_boolean(m_context, value.get()); - } - else if (value.is_number()) { - return jsc::Value::from_number(m_context, value.get()); - } - else if (value.is_string()) { - return jsc::Value::from_string(m_context, value.get()); - } - else if (value.is_array()) { - size_t count = value.size(); - JSValueRef js_values[count]; - - for (size_t i = 0; i < count; i++) { - js_values[i] = deserialize_json_value(value.at(i)); - } - - return jsc::Object::create_array(m_context, (uint32_t)count, js_values); - } - else { - throw std::runtime_error("deserialize_json_value: Unkown value"); - } - - assert(0); -} - -RPCServer::RPCServer() - : m_impl(new RPCServerImpl()) -{ -} - -RPCServer::~RPCServer() = default; - -std::string RPCServer::perform_request(std::string const& name, std::string const& json_args) -{ - return m_impl->perform_request(name, json::parse(json_args)).dump(); -} - -bool RPCServer::try_run_task() -{ - return m_impl->try_run_task(); -} diff --git a/src/jsc/rpc.hpp b/src/jsc/rpc.hpp deleted file mode 100644 index 0923b9be72..0000000000 --- a/src/jsc/rpc.hpp +++ /dev/null @@ -1,40 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Copyright 2016 Realm Inc. -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include -#include - -namespace realm { -namespace rpc { - -class RPCServerImpl; -class RPCServer { -public: - RPCServer(); - ~RPCServer(); - std::string perform_request(std::string const& name, std::string const& json_args); - bool try_run_task(); - -private: - std::unique_ptr m_impl; -}; - -} // namespace rpc -} // namespace realm From cb013348227c6329bd7d033a4bf03dcfd1d38cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Mon, 10 Jan 2022 16:37:13 +0100 Subject: [PATCH 2/9] Providing a "soft" landing for users running in legacy debugging mode --- lib/react-native/index.js | 22 ++++++++++++++++------ react-native/ios/RealmReact/RealmReact.mm | 7 +++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/react-native/index.js b/lib/react-native/index.js index 00943b2e23..72f4d9581d 100644 --- a/lib/react-native/index.js +++ b/lib/react-native/index.js @@ -25,25 +25,35 @@ if (typeof Reflect !== "undefined" && Reflect.construct) { Reflect.construct.sham = 1; } +const usingLegacyChromeDebugger = typeof DedicatedWorkerGlobalScope !== "undefined"; + +if (usingLegacyChromeDebugger) { + throw new Error("This version of Realm JS doesn't support the legacy Chrome Debugger"); +} + if (Platform.OS === "android") { - // Getting the native module on Android will inject the Realm global (on Android) + // Getting the native module on Android will inject the Realm global + // eslint-disable-next-line no-unused-vars const RealmNativeModule = NativeModules.Realm; - console.log({ RealmNativeModule, Realm: global.Realm }); } +// TODO: Remove the need to store Realm as a global +// @see https://github.com/realm/realm-js/issues/2126 +const Realm = globalThis.Realm; + // Otherwise, we must be in a "normal" react native situation. // In that case, the Realm type should have been injected by the native code. // If it hasn't, the user likely forgot to install the RealmJS CocoaPod -if (typeof global.Realm === "undefined") { +if (typeof Realm === "undefined") { throw new Error( 'Missing Realm constructor. Did you run "pod install"? Please see https://realm.io/docs/react-native/latest/#missing-realm-constructor for troubleshooting', ); } -require("../extensions")(global.Realm); +require("../extensions")(Realm); const utils = require("../utils"); const versions = utils.getVersions(); -global.Realm.App._setVersions(versions); +Realm.App._setVersions(versions); -module.exports = global.Realm; +module.exports = Realm; diff --git a/react-native/ios/RealmReact/RealmReact.mm b/react-native/ios/RealmReact/RealmReact.mm index 17a589fb6a..46eb67b254 100644 --- a/react-native/ios/RealmReact/RealmReact.mm +++ b/react-native/ios/RealmReact/RealmReact.mm @@ -109,7 +109,10 @@ - (void)setBridge:(RCTBridge *)bridge { s_currentModule = self; if (objc_lookUpClass("RCTWebSocketExecutor") && [bridge executorClass] == objc_lookUpClass("RCTWebSocketExecutor")) { - @throw [NSException exceptionWithName:@"Invalid Executor" reason:@"Chrome debug mode not supported" userInfo:nil]; + // Skip native initialization when in legacy Chrome debugging mode +#if !DEBUG + @throw [NSException exceptionWithName:@"Invalid Executor" reason:@"Chrome debug mode not supported in Release builds" userInfo:nil]; +#endif } else if ([bridge isKindOfClass:objc_lookUpClass("RCTCxxBridge")] || [NSStringFromClass([bridge class]) isEqual: @"RCTCxxBridge"]) { __weak __typeof__(self) weakSelf = self; __weak __typeof__(bridge) weakBridge = bridge; @@ -135,4 +138,4 @@ - (void)setBridge:(RCTBridge *)bridge { } } -@end \ No newline at end of file +@end From c393c46b149e12717da4a2d09e1b3e058b1dcbdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Mon, 10 Jan 2022 16:38:10 +0100 Subject: [PATCH 3/9] Simplified index.js as we have react-native/index.js --- lib/index.js | 47 ++++++++++------------------------------------- 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/lib/index.js b/lib/index.js index 2680edf0ef..dc020f8dd9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -17,46 +17,19 @@ //////////////////////////////////////////////////////////////////////////// const utils = require("./utils"); +const analytics = require("./submit-analytics"); -// Prevent React Native packager from seeing modules required with this -const nodeRequire = require; - -function getRealmConstructor(environment) { - switch (environment) { - case "node.js": - case "electron": - var analytics = nodeRequire("./submit-analytics"); - analytics.submitProductionAnalytics("Run").catch(() => { - // fail silently -- the caller is not responsible for handling - // errors in analytics submission - }); - - return nodeRequire("bindings")("realm.node").Realm; - case "reactnative": - //switch how babel transpiled code creates children objects. - //Inheriting from Realm.Object with class syntax does not support using Reflect.construct the way babel transpiles it. - //Defining Reflect.construct.sham makes the transpiled code use different standard mechanism for inheriting. (Function.apply with setPrototypeOf) - if (typeof Reflect !== "undefined" && Reflect.construct) { - Reflect.construct.sham = 1; - } - return global.Realm; - case "jscore": - return global.Realm; - case "chromedebugger": - case "vscodedebugger": - // This condition is for stripping "browser" folder from production bundles. - if (global.__DEV__) { - return require("./browser").default; // (exported as ES6 module) - } else { - throw new Error("Can´t use debugger if __DEV__ isn´t true."); - } - default: - throw new Error("Unexpected execution environment (" + environment + ")"); - } +const environment = utils.getEnvironment(); +if (environment !== "node.js" || environment !== "electron") { + throw new Error(`Unexpected execution environment (${environment})`); } -const environment = utils.getEnvironment(); -const realmConstructor = getRealmConstructor(environment); +analytics.submitProductionAnalytics("Run").catch(() => { + // fail silently -- the caller is not responsible for handling + // errors in analytics submission +}); + +const realmConstructor = require("bindings")("realm.node").Realm; require("./extensions")(realmConstructor, environment); From 21a3cf23291c155dd34630526e75ce0d6d063264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Mon, 10 Jan 2022 16:52:08 +0100 Subject: [PATCH 4/9] Removed some logging --- .../android/src/main/java/io/realm/react/RealmReactPackage.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/react-native/android/src/main/java/io/realm/react/RealmReactPackage.java b/react-native/android/src/main/java/io/realm/react/RealmReactPackage.java index 3668be3242..8c075428d4 100644 --- a/react-native/android/src/main/java/io/realm/react/RealmReactPackage.java +++ b/react-native/android/src/main/java/io/realm/react/RealmReactPackage.java @@ -31,7 +31,6 @@ public class RealmReactPackage extends TurboReactPackage implements ReactPackage { @Override public NativeModule getModule(String name, final ReactApplicationContext reactContext) { - Log.d("RealmJS", "Asked to get module " + name); if (name.equals(RealmReactModule.NAME)) { return new RealmReactModule(reactContext); } else { @@ -41,7 +40,6 @@ public NativeModule getModule(String name, final ReactApplicationContext reactCo @Override public ReactModuleInfoProvider getReactModuleInfoProvider() { - Log.d("RealmJS", "Asked to getReactModuleInfoProvider"); return new ReactModuleInfoProvider() { @Override public Map getReactModuleInfos() { From 801b999ad9d7830a3b92098516c9bd7634b37fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Mon, 10 Jan 2022 17:16:05 +0100 Subject: [PATCH 5/9] Adding a note to the CHANGELOG --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d906a4ca40..e15dea2497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,26 @@ +x.x.x Release notes (yyyy-MM-dd) +============================================================= +### Breaking change +* Removed all code related to the legacy Chrome Debugger. + +### Enhancements +* None. + +### Fixed +* None. + +### Compatibility +* MongoDB Realm Cloud. +* Realm Studio v11.0.0. +* APIs are backwards compatible with all previous releases of Realm JavaScript in the 10.5.x series. +* File format: generates Realms with format v22 (reads and upgrades file format v5 or later for non-synced Realm, upgrades file format v10 or later for synced Realms). + +### Internal +* Remove the previous implementation to the JavaScriptCore engine (in `src/jsc`). +* +* +* + 10.20.0-beta.0 Release notes (2021-12-21) ============================================================= NOTE: This release is rebased on our `10.11.0` release and as such contain the same enhancements and fixes. From 14aa4c8f492574b615270754423401c72775baea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Mon, 10 Jan 2022 17:20:30 +0100 Subject: [PATCH 6/9] Stop integration testing in legacy debug mode --- .github/workflows/integration-tests.yml | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index f9d74ef353..bfa6dd277d 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -221,16 +221,6 @@ jobs: MOCHA_REMOTE_EXIT_ON_ERROR: true RETRIES: 5 RETRY_DELAY: 300000 # 5 min - - name: Run tests (${{matrix.platform.name}} / Chrome Debugging) - if: ${{ false }} - run: npm run test:${{matrix.platform.name}}:chrome --prefix integration-tests/environments/react-native - env: - MOCHA_REMOTE_CONTEXT: missingServer - MOCHA_REMOTE_REPORTER: mocha-github-actions-reporter - MOCHA_REMOTE_EXIT_ON_ERROR: true - HEADLESS_DEBUGGER: true - RETRIES: 5 - RETRY_DELAY: 300000 # 5 min react-native-android: name: React Native on Android (${{ matrix.type }} using ${{ matrix.engine }}) runs-on: macos-latest @@ -308,16 +298,3 @@ jobs: MOCHA_REMOTE_REPORTER: mocha-github-actions-reporter MOCHA_REMOTE_EXIT_ON_ERROR: true SPAWN_LOGCAT: true - - name: Run tests (Android / Chrome Debugging) - if: ${{ false }} - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: 29 - target: google_apis - script: npm run test:android:chrome --prefix integration-tests/environments/react-native - env: - MOCHA_REMOTE_CONTEXT: missingServer - MOCHA_REMOTE_REPORTER: mocha-github-actions-reporter - MOCHA_REMOTE_EXIT_ON_ERROR: true - HEADLESS_DEBUGGER: true - SPAWN_LOGCAT: true From e50523f554dc0114c6ff377129c496deff163814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 12 Jan 2022 08:59:34 +0100 Subject: [PATCH 7/9] Incorporated feedback --- CHANGELOG.md | 2 +- lib/react-native/index.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e15dea2497..9e5b255b75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ x.x.x Release notes (yyyy-MM-dd) ============================================================= ### Breaking change -* Removed all code related to the legacy Chrome Debugger. +* Removed all code related to the legacy Chrome Debugger. Please use [Flipper](https://fbflipper.com/) as debugger. ### Enhancements * None. diff --git a/lib/react-native/index.js b/lib/react-native/index.js index 72f4d9581d..82cb98b974 100644 --- a/lib/react-native/index.js +++ b/lib/react-native/index.js @@ -28,7 +28,7 @@ if (typeof Reflect !== "undefined" && Reflect.construct) { const usingLegacyChromeDebugger = typeof DedicatedWorkerGlobalScope !== "undefined"; if (usingLegacyChromeDebugger) { - throw new Error("This version of Realm JS doesn't support the legacy Chrome Debugger"); + throw new Error("This version of Realm JS doesn't support the legacy Chrome Debugger. Please use Flipper instead."); } if (Platform.OS === "android") { @@ -46,7 +46,7 @@ const Realm = globalThis.Realm; // If it hasn't, the user likely forgot to install the RealmJS CocoaPod if (typeof Realm === "undefined") { throw new Error( - 'Missing Realm constructor. Did you run "pod install"? Please see https://realm.io/docs/react-native/latest/#missing-realm-constructor for troubleshooting', + 'Missing Realm constructor. Did you run "pod install"? Please see https://docs.mongodb.com/realm/sdk/react-native/install/ for troubleshooting', ); } From 6f344e97218367c654e7f6449758a6a0786d0d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 12 Jan 2022 09:01:21 +0100 Subject: [PATCH 8/9] =?UTF-8?q?Fixed=20the=20environment=20check=20?= =?UTF-8?q?=F0=9F=A4=A6=E2=80=8D=E2=99=82=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index dc020f8dd9..72e79a92c9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -20,7 +20,7 @@ const utils = require("./utils"); const analytics = require("./submit-analytics"); const environment = utils.getEnvironment(); -if (environment !== "node.js" || environment !== "electron") { +if (environment !== "node.js" && environment !== "electron") { throw new Error(`Unexpected execution environment (${environment})`); } From 6c5924b97e156b6b1e96274c2179c81f8fff5c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 12 Jan 2022 09:40:08 +0100 Subject: [PATCH 9/9] Removed all mentions of GCDWebServer --- .gitmodules | 3 - .../xcshareddata/Realm.xcscmblueprint | 6 - RealmJS.podspec | 2 - packages/realm-react/example/ios/Podfile.lock | 10 +- react-native/android/build.gradle | 24 -- .../ios/RealmReact.xcodeproj/project.pbxproj | 213 ------------------ vendor/GCDWebServer | 1 - 7 files changed, 2 insertions(+), 257 deletions(-) delete mode 160000 vendor/GCDWebServer diff --git a/.gitmodules b/.gitmodules index e4a420eacc..1582de9405 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "vendor/GCDWebServer"] - path = vendor/GCDWebServer - url = https://github.com/swisspol/GCDWebServer.git [submodule "docs/jsdoc-template"] path = docs/jsdoc-template url = https://github.com/realm/realm-jsdoc.git diff --git a/Realm.xcworkspace/xcshareddata/Realm.xcscmblueprint b/Realm.xcworkspace/xcshareddata/Realm.xcscmblueprint index ab8ab04a1e..30f010e748 100644 --- a/Realm.xcworkspace/xcshareddata/Realm.xcscmblueprint +++ b/Realm.xcworkspace/xcshareddata/Realm.xcscmblueprint @@ -11,7 +11,6 @@ "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "5EE721F9-041C-4877-9E73-A925C9DB080A", "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { "40F53A12E4AE40C654358321B91166ABD3E910A6" : "realm-js\/", - "F6F96CA34C5878B0A9123C7C37855491A5E599DA" : "realm-js\/vendor\/GCDWebServer\/", "8F3C415DA79CDA7D23734F285B95F9F9A3C0CB81" : "realm-js\/src\/object-store\/" }, "DVTSourceControlWorkspaceBlueprintNameKey" : "Realm", @@ -27,11 +26,6 @@ "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/realm\/realm-object-store.git", "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "8F3C415DA79CDA7D23734F285B95F9F9A3C0CB81" - }, - { - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/swisspol\/GCDWebServer.git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "F6F96CA34C5878B0A9123C7C37855491A5E599DA" } ] } \ No newline at end of file diff --git a/RealmJS.podspec b/RealmJS.podspec index c2ea1657e5..6b9f6fbd38 100644 --- a/RealmJS.podspec +++ b/RealmJS.podspec @@ -67,6 +67,4 @@ Pod::Spec.new do |s| s.vendored_frameworks = 'react-native/ios/realm-js-ios.xcframework' s.dependency 'React' - # TODO: Ensure the same version of GCDWebServer is used for Android - # s.dependency 'GCDWebServer' end diff --git a/packages/realm-react/example/ios/Podfile.lock b/packages/realm-react/example/ios/Podfile.lock index 9af92c8cd3..191fe109a1 100644 --- a/packages/realm-react/example/ios/Podfile.lock +++ b/packages/realm-react/example/ios/Podfile.lock @@ -71,9 +71,6 @@ PODS: - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin - fmt (6.2.1) - - GCDWebServer (3.5.4): - - GCDWebServer/Core (= 3.5.4) - - GCDWebServer/Core (3.5.4) - glog (0.3.5) - libevent (2.1.12) - OpenSSL-Universal (1.1.180) @@ -338,8 +335,7 @@ PODS: - React-cxxreact (= 0.65.1) - React-jsi (= 0.65.1) - React-perflogger (= 0.65.1) - - RealmJS (10.10.1): - - GCDWebServer + - RealmJS (10.20.0-beta.0): - React - Yoga (1.14.0) - YogaKit (1.18.1): @@ -414,7 +410,6 @@ SPEC REPOS: - Flipper-RSocket - FlipperKit - fmt - - GCDWebServer - libevent - OpenSSL-Universal - YogaKit @@ -497,7 +492,6 @@ SPEC CHECKSUMS: Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541 FlipperKit: aec2d931adeee48a07bab1ea8bcc8a6bb87dfce4 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 - GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4 glog: 5337263514dd6f09803962437687240c5dc39aa4 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b @@ -525,7 +519,7 @@ SPEC CHECKSUMS: React-RCTVibration: 92d41c2442e5328cc4d342cd7f78e5876b68bae5 React-runtimeexecutor: 85187f19dd9c47a7c102f9994f9d14e4dc2110de ReactCommon: eafed38eec7b591c31751bfa7494801618460459 - RealmJS: 2925b36a86fc179b0b58ad48386e43eb95188e9a + RealmJS: 6e47a0a9619d19dd238ef635abee5724cb677247 Yoga: aa0cb45287ebe1004c02a13f279c55a95f1572f4 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a diff --git a/react-native/android/build.gradle b/react-native/android/build.gradle index 69785d5ca0..32f927cbf0 100644 --- a/react-native/android/build.gradle +++ b/react-native/android/build.gradle @@ -21,25 +21,6 @@ allprojects { apply plugin: 'com.android.library' -tasks.register('forwardDebugPort', Exec) { - def adb = android.getAdbExe()?.toString() ?: 'false' - commandLine adb, 'forward', 'tcp:8083', 'tcp:8083' - ignoreExitValue true - doLast { - if (execResult.getExitValue() != 0) { - logger.error( - '===========================================================================\n' + - 'WARNING: Failed to automatically forward port 8083.\n' + - 'In order to use Realm in Chrome debugging mode, port 8083 must be forwarded\n' + - 'from localhost to the device or emulator being used to run the application.\n' + - 'You may need to add the appropriate flags to the command that failed:\n' + - ' adb forward tcp:8083 tcp:8083\n' + - '===========================================================================\n' - ) - } - } -} - android { compileSdkVersion rootProject.hasProperty("compileSdkVersion") ? rootProject.compileSdkVersion : 28 buildToolsVersion rootProject.hasProperty("buildToolsVersion") ? rootProject.buildToolsVersion : "28.0.3" @@ -53,10 +34,6 @@ android { jniDebuggable true } } - - tasks.withType(JavaCompile) { - compileTask -> compileTask.dependsOn forwardDebugPort - } } String getAppId () { @@ -96,6 +73,5 @@ try { project.dependencies { add(dependencyType, fileTree(dir: 'libs', include: ['*.jar'])) - add(dependencyType, 'org.nanohttpd:nanohttpd:2.2.0') add(dependencyType, 'com.facebook.react:react-native:+') } diff --git a/react-native/ios/RealmReact.xcodeproj/project.pbxproj b/react-native/ios/RealmReact.xcodeproj/project.pbxproj index bd46af679a..35ed2e81aa 100644 --- a/react-native/ios/RealmReact.xcodeproj/project.pbxproj +++ b/react-native/ios/RealmReact.xcodeproj/project.pbxproj @@ -8,35 +8,12 @@ /* Begin PBXBuildFile section */ 85B3572725FEB5B9003A02D4 /* realm-js-ios.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 85B3572625FEB5B9003A02D4 /* realm-js-ios.xcframework */; }; - 85B358EA25FF80CF003A02D4 /* GCDWebServerResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358CE25FF80CF003A02D4 /* GCDWebServerResponse.m */; }; - 85B358EB25FF80CF003A02D4 /* GCDWebServerRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358D125FF80CF003A02D4 /* GCDWebServerRequest.m */; }; - 85B358EC25FF80CF003A02D4 /* GCDWebServerFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358D425FF80CF003A02D4 /* GCDWebServerFunctions.m */; }; - 85B358ED25FF80CF003A02D4 /* GCDWebServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358D525FF80CF003A02D4 /* GCDWebServer.m */; }; - 85B358EE25FF80CF003A02D4 /* GCDWebServerConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358D625FF80CF003A02D4 /* GCDWebServerConnection.m */; }; - 85B358EF25FF80CF003A02D4 /* GCDWebServerErrorResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358DB25FF80CF003A02D4 /* GCDWebServerErrorResponse.m */; }; - 85B358F025FF80CF003A02D4 /* GCDWebServerFileResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358DD25FF80CF003A02D4 /* GCDWebServerFileResponse.m */; }; - 85B358F125FF80CF003A02D4 /* GCDWebServerDataResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358DE25FF80CF003A02D4 /* GCDWebServerDataResponse.m */; }; - 85B358F225FF80CF003A02D4 /* GCDWebServerStreamedResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358E025FF80CF003A02D4 /* GCDWebServerStreamedResponse.m */; }; - 85B358F325FF80CF003A02D4 /* GCDWebServerURLEncodedFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358E525FF80CF003A02D4 /* GCDWebServerURLEncodedFormRequest.m */; }; - 85B358F425FF80CF003A02D4 /* GCDWebServerMultiPartFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358E625FF80CF003A02D4 /* GCDWebServerMultiPartFormRequest.m */; }; - 85B358F525FF80CF003A02D4 /* GCDWebServerDataRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358E725FF80CF003A02D4 /* GCDWebServerDataRequest.m */; }; - 85B358F625FF80CF003A02D4 /* GCDWebServerFileRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 85B358E825FF80CF003A02D4 /* GCDWebServerFileRequest.m */; }; - 85B358F925FF80DB003A02D4 /* libGCDWebServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 85B358BB25FF8070003A02D4 /* libGCDWebServer.a */; }; F60690171CA2766F0003FB26 /* RealmReact.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = F60690161CA2766F0003FB26 /* RealmReact.h */; }; F60690191CA2766F0003FB26 /* RealmReact.mm in Sources */ = {isa = PBXBuildFile; fileRef = F60690181CA2766F0003FB26 /* RealmReact.mm */; }; F60690211CA277410003FB26 /* RealmAnalytics.mm in Sources */ = {isa = PBXBuildFile; fileRef = F60690201CA277410003FB26 /* RealmAnalytics.mm */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ - 85B358B925FF8070003A02D4 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; F60690111CA2766F0003FB26 /* Copy Headers */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -53,35 +30,6 @@ /* Begin PBXFileReference section */ 3F8D968A220CE21400327C8C /* RealmReact.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = RealmReact.xcconfig; sourceTree = ""; }; 85B3572625FEB5B9003A02D4 /* realm-js-ios.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = "realm-js-ios.xcframework"; sourceTree = ""; }; - 85B358BB25FF8070003A02D4 /* libGCDWebServer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libGCDWebServer.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 85B358CC25FF80CF003A02D4 /* GCDWebServerFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerFunctions.h; sourceTree = ""; }; - 85B358CD25FF80CF003A02D4 /* GCDWebServerPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerPrivate.h; sourceTree = ""; }; - 85B358CE25FF80CF003A02D4 /* GCDWebServerResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerResponse.m; sourceTree = ""; }; - 85B358CF25FF80CF003A02D4 /* GCDWebServerConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerConnection.h; sourceTree = ""; }; - 85B358D025FF80CF003A02D4 /* GCDWebServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServer.h; sourceTree = ""; }; - 85B358D125FF80CF003A02D4 /* GCDWebServerRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerRequest.m; sourceTree = ""; }; - 85B358D225FF80CF003A02D4 /* GCDWebServerHTTPStatusCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerHTTPStatusCodes.h; sourceTree = ""; }; - 85B358D325FF80CF003A02D4 /* GCDWebServerResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerResponse.h; sourceTree = ""; }; - 85B358D425FF80CF003A02D4 /* GCDWebServerFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerFunctions.m; sourceTree = ""; }; - 85B358D525FF80CF003A02D4 /* GCDWebServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServer.m; sourceTree = ""; }; - 85B358D625FF80CF003A02D4 /* GCDWebServerConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerConnection.m; sourceTree = ""; }; - 85B358D725FF80CF003A02D4 /* GCDWebServerRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerRequest.h; sourceTree = ""; }; - 85B358D925FF80CF003A02D4 /* GCDWebServerFileResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerFileResponse.h; sourceTree = ""; }; - 85B358DA25FF80CF003A02D4 /* GCDWebServerStreamedResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerStreamedResponse.h; sourceTree = ""; }; - 85B358DB25FF80CF003A02D4 /* GCDWebServerErrorResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerErrorResponse.m; sourceTree = ""; }; - 85B358DC25FF80CF003A02D4 /* GCDWebServerDataResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerDataResponse.h; sourceTree = ""; }; - 85B358DD25FF80CF003A02D4 /* GCDWebServerFileResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerFileResponse.m; sourceTree = ""; }; - 85B358DE25FF80CF003A02D4 /* GCDWebServerDataResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerDataResponse.m; sourceTree = ""; }; - 85B358DF25FF80CF003A02D4 /* GCDWebServerErrorResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerErrorResponse.h; sourceTree = ""; }; - 85B358E025FF80CF003A02D4 /* GCDWebServerStreamedResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerStreamedResponse.m; sourceTree = ""; }; - 85B358E225FF80CF003A02D4 /* GCDWebServerDataRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerDataRequest.h; sourceTree = ""; }; - 85B358E325FF80CF003A02D4 /* GCDWebServerMultiPartFormRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerMultiPartFormRequest.h; sourceTree = ""; }; - 85B358E425FF80CF003A02D4 /* GCDWebServerFileRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerFileRequest.h; sourceTree = ""; }; - 85B358E525FF80CF003A02D4 /* GCDWebServerURLEncodedFormRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerURLEncodedFormRequest.m; sourceTree = ""; }; - 85B358E625FF80CF003A02D4 /* GCDWebServerMultiPartFormRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerMultiPartFormRequest.m; sourceTree = ""; }; - 85B358E725FF80CF003A02D4 /* GCDWebServerDataRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerDataRequest.m; sourceTree = ""; }; - 85B358E825FF80CF003A02D4 /* GCDWebServerFileRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDWebServerFileRequest.m; sourceTree = ""; }; - 85B358E925FF80CF003A02D4 /* GCDWebServerURLEncodedFormRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCDWebServerURLEncodedFormRequest.h; sourceTree = ""; }; F60690131CA2766F0003FB26 /* libRealmReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRealmReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; F60690161CA2766F0003FB26 /* RealmReact.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RealmReact.h; sourceTree = ""; }; F60690181CA2766F0003FB26 /* RealmReact.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = RealmReact.mm; sourceTree = ""; }; @@ -90,18 +38,10 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 85B358B825FF8070003A02D4 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 85CA5FE41F1536660038172D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 85B358F925FF80DB003A02D4 /* libGCDWebServer.a in Frameworks */, 85B3572725FEB5B9003A02D4 /* realm-js-ios.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -117,68 +57,6 @@ name = Frameworks; sourceTree = ""; }; - 85B358BC25FF8070003A02D4 /* GCDWebServer */ = { - isa = PBXGroup; - children = ( - 85B358CB25FF80CF003A02D4 /* Core */, - 85B358E125FF80CF003A02D4 /* Requests */, - 85B358D825FF80CF003A02D4 /* Responses */, - ); - path = GCDWebServer; - sourceTree = ""; - }; - 85B358CB25FF80CF003A02D4 /* Core */ = { - isa = PBXGroup; - children = ( - 85B358CC25FF80CF003A02D4 /* GCDWebServerFunctions.h */, - 85B358CD25FF80CF003A02D4 /* GCDWebServerPrivate.h */, - 85B358CE25FF80CF003A02D4 /* GCDWebServerResponse.m */, - 85B358CF25FF80CF003A02D4 /* GCDWebServerConnection.h */, - 85B358D025FF80CF003A02D4 /* GCDWebServer.h */, - 85B358D125FF80CF003A02D4 /* GCDWebServerRequest.m */, - 85B358D225FF80CF003A02D4 /* GCDWebServerHTTPStatusCodes.h */, - 85B358D325FF80CF003A02D4 /* GCDWebServerResponse.h */, - 85B358D425FF80CF003A02D4 /* GCDWebServerFunctions.m */, - 85B358D525FF80CF003A02D4 /* GCDWebServer.m */, - 85B358D625FF80CF003A02D4 /* GCDWebServerConnection.m */, - 85B358D725FF80CF003A02D4 /* GCDWebServerRequest.h */, - ); - name = Core; - path = ../../../vendor/GCDWebServer/GCDWebServer/Core; - sourceTree = ""; - }; - 85B358D825FF80CF003A02D4 /* Responses */ = { - isa = PBXGroup; - children = ( - 85B358D925FF80CF003A02D4 /* GCDWebServerFileResponse.h */, - 85B358DA25FF80CF003A02D4 /* GCDWebServerStreamedResponse.h */, - 85B358DB25FF80CF003A02D4 /* GCDWebServerErrorResponse.m */, - 85B358DC25FF80CF003A02D4 /* GCDWebServerDataResponse.h */, - 85B358DD25FF80CF003A02D4 /* GCDWebServerFileResponse.m */, - 85B358DE25FF80CF003A02D4 /* GCDWebServerDataResponse.m */, - 85B358DF25FF80CF003A02D4 /* GCDWebServerErrorResponse.h */, - 85B358E025FF80CF003A02D4 /* GCDWebServerStreamedResponse.m */, - ); - name = Responses; - path = ../../../vendor/GCDWebServer/GCDWebServer/Responses; - sourceTree = ""; - }; - 85B358E125FF80CF003A02D4 /* Requests */ = { - isa = PBXGroup; - children = ( - 85B358E225FF80CF003A02D4 /* GCDWebServerDataRequest.h */, - 85B358E325FF80CF003A02D4 /* GCDWebServerMultiPartFormRequest.h */, - 85B358E425FF80CF003A02D4 /* GCDWebServerFileRequest.h */, - 85B358E525FF80CF003A02D4 /* GCDWebServerURLEncodedFormRequest.m */, - 85B358E625FF80CF003A02D4 /* GCDWebServerMultiPartFormRequest.m */, - 85B358E725FF80CF003A02D4 /* GCDWebServerDataRequest.m */, - 85B358E825FF80CF003A02D4 /* GCDWebServerFileRequest.m */, - 85B358E925FF80CF003A02D4 /* GCDWebServerURLEncodedFormRequest.h */, - ); - name = Requests; - path = ../../../vendor/GCDWebServer/GCDWebServer/Requests; - sourceTree = ""; - }; F606900A1CA2766F0003FB26 = { isa = PBXGroup; children = ( @@ -193,7 +71,6 @@ isa = PBXGroup; children = ( F60690131CA2766F0003FB26 /* libRealmReact.a */, - 85B358BB25FF8070003A02D4 /* libGCDWebServer.a */, ); name = Products; sourceTree = ""; @@ -213,7 +90,6 @@ F60690221CA277BE0003FB26 /* Libraries */ = { isa = PBXGroup; children = ( - 85B358BC25FF8070003A02D4 /* GCDWebServer */, ); name = Libraries; sourceTree = ""; @@ -221,23 +97,6 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 85B358BA25FF8070003A02D4 /* GCDWebServer */ = { - isa = PBXNativeTarget; - buildConfigurationList = 85B358C125FF8070003A02D4 /* Build configuration list for PBXNativeTarget "GCDWebServer" */; - buildPhases = ( - 85B358B725FF8070003A02D4 /* Sources */, - 85B358B825FF8070003A02D4 /* Frameworks */, - 85B358B925FF8070003A02D4 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = GCDWebServer; - productName = GCDWebServer; - productReference = 85B358BB25FF8070003A02D4 /* libGCDWebServer.a */; - productType = "com.apple.product-type.library.static"; - }; F60690121CA2766F0003FB26 /* RealmReact */ = { isa = PBXNativeTarget; buildConfigurationList = F606901C1CA2766F0003FB26 /* Build configuration list for PBXNativeTarget "RealmReact" */; @@ -264,9 +123,6 @@ LastUpgradeCheck = 1010; ORGANIZATIONNAME = Realm; TargetAttributes = { - 85B358BA25FF8070003A02D4 = { - CreatedOnToolsVersion = 12.4; - }; F60690121CA2766F0003FB26 = { CreatedOnToolsVersion = 7.3; }; @@ -286,32 +142,11 @@ projectRoot = ""; targets = ( F60690121CA2766F0003FB26 /* RealmReact */, - 85B358BA25FF8070003A02D4 /* GCDWebServer */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - 85B358B725FF8070003A02D4 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 85B358F425FF80CF003A02D4 /* GCDWebServerMultiPartFormRequest.m in Sources */, - 85B358EF25FF80CF003A02D4 /* GCDWebServerErrorResponse.m in Sources */, - 85B358F525FF80CF003A02D4 /* GCDWebServerDataRequest.m in Sources */, - 85B358F125FF80CF003A02D4 /* GCDWebServerDataResponse.m in Sources */, - 85B358ED25FF80CF003A02D4 /* GCDWebServer.m in Sources */, - 85B358EB25FF80CF003A02D4 /* GCDWebServerRequest.m in Sources */, - 85B358F025FF80CF003A02D4 /* GCDWebServerFileResponse.m in Sources */, - 85B358EE25FF80CF003A02D4 /* GCDWebServerConnection.m in Sources */, - 85B358F225FF80CF003A02D4 /* GCDWebServerStreamedResponse.m in Sources */, - 85B358F325FF80CF003A02D4 /* GCDWebServerURLEncodedFormRequest.m in Sources */, - 85B358EA25FF80CF003A02D4 /* GCDWebServerResponse.m in Sources */, - 85B358EC25FF80CF003A02D4 /* GCDWebServerFunctions.m in Sources */, - 85B358F625FF80CF003A02D4 /* GCDWebServerFileRequest.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; F606900F1CA2766F0003FB26 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -324,45 +159,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ - 85B358C225FF8070003A02D4 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 85B358C325FF8070003A02D4 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu11; - MTL_FAST_MATH = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; F606901A1CA2766F0003FB26 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 3F8D968A220CE21400327C8C /* RealmReact.xcconfig */; @@ -526,15 +322,6 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 85B358C125FF8070003A02D4 /* Build configuration list for PBXNativeTarget "GCDWebServer" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 85B358C225FF8070003A02D4 /* Debug */, - 85B358C325FF8070003A02D4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; F606900E1CA2766F0003FB26 /* Build configuration list for PBXProject "RealmReact" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/vendor/GCDWebServer b/vendor/GCDWebServer deleted file mode 160000 index c98941121a..0000000000 --- a/vendor/GCDWebServer +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c98941121a4b96a4fa4ad785790a4a3e119227a5