├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE_1_0.txt ├── README.md ├── benchmark ├── base.js ├── crypto.js ├── deltablue.js ├── earley-boyer.js ├── raytrace.js ├── regexp.js ├── richards.js ├── run.ds ├── splay.js └── v8 run.html ├── build.bat ├── build.sh ├── ds-ext ├── dub.json └── source │ └── ext.d ├── ds ├── dub.json └── source │ └── testscript.d ├── dub.json ├── engine ├── dub.json └── source │ └── dmdscript │ ├── RandAA.d │ ├── darguments.d │ ├── darray.d │ ├── dboolean.d │ ├── ddate.d │ ├── ddeclaredfunction.d │ ├── derror.d │ ├── dfunction.d │ ├── dglobal.d │ ├── dmath.d │ ├── dnative.d │ ├── dnumber.d │ ├── dobject.d │ ├── dregexp.d │ ├── dstring.d │ ├── errmsgs.d │ ├── expression.d │ ├── extending.d │ ├── functiondefinition.d │ ├── identifier.d │ ├── ir.d │ ├── irstate.d │ ├── iterator.d │ ├── lexer.d │ ├── opcodes.d │ ├── outbuffer.d │ ├── parse.d │ ├── patches.d │ ├── program.d │ ├── property.d │ ├── protoerror.d │ ├── scopex.d │ ├── script.d │ ├── statement.d │ ├── symbol.d │ ├── text.d │ ├── threadcontext.d │ ├── utf.d │ └── value.d ├── ext.ds ├── readme.txt ├── run-test262.sh ├── samples ├── eval.ds ├── seive.ds └── simple.ds ├── test262-patches ├── test262-_monkeyYaml.py.patch ├── test262-parseTestRecord.py.patch └── test262-test262.py.patch ├── textgen.d └── timed-dmdscript.sh /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Test Suite 2 | 3 | # Only triggers on pushes/PRs to master 4 | on: 5 | pull_request: 6 | branches: 7 | - master 8 | push: 9 | branches: 10 | - master 11 | 12 | jobs: 13 | test: 14 | name: CI 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | os: [ubuntu-latest, windows-latest] 19 | dc: [dmd-latest, ldc-latest, ldc-1.15.0] 20 | arch: [x86_64] 21 | include: 22 | - {os: windows-latest, dc: ldc-latest, arch: x86} 23 | 24 | runs-on: ${{ matrix.os }} 25 | steps: 26 | - uses: actions/checkout@v4 27 | 28 | - name: Install D compiler 29 | uses: dlang-community/setup-dlang@v2 30 | with: 31 | compiler: ${{ matrix.dc }} 32 | 33 | - name: Run tests 34 | shell: bash 35 | run: dub test :engine -a ${{matrix.arch}} 36 | testsuite: 37 | name: Test262 38 | strategy: 39 | fail-fast: false 40 | matrix: 41 | os: [ubuntu-latest] 42 | dc: [ldc-latest] 43 | 44 | runs-on: ${{ matrix.os }} 45 | steps: 46 | - uses: actions/checkout@v4 47 | 48 | - name: Install D compiler 49 | uses: dlang-community/setup-dlang@v2 50 | with: 51 | compiler: ${{matrix.dc}} 52 | 53 | - name: Run tests 54 | shell: bash 55 | run: ./run-test262.sh 56 | 57 | - name: Upload log 58 | uses: actions/upload-artifact@v3 59 | if: always() 60 | with: 61 | name: runtest262 log 62 | path: dmdscript-test262.log 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.dll 3 | *.dylib 4 | *.exe 5 | *.lib 6 | *.lst 7 | *.o 8 | *.obj 9 | *.so 10 | 11 | .dub 12 | dub.selections.json 13 | 14 | /dmdscript 15 | /dmdscript-ext 16 | /ds/dmdscript_ds 17 | /ds-ext/dmdscript_ds-ext 18 | -------------------------------------------------------------------------------- /LICENSE_1_0.txt: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DMDScript 2 | ========= 3 | 4 | An implementation of the ECMA 262 (Javascript) programming language 5 | -------------------------------------------------------------------------------- /benchmark/base.js: -------------------------------------------------------------------------------- 1 | // Copyright 2008 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | 29 | // Simple framework for running the benchmark suites and 30 | // computing a score based on the timing measurements. 31 | 32 | 33 | // A benchmark has a name (string) and a function that will be run to 34 | // do the performance measurement. The optional setup and tearDown 35 | // arguments are functions that will be invoked before and after 36 | // running the benchmark, but the running time of these functions will 37 | // not be accounted for in the benchmark score. 38 | function Benchmark(name, run, setup, tearDown) { 39 | this.name = name; 40 | this.run = run; 41 | this.Setup = setup ? setup : function() { }; 42 | this.TearDown = tearDown ? tearDown : function() { }; 43 | } 44 | 45 | 46 | // Benchmark results hold the benchmark and the measured time used to 47 | // run the benchmark. The benchmark score is computed later once a 48 | // full benchmark suite has run to completion. 49 | function BenchmarkResult(benchmark, time) { 50 | this.benchmark = benchmark; 51 | this.time = time; 52 | } 53 | 54 | 55 | // Automatically convert results to numbers. Used by the geometric 56 | // mean computation. 57 | BenchmarkResult.prototype.valueOf = function() { 58 | return this.time; 59 | } 60 | 61 | 62 | // Suites of benchmarks consist of a name and the set of benchmarks in 63 | // addition to the reference timing that the final score will be based 64 | // on. This way, all scores are relative to a reference run and higher 65 | // scores implies better performance. 66 | function BenchmarkSuite(name, reference, benchmarks) { 67 | this.name = name; 68 | this.reference = reference; 69 | this.benchmarks = benchmarks; 70 | BenchmarkSuite.suites.push(this); 71 | } 72 | 73 | 74 | // Keep track of all declared benchmark suites. 75 | BenchmarkSuite.suites = []; 76 | 77 | 78 | // Scores are not comparable across versions. Bump the version if 79 | // you're making changes that will affect that scores, e.g. if you add 80 | // a new benchmark or change an existing one. 81 | BenchmarkSuite.version = '6'; 82 | 83 | 84 | // To make the benchmark results predictable, we replace Math.random 85 | // with a 100% deterministic alternative. 86 | Math.random = (function() { 87 | var seed = 49734321; 88 | return function() { 89 | // Robert Jenkins' 32 bit integer hash function. 90 | seed = ((seed + 0x7ed55d16) + (seed << 12)) & 0xffffffff; 91 | seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff; 92 | seed = ((seed + 0x165667b1) + (seed << 5)) & 0xffffffff; 93 | seed = ((seed + 0xd3a2646c) ^ (seed << 9)) & 0xffffffff; 94 | seed = ((seed + 0xfd7046c5) + (seed << 3)) & 0xffffffff; 95 | seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff; 96 | return (seed & 0xfffffff) / 0x10000000; 97 | }; 98 | })(); 99 | 100 | 101 | // Runs all registered benchmark suites and optionally yields between 102 | // each individual benchmark to avoid running for too long in the 103 | // context of browsers. Once done, the final score is reported to the 104 | // runner. 105 | BenchmarkSuite.RunSuites = function(runner) { 106 | var continuation = null; 107 | var suites = BenchmarkSuite.suites; 108 | var length = suites.length; 109 | BenchmarkSuite.scores = []; 110 | var index = 0; 111 | function RunStep() { 112 | while (continuation || index < length) { 113 | if (continuation) { 114 | continuation = continuation(); 115 | } else { 116 | var suite = suites[index++]; 117 | if (runner.NotifyStart) runner.NotifyStart(suite.name); 118 | continuation = suite.RunStep(runner); 119 | } 120 | if (continuation && typeof window != 'undefined' && window.setTimeout) { 121 | window.setTimeout(RunStep, 25); 122 | return; 123 | } 124 | } 125 | if (runner.NotifyScore) { 126 | var score = BenchmarkSuite.GeometricMean(BenchmarkSuite.scores); 127 | var formatted = BenchmarkSuite.FormatScore(100 * score); 128 | runner.NotifyScore(formatted); 129 | } 130 | } 131 | RunStep(); 132 | } 133 | 134 | 135 | // Counts the total number of registered benchmarks. Useful for 136 | // showing progress as a percentage. 137 | BenchmarkSuite.CountBenchmarks = function() { 138 | var result = 0; 139 | var suites = BenchmarkSuite.suites; 140 | for (var i = 0; i < suites.length; i++) { 141 | result += suites[i].benchmarks.length; 142 | } 143 | return result; 144 | } 145 | 146 | 147 | // Computes the geometric mean of a set of numbers. 148 | BenchmarkSuite.GeometricMean = function(numbers) { 149 | var log = 0; 150 | for (var i = 0; i < numbers.length; i++) { 151 | log += Math.log(numbers[i]); 152 | } 153 | return Math.pow(Math.E, log / numbers.length); 154 | } 155 | 156 | 157 | // Converts a score value to a string with at least three significant 158 | // digits. 159 | BenchmarkSuite.FormatScore = function(value) { 160 | if (value > 100) { 161 | return value.toFixed(0); 162 | } else { 163 | return value.toPrecision(3); 164 | } 165 | } 166 | 167 | // Notifies the runner that we're done running a single benchmark in 168 | // the benchmark suite. This can be useful to report progress. 169 | BenchmarkSuite.prototype.NotifyStep = function(result) { 170 | this.results.push(result); 171 | if (this.runner.NotifyStep) this.runner.NotifyStep(result.benchmark.name); 172 | } 173 | 174 | 175 | // Notifies the runner that we're done with running a suite and that 176 | // we have a result which can be reported to the user if needed. 177 | BenchmarkSuite.prototype.NotifyResult = function() { 178 | var mean = BenchmarkSuite.GeometricMean(this.results); 179 | var score = this.reference / mean; 180 | BenchmarkSuite.scores.push(score); 181 | if (this.runner.NotifyResult) { 182 | var formatted = BenchmarkSuite.FormatScore(100 * score); 183 | this.runner.NotifyResult(this.name, formatted); 184 | } 185 | } 186 | 187 | 188 | // Notifies the runner that running a benchmark resulted in an error. 189 | BenchmarkSuite.prototype.NotifyError = function(error) { 190 | if (this.runner.NotifyError) { 191 | this.runner.NotifyError(this.name, error); 192 | } 193 | if (this.runner.NotifyStep) { 194 | this.runner.NotifyStep(this.name); 195 | } 196 | } 197 | 198 | 199 | // Runs a single benchmark for at least a second and computes the 200 | // average time it takes to run a single iteration. 201 | BenchmarkSuite.prototype.RunSingleBenchmark = function(benchmark, data) { 202 | function Measure(data) { 203 | var elapsed = 0; 204 | var start = new Date(); 205 | for (var n = 0; elapsed < 1000; n++) { 206 | benchmark.run(); 207 | elapsed = new Date() - start; 208 | } 209 | if (data != null) { 210 | data.runs += n; 211 | data.elapsed += elapsed; 212 | } 213 | } 214 | 215 | if (data == null) { 216 | // Measure the benchmark once for warm up and throw the result 217 | // away. Return a fresh data object. 218 | Measure(null); 219 | return { runs: 0, elapsed: 0 }; 220 | } else { 221 | Measure(data); 222 | // If we've run too few iterations, we continue for another second. 223 | if (data.runs < 32) return data; 224 | var usec = (data.elapsed * 1000) / data.runs; 225 | this.NotifyStep(new BenchmarkResult(benchmark, usec)); 226 | return null; 227 | } 228 | } 229 | 230 | 231 | // This function starts running a suite, but stops between each 232 | // individual benchmark in the suite and returns a continuation 233 | // function which can be invoked to run the next benchmark. Once the 234 | // last benchmark has been executed, null is returned. 235 | BenchmarkSuite.prototype.RunStep = function(runner) { 236 | this.results = []; 237 | this.runner = runner; 238 | var length = this.benchmarks.length; 239 | var index = 0; 240 | var suite = this; 241 | var data; 242 | 243 | // Run the setup, the actual benchmark, and the tear down in three 244 | // separate steps to allow the framework to yield between any of the 245 | // steps. 246 | 247 | function RunNextSetup() { 248 | if (index < length) { 249 | try { 250 | suite.benchmarks[index].Setup(); 251 | } catch (e) { 252 | suite.NotifyError(e); 253 | return null; 254 | } 255 | return RunNextBenchmark; 256 | } 257 | suite.NotifyResult(); 258 | return null; 259 | } 260 | 261 | function RunNextBenchmark() { 262 | try { 263 | data = suite.RunSingleBenchmark(suite.benchmarks[index], data); 264 | } catch (e) { 265 | suite.NotifyError(e); 266 | return null; 267 | } 268 | // If data is null, we're done with this benchmark. 269 | return (data == null) ? RunNextTearDown : RunNextBenchmark(); 270 | } 271 | 272 | function RunNextTearDown() { 273 | try { 274 | suite.benchmarks[index++].TearDown(); 275 | } catch (e) { 276 | suite.NotifyError(e); 277 | return null; 278 | } 279 | return RunNextSetup; 280 | } 281 | 282 | // Start out running the setup. 283 | return RunNextSetup(); 284 | } 285 | -------------------------------------------------------------------------------- /benchmark/run.ds: -------------------------------------------------------------------------------- 1 | function Run() { 2 | BenchmarkSuite.RunSuites({ NotifyStep: ShowProgress, 3 | NotifyError: AddError, 4 | NotifyResult: AddResult, 5 | NotifyScore: AddScore }); 6 | } 7 | var completed = 0; 8 | var benchmarks = BenchmarkSuite.CountBenchmarks(); 9 | var success = true; 10 | 11 | function ShowProgress(name) { 12 | var percentage = ((++completed) / benchmarks) * 100; 13 | println("\rRunning: " + Math.round(percentage) + "% completed."); 14 | } 15 | 16 | function AddResult(name, result) { 17 | var text = name + ': ' + result; 18 | println(text); 19 | } 20 | 21 | 22 | function AddError(name, error) { 23 | AddResult(name, 'error'); 24 | //println(text); 25 | success = false; 26 | } 27 | 28 | 29 | function AddScore(score) { 30 | if (success) { 31 | //results.push("Score: " + score); 32 | } 33 | } 34 | 35 | function Run() { 36 | BenchmarkSuite.RunSuites({ NotifyStep: ShowProgress, 37 | NotifyError: AddError, 38 | NotifyResult: AddResult, 39 | NotifyScore: AddScore }); 40 | } 41 | 42 | 43 | println("Version: ", BenchmarkSuite.version); 44 | Run(); 45 | 46 | -------------------------------------------------------------------------------- /benchmark/splay.js: -------------------------------------------------------------------------------- 1 | // Copyright 2009 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | // This benchmark is based on a JavaScript log processing module used 29 | // by the V8 profiler to generate execution time profiles for runs of 30 | // JavaScript applications, and it effectively measures how fast the 31 | // JavaScript engine is at allocating nodes and reclaiming the memory 32 | // used for old nodes. Because of the way splay trees work, the engine 33 | // also has to deal with a lot of changes to the large tree object 34 | // graph. 35 | 36 | var Splay = new BenchmarkSuite('Splay', 81491, [ 37 | new Benchmark("Splay", SplayRun, SplaySetup, SplayTearDown) 38 | ]); 39 | 40 | 41 | // Configuration. 42 | var kSplayTreeSize = 8000; 43 | var kSplayTreeModifications = 80; 44 | var kSplayTreePayloadDepth = 5; 45 | 46 | var splayTree = null; 47 | 48 | 49 | function GeneratePayloadTree(depth, tag) { 50 | if (depth == 0) { 51 | return { 52 | array : [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], 53 | string : 'String for key ' + tag + ' in leaf node' 54 | }; 55 | } else { 56 | return { 57 | left: GeneratePayloadTree(depth - 1, tag), 58 | right: GeneratePayloadTree(depth - 1, tag) 59 | }; 60 | } 61 | } 62 | 63 | 64 | function GenerateKey() { 65 | // The benchmark framework guarantees that Math.random is 66 | // deterministic; see base.js. 67 | return Math.random(); 68 | } 69 | 70 | 71 | function InsertNewNode() { 72 | // Insert new node with a unique key. 73 | var key; 74 | do { 75 | key = GenerateKey(); 76 | } while (splayTree.find(key) != null); 77 | var payload = GeneratePayloadTree(kSplayTreePayloadDepth, String(key)); 78 | splayTree.insert(key, payload); 79 | return key; 80 | } 81 | 82 | 83 | 84 | function SplaySetup() { 85 | splayTree = new SplayTree(); 86 | for (var i = 0; i < kSplayTreeSize; i++) InsertNewNode(); 87 | } 88 | 89 | 90 | function SplayTearDown() { 91 | // Allow the garbage collector to reclaim the memory 92 | // used by the splay tree no matter how we exit the 93 | // tear down function. 94 | var keys = splayTree.exportKeys(); 95 | splayTree = null; 96 | 97 | // Verify that the splay tree has the right size. 98 | var length = keys.length; 99 | if (length != kSplayTreeSize) { 100 | throw new Error("Splay tree has wrong size"); 101 | } 102 | 103 | // Verify that the splay tree has sorted, unique keys. 104 | for (var i = 0; i < length - 1; i++) { 105 | if (keys[i] >= keys[i + 1]) { 106 | throw new Error("Splay tree not sorted"); 107 | } 108 | } 109 | } 110 | 111 | 112 | function SplayRun() { 113 | // Replace a few nodes in the splay tree. 114 | for (var i = 0; i < kSplayTreeModifications; i++) { 115 | var key = InsertNewNode(); 116 | var greatest = splayTree.findGreatestLessThan(key); 117 | if (greatest == null) splayTree.remove(key); 118 | else splayTree.remove(greatest.key); 119 | } 120 | } 121 | 122 | 123 | /** 124 | * Constructs a Splay tree. A splay tree is a self-balancing binary 125 | * search tree with the additional property that recently accessed 126 | * elements are quick to access again. It performs basic operations 127 | * such as insertion, look-up and removal in O(log(n)) amortized time. 128 | * 129 | * @constructor 130 | */ 131 | function SplayTree() { 132 | }; 133 | 134 | 135 | /** 136 | * Pointer to the root node of the tree. 137 | * 138 | * @type {SplayTree.Node} 139 | * @private 140 | */ 141 | SplayTree.prototype.root_ = null; 142 | 143 | 144 | /** 145 | * @return {boolean} Whether the tree is empty. 146 | */ 147 | SplayTree.prototype.isEmpty = function() { 148 | return !this.root_; 149 | }; 150 | 151 | 152 | /** 153 | * Inserts a node into the tree with the specified key and value if 154 | * the tree does not already contain a node with the specified key. If 155 | * the value is inserted, it becomes the root of the tree. 156 | * 157 | * @param {number} key Key to insert into the tree. 158 | * @param {*} value Value to insert into the tree. 159 | */ 160 | SplayTree.prototype.insert = function(key, value) { 161 | if (this.isEmpty()) { 162 | this.root_ = new SplayTree.Node(key, value); 163 | return; 164 | } 165 | // Splay on the key to move the last node on the search path for 166 | // the key to the root of the tree. 167 | this.splay_(key); 168 | if (this.root_.key == key) { 169 | return; 170 | } 171 | var node = new SplayTree.Node(key, value); 172 | if (key > this.root_.key) { 173 | node.left = this.root_; 174 | node.right = this.root_.right; 175 | this.root_.right = null; 176 | } else { 177 | node.right = this.root_; 178 | node.left = this.root_.left; 179 | this.root_.left = null; 180 | } 181 | this.root_ = node; 182 | }; 183 | 184 | 185 | /** 186 | * Removes a node with the specified key from the tree if the tree 187 | * contains a node with this key. The removed node is returned. If the 188 | * key is not found, an exception is thrown. 189 | * 190 | * @param {number} key Key to find and remove from the tree. 191 | * @return {SplayTree.Node} The removed node. 192 | */ 193 | SplayTree.prototype.remove = function(key) { 194 | if (this.isEmpty()) { 195 | throw Error('Key not found: ' + key); 196 | } 197 | this.splay_(key); 198 | if (this.root_.key != key) { 199 | throw Error('Key not found: ' + key); 200 | } 201 | var removed = this.root_; 202 | if (!this.root_.left) { 203 | this.root_ = this.root_.right; 204 | } else { 205 | var right = this.root_.right; 206 | this.root_ = this.root_.left; 207 | // Splay to make sure that the new root has an empty right child. 208 | this.splay_(key); 209 | // Insert the original right child as the right child of the new 210 | // root. 211 | this.root_.right = right; 212 | } 213 | return removed; 214 | }; 215 | 216 | 217 | /** 218 | * Returns the node having the specified key or null if the tree doesn't contain 219 | * a node with the specified key. 220 | * 221 | * @param {number} key Key to find in the tree. 222 | * @return {SplayTree.Node} Node having the specified key. 223 | */ 224 | SplayTree.prototype.find = function(key) { 225 | if (this.isEmpty()) { 226 | return null; 227 | } 228 | this.splay_(key); 229 | return this.root_.key == key ? this.root_ : null; 230 | }; 231 | 232 | 233 | /** 234 | * @return {SplayTree.Node} Node having the maximum key value. 235 | */ 236 | SplayTree.prototype.findMax = function(opt_startNode) { 237 | if (this.isEmpty()) { 238 | return null; 239 | } 240 | var current = opt_startNode || this.root_; 241 | while (current.right) { 242 | current = current.right; 243 | } 244 | return current; 245 | }; 246 | 247 | 248 | /** 249 | * @return {SplayTree.Node} Node having the maximum key value that 250 | * is less than the specified key value. 251 | */ 252 | SplayTree.prototype.findGreatestLessThan = function(key) { 253 | if (this.isEmpty()) { 254 | return null; 255 | } 256 | // Splay on the key to move the node with the given key or the last 257 | // node on the search path to the top of the tree. 258 | this.splay_(key); 259 | // Now the result is either the root node or the greatest node in 260 | // the left subtree. 261 | if (this.root_.key < key) { 262 | return this.root_; 263 | } else if (this.root_.left) { 264 | return this.findMax(this.root_.left); 265 | } else { 266 | return null; 267 | } 268 | }; 269 | 270 | 271 | /** 272 | * @return {Array<*>} An array containing all the keys of tree's nodes. 273 | */ 274 | SplayTree.prototype.exportKeys = function() { 275 | var result = []; 276 | if (!this.isEmpty()) { 277 | this.root_.traverse_(function(node) { result.push(node.key); }); 278 | } 279 | return result; 280 | }; 281 | 282 | 283 | /** 284 | * Perform the splay operation for the given key. Moves the node with 285 | * the given key to the top of the tree. If no node has the given 286 | * key, the last node on the search path is moved to the top of the 287 | * tree. This is the simplified top-down splaying algorithm from: 288 | * "Self-adjusting Binary Search Trees" by Sleator and Tarjan 289 | * 290 | * @param {number} key Key to splay the tree on. 291 | * @private 292 | */ 293 | SplayTree.prototype.splay_ = function(key) { 294 | if (this.isEmpty()) { 295 | return; 296 | } 297 | // Create a dummy node. The use of the dummy node is a bit 298 | // counter-intuitive: The right child of the dummy node will hold 299 | // the L tree of the algorithm. The left child of the dummy node 300 | // will hold the R tree of the algorithm. Using a dummy node, left 301 | // and right will always be nodes and we avoid special cases. 302 | var dummy, left, right; 303 | dummy = left = right = new SplayTree.Node(null, null); 304 | var current = this.root_; 305 | while (true) { 306 | if (key < current.key) { 307 | if (!current.left) { 308 | break; 309 | } 310 | if (key < current.left.key) { 311 | // Rotate right. 312 | var tmp = current.left; 313 | current.left = tmp.right; 314 | tmp.right = current; 315 | current = tmp; 316 | if (!current.left) { 317 | break; 318 | } 319 | } 320 | // Link right. 321 | right.left = current; 322 | right = current; 323 | current = current.left; 324 | } else if (key > current.key) { 325 | if (!current.right) { 326 | break; 327 | } 328 | if (key > current.right.key) { 329 | // Rotate left. 330 | var tmp = current.right; 331 | current.right = tmp.left; 332 | tmp.left = current; 333 | current = tmp; 334 | if (!current.right) { 335 | break; 336 | } 337 | } 338 | // Link left. 339 | left.right = current; 340 | left = current; 341 | current = current.right; 342 | } else { 343 | break; 344 | } 345 | } 346 | // Assemble. 347 | left.right = current.left; 348 | right.left = current.right; 349 | current.left = dummy.right; 350 | current.right = dummy.left; 351 | this.root_ = current; 352 | }; 353 | 354 | 355 | /** 356 | * Constructs a Splay tree node. 357 | * 358 | * @param {number} key Key. 359 | * @param {*} value Value. 360 | */ 361 | SplayTree.Node = function(key, value) { 362 | this.key = key; 363 | this.value = value; 364 | }; 365 | 366 | 367 | /** 368 | * @type {SplayTree.Node} 369 | */ 370 | SplayTree.Node.prototype.left = null; 371 | 372 | 373 | /** 374 | * @type {SplayTree.Node} 375 | */ 376 | SplayTree.Node.prototype.right = null; 377 | 378 | 379 | /** 380 | * Performs an ordered traversal of the subtree starting at 381 | * this SplayTree.Node. 382 | * 383 | * @param {function(SplayTree.Node)} f Visitor function. 384 | * @private 385 | */ 386 | SplayTree.Node.prototype.traverse_ = function(f) { 387 | var current = this; 388 | while (current) { 389 | var left = current.left; 390 | if (left) left.traverse_(f); 391 | f(current); 392 | current = current.right; 393 | } 394 | }; 395 | -------------------------------------------------------------------------------- /benchmark/v8 run.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | V8 Benchmark Suite 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 91 | 92 | 93 |
94 |

V8 Benchmark Suite - version ?

95 |
96 | Warning! This is not the latest version of the V8 benchmark 97 | suite. Consider running the 98 | 99 | latest version. 100 |
101 | 102 | 103 |
104 | This page contains a suite of pure JavaScript benchmarks that we have 105 | used to tune V8. The final score is computed as the geometric mean of 106 | the individual results to make it independent of the running times of 107 | the individual benchmarks and of a reference system (score 108 | 100). Scores are not comparable across benchmark suite versions and 109 | higher scores means better performance: Bigger is better! 110 | 111 |
    112 |
  • Richards
    OS kernel simulation benchmark, originally written in BCPL by Martin Richards (539 lines).
  • 113 |
  • DeltaBlue
    One-way constraint solver, originally written in Smalltalk by John Maloney and Mario Wolczko (880 lines).
  • 114 |
  • Crypto
    Encryption and decryption benchmark based on code by Tom Wu (1698 lines).
  • 115 |
  • RayTrace
    Ray tracer benchmark based on code by Adam Burmister (904 lines).
  • 116 |
  • EarleyBoyer
    Classic Scheme benchmarks, translated to JavaScript by Florian Loitsch's Scheme2Js compiler (4684 lines).
  • 117 |
  • RegExp
    Regular expression benchmark generated by extracting regular expression operations from 50 of the most popular web pages 118 | (1761 lines). 119 |
  • 120 |
  • Splay
    Data manipulation benchmark that deals with splay trees and exercises the automatic memory management subsystem (394 lines).
  • 121 |
122 | 123 |

124 | Note that benchmark results are not comparable unless both results are 125 | run with the same revision of the benchmark suite. We will be making 126 | revisions from time to time in order to fix bugs or expand the scope 127 | of the benchmark suite. For previous revisions and the change log see 128 | the revisions page. 129 |

130 | 131 |
132 |
133 |
Starting...
134 |
135 |
136 |
137 |
138 | 139 |
140 | 141 | 142 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | ; Simple build script that just calls dub for each sub-package 2 | set BUILD=release 3 | dub build --build=%BUILD% dmdscript:engine 4 | dub build --build=%BUILD% dmdscript:ds 5 | dub build --build=%BUILD% dmdscript:ds-ext 6 | copy ds\dmdscript_ds.exe dmdscript.exe 7 | copy ds-ext\dmdscript_ds-ext.exe dmdscript-ext.exe -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | BUILD=release # debug 3 | for t in dmdscript:engine dmdscript:ds dmdscript:ds-ext 4 | do 5 | dub build --build=$BUILD $t || exit 1 6 | done 7 | # copy 2 sample binaries to the root folder 8 | cp ds/dmdscript_ds ./dmdscript 9 | cp ds-ext/dmdscript_ds-ext ./dmdscript-ext 10 | -------------------------------------------------------------------------------- /ds-ext/dub.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ds-ext", 3 | "description": "DMDScript example of extending an interpreter", 4 | "copyright": "Copyright (c) 2000-2002 by Chromium Communications, Copyright (c) 2004-2010 by Digital Mars", 5 | "authors": ["Walter Bright", "Dmitry Olshansky"], 6 | "dependencies": { 7 | "dmdscript:engine" : "*" 8 | }, 9 | "targetType": "executable", 10 | "license": "BSL-1.0", 11 | } 12 | -------------------------------------------------------------------------------- /ds-ext/source/ext.d: -------------------------------------------------------------------------------- 1 | import dmdscript.program; 2 | import dmdscript.script; 3 | import dmdscript.extending; 4 | 5 | import std.file; 6 | import std.stdio; 7 | import std.typecons; 8 | 9 | int func(int a,int b){ return a*b; } 10 | 11 | struct A{ 12 | int magic; 13 | this(int m){ magic = m; } 14 | void f(string a){ 15 | writeln(magic,":",a); 16 | } 17 | } 18 | 19 | 20 | void main(){ 21 | Program p = new Program; 22 | extendGlobal!func(p,"mul"); 23 | auto src = cast(string)std.file.read("ext.ds"); 24 | void function(string) fn = &A.f; 25 | Wrap!(A,"A").methods!(A.f)(); 26 | 27 | p.compile("TestExtending",src,null); 28 | p.execute(null); 29 | } 30 | -------------------------------------------------------------------------------- /ds/dub.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ds", 3 | "description": "DMDScript stand-alone interpreter sample program", 4 | "copyright": "Copyright (c) 2000-2002 by Chromium Communications, Copyright (c) 2004-2010 by Digital Mars", 5 | "authors": ["Walter Bright", "Dmitry Olshansky"], 6 | "dependencies": { 7 | "dmdscript:engine" : "*" 8 | }, 9 | "targetType": "executable", 10 | "license": "BSL-1.0", 11 | } 12 | -------------------------------------------------------------------------------- /ds/source/testscript.d: -------------------------------------------------------------------------------- 1 | /* Digital Mars DMDScript source code. 2 | * Copyright (c) 2000-2002 by Chromium Communications 3 | * D version Copyright (c) 2004-2010 by Digital Mars 4 | * Distributed under the Boost Software License, Version 1.0. 5 | * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | * written by Walter Bright 7 | * http://www.digitalmars.com 8 | * 9 | * D2 port by Dmitry Olshansky 10 | * 11 | * DMDScript is implemented in the D Programming Language, 12 | * http://www.digitalmars.com/d/ 13 | * 14 | * For a C++ implementation of DMDScript, including COM support, see 15 | * http://www.digitalmars.com/dscript/cppscript.html 16 | */ 17 | 18 | module testscript; 19 | 20 | import std.path; 21 | import std.file; 22 | import std.stdio; 23 | import std.exception; 24 | import core.stdc.stdlib; 25 | import core.memory; 26 | 27 | import dmdscript.script; 28 | import dmdscript.program; 29 | import dmdscript.errmsgs; 30 | 31 | enum 32 | { 33 | EXITCODE_INIT_ERROR = 1, 34 | EXITCODE_INVALID_ARGS = 2, 35 | EXITCODE_RUNTIME_ERROR = 3, 36 | } 37 | //Ehm, well, this fools VisualD, and of little convinience anyway 38 | /*version (Windows) 39 | { 40 | pragma(lib, "dmdscript"); 41 | }*/ 42 | 43 | 44 | 45 | /************************************************** 46 | Usage: 47 | 48 | ds 49 | will run test.ds 50 | 51 | ds foo 52 | will run foo.ds 53 | 54 | ds foo.js 55 | will run foo.js 56 | 57 | ds foo1 foo2 foo.bar 58 | will run foo1.ds, foo2.ds, foo.bar 59 | 60 | The -iinc flag will prefix the source files with the contents of file inc. 61 | There can be multiple -i's. The include list is reset to empty any time 62 | a new -i is encountered that is not preceded by a -i. 63 | 64 | ds -iinc foo 65 | will prefix foo.ds with inc 66 | 67 | ds -iinc1 -iinc2 foo bar 68 | will prefix foo.ds with inc1+inc2, and will prefix bar.ds 69 | with inc1+inc2 70 | 71 | ds -iinc1 -iinc2 foo -iinc3 bar 72 | will prefix foo.ds with inc1+inc2, and will prefix bar.ds 73 | with inc3 74 | 75 | ds -iinc1 -iinc2 foo -i bar 76 | will prefix foo.ds with inc1+inc2, and will prefix bar.ds 77 | with nothing 78 | 79 | */ 80 | 81 | int main(string[] args) 82 | { 83 | uint errors = 0; 84 | string[] includes; 85 | SrcFile[] srcfiles; 86 | int result; 87 | bool verbose; 88 | ErrInfo errinfo; 89 | //GC.disable(); 90 | if(args.length == 1) 91 | stderr.writefln(dmdscript.script.banner()); 92 | for (size_t i = 1; i < args.length; i++) 93 | { string p = args[i]; 94 | 95 | if (p[0] == '-') 96 | { 97 | switch (p[1]) 98 | { 99 | case 'i': 100 | if (p[2]) 101 | includes ~= p[2 .. $]; 102 | break; 103 | 104 | case 'v': 105 | verbose = 1; 106 | break; 107 | 108 | default: 109 | writefln(errmsgtbl[ERR_BAD_SWITCH],p); 110 | errors++; 111 | break; 112 | } 113 | } 114 | else 115 | { 116 | srcfiles ~= new SrcFile(p, includes); 117 | includes = null; 118 | } 119 | } 120 | if (errors) 121 | return EXITCODE_INVALID_ARGS; 122 | 123 | if (srcfiles.length == 0) 124 | { 125 | srcfiles ~= new SrcFile("test", null); 126 | } 127 | 128 | stderr.writefln("%d source files", srcfiles.length); 129 | 130 | // Read files, parse them, execute them 131 | foreach (SrcFile m; srcfiles) 132 | { 133 | if (verbose) 134 | writefln("read %s:", m.srcfile); 135 | m.read(); 136 | if (verbose) 137 | writefln("compile %s:", m.srcfile); 138 | m.compile(); 139 | if (verbose) 140 | writefln("execute %s:", m.srcfile); 141 | m.execute(); 142 | } 143 | return EXIT_SUCCESS; 144 | } 145 | 146 | 147 | class SrcFile 148 | { 149 | string srcfile; 150 | string[] includes; 151 | 152 | Program program; 153 | tchar[] buffer; 154 | 155 | this(string srcfilename, string[] includes) 156 | { 157 | /* DMDScript source files default to a '.ds' extension 158 | */ 159 | 160 | srcfile = defaultExtension(srcfilename, "ds"); 161 | this.includes = includes; 162 | } 163 | 164 | void read() 165 | { 166 | /* Read the source file, prepend the include files, 167 | * and put it all in buffer[]. Allocate an extra byte 168 | * to buffer[] and terminate it with a 0x1A. 169 | * (If the 0x1A isn't at the end, the lexer will put 170 | * one there, forcing an extra copy to be made of the 171 | * source text.) 172 | */ 173 | 174 | //writef("read file '%s'\n",srcfile); 175 | 176 | // Read the includes[] files 177 | size_t i; 178 | void[] buf; 179 | ulong len; 180 | 181 | len = std.file.getSize(srcfile); 182 | foreach (string filename; includes) 183 | { 184 | len += std.file.getSize(filename); 185 | } 186 | len++; // leave room for sentinal 187 | 188 | assert(len < uint.max); 189 | 190 | // Prefix the includes[] files 191 | 192 | int sz = cast(int)len; 193 | buffer = new tchar[sz]; 194 | 195 | foreach (string filename; includes) 196 | { 197 | buf = std.file.read(filename); 198 | buffer[i .. i + buf.length] = cast(string)buf[]; 199 | i += buf.length; 200 | } 201 | 202 | buf = std.file.read(srcfile); 203 | buffer[i .. i + buf.length] = cast(string)buf[]; 204 | i += buf.length; 205 | 206 | buffer[i] = 0x1A; // ending sentinal 207 | i++; 208 | assert(i == len); 209 | } 210 | 211 | void compile() 212 | { 213 | /* Create a DMDScript program, and compile our text buffer. 214 | */ 215 | 216 | program = new Program(); 217 | program.compile(srcfile, assumeUnique(buffer), null); 218 | } 219 | 220 | void execute() 221 | { 222 | /* Execute the resulting program. 223 | */ 224 | 225 | program.execute(null); 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /dub.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dmdscript", 3 | "description": "An implementation of the ECMA 262 (Javascript) programming language ", 4 | "copyright": "Copyright (c) 2000-2002 by Chromium Communications, Copyright (c) 2004-2010 by Digital Mars", 5 | "authors": ["Walter Bright", "Dmitry Olshansky"], 6 | "dependencies": { 7 | "dmdscript:engine" : "*", 8 | "dmdscript:ds" : "*", 9 | "dmdscript:ds-ext": "*" 10 | }, 11 | 12 | "targetType": "none", 13 | "subPackages" : [ 14 | "./ds", "./ds-ext", "./engine" 15 | ], 16 | "license": "BSL-1.0", 17 | } 18 | -------------------------------------------------------------------------------- /engine/dub.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "engine", 3 | "description": "DMDScript interpreter library", 4 | "copyright": "Copyright (c) 2000-2002 by Chromium Communications, Copyright (c) 2004-2010 by Digital Mars", 5 | "authors": ["Walter Bright", "Dmitry Olshansky"], 6 | "dependencies": { 7 | "undead" : ">=1.0.3" 8 | }, 9 | "targetType": "library", 10 | "license": "BSL-1.0", 11 | } 12 | -------------------------------------------------------------------------------- /engine/source/dmdscript/darguments.d: -------------------------------------------------------------------------------- 1 | /* Digital Mars DMDScript source code. 2 | * Copyright (c) 2000-2002 by Chromium Communications 3 | * D version Copyright (c) 2004-2010 by Digital Mars 4 | * Distributed under the Boost Software License, Version 1.0. 5 | * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | * written by Walter Bright 7 | * http://www.digitalmars.com 8 | * 9 | * D2 port by Dmitry Olshansky 10 | * 11 | * DMDScript is implemented in the D Programming Language, 12 | * http://www.digitalmars.com/d/ 13 | * 14 | * For a C++ implementation of DMDScript, including COM support, see 15 | * http://www.digitalmars.com/dscript/cppscript.html 16 | */ 17 | 18 | 19 | module dmdscript.darguments; 20 | 21 | import dmdscript.script; 22 | import dmdscript.dobject; 23 | import dmdscript.identifier; 24 | import dmdscript.value; 25 | import dmdscript.text; 26 | import dmdscript.property; 27 | 28 | // The purpose of Darguments is to implement "value sharing" 29 | // per ECMA 10.1.8 between the activation object and the 30 | // arguments object. 31 | // We implement it by forwarding the property calls from the 32 | // arguments object to the activation object. 33 | 34 | class Darguments : Dobject 35 | { 36 | Dobject actobj; // activation object 37 | Identifier*[] parameters; 38 | 39 | override int isDarguments() const 40 | { 41 | return true; 42 | } 43 | 44 | this(CallContext* cc, Dobject caller, Dobject callee, Dobject actobj, 45 | Identifier *[] parameters, Value[] arglist) 46 | 47 | { 48 | super(cc, Dobject.getPrototype(cc)); 49 | 50 | this.actobj = actobj; 51 | this.parameters = parameters; 52 | 53 | if(caller) 54 | Put(cc, TEXT_caller, caller, DontEnum); 55 | else 56 | Put(cc, TEXT_caller, &vnull, DontEnum); 57 | 58 | Put(cc, TEXT_callee, callee, DontEnum); 59 | Put(cc, TEXT_length, arglist.length, DontEnum); 60 | 61 | for(uint a = 0; a < arglist.length; a++) 62 | { 63 | Put(cc, a, &arglist[a], DontEnum); 64 | } 65 | } 66 | 67 | override Value* Get(d_string PropertyName) 68 | { 69 | d_uint32 index; 70 | 71 | return (StringToIndex(PropertyName, index) && index < parameters.length) 72 | ? actobj.Get(index) 73 | : Dobject.Get(PropertyName); 74 | } 75 | 76 | override Value* Get(d_uint32 index) 77 | { 78 | return (index < parameters.length) 79 | ? actobj.Get(index) 80 | : Dobject.Get(index); 81 | } 82 | 83 | override Value* Get(d_uint32 index, Value* vindex) 84 | { 85 | return (index < parameters.length) 86 | ? actobj.Get(index, vindex) 87 | : Dobject.Get(index, vindex); 88 | } 89 | 90 | override Value* Put(CallContext* cc, string PropertyName, Value* value, uint attributes) 91 | { 92 | d_uint32 index; 93 | 94 | if(StringToIndex(PropertyName, index) && index < parameters.length) 95 | return actobj.Put(cc, PropertyName, value, attributes); 96 | else 97 | return Dobject.Put(cc, PropertyName, value, attributes); 98 | } 99 | 100 | override Value* Put(CallContext* cc, Identifier* key, Value* value, uint attributes) 101 | { 102 | d_uint32 index; 103 | 104 | if(StringToIndex(key.value.string, index) && index < parameters.length) 105 | return actobj.Put(cc, key, value, attributes); 106 | else 107 | return Dobject.Put(cc, key, value, attributes); 108 | } 109 | 110 | override Value* Put(CallContext* cc, string PropertyName, Dobject o, uint attributes) 111 | { 112 | d_uint32 index; 113 | 114 | if(StringToIndex(PropertyName, index) && index < parameters.length) 115 | return actobj.Put(cc, PropertyName, o, attributes); 116 | else 117 | return Dobject.Put(cc, PropertyName, o, attributes); 118 | } 119 | 120 | override Value* Put(CallContext* cc, string PropertyName, d_number n, uint attributes) 121 | { 122 | d_uint32 index; 123 | 124 | if(StringToIndex(PropertyName, index) && index < parameters.length) 125 | return actobj.Put(cc, PropertyName, n, attributes); 126 | else 127 | return Dobject.Put(cc, PropertyName, n, attributes); 128 | } 129 | 130 | override Value* Put(CallContext* cc, d_uint32 index, Value* vindex, Value* value, uint attributes) 131 | { 132 | if(index < parameters.length) 133 | return actobj.Put(cc, index, vindex, value, attributes); 134 | else 135 | return Dobject.Put(cc, index, vindex, value, attributes); 136 | } 137 | 138 | override Value* Put(CallContext* cc, d_uint32 index, Value* value, uint attributes) 139 | { 140 | if(index < parameters.length) 141 | return actobj.Put(cc, index, value, attributes); 142 | else 143 | return Dobject.Put(cc, index, value, attributes); 144 | } 145 | 146 | override int CanPut(d_string PropertyName) 147 | { 148 | d_uint32 index; 149 | 150 | return (StringToIndex(PropertyName, index) && index < parameters.length) 151 | ? actobj.CanPut(PropertyName) 152 | : Dobject.CanPut(PropertyName); 153 | } 154 | 155 | override int HasProperty(d_string PropertyName) 156 | { 157 | d_uint32 index; 158 | 159 | return (StringToIndex(PropertyName, index) && index < parameters.length) 160 | ? actobj.HasProperty(PropertyName) 161 | : Dobject.HasProperty(PropertyName); 162 | } 163 | 164 | override int Delete(d_string PropertyName) 165 | { 166 | d_uint32 index; 167 | 168 | return (StringToIndex(PropertyName, index) && index < parameters.length) 169 | ? actobj.Delete(PropertyName) 170 | : Dobject.Delete(PropertyName); 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /engine/source/dmdscript/dboolean.d: -------------------------------------------------------------------------------- 1 | /* Digital Mars DMDScript source code. 2 | * Copyright (c) 2000-2002 by Chromium Communications 3 | * D version Copyright (c) 2004-2010 by Digital Mars 4 | * Distributed under the Boost Software License, Version 1.0. 5 | * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | * written by Walter Bright 7 | * http://www.digitalmars.com 8 | * 9 | * D2 port by Dmitry Olshansky 10 | * 11 | * DMDScript is implemented in the D Programming Language, 12 | * http://www.digitalmars.com/d/ 13 | * 14 | * For a C++ implementation of DMDScript, including COM support, see 15 | * http://www.digitalmars.com/dscript/cppscript.html 16 | */ 17 | 18 | module dmdscript.dboolean; 19 | 20 | import dmdscript.script; 21 | import dmdscript.dobject; 22 | import dmdscript.value; 23 | import dmdscript.threadcontext; 24 | import dmdscript.dfunction; 25 | import dmdscript.text; 26 | import dmdscript.property; 27 | import dmdscript.errmsgs; 28 | import dmdscript.dnative; 29 | 30 | /* ===================== Dboolean_constructor ==================== */ 31 | 32 | class DbooleanConstructor : Dfunction 33 | { 34 | this(CallContext* cc) 35 | { 36 | super(cc, 1, cc.tc.Dfunction_prototype); 37 | name = "Boolean"; 38 | } 39 | 40 | override void *Construct(CallContext *cc, Value *ret, Value[] arglist) 41 | { 42 | // ECMA 15.6.2 43 | d_boolean b; 44 | Dobject o; 45 | 46 | b = (arglist.length) ? arglist[0].toBoolean(cc) : false; 47 | o = new Dboolean(cc, b); 48 | ret.putVobject(o); 49 | return null; 50 | } 51 | 52 | override void *Call(CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 53 | { 54 | // ECMA 15.6.1 55 | d_boolean b; 56 | 57 | b = (arglist.length) ? arglist[0].toBoolean(cc) : false; 58 | ret.putVboolean(b); 59 | return null; 60 | } 61 | } 62 | 63 | 64 | /* ===================== Dboolean_prototype_toString =============== */ 65 | 66 | void* Dboolean_prototype_toString(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) 67 | { 68 | // othis must be a Boolean 69 | if(!othis.isClass(TEXT_Boolean)) 70 | { 71 | ErrInfo errinfo; 72 | 73 | ret.putVundefined(); 74 | return Dobject.RuntimeError(&errinfo, cc, errmsgtbl[ERR_FUNCTION_WANTS_BOOL], 75 | TEXT_toString, 76 | othis.classname); 77 | } 78 | else 79 | { 80 | Value *v; 81 | 82 | v = &(cast(Dboolean)othis).value; 83 | ret.putVstring(v.toString(cc)); 84 | } 85 | return null; 86 | } 87 | 88 | /* ===================== Dboolean_prototype_valueOf =============== */ 89 | 90 | void* Dboolean_prototype_valueOf(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) 91 | { 92 | //FuncLog f("Boolean.prototype.valueOf()"); 93 | //logflag = 1; 94 | 95 | // othis must be a Boolean 96 | if(!othis.isClass(TEXT_Boolean)) 97 | { 98 | ErrInfo errinfo; 99 | 100 | ret.putVundefined(); 101 | return Dobject.RuntimeError(&errinfo, cc, errmsgtbl[ERR_FUNCTION_WANTS_BOOL], 102 | TEXT_valueOf, 103 | othis.classname); 104 | } 105 | else 106 | { 107 | Value *v; 108 | 109 | v = &(cast(Dboolean)othis).value; 110 | Value.copy(ret, v); 111 | } 112 | return null; 113 | } 114 | 115 | /* ===================== Dboolean_prototype ==================== */ 116 | 117 | class DbooleanPrototype : Dboolean 118 | { 119 | this(CallContext* cc) 120 | { 121 | super(cc, cc.tc.Dobject_prototype); 122 | //Dobject f = Dfunction_prototype; 123 | 124 | Put(cc, TEXT_constructor, cc.tc.Dboolean_constructor, DontEnum); 125 | 126 | static enum NativeFunctionData[] nfd = 127 | [ 128 | { TEXT_toString, &Dboolean_prototype_toString, 0 }, 129 | { TEXT_valueOf, &Dboolean_prototype_valueOf, 0 }, 130 | ]; 131 | 132 | DnativeFunction.initialize(this, cc, nfd, DontEnum); 133 | } 134 | } 135 | 136 | 137 | /* ===================== Dboolean ==================== */ 138 | 139 | class Dboolean : Dobject 140 | { 141 | this(CallContext* cc, d_boolean b) 142 | { 143 | super(cc, Dboolean.getPrototype(cc)); 144 | value.putVboolean(b); 145 | classname = TEXT_Boolean; 146 | } 147 | 148 | this(CallContext* cc, Dobject prototype) 149 | { 150 | super(cc, prototype); 151 | value.putVboolean(false); 152 | classname = TEXT_Boolean; 153 | } 154 | 155 | static Dfunction getConstructor(CallContext* cc) 156 | { 157 | return cc.tc.Dboolean_constructor; 158 | } 159 | 160 | static Dobject getPrototype(CallContext* cc) 161 | { 162 | return cc.tc.Dboolean_prototype; 163 | } 164 | 165 | static void initialize(CallContext* cc) 166 | { 167 | cc.tc.Dboolean_constructor = new DbooleanConstructor(cc); 168 | cc.tc.Dboolean_prototype = new DbooleanPrototype(cc); 169 | 170 | cc.tc.Dboolean_constructor.Put(cc, TEXT_prototype, cc.tc.Dboolean_prototype, DontEnum | DontDelete | ReadOnly); 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /engine/source/dmdscript/ddeclaredfunction.d: -------------------------------------------------------------------------------- 1 | /* Digital Mars DMDScript source code. 2 | * Copyright (c) 2000-2002 by Chromium Communications 3 | * D version Copyright (c) 2004-2010 by Digital Mars 4 | * Distributed under the Boost Software License, Version 1.0. 5 | * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | * written by Walter Bright 7 | * http://www.digitalmars.com 8 | * 9 | * D2 port by Dmitry Olshansky 10 | * 11 | * DMDScript is implemented in the D Programming Language, 12 | * http://www.digitalmars.com/d/ 13 | * 14 | * For a C++ implementation of DMDScript, including COM support, see 15 | * http://www.digitalmars.com/dscript/cppscript.html 16 | */ 17 | 18 | module dmdscript.ddeclaredfunction; 19 | 20 | import std.stdio; 21 | import core.stdc.stdlib; 22 | import std.exception; 23 | import dmdscript.script; 24 | import dmdscript.dobject; 25 | import dmdscript.dfunction; 26 | import dmdscript.darguments; 27 | import dmdscript.opcodes; 28 | import dmdscript.ir; 29 | import dmdscript.identifier; 30 | import dmdscript.value; 31 | import dmdscript.functiondefinition; 32 | import dmdscript.text; 33 | import dmdscript.property; 34 | 35 | /* ========================== DdeclaredFunction ================== */ 36 | 37 | class DdeclaredFunction : Dfunction 38 | { 39 | FunctionDefinition fd; 40 | 41 | this(CallContext* cc, FunctionDefinition fd) 42 | { 43 | super(cc, cast(uint)fd.parameters.length, Dfunction.getPrototype(cc)); 44 | assert(Dfunction.getPrototype(cc)); 45 | assert(internal_prototype); 46 | this.fd = fd; 47 | 48 | Dobject o; 49 | 50 | // ECMA 3 13.2 51 | o = new Dobject(cc, Dobject.getPrototype(cc)); // step 9 52 | Put(cc, TEXT_prototype, o, DontEnum); // step 11 53 | o.Put(cc, TEXT_constructor, this, DontEnum); // step 10 54 | } 55 | 56 | override void *Call(CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 57 | { 58 | // 1. Create activation object per ECMA 10.1.6 59 | // 2. Instantiate function variables as properties of 60 | // activation object 61 | // 3. The 'this' value is the activation object 62 | 63 | Dobject actobj; // activation object 64 | Darguments args; 65 | Value[] locals; 66 | uint i; 67 | void *result; 68 | 69 | //writefln("DdeclaredFunction.Call() '%s'", toString()); 70 | //writefln("this.scopex.length = %d", this.scopex.length); 71 | //writefln("\tinstantiate(this = %x, fd = %x)", cast(uint)cast(void*)this, cast(uint)cast(void*)fd); 72 | 73 | // if it's an empty function, just return 74 | if(fd.code[0].opcode == IRret) 75 | { 76 | return null; 77 | } 78 | 79 | // Generate the activation object 80 | // ECMA v3 10.1.6 81 | actobj = new Dobject(cc, null); 82 | 83 | Value vtmp;//should not be referenced by the end of func 84 | if(fd.name){ 85 | vtmp.putVobject(this); 86 | actobj.Put(cc, fd.name,&vtmp,DontDelete); 87 | } 88 | // Instantiate the parameters 89 | { 90 | uint a = 0; 91 | foreach(Identifier* p; fd.parameters) 92 | { 93 | Value* v = (a < arglist.length) ? &arglist[a++] : &vundefined; 94 | actobj.Put(cc, p.toString(), v, DontDelete); 95 | } 96 | } 97 | 98 | // Generate the Arguments Object 99 | // ECMA v3 10.1.8 100 | args = new Darguments(cc, cc.caller, this, actobj, fd.parameters, arglist); 101 | 102 | actobj.Put(cc, TEXT_arguments, args, DontDelete); 103 | 104 | // The following is not specified by ECMA, but seems to be supported 105 | // by jscript. The url www.grannymail.com has the following code 106 | // which looks broken to me but works in jscript: 107 | // 108 | // function MakeArray() { 109 | // this.length = MakeArray.arguments.length 110 | // for (var i = 0; i < this.length; i++) 111 | // this[i+1] = arguments[i] 112 | // } 113 | // var cardpic = new MakeArray("LL","AP","BA","MB","FH","AW","CW","CV","DZ"); 114 | Put(cc, TEXT_arguments, args, DontDelete); // make grannymail bug work 115 | 116 | 117 | 118 | 119 | Dobject[] newScopex; 120 | newScopex = this.scopex.dup;//copy this function object scope chain 121 | assert(newScopex.length != 0); 122 | newScopex ~= actobj;//and put activation object on top of it 123 | 124 | fd.instantiate(cc, newScopex, actobj, DontDelete); 125 | 126 | Dobject[] scopesave = cc.scopex; 127 | cc.scopex = newScopex; 128 | auto scoperootsave = cc.scoperoot; 129 | cc.scoperoot++;//to accaunt extra activation object on scopex chain 130 | Dobject variablesave = cc.variable; 131 | cc.variable = actobj; 132 | auto callersave = cc.caller; 133 | cc.caller = this; 134 | auto callerfsave = cc.callerf; 135 | cc.callerf = fd; 136 | 137 | Value[] p1; 138 | Value* v; 139 | if(fd.nlocals < 128) 140 | v = cast(Value*)alloca(fd.nlocals * Value.sizeof); 141 | if(v) 142 | locals = v[0 .. fd.nlocals]; 143 | else 144 | { 145 | p1 = new Value[fd.nlocals]; 146 | locals = p1; 147 | } 148 | 149 | result = IR.call(cc, othis, fd.code, ret, locals.ptr); 150 | 151 | destroy(p1); 152 | 153 | cc.callerf = callerfsave; 154 | cc.caller = callersave; 155 | cc.variable = variablesave; 156 | cc.scopex = scopesave; 157 | cc.scoperoot = scoperootsave; 158 | 159 | // Remove the arguments object 160 | //Value* v; 161 | //v=Get(TEXT_arguments); 162 | //writef("1v = %x, %s, v.object = %x\n", v, v.getType(), v.object); 163 | Put(cc, TEXT_arguments, &vundefined, 0); 164 | //actobj.Put(TEXT_arguments, &vundefined, 0); 165 | 166 | version(none) 167 | { 168 | writef("args = %x, actobj = %x\n", args, actobj); 169 | v = Get(TEXT_arguments); 170 | writef("2v = %x, %s, v.object = %x\n", v, v.getType(), v.object); 171 | v.object = null; 172 | 173 | { 174 | uint *p = cast(uint *)0x40a49a80; 175 | uint i; 176 | for(i = 0; i < 16; i++) 177 | { 178 | writef("p[%x] = %x\n", &p[i], p[i]); 179 | } 180 | } 181 | } 182 | 183 | return result; 184 | } 185 | 186 | override void *Construct(CallContext *cc, Value *ret, Value[] arglist) 187 | { 188 | // ECMA 3 13.2.2 189 | Dobject othis; 190 | Dobject proto; 191 | Value* v; 192 | void *result; 193 | 194 | v = Get(TEXT_prototype); 195 | if(v.isPrimitive()) 196 | proto = Dobject.getPrototype(cc); 197 | else 198 | proto = v.toObject(cc); 199 | othis = new Dobject(cc, proto); 200 | result = Call(cc, othis, ret, arglist); 201 | if(!result) 202 | { 203 | if(ret.isPrimitive()) 204 | ret.putVobject(othis); 205 | } 206 | return result; 207 | } 208 | 209 | override string toString() 210 | { 211 | char[] s; 212 | 213 | //writef("DdeclaredFunction.toString()\n"); 214 | fd.toBuffer(s); 215 | return assumeUnique(s); 216 | } 217 | } 218 | 219 | 220 | -------------------------------------------------------------------------------- /engine/source/dmdscript/derror.d: -------------------------------------------------------------------------------- 1 | /* Digital Mars DMDScript source code. 2 | * Copyright (c) 2000-2002 by Chromium Communications 3 | * D version Copyright (c) 2004-2010 by Digital Mars 4 | * Distributed under the Boost Software License, Version 1.0. 5 | * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | * written by Walter Bright 7 | * http://www.digitalmars.com 8 | * 9 | * D2 port by Dmitry Olshansky 10 | * 11 | * DMDScript is implemented in the D Programming Language, 12 | * http://www.digitalmars.com/d/ 13 | * 14 | * For a C++ implementation of DMDScript, including COM support, see 15 | * http://www.digitalmars.com/dscript/cppscript.html 16 | */ 17 | 18 | module dmdscript.derror; 19 | 20 | import dmdscript.script; 21 | import dmdscript.dobject; 22 | import dmdscript.dfunction; 23 | import dmdscript.value; 24 | import dmdscript.threadcontext; 25 | import dmdscript.dnative; 26 | import dmdscript.text; 27 | import dmdscript.property; 28 | 29 | 30 | // Comes from MAKE_HRESULT(SEVERITY_ERROR, FACILITY_CONTROL, 0) 31 | const uint FACILITY = 0x800A0000; 32 | 33 | /* ===================== Derror_constructor ==================== */ 34 | 35 | class DerrorConstructor : Dfunction 36 | { 37 | this(CallContext* cc) 38 | { 39 | super(cc, 1, cc.tc.Dfunction_prototype); 40 | } 41 | 42 | override void* Construct(CallContext *cc, Value *ret, Value[] arglist) 43 | { 44 | // ECMA 15.7.2 45 | Dobject o; 46 | Value* m; 47 | Value* n; 48 | Value vemptystring; 49 | 50 | vemptystring.putVstring(null); 51 | switch(arglist.length) 52 | { 53 | case 0: // ECMA doesn't say what we do if m is undefined 54 | m = &vemptystring; 55 | n = &vundefined; 56 | break; 57 | case 1: 58 | m = &arglist[0]; 59 | if(m.isNumber()) 60 | { 61 | n = m; 62 | m = &vemptystring; 63 | } 64 | else 65 | n = &vundefined; 66 | break; 67 | default: 68 | m = &arglist[0]; 69 | n = &arglist[1]; 70 | break; 71 | } 72 | o = new Derror(cc, m, n); 73 | ret.putVobject(o); 74 | return null; 75 | } 76 | 77 | override void* Call(CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 78 | { 79 | // ECMA v3 15.11.1 80 | return Construct(cc, ret, arglist); 81 | } 82 | } 83 | 84 | 85 | /* ===================== Derror_prototype_toString =============== */ 86 | 87 | void* Derror_prototype_toString(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) 88 | { 89 | // ECMA v3 15.11.4.3 90 | // Return implementation defined string 91 | Value* v; 92 | 93 | //writef("Error.prototype.toString()\n"); 94 | v = othis.Get(TEXT_message); 95 | if(!v) 96 | v = &vundefined; 97 | ret.putVstring(othis.Get(TEXT_name).toString(cc)~": "~v.toString(cc)); 98 | return null; 99 | } 100 | 101 | /* ===================== Derror_prototype ==================== */ 102 | 103 | class DerrorPrototype : Derror 104 | { 105 | this(CallContext* cc) 106 | { 107 | super(cc, cc.tc.Dobject_prototype); 108 | Dobject f = cc.tc.Dfunction_prototype; 109 | //d_string m = d_string_ctor(DTEXT("Error.prototype.message")); 110 | 111 | Put(cc, TEXT_constructor, cc.tc.Derror_constructor, DontEnum); 112 | 113 | static enum NativeFunctionData[] nfd = 114 | [ 115 | { TEXT_toString, &Derror_prototype_toString, 0 }, 116 | ]; 117 | 118 | DnativeFunction.initialize(this, cc, nfd, 0); 119 | 120 | Put(cc, TEXT_name, TEXT_Error, 0); 121 | Put(cc, TEXT_message, TEXT_, 0); 122 | Put(cc, TEXT_description, TEXT_, 0); 123 | Put(cc, TEXT_number, cast(d_number)(/*FACILITY |*/ 0), 0); 124 | } 125 | } 126 | 127 | 128 | /* ===================== Derror ==================== */ 129 | 130 | class Derror : Dobject 131 | { 132 | this(CallContext* cc, Value * m, Value * v2) 133 | { 134 | super(cc, getPrototype(cc)); 135 | classname = TEXT_Error; 136 | 137 | immutable(char)[] msg; 138 | msg = m.toString(cc); 139 | Put(cc, TEXT_message, msg, 0); 140 | Put(cc, TEXT_description, msg, 0); 141 | if(m.isString()) 142 | { 143 | } 144 | else if(m.isNumber()) 145 | { 146 | d_number n = m.toNumber(cc); 147 | n = cast(d_number)(/*FACILITY |*/ cast(int)n); 148 | Put(cc, TEXT_number, n, 0); 149 | } 150 | if(v2.isString()) 151 | { 152 | Put(cc, TEXT_description, v2.toString(cc), 0); 153 | Put(cc, TEXT_message, v2.toString(cc), 0); 154 | } 155 | else if(v2.isNumber()) 156 | { 157 | d_number n = v2.toNumber(cc); 158 | n = cast(d_number)(/*FACILITY |*/ cast(int)n); 159 | Put(cc, TEXT_number, n, 0); 160 | } 161 | } 162 | 163 | this(CallContext* cc, Dobject prototype) 164 | { 165 | super(cc, prototype); 166 | classname = TEXT_Error; 167 | } 168 | 169 | static Dfunction getConstructor(CallContext* cc) 170 | { 171 | return cc.tc.Derror_constructor; 172 | } 173 | 174 | static Dobject getPrototype(CallContext* cc) 175 | { 176 | return cc.tc.Derror_prototype; 177 | } 178 | 179 | static void initialize(CallContext* cc) 180 | { 181 | cc.tc.Derror_constructor = new DerrorConstructor(cc); 182 | cc.tc.Derror_prototype = new DerrorPrototype(cc); 183 | 184 | cc.tc.Derror_constructor.Put(cc, TEXT_prototype, cc.tc.Derror_prototype, DontEnum | DontDelete | ReadOnly); 185 | } 186 | } 187 | 188 | -------------------------------------------------------------------------------- /engine/source/dmdscript/dfunction.d: -------------------------------------------------------------------------------- 1 | /* Digital Mars DMDScript source code. 2 | * Copyright (c) 2000-2002 by Chromium Communications 3 | * D version Copyright (c) 2004-2010 by Digital Mars 4 | * Distributed under the Boost Software License, Version 1.0. 5 | * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | * written by Walter Bright 7 | * http://www.digitalmars.com 8 | * 9 | * D2 port by Dmitry Olshansky 10 | * 11 | * DMDScript is implemented in the D Programming Language, 12 | * http://www.digitalmars.com/d/ 13 | * 14 | * For a C++ implementation of DMDScript, including COM support, see 15 | * http://www.digitalmars.com/dscript/cppscript.html 16 | */ 17 | 18 | 19 | module dmdscript.dfunction; 20 | 21 | import std.string; 22 | import core.stdc.stdlib; 23 | 24 | import dmdscript.script; 25 | import dmdscript.dobject; 26 | import dmdscript.value; 27 | import dmdscript.protoerror; 28 | import dmdscript.threadcontext; 29 | import dmdscript.text; 30 | import dmdscript.errmsgs; 31 | import dmdscript.property; 32 | import dmdscript.scopex; 33 | import dmdscript.dnative; 34 | import dmdscript.functiondefinition; 35 | import dmdscript.parse; 36 | import dmdscript.ddeclaredfunction; 37 | 38 | /* ===================== Dfunction_constructor ==================== */ 39 | 40 | class DfunctionConstructor : Dfunction 41 | { 42 | this(CallContext* cc) 43 | { 44 | super(cc, 1, cc.tc.Dfunction_prototype); 45 | 46 | // Actually put in later by Dfunction::initialize() 47 | //unsigned attributes = DontEnum | DontDelete | ReadOnly; 48 | //Put(TEXT_prototype, Dfunction::getPrototype(), attributes); 49 | } 50 | 51 | override void *Construct(CallContext *cc, Value *ret, Value[] arglist) 52 | { 53 | // ECMA 15.3.2.1 54 | immutable(char)[] bdy; 55 | immutable(char)[] P; 56 | FunctionDefinition fd; 57 | ErrInfo errinfo; 58 | 59 | //writef("Dfunction_constructor::Construct()\n"); 60 | 61 | // Get parameter list (P) and body from arglist[] 62 | if(arglist.length) 63 | { 64 | bdy = arglist[arglist.length - 1].toString(cc); 65 | if(arglist.length >= 2) 66 | { 67 | for(uint a = 0; a < arglist.length - 1; a++) 68 | { 69 | if(a) 70 | P ~= ','; 71 | P ~= arglist[a].toString(cc); 72 | } 73 | } 74 | } 75 | 76 | if(Parser.parseFunctionDefinition(fd, P, bdy, errinfo)) 77 | goto Lsyntaxerror; 78 | 79 | if(fd) 80 | { 81 | Scope sc; 82 | 83 | sc.ctor(fd); 84 | fd.semantic(&sc); 85 | errinfo = sc.errinfo; 86 | if(errinfo.message) 87 | goto Lsyntaxerror; 88 | fd.toIR(null); 89 | Dfunction fobj = new DdeclaredFunction(cc, fd); 90 | assert(cc.scoperoot <= cc.scopex.length); 91 | fobj.scopex = cc.scopex[0..cc.scoperoot].dup; 92 | ret.putVobject(fobj); 93 | } 94 | else 95 | ret.putVundefined(); 96 | 97 | return null; 98 | 99 | Lsyntaxerror: 100 | Dobject o; 101 | 102 | ret.putVundefined(); 103 | o = new syntaxerror.D0(cc, &errinfo); 104 | Value* v = new Value; 105 | v.putVobject(o); 106 | return v; 107 | } 108 | 109 | override void *Call(CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 110 | { 111 | // ECMA 15.3.1 112 | return Construct(cc, ret, arglist); 113 | } 114 | } 115 | 116 | 117 | /* ===================== Dfunction_prototype_toString =============== */ 118 | 119 | void* Dfunction_prototype_toString(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) 120 | { 121 | immutable(char)[] s; 122 | Dfunction f; 123 | 124 | //writef("function.prototype.toString()\n"); 125 | // othis must be a Function 126 | if(!othis.isClass(TEXT_Function)) 127 | { 128 | ErrInfo errinfo; 129 | ret.putVundefined(); 130 | return Dobject.RuntimeError(&errinfo, cc, ERR_TS_NOT_TRANSFERRABLE); 131 | } 132 | else 133 | { 134 | // Generate string that looks like a FunctionDeclaration 135 | // FunctionDeclaration: 136 | // function Identifier (Identifier, ...) Block 137 | 138 | // If anonymous function, the name should be "anonymous" 139 | // per ECMA 15.3.2.1.19 140 | 141 | f = cast(Dfunction)othis; 142 | s = f.toString(); 143 | ret.putVstring(s); 144 | } 145 | return null; 146 | } 147 | 148 | /* ===================== Dfunction_prototype_apply =============== */ 149 | 150 | void* Dfunction_prototype_apply(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) 151 | { 152 | // ECMA v3 15.3.4.3 153 | 154 | Value* thisArg; 155 | Value* argArray; 156 | Dobject o; 157 | void* v; 158 | 159 | thisArg = &vundefined; 160 | argArray = &vundefined; 161 | switch(arglist.length) 162 | { 163 | case 0: 164 | break; 165 | default: 166 | argArray = &arglist[1]; 167 | goto case; 168 | case 1: 169 | thisArg = &arglist[0]; 170 | break; 171 | } 172 | 173 | if(thisArg.isUndefinedOrNull()) 174 | o = cc.global; 175 | else 176 | o = thisArg.toObject(cc); 177 | 178 | if(argArray.isUndefinedOrNull()) 179 | { 180 | v = othis.Call(cc, o, ret, null); 181 | } 182 | else 183 | { 184 | if(argArray.isPrimitive()) 185 | { 186 | Ltypeerror: 187 | ret.putVundefined(); 188 | ErrInfo errinfo; 189 | return Dobject.RuntimeError(&errinfo, cc, ERR_ARRAY_ARGS); 190 | } 191 | Dobject a; 192 | 193 | a = argArray.toObject(cc); 194 | 195 | // Must be array or arguments object 196 | if(!a.isDarray() && !a.isDarguments()) 197 | goto Ltypeerror; 198 | 199 | uint len; 200 | uint i; 201 | Value[] alist; 202 | Value* x; 203 | 204 | x = a.Get(TEXT_length); 205 | len = x ? x.toUint32(cc) : 0; 206 | 207 | Value[] p1; 208 | Value* v1; 209 | if(len < 128) 210 | v1 = cast(Value*)alloca(len * Value.sizeof); 211 | if(v1) 212 | alist = v1[0 .. len]; 213 | else 214 | { 215 | p1 = new Value[len]; 216 | alist = p1; 217 | } 218 | 219 | for(i = 0; i < len; i++) 220 | { 221 | x = a.Get(i); 222 | Value.copy(&alist[i], x); 223 | } 224 | 225 | v = othis.Call(cc, o, ret, alist); 226 | 227 | destroy(p1); 228 | } 229 | return v; 230 | } 231 | 232 | /* ===================== Dfunction_prototype_call =============== */ 233 | 234 | void* Dfunction_prototype_call(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) 235 | { 236 | // ECMA v3 15.3.4.4 237 | Value* thisArg; 238 | Dobject o; 239 | void* v; 240 | 241 | if(arglist.length == 0) 242 | { 243 | o = cc.global; 244 | v = othis.Call(cc, o, ret, arglist); 245 | } 246 | else 247 | { 248 | thisArg = &arglist[0]; 249 | if(thisArg.isUndefinedOrNull()) 250 | o = cc.global; 251 | else 252 | o = thisArg.toObject(cc); 253 | v = othis.Call(cc, o, ret, arglist[1 .. $]); 254 | } 255 | return v; 256 | } 257 | 258 | /* ===================== Dfunction_prototype ==================== */ 259 | 260 | class DfunctionPrototype : Dfunction 261 | { 262 | this(CallContext* cc) 263 | { 264 | super(cc, 0, cc.tc.Dobject_prototype); 265 | 266 | uint attributes = DontEnum; 267 | 268 | classname = TEXT_Function; 269 | name = "prototype"; 270 | Put(cc, TEXT_constructor, cc.tc.Dfunction_constructor, attributes); 271 | 272 | static enum NativeFunctionData[] nfd = 273 | [ 274 | { TEXT_toString, &Dfunction_prototype_toString, 0 }, 275 | { TEXT_apply, &Dfunction_prototype_apply, 2 }, 276 | { TEXT_call, &Dfunction_prototype_call, 1 }, 277 | ]; 278 | 279 | DnativeFunction.initialize(this, cc, nfd, attributes); 280 | } 281 | 282 | override void *Call(CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 283 | { 284 | // ECMA v3 15.3.4 285 | // Accept any arguments and return "undefined" 286 | ret.putVundefined(); 287 | return null; 288 | } 289 | } 290 | 291 | 292 | /* ===================== Dfunction ==================== */ 293 | 294 | class Dfunction : Dobject 295 | { const (char)[] name; 296 | Dobject[] scopex; // Function object's scope chain per 13.2 step 7 297 | 298 | this(CallContext* cc, d_uint32 length) 299 | { 300 | this(cc, length, Dfunction.getPrototype(cc)); 301 | } 302 | 303 | this(CallContext* cc, d_uint32 length, Dobject prototype) 304 | { 305 | super(cc, prototype); 306 | classname = TEXT_Function; 307 | name = TEXT_Function; 308 | Put(cc, TEXT_length, length, DontDelete | DontEnum | ReadOnly); 309 | Put(cc, TEXT_arity, length, DontDelete | DontEnum | ReadOnly); 310 | } 311 | 312 | override immutable(char)[] getTypeof() 313 | { // ECMA 11.4.3 314 | return TEXT_function; 315 | } 316 | 317 | override string toString() 318 | { 319 | // Native overrides of this function replace Identifier with the actual name. 320 | // Don't need to do parameter list, though. 321 | immutable(char)[] s; 322 | 323 | s = std.string.format("function %s() { [native code] }", name); 324 | return s; 325 | } 326 | 327 | override void *HasInstance(CallContext* cc, Value* ret, Value* v) 328 | { 329 | // ECMA v3 15.3.5.3 330 | Dobject V; 331 | Value* w; 332 | Dobject o; 333 | 334 | if(v.isPrimitive()) 335 | goto Lfalse; 336 | V = v.toObject(cc); 337 | w = Get(TEXT_prototype); 338 | if(w.isPrimitive()) 339 | { 340 | ErrInfo errinfo; 341 | return RuntimeError(&errinfo, cc, errmsgtbl[ERR_MUST_BE_OBJECT], w.getType()); 342 | } 343 | o = w.toObject(cc); 344 | for(;; ) 345 | { 346 | V = V.internal_prototype; 347 | if(!V) 348 | goto Lfalse; 349 | if(o == V) 350 | goto Ltrue; 351 | } 352 | 353 | Ltrue: 354 | ret.putVboolean(true); 355 | return null; 356 | 357 | Lfalse: 358 | ret.putVboolean(false); 359 | return null; 360 | } 361 | 362 | static Dfunction isFunction(Value* v, CallContext* cc) 363 | { 364 | Dfunction r; 365 | Dobject o; 366 | 367 | r = null; 368 | if(!v.isPrimitive()) 369 | { 370 | o = v.toObject(cc); 371 | if(o.isClass(TEXT_Function)) 372 | r = cast(Dfunction)o; 373 | } 374 | return r; 375 | } 376 | 377 | 378 | static Dfunction getConstructor(CallContext* cc) 379 | { 380 | return cc.tc.Dfunction_constructor; 381 | } 382 | 383 | static Dobject getPrototype(CallContext* cc) 384 | { 385 | return cc.tc.Dfunction_prototype; 386 | } 387 | 388 | static void initialize(CallContext* cc) 389 | { 390 | cc.tc.Dfunction_constructor = new DfunctionConstructor(cc); 391 | cc.tc.Dfunction_prototype = new DfunctionPrototype(cc); 392 | 393 | cc.tc.Dfunction_constructor.Put(cc, TEXT_prototype, cc.tc.Dfunction_prototype, DontEnum | DontDelete | ReadOnly); 394 | 395 | cc.tc.Dfunction_constructor.internal_prototype = cc.tc.Dfunction_prototype; 396 | cc.tc.Dfunction_constructor.proptable.previous = cc.tc.Dfunction_prototype.proptable; 397 | } 398 | } 399 | -------------------------------------------------------------------------------- /engine/source/dmdscript/dmath.d: -------------------------------------------------------------------------------- 1 | /* Digital Mars DMDScript source code. 2 | * Copyright (c) 2000-2002 by Chromium Communications 3 | * D version Copyright (c) 2004-2010 by Digital Mars 4 | * Distributed under the Boost Software License, Version 1.0. 5 | * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | * written by Walter Bright 7 | * http://www.digitalmars.com 8 | * 9 | * D2 port by Dmitry Olshansky 10 | * 11 | * DMDScript is implemented in the D Programming Language, 12 | * http://www.digitalmars.com/d/ 13 | * 14 | * For a C++ implementation of DMDScript, including COM support, see 15 | * http://www.digitalmars.com/dscript/cppscript.html 16 | */ 17 | 18 | module dmdscript.dmath; 19 | 20 | import std.math; 21 | import std.random; 22 | 23 | import dmdscript.script; 24 | import dmdscript.value; 25 | import dmdscript.dobject; 26 | import dmdscript.dnative; 27 | import dmdscript.threadcontext; 28 | import dmdscript.text; 29 | import dmdscript.property; 30 | 31 | d_number math_helper(Value[] arglist, CallContext* cc) 32 | { 33 | Value *v; 34 | 35 | v = arglist.length ? &arglist[0] : &vundefined; 36 | return v.toNumber(cc); 37 | } 38 | 39 | void* Dmath_abs(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 40 | { 41 | // ECMA 15.8.2.1 42 | d_number result; 43 | 44 | result = fabs(math_helper(arglist, cc)); 45 | ret.putVnumber(result); 46 | return null; 47 | } 48 | 49 | void* Dmath_acos(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 50 | { 51 | // ECMA 15.8.2.2 52 | d_number result; 53 | 54 | result = acos(math_helper(arglist, cc)); 55 | ret.putVnumber(result); 56 | return null; 57 | } 58 | 59 | void* Dmath_asin(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 60 | { 61 | // ECMA 15.8.2.3 62 | d_number result; 63 | 64 | result = asin(math_helper(arglist, cc)); 65 | ret.putVnumber(result); 66 | return null; 67 | } 68 | 69 | void* Dmath_atan(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 70 | { 71 | // ECMA 15.8.2.4 72 | d_number result; 73 | 74 | result = atan(math_helper(arglist, cc)); 75 | ret.putVnumber(result); 76 | return null; 77 | } 78 | 79 | void* Dmath_atan2(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 80 | { 81 | // ECMA 15.8.2.5 82 | d_number n1; 83 | Value *v2; 84 | d_number result; 85 | 86 | n1 = math_helper(arglist, cc); 87 | v2 = (arglist.length >= 2) ? &arglist[1] : &vundefined; 88 | result = atan2(n1, v2.toNumber(cc)); 89 | ret.putVnumber(result); 90 | return null; 91 | } 92 | 93 | void* Dmath_ceil(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 94 | { 95 | // ECMA 15.8.2.6 96 | d_number result; 97 | 98 | result = ceil(math_helper(arglist, cc)); 99 | ret.putVnumber(result); 100 | return null; 101 | } 102 | 103 | void* Dmath_cos(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 104 | { 105 | // ECMA 15.8.2.7 106 | d_number result; 107 | 108 | result = cos(math_helper(arglist, cc)); 109 | ret.putVnumber(result); 110 | return null; 111 | } 112 | 113 | void* Dmath_exp(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 114 | { 115 | // ECMA 15.8.2.8 116 | d_number result; 117 | 118 | result = std.math.exp(math_helper(arglist, cc)); 119 | ret.putVnumber(result); 120 | return null; 121 | } 122 | 123 | void* Dmath_floor(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 124 | { 125 | // ECMA 15.8.2.9 126 | d_number result; 127 | 128 | result = std.math.floor(math_helper(arglist, cc)); 129 | ret.putVnumber(result); 130 | return null; 131 | } 132 | 133 | void* Dmath_log(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 134 | { 135 | // ECMA 15.8.2.10 136 | d_number result; 137 | 138 | result = log(math_helper(arglist, cc)); 139 | ret.putVnumber(result); 140 | return null; 141 | } 142 | 143 | void* Dmath_max(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 144 | { 145 | // ECMA v3 15.8.2.11 146 | d_number n; 147 | d_number result; 148 | uint a; 149 | 150 | result = -d_number.infinity; 151 | foreach(Value v; arglist) 152 | { 153 | n = v.toNumber(cc); 154 | if(isNaN(n)) 155 | { 156 | result = d_number.nan; 157 | break; 158 | } 159 | if(result == n) 160 | { 161 | // if n is +0 and result is -0, pick n 162 | if(n == 0 && !signbit(n)) 163 | result = n; 164 | } 165 | else if(n > result) 166 | result = n; 167 | } 168 | ret.putVnumber(result); 169 | return null; 170 | } 171 | 172 | void* Dmath_min(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 173 | { 174 | // ECMA v3 15.8.2.12 175 | d_number n; 176 | d_number result; 177 | uint a; 178 | 179 | result = d_number.infinity; 180 | foreach(Value v; arglist) 181 | { 182 | n = v.toNumber(cc); 183 | if(isNaN(n)) 184 | { 185 | result = d_number.nan; 186 | break; 187 | } 188 | if(result == n) 189 | { 190 | // if n is -0 and result is +0, pick n 191 | if(n == 0 && signbit(n)) 192 | result = n; 193 | } 194 | else if(n < result) 195 | result = n; 196 | } 197 | ret.putVnumber(result); 198 | return null; 199 | } 200 | 201 | void* Dmath_pow(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 202 | { 203 | // ECMA 15.8.2.13 204 | d_number n1; 205 | Value *v2; 206 | d_number result; 207 | 208 | n1 = math_helper(arglist, cc); 209 | v2 = (arglist.length >= 2) ? &arglist[1] : &vundefined; 210 | result = pow(n1, v2.toNumber(cc)); 211 | ret.putVnumber(result); 212 | return null; 213 | } 214 | 215 | void* Dmath_random(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 216 | { 217 | // ECMA 15.8.2.14 218 | // 0.0 <= result < 1.0 219 | d_number result; 220 | //+++ old random +++ 221 | version(none) 222 | { 223 | ulong x; 224 | 225 | // Only want 53 bits of precision 226 | x = (cast(ulong)std.random.rand() << 32) + std.random.rand(); 227 | //PRINTF("x = x%016llx\n",x); 228 | x &= 0xFFFFFFFFFFFFF800L; 229 | result = x * (1 / (0x100000000L * cast(double)0x100000000L)) 230 | + (1 / (0x200000000L * cast(double)0x100000000L)); 231 | 232 | // Experiments on linux show that this will never be exactly 233 | // 1.0, so is the assert() worth it? 234 | assert(result >= 0 && result < 1.0); 235 | } 236 | //+++ patched random +++ 237 | result = std.random.uniform(0.0, 1.0); 238 | assert(result >= 0 && result < 1.0); 239 | ret.putVnumber(result); 240 | return null; 241 | } 242 | 243 | void* Dmath_round(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 244 | { 245 | // ECMA 15.8.2.15 246 | d_number result; 247 | 248 | result = math_helper(arglist, cc); 249 | if(!isNaN(result)) 250 | result = copysign(std.math.floor(result + .5), result); 251 | ret.putVnumber(result); 252 | return null; 253 | } 254 | 255 | void* Dmath_sin(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 256 | { 257 | // ECMA 15.8.2.16 258 | d_number result; 259 | 260 | result = sin(math_helper(arglist, cc)); 261 | ret.putVnumber(result); 262 | return null; 263 | } 264 | 265 | void* Dmath_sqrt(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 266 | { 267 | // ECMA 15.8.2.17 268 | d_number result; 269 | 270 | result = sqrt(math_helper(arglist, cc)); 271 | ret.putVnumber(result); 272 | return null; 273 | } 274 | 275 | void* Dmath_tan(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 276 | { 277 | // ECMA 15.8.2.18 278 | d_number result; 279 | 280 | result = tan(math_helper(arglist, cc)); 281 | ret.putVnumber(result); 282 | return null; 283 | } 284 | 285 | /* ===================== Dmath ==================== */ 286 | 287 | class Dmath : Dobject 288 | { 289 | this(CallContext* cc) 290 | { 291 | super(cc, cc.tc.Dobject_prototype); 292 | 293 | //writef("Dmath::Dmath(%x)\n", this); 294 | uint attributes = DontEnum | DontDelete | ReadOnly; 295 | 296 | struct MathConst 297 | { d_string name; 298 | d_number value; } 299 | 300 | static enum MathConst[] table = 301 | [ 302 | { TEXT_E, std.math.E }, 303 | { TEXT_LN10, std.math.LN10 }, 304 | { TEXT_LN2, std.math.LN2 }, 305 | { TEXT_LOG2E, std.math.LOG2E }, 306 | { TEXT_LOG10E, std.math.LOG10E }, 307 | { TEXT_PI, std.math.PI }, 308 | { TEXT_SQRT1_2, std.math.SQRT1_2 }, 309 | { TEXT_SQRT2, std.math.SQRT2 }, 310 | ]; 311 | 312 | for(size_t u = 0; u < table.length; u++) 313 | { 314 | Value *v; 315 | 316 | v = Put(cc, table[u].name, table[u].value, attributes); 317 | //writef("Put(%s,%.5g) = %x\n", *table[u].name, table[u].value, v); 318 | } 319 | 320 | classname = TEXT_Math; 321 | 322 | static enum NativeFunctionData[] nfd = 323 | [ 324 | { TEXT_abs, &Dmath_abs, 1 }, 325 | { TEXT_acos, &Dmath_acos, 1 }, 326 | { TEXT_asin, &Dmath_asin, 1 }, 327 | { TEXT_atan, &Dmath_atan, 1 }, 328 | { TEXT_atan2, &Dmath_atan2, 2 }, 329 | { TEXT_ceil, &Dmath_ceil, 1 }, 330 | { TEXT_cos, &Dmath_cos, 1 }, 331 | { TEXT_exp, &Dmath_exp, 1 }, 332 | { TEXT_floor, &Dmath_floor, 1 }, 333 | { TEXT_log, &Dmath_log, 1 }, 334 | { TEXT_max, &Dmath_max, 2 }, 335 | { TEXT_min, &Dmath_min, 2 }, 336 | { TEXT_pow, &Dmath_pow, 2 }, 337 | { TEXT_random, &Dmath_random, 0 }, 338 | { TEXT_round, &Dmath_round, 1 }, 339 | { TEXT_sin, &Dmath_sin, 1 }, 340 | { TEXT_sqrt, &Dmath_sqrt, 1 }, 341 | { TEXT_tan, &Dmath_tan, 1 }, 342 | ]; 343 | 344 | DnativeFunction.initialize(this, cc, nfd, attributes); 345 | } 346 | 347 | static void initialize(CallContext* cc) 348 | { 349 | cc.tc.Dmath_object = new Dmath(cc); 350 | } 351 | } 352 | 353 | -------------------------------------------------------------------------------- /engine/source/dmdscript/dnative.d: -------------------------------------------------------------------------------- 1 | /* Digital Mars DMDScript source code. 2 | * Copyright (c) 2000-2002 by Chromium Communications 3 | * D version Copyright (c) 2004-2010 by Digital Mars 4 | * Distributed under the Boost Software License, Version 1.0. 5 | * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | * written by Walter Bright 7 | * http://www.digitalmars.com 8 | * 9 | * D2 port by Dmitry Olshansky 10 | * 11 | * DMDScript is implemented in the D Programming Language, 12 | * http://www.digitalmars.com/d/ 13 | * 14 | * For a C++ implementation of DMDScript, including COM support, see 15 | * http://www.digitalmars.com/dscript/cppscript.html 16 | */ 17 | 18 | 19 | module dmdscript.dnative; 20 | 21 | import dmdscript.script; 22 | import dmdscript.dobject; 23 | import dmdscript.dfunction; 24 | import dmdscript.value; 25 | 26 | /******************* DnativeFunction ****************************/ 27 | 28 | alias void *function(Dobject pthis, CallContext *cc, Dobject othis, Value* ret, Value[] arglist) PCall; 29 | 30 | struct NativeFunctionData 31 | { 32 | d_string string; 33 | PCall pcall; 34 | d_uint32 length; 35 | } 36 | 37 | class DnativeFunction : Dfunction 38 | { 39 | PCall pcall; 40 | 41 | this(CallContext* cc, PCall func, d_string name, d_uint32 length) 42 | { 43 | super(cc, length); 44 | this.name = name; 45 | pcall = func; 46 | } 47 | 48 | this(CallContext* cc, PCall func, d_string name, d_uint32 length, Dobject o) 49 | { 50 | super(cc, length, o); 51 | this.name = name; 52 | pcall = func; 53 | } 54 | 55 | override void* Call(CallContext *cc, Dobject othis, Value* ret, Value[] arglist) 56 | { 57 | return (*pcall)(this, cc, othis, ret, arglist); 58 | } 59 | 60 | /********************************* 61 | * Initalize table of native functions designed 62 | * to go in as properties of o. 63 | */ 64 | 65 | static void initialize(Dobject o, CallContext* cc, NativeFunctionData[] nfd, uint attributes) 66 | { 67 | Dobject f = Dfunction.getPrototype(cc); 68 | 69 | for(size_t i = 0; i < nfd.length; i++) 70 | { 71 | NativeFunctionData* n = &nfd[i]; 72 | 73 | o.Put(cc, n.string, 74 | new DnativeFunction(cc, n.pcall, n.string, n.length, f), 75 | attributes); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /engine/source/dmdscript/errmsgs.d: -------------------------------------------------------------------------------- 1 | // File generated by textgen.d 2 | // 3 | // *** ERROR MESSAGES *** 4 | // 5 | module dmdscript.errmsgs; 6 | enum 7 | { 8 | ERR_RUNTIME_PREFIX = 0, 9 | ERR_COM_NO_DEFAULT_VALUE = 1, 10 | ERR_COM_NO_CONSTRUCT_PROPERTY = 2, 11 | ERR_DISP_E_TYPEMISMATCH = 3, 12 | ERR_DISP_E_BADPARAMCOUNT = 4, 13 | ERR_COM_FUNCTION_ERROR = 5, 14 | ERR_COM_OBJECT_ERROR = 6, 15 | ERR_BAD_SWITCH = 7, 16 | ERR_UNDEFINED_LABEL = 8, 17 | ERR_BAD_C_COMMENT = 9, 18 | ERR_BAD_HTML_COMMENT = 10, 19 | ERR_BAD_CHAR_C = 11, 20 | ERR_BAD_CHAR_X = 12, 21 | ERR_BAD_HEX_SEQUENCE = 13, 22 | ERR_UNDEFINED_ESC_SEQUENCE = 14, 23 | ERR_STRING_NO_END_QUOTE = 15, 24 | ERR_UNTERMINATED_STRING = 16, 25 | ERR_BAD_U_SEQUENCE = 17, 26 | ERR_UNRECOGNIZED_N_LITERAL = 18, 27 | ERR_FPL_EXPECTED_IDENTIFIER = 19, 28 | ERR_FPL_EXPECTED_COMMA = 20, 29 | ERR_EXPECTED_IDENTIFIER = 21, 30 | ERR_EXPECTED_GENERIC = 22, 31 | ERR_EXPECTED_IDENTIFIER_PARAM = 23, 32 | ERR_EXPECTED_IDENTIFIER_2PARAM = 24, 33 | ERR_UNTERMINATED_BLOCK = 25, 34 | ERR_TOO_MANY_IN_VARS = 26, 35 | ERR_IN_EXPECTED = 27, 36 | ERR_GOTO_LABEL_EXPECTED = 28, 37 | ERR_TRY_CATCH_EXPECTED = 29, 38 | ERR_STATEMENT_EXPECTED = 30, 39 | ERR_EXPECTED_EXPRESSION = 31, 40 | ERR_OBJ_LITERAL_IN_INITIALIZER = 32, 41 | ERR_LABEL_ALREADY_DEFINED = 33, 42 | ERR_SWITCH_REDUNDANT_CASE = 34, 43 | ERR_MISPLACED_SWITCH_CASE = 35, 44 | ERR_SWITCH_REDUNDANT_DEFAULT = 36, 45 | ERR_MISPLACED_SWITCH_DEFAULT = 37, 46 | ERR_INIT_NOT_EXPRESSION = 38, 47 | ERR_MISPLACED_BREAK = 39, 48 | ERR_MISPLACED_CONTINUE = 40, 49 | ERR_UNDEFINED_STATEMENT_LABEL = 41, 50 | ERR_GOTO_INTO_WITH = 42, 51 | ERR_MISPLACED_RETURN = 43, 52 | ERR_NO_THROW_EXPRESSION = 44, 53 | ERR_UNDEFINED_OBJECT_SYMBOL = 45, 54 | ERR_FUNCTION_WANTS_NUMBER = 46, 55 | ERR_FUNCTION_WANTS_STRING = 47, 56 | ERR_FUNCTION_WANTS_DATE = 48, 57 | ERR_UNDEFINED_NO_CALL2 = 49, 58 | ERR_UNDEFINED_NO_CALL3 = 50, 59 | ERR_FUNCTION_WANTS_BOOL = 51, 60 | ERR_ARRAY_LEN_OUT_OF_BOUNDS = 52, 61 | ERR_VALUE_OUT_OF_RANGE = 53, 62 | ERR_TYPE_ERROR = 54, 63 | ERR_REGEXP_COMPILE = 55, 64 | ERR_NOT_TRANSFERRABLE = 56, 65 | ERR_CANNOT_CONVERT_TO_OBJECT2 = 57, 66 | ERR_CANNOT_CONVERT_TO_OBJECT3 = 58, 67 | ERR_CANNOT_CONVERT_TO_OBJECT4 = 59, 68 | ERR_CANNOT_ASSIGN_TO = 60, 69 | ERR_CANNOT_ASSIGN = 61, 70 | ERR_CANNOT_ASSIGN_TO2 = 62, 71 | ERR_FUNCTION_NOT_LVALUE = 63, 72 | ERR_RHS_MUST_BE_OBJECT = 64, 73 | ERR_CANNOT_PUT_TO_PRIMITIVE = 65, 74 | ERR_CANNOT_PUT_INDEX_TO_PRIMITIVE = 66, 75 | ERR_OBJECT_CANNOT_BE_PRIMITIVE = 67, 76 | ERR_CANNOT_GET_FROM_PRIMITIVE = 68, 77 | ERR_CANNOT_GET_INDEX_FROM_PRIMITIVE = 69, 78 | ERR_PRIMITIVE_NO_CONSTRUCT = 70, 79 | ERR_PRIMITIVE_NO_CALL = 71, 80 | ERR_FOR_IN_MUST_BE_OBJECT = 72, 81 | ERR_ASSERT = 73, 82 | ERR_OBJECT_NO_CALL = 74, 83 | ERR_S_S = 75, 84 | ERR_NO_DEFAULT_PUT = 76, 85 | ERR_S_NO_CONSTRUCT = 77, 86 | ERR_S_NO_CALL = 78, 87 | ERR_S_NO_INSTANCE = 79, 88 | ERR_LENGTH_INT = 80, 89 | ERR_TLS_NOT_TRANSFERRABLE = 81, 90 | ERR_TS_NOT_TRANSFERRABLE = 82, 91 | ERR_ARRAY_ARGS = 83, 92 | ERR_MUST_BE_OBJECT = 84, 93 | ERR_VBARRAY_EXPECTED = 85, 94 | ERR_VBARRAY_SUBSCRIPT = 86, 95 | ERR_ACTIVEX = 87, 96 | ERR_NO_PROPERTY = 88, 97 | ERR_PUT_FAILED = 89, 98 | ERR_GET_FAILED = 90, 99 | ERR_NOT_COLLECTION = 91, 100 | ERR_NOT_VALID_UTF = 92, 101 | ERR_UNDEFINED_VAR = 93, 102 | ERR_CANT_BREAK_INTERNAL = 94, 103 | ERR_E_UNEXPECTED = 95, 104 | }; 105 | // *** ERROR MESSAGES *** 106 | // 107 | immutable string[] errmsgtbl = [ 108 | "DMDScript fatal runtime error: ", 109 | "No default value for COM object", 110 | "%s does not have a [[Construct]] property", 111 | "argument type mismatch for %s", 112 | "wrong number of arguments for %s", 113 | "%s Invoke() fails with COM error %x", 114 | "Dcomobject: %s.%s fails with COM error %x", 115 | "unrecognized switch '%s'", 116 | "undefined label '%s' in function '%s'", 117 | "unterminated /* */ comment", 118 | "