]> git.saurik.com Git - cycript.git/blame - Library.cpp
new operator must return JSObject even for errors.
[cycript.git] / Library.cpp
CommitLineData
7341eedb
JF
1/* Cycript - The Truly Universal Scripting Language
2 * Copyright (C) 2009-2016 Jay Freeman (saurik)
37954781
JF
3*/
4
f95d2598 5/* GNU Affero General Public License, Version 3 {{{ */
37954781 6/*
f95d2598
JF
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c15969fd 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f95d2598
JF
15 * GNU Affero General Public License for more details.
16
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
b3378a02 19**/
37954781
JF
20/* }}} */
21
37954781
JF
22#include "cycript.hpp"
23
37954781 24#include <iostream>
37954781
JF
25#include <set>
26#include <map>
37954781 27#include <sstream>
37954781 28
20052ff7
JF
29#include <dlfcn.h>
30
31#include <sys/mman.h>
32
8d20f0f1 33#include "Code.hpp"
20052ff7 34#include "ConvertUTF.h"
8a392978 35#include "Driver.hpp"
37954781 36#include "Error.hpp"
2f51d6ab 37#include "Execute.hpp"
20052ff7 38#include "Pooling.hpp"
b12a9965 39#include "String.hpp"
20052ff7 40#include "Syntax.hpp"
59cd74c1 41
142cb9e3 42/* C Strings {{{ */
b799113b 43CYUTF8String CYPoolUTF8String(CYPool &pool, CYUTF16String utf16) {
59cd74c1
JF
44 // XXX: this is wrong
45 size_t size(utf16.size * 5);
8a3643b2 46 char *temp(new(pool) char[size + 1]);
59cd74c1 47
142cb9e3
JF
48 const uint16_t *lhs(utf16.data);
49 uint8_t *rhs(reinterpret_cast<uint8_t *>(temp));
50 _assert(ConvertUTF16toUTF8(&lhs, lhs + utf16.size, &rhs, rhs + size, lenientConversion) == conversionOK);
59cd74c1 51
142cb9e3
JF
52 *rhs = 0;
53 return CYUTF8String(temp, reinterpret_cast<char *>(rhs) - temp);
59cd74c1
JF
54}
55
b799113b 56CYUTF16String CYPoolUTF16String(CYPool &pool, CYUTF8String utf8) {
59cd74c1
JF
57 // XXX: this is wrong
58 size_t size(utf8.size * 5);
8a3643b2 59 uint16_t *temp(new (pool) uint16_t[size + 1]);
59cd74c1 60
142cb9e3
JF
61 const uint8_t *lhs(reinterpret_cast<const uint8_t *>(utf8.data));
62 uint16_t *rhs(temp);
63 _assert(ConvertUTF8toUTF16(&lhs, lhs + utf8.size, &rhs, rhs + size, lenientConversion) == conversionOK);
59cd74c1 64
142cb9e3
JF
65 *rhs = 0;
66 return CYUTF16String(temp, rhs - temp);
59cd74c1
JF
67}
68/* }}} */
37954781
JF
69/* Index Offsets {{{ */
70size_t CYGetIndex(const CYUTF8String &value) {
71 if (value.data[0] != '0') {
ba4fa42f
JF
72 size_t index(0);
73 for (size_t i(0); i != value.size; ++i) {
74 if (!DigitRange_[value.data[i]])
75 return _not(size_t);
76 index *= 10;
77 index += value.data[i] - '0';
78 }
79 return index;
80 } else if (value.size == 1)
37954781 81 return 0;
ba4fa42f
JF
82 else
83 return _not(size_t);
37954781
JF
84}
85
ba4fa42f 86// XXX: this isn't actually right
37954781
JF
87bool CYGetOffset(const char *value, ssize_t &index) {
88 if (value[0] != '0') {
89 char *end;
90 index = strtol(value, &end, 10);
91 if (value + strlen(value) == end)
92 return true;
93 } else if (value[1] == '\0') {
94 index = 0;
95 return true;
96 }
97
98 return false;
99}
100/* }}} */
37954781
JF
101
102bool CYIsKey(CYUTF8String value) {
103 const char *data(value.data);
104 size_t size(value.size);
105
106 if (size == 0)
107 return false;
108
109 if (DigitRange_[data[0]]) {
110 size_t index(CYGetIndex(value));
111 if (index == _not(size_t))
112 return false;
113 } else {
114 if (!WordStartRange_[data[0]])
115 return false;
116 for (size_t i(1); i != size; ++i)
117 if (!WordEndRange_[data[i]])
118 return false;
119 }
120
121 return true;
122}
37954781 123
e66ced89
JF
124_visible bool CYStartsWith(const CYUTF8String &haystack, const CYUTF8String &needle) {
125 return haystack.size >= needle.size && strncmp(haystack.data, needle.data, needle.size) == 0;
126}
127
c3d9dbc7 128CYUTF8String CYPoolCode(CYPool &pool, std::streambuf &stream) {
2eb8215d 129 CYLocalPool local;
2c1d569a 130 CYDriver driver(local, stream);
80280368
JF
131
132 if (driver.Parse()) {
133 if (!driver.errors_.empty())
134 CYThrow("%s", driver.errors_.front().message_.c_str());
135 CYThrow("syntax error");
136 }
59cd74c1 137
029bc65b 138 CYOptions options;
2eb8215d 139 CYContext context(options);
a7d8b413 140 driver.script_->Replace(context);
57930129 141
efd689d8 142 std::stringbuf str;
029bc65b 143 CYOutput out(str, options);
a7d8b413 144 out << *driver.script_;
8409b00d 145 return pool.strdup(str.str().c_str());
57930129 146}
59cd74c1 147
8d20f0f1
JF
148CYUTF8String CYPoolCode(CYPool &pool, CYUTF8String code) {
149 CYStream stream(code.data, code.data + code.size);
150 return CYPoolCode(pool, stream);
151}
152
b799113b 153CYPool &CYGetGlobalPool() {
b799113b
JF
154 static CYPool pool;
155 return pool;
37954781 156}